1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  */ /*!
26  * \file  es31cTextureStorageMultisampleDependenciesTests.cpp
27  * \brief Implements conformance tests that verify dependencies of
28  *        multisample textures on other parts of core ES3.1 API
29  *        (ES3.1 only)
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "es31cTextureStorageMultisampleDependenciesTests.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuRenderTarget.hpp"
38 #include "tcuTestLog.hpp"
39 
40 #include <cmath>
41 #include <memory.h>
42 #include <string>
43 #include <vector>
44 
45 namespace glcts
46 {
47 /** Constructor.
48  *
49  *  @param context CTS context handle.
50  **/
MultisampleTextureDependenciesFBOIncompleteness1Test(Context & context)51 MultisampleTextureDependenciesFBOIncompleteness1Test::MultisampleTextureDependenciesFBOIncompleteness1Test(
52     Context &context)
53     : TestCase(context, "fbo_with_attachments_of_varying_amount_of_samples",
54                "FBOs with multisample texture attachments, whose amount"
55                " of samples differs between attachments, should be "
56                "considered incomplete")
57     , fbo_id(0)
58     , to_id_multisample_2d_array(0)
59 {
60     memset(to_ids_multisample_2d, 0, sizeof(to_ids_multisample_2d));
61 }
62 
63 /** Deinitializes ES objects created during test execution */
deinit()64 void MultisampleTextureDependenciesFBOIncompleteness1Test::deinit()
65 {
66     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
67 
68     if (fbo_id != 0)
69     {
70         gl.deleteFramebuffers(1, &fbo_id);
71 
72         fbo_id = 0;
73     }
74 
75     if (to_ids_multisample_2d[0] != 0)
76     {
77         gl.deleteTextures(1, to_ids_multisample_2d + 0);
78 
79         to_ids_multisample_2d[0] = 0;
80     }
81 
82     if (to_ids_multisample_2d[1] != 0)
83     {
84         gl.deleteTextures(1, to_ids_multisample_2d + 1);
85 
86         to_ids_multisample_2d[1] = 0;
87     }
88 
89     if (to_id_multisample_2d_array != 0)
90     {
91         gl.deleteTextures(1, &to_id_multisample_2d_array);
92 
93         to_id_multisample_2d_array = 0;
94     }
95 
96     /* Call base class' deinit() */
97     TestCase::deinit();
98 }
99 
100 /** Executes test iteration.
101  *
102  *  @return Returns STOP when test has finished executing.
103  */
iterate()104 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness1Test::iterate()
105 {
106     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
107     bool are_2d_ms_array_tos_supported =
108         m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
109 
110     /* Set up texture objects */
111     gl.genTextures(1, to_ids_multisample_2d);
112 
113     if (are_2d_ms_array_tos_supported)
114     {
115         gl.genTextures(1, &to_id_multisample_2d_array);
116         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
117     }
118     else
119     {
120         gl.genTextures(1, to_ids_multisample_2d + 1);
121     }
122 
123     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture objects");
124 
125     /* Query possible sample count values for both texture targets
126      and format used in test */
127     glw::GLint num_sample_counts_2dms   = 1;
128     glw::GLint num_sample_counts_2dms_a = 1;
129 
130     gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &num_sample_counts_2dms);
131 
132     if (are_2d_ms_array_tos_supported)
133     {
134         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1,
135                                &num_sample_counts_2dms_a);
136     }
137 
138     std::vector<glw::GLint> sample_counts_2dms(num_sample_counts_2dms);
139     std::vector<glw::GLint> sample_counts_2dms_a(num_sample_counts_2dms_a);
140 
141     gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, num_sample_counts_2dms,
142                            &sample_counts_2dms[0]);
143 
144     if (are_2d_ms_array_tos_supported)
145     {
146         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, num_sample_counts_2dms_a,
147                                &sample_counts_2dms_a[0]);
148     }
149 
150     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set query internal formats");
151 
152     /* This will store actual sample counts to be used in test */
153     glw::GLint samples_attachment_1 = 0;
154     glw::GLint samples_attachment_2 = 0;
155 
156     /* Choose two different sample counts, supported by implementation */
157     if (are_2d_ms_array_tos_supported)
158     {
159         for (glw::GLint i_2dms = 0; i_2dms < num_sample_counts_2dms; i_2dms++)
160         {
161             for (glw::GLint i_2dms_a = 0; i_2dms_a < num_sample_counts_2dms_a; i_2dms_a++)
162             {
163                 if (sample_counts_2dms[i_2dms] != sample_counts_2dms_a[i_2dms_a] && sample_counts_2dms[i_2dms] != 1 &&
164                     sample_counts_2dms_a[i_2dms_a] != 1)
165                 {
166                     /* found two differing non-1 sample counts ! */
167                     samples_attachment_1 = sample_counts_2dms[i_2dms];
168                     samples_attachment_2 = sample_counts_2dms_a[i_2dms_a];
169                 }
170             }
171         }
172     } /* if (are_2d_ms_array_tos_supported) */
173     else
174     {
175         for (glw::GLuint index = 1; index < sample_counts_2dms.size(); ++index)
176         {
177             if (sample_counts_2dms[index - 1] != 1 && sample_counts_2dms[index] != 1 &&
178                 sample_counts_2dms[index - 1] != sample_counts_2dms[index])
179             {
180                 samples_attachment_1 = sample_counts_2dms[index - 1];
181                 samples_attachment_2 = sample_counts_2dms[index];
182 
183                 break;
184             }
185         }
186     }
187 
188     if (samples_attachment_1 == 0 || samples_attachment_2 == 0)
189     {
190         /* It may be the case implementation support only one
191          sample count on both targets with used format.
192 
193          In such case cannot perform the test - cannot make
194          FBO incomplete due to sample count mismatch
195          */
196         m_testCtx.setTestResult(
197             QP_TEST_RESULT_NOT_SUPPORTED,
198             "Can't test incomplete FBO due to mismatch sample count: only 1 sample count available");
199 
200         return STOP;
201     }
202 
203     for (int n_texture_2d = 0; n_texture_2d < (are_2d_ms_array_tos_supported ? 1 : 2); ++n_texture_2d)
204     {
205         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_ids_multisample_2d[n_texture_2d]);
206         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
207 
208         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
209                                    (n_texture_2d == 0) ? samples_attachment_1 : samples_attachment_2, GL_RGBA8,
210                                    2,         /* width */
211                                    2,         /* height */
212                                    GL_FALSE); /* fixedsamplelocations */
213 
214         GLU_EXPECT_NO_ERROR(gl.getError(),
215                             "glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
216     }
217 
218     if (are_2d_ms_array_tos_supported)
219     {
220         gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samples_attachment_2, /* samples */
221                                    GL_RGBA8, 2,                                               /* width */
222                                    2,                                                         /* height */
223                                    2,                                                         /* depth */
224                                    GL_FALSE);                                                 /* fixedsamplelocations */
225 
226         GLU_EXPECT_NO_ERROR(
227             gl.getError(),
228             "gltexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target");
229     }
230 
231     /* Set up a framebuffer object */
232     gl.genFramebuffers(1, &fbo_id);
233     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
234 
235     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
236 
237     /* Set up FBO attachments */
238     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
239                             to_ids_multisample_2d[0], 0); /* level */
240 
241     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up zeroth color attachment");
242 
243     if (are_2d_ms_array_tos_supported)
244     {
245         gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_multisample_2d_array, 0, /* level */
246                                    0);                                                                       /* layer */
247     }
248     else
249     {
250         gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
251                                 to_ids_multisample_2d[1], 0); /* level */
252     }
253 
254     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first color attachment");
255 
256     /* Make sure the draw framebuffer is considered incomplete */
257     glw::GLenum fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
258 
259     if (fbo_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
260     {
261         m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
262                            << "as opposed to expected status: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"
263                            << tcu::TestLog::EndMessage;
264 
265         TCU_FAIL("Invalid FBO completeness status reported.");
266     }
267 
268     /* All done */
269     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
270 
271     return STOP;
272 }
273 
274 /** Constructor.
275  *
276  *  @param context CTS context handle.
277  **/
MultisampleTextureDependenciesFBOIncompleteness2Test(Context & context)278 MultisampleTextureDependenciesFBOIncompleteness2Test::MultisampleTextureDependenciesFBOIncompleteness2Test(
279     Context &context)
280     : TestCase(context, "fbo_with_single_and_multisample_attachments",
281                "FBOs with multisample texture and normal 2D texture attachments "
282                "should be considered incomplete")
283     , fbo_id(0)
284     , to_id_2d(0)
285     , to_id_multisample_2d(0)
286     , to_id_multisample_2d_array(0)
287 {
288     /* Left blank on purpose */
289 }
290 
291 /** Deinitializes ES objects created during test execution */
deinit()292 void MultisampleTextureDependenciesFBOIncompleteness2Test::deinit()
293 {
294     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
295 
296     if (fbo_id != 0)
297     {
298         gl.deleteFramebuffers(1, &fbo_id);
299 
300         fbo_id = 0;
301     }
302 
303     if (to_id_2d != 0)
304     {
305         gl.deleteTextures(1, &to_id_2d);
306 
307         to_id_2d = 0;
308     }
309 
310     if (to_id_multisample_2d != 0)
311     {
312         gl.deleteTextures(1, &to_id_multisample_2d);
313 
314         to_id_multisample_2d = 0;
315     }
316 
317     if (to_id_multisample_2d_array != 0)
318     {
319         gl.deleteTextures(1, &to_id_multisample_2d_array);
320 
321         to_id_multisample_2d_array = 0;
322     }
323 
324     /* Call base class' deinit() */
325     TestCase::deinit();
326 }
327 
328 /** Executes test iteration.
329  *
330  *  @return Returns STOP when test has finished executing.
331  */
iterate()332 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness2Test::iterate()
333 {
334     bool are_2d_ms_array_tos_supported =
335         m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
336     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
337 
338     /* Set up texture objects */
339     gl.genTextures(1, &to_id_2d);
340     gl.genTextures(1, &to_id_multisample_2d);
341 
342     if (are_2d_ms_array_tos_supported)
343     {
344         gl.genTextures(1, &to_id_multisample_2d_array);
345     }
346 
347     gl.bindTexture(GL_TEXTURE_2D, to_id_2d);
348     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
349 
350     if (are_2d_ms_array_tos_supported)
351     {
352         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
353     }
354 
355     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture objects");
356 
357     gl.texImage2D(GL_TEXTURE_2D, 0, /* level */
358                   GL_RGB565, 2,     /* width */
359                   2,                /* height */
360                   0,                /* border */
361                   GL_RGB,           /* format */
362                   GL_UNSIGNED_BYTE, /* type */
363                   NULL);            /* pixels */
364 
365     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed for GL_TEXTURE_2D texture target");
366 
367     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
368                                GL_RGB565, 2,                 /* width */
369                                2,                            /* height */
370                                GL_FALSE);                    /* fixedsamplelocations */
371 
372     GLU_EXPECT_NO_ERROR(gl.getError(),
373                         "glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
374 
375     if (are_2d_ms_array_tos_supported)
376     {
377         gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, /* samples */
378                                    GL_RGB565, 2,                           /* width */
379                                    2,                                      /* height */
380                                    2,                                      /* depth */
381                                    GL_FALSE);                              /* fixedsamplelocations */
382 
383         GLU_EXPECT_NO_ERROR(
384             gl.getError(),
385             "gltexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target");
386     }
387 
388     /* Set up a framebuffer object */
389     gl.genFramebuffers(1, &fbo_id);
390     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
391 
392     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
393 
394     /* Set up FBO attachments */
395     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, to_id_2d, 0); /* level */
396 
397     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up zeroth color attachment");
398 
399     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d,
400                             0); /* level */
401 
402     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first color attachment");
403 
404     /* Make sure the draw framebuffer is considered incomplete */
405     glw::GLenum fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
406 
407     if (fbo_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
408     {
409         m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
410                            << "as opposed to expected status: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"
411                            << tcu::TestLog::EndMessage;
412 
413         TCU_FAIL("Invalid FBO completeness status reported.");
414     }
415 
416     /* Detach the first color attachment */
417     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, 0, /* texture */
418                             0);                                                                      /* level */
419 
420     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not detach first color attachment from the draw FBO");
421 
422     /* Verify the FBO is now considered complete */
423     fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
424 
425     if (fbo_status != GL_FRAMEBUFFER_COMPLETE)
426     {
427         m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
428                            << "as opposed to expected status: GL_FRAMEBUFFER_COMPLETE" << tcu::TestLog::EndMessage;
429 
430         TCU_FAIL("Invalid FBO completeness status reported.");
431     }
432 
433     if (are_2d_ms_array_tos_supported)
434     {
435         /* Attach the arrayed multisample texture object */
436         gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_multisample_2d_array, 0, /* level */
437                                    0);                                                                       /* layer */
438 
439         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first color attachment");
440 
441         /* Make sure the draw framebuffer is considered incomplete */
442         fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
443 
444         if (fbo_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
445         {
446             m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
447                                << "as opposed to expected status: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"
448                                << tcu::TestLog::EndMessage;
449 
450             TCU_FAIL("Invalid FBO completeness status reported.");
451         }
452     }
453 
454     /* All done */
455     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
456 
457     return STOP;
458 }
459 
460 /** Constructor.
461  *
462  *  @param context CTS context handle.
463  **/
MultisampleTextureDependenciesFBOIncompleteness3Test(Context & context)464 MultisampleTextureDependenciesFBOIncompleteness3Test::MultisampleTextureDependenciesFBOIncompleteness3Test(
465     Context &context)
466     : TestCase(context, "fbo_with_fixed_and_varying_sample_locations_attachments",
467                "FBOs with multisample texture attachments of different fixed "
468                "sample location settings should be considered incomplete")
469     , fbo_id(0)
470     , to_id_2d_multisample_color_1(0)
471     , to_id_2d_multisample_color_2(0)
472     , to_id_2d_multisample_depth(0)
473     , to_id_2d_multisample_depth_stencil(0)
474 {
475     /* Left blank on purpose */
476 }
477 
478 /** Deinitializes ES objects created during test execution */
deinit()479 void MultisampleTextureDependenciesFBOIncompleteness3Test::deinit()
480 {
481     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
482 
483     if (fbo_id != 0)
484     {
485         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
486         gl.deleteFramebuffers(1, &fbo_id);
487 
488         fbo_id = 0;
489     }
490 
491     if (to_id_2d_multisample_color_1 != 0)
492     {
493         gl.deleteTextures(1, &to_id_2d_multisample_color_1);
494 
495         to_id_2d_multisample_color_1 = 0;
496     }
497 
498     if (to_id_2d_multisample_color_2 != 0)
499     {
500         gl.deleteTextures(1, &to_id_2d_multisample_color_2);
501 
502         to_id_2d_multisample_color_2 = 0;
503     }
504 
505     if (to_id_2d_multisample_depth != 0)
506     {
507         gl.deleteTextures(1, &to_id_2d_multisample_depth);
508 
509         to_id_2d_multisample_depth = 0;
510     }
511 
512     if (to_id_2d_multisample_depth_stencil != 0)
513     {
514         gl.deleteTextures(1, &to_id_2d_multisample_depth_stencil);
515 
516         to_id_2d_multisample_depth_stencil = 0;
517     }
518 
519     /* Call base class' deinit() */
520     TestCase::deinit();
521 }
522 
523 /** Executes test iteration.
524  *
525  *  @return Returns STOP when test has finished executing.
526  */
iterate()527 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness3Test::iterate()
528 {
529     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
530 
531     /* Only execute if GL_MAX_SAMPLES pname value >= 2 */
532     glw::GLint gl_max_samples_value = 0;
533 
534     gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
535     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() generated an error for GL_MAX_SAMPLES pname");
536 
537     if (gl_max_samples_value < 2)
538     {
539         throw tcu::NotSupportedError("GL_MAX_SAMPLES pname value < 2, skipping");
540     }
541 
542     /* Only execute if GL_RGBA8, GL_DEPTH_COMPONENT16, GL_DEPTH24_STENCIL8 internalformats
543      * can be rendered to with at least 2 samples per fragment.
544      */
545     glw::GLint depth_component16_internalformat_max_samples = 0;
546     glw::GLint depth24_stencil8_internalformat_max_samples  = 0;
547     glw::GLint rgba8_internalformat_max_samples             = 0;
548 
549     gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH_COMPONENT16, GL_SAMPLES, 1, /* bufSize */
550                            &depth_component16_internalformat_max_samples);
551     gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH24_STENCIL8, GL_SAMPLES, 1, /* bufSize */
552                            &depth24_stencil8_internalformat_max_samples);
553     gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, 1, /* bufSize */
554                            &rgba8_internalformat_max_samples);
555 
556     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for at least one GL_SAMPLES query");
557 
558     if (depth_component16_internalformat_max_samples < 2)
559     {
560         throw tcu::NotSupportedError("GL_SAMPLES is lower than 2 for GL_DEPTH_COMPONENT16 internalformat");
561     }
562 
563     if (depth24_stencil8_internalformat_max_samples < 2)
564     {
565         throw tcu::NotSupportedError("GL_SAMPLES is lower than 2 for GL_DEPTH24_STENCIL8 internalformat");
566     }
567 
568     if (rgba8_internalformat_max_samples < 2)
569     {
570         throw tcu::NotSupportedError("GL_SAMPLES is lower than 2 for GL_RGBA8 internalformat");
571     }
572 
573     /* Set up texture objects */
574     gl.genTextures(1, &to_id_2d_multisample_color_1);
575     gl.genTextures(1, &to_id_2d_multisample_color_2);
576     gl.genTextures(1, &to_id_2d_multisample_depth);
577     gl.genTextures(1, &to_id_2d_multisample_depth_stencil);
578 
579     GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
580 
581     /* Set up a framebuffer object */
582     gl.genFramebuffers(1, &fbo_id);
583     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
584 
585     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
586 
587     /* Set up first GL_RGBA8 multisample texture storage */
588     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_color_1);
589     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
590                                GL_RGBA8, 2,                  /* width */
591                                2,                            /* height */
592                                GL_FALSE);                    /* fixedsamplelocations */
593 
594     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first GL_RGBA8 multisample texture storage.");
595 
596     /* Set up second GL_RGBA8 multisample texture storage */
597     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_color_2);
598     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
599                                GL_RGBA8, 2,                  /* width */
600                                2,                            /* height */
601                                GL_TRUE);                     /* fixedsamplelocations */
602 
603     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up second GL_RGBA8 multisample texture storage.");
604 
605     /* Set up GL_DEPTH_COMPONENT16 multisample texture storage */
606     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_depth);
607     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
608                                GL_DEPTH_COMPONENT16, 2,      /* width */
609                                2,                            /* height */
610                                GL_TRUE);                     /* fixedsamplelocations */
611 
612     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up GL_DEPTH_COMPONENT16 multisample texture storage.");
613 
614     /* Set up GL_DEPTH24_STENCIL8 multisample texture storage */
615     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_depth_stencil);
616     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
617                                GL_DEPTH24_STENCIL8, 2,       /* width */
618                                2,                            /* height */
619                                GL_TRUE);                     /* fixedsamplelocations */
620 
621     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up GL_DEPTH24_STENCIL8 multisample texture storage.");
622 
623     /* Set up FBO's zeroth color attachment */
624     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
625                             to_id_2d_multisample_color_1, 0); /* level */
626 
627     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
628                             to_id_2d_multisample_color_2, 0); /* level */
629 
630     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up FBO color attachments");
631 
632     /* FBO should now be considered incomplete */
633     glw::GLenum fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
634 
635     if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
636     {
637         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
638                            << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
639 
640         TCU_FAIL("Invalid FBO completeness status reported.");
641     }
642 
643     /* Detach the first color attachment */
644     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, /* texture */
645                             0);                                                          /* level */
646 
647     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not detach FBO's first color attachment");
648 
649     /* Configure FBO's depth attachment */
650     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
651                             to_id_2d_multisample_depth, 0); /* level */
652 
653     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not configure FBO's depth attachment");
654 
655     /* FBO should now be considered incomplete */
656     fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
657 
658     if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
659     {
660         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
661                            << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
662 
663         TCU_FAIL("Invalid FBO completeness status reported.");
664     }
665 
666     /* Detach depth attachment */
667     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, /* texture */
668                             0);                                                         /* level */
669 
670     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not detach FBO's depth attachment");
671 
672     /* Configure FBO's depth+stencil attachment */
673     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
674                             to_id_2d_multisample_depth_stencil, 0); /* level */
675 
676     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not configure FBO's depth+stencil attachment");
677 
678     /* FBO should now be considered incomplete */
679     fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
680 
681     if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
682     {
683         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
684                            << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
685 
686         TCU_FAIL("Invalid FBO completeness status reported.");
687     }
688 
689     /* All done */
690     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
691 
692     return STOP;
693 }
694 
695 /** Constructor.
696  *
697  *  @param context CTS context handle.
698  **/
MultisampleTextureDependenciesFBOIncompleteness4Test(Context & context)699 MultisampleTextureDependenciesFBOIncompleteness4Test::MultisampleTextureDependenciesFBOIncompleteness4Test(
700     Context &context)
701     : TestCase(context, "fbo_with_different_fixedsamplelocations_texture_and_renderbuffer_attachments",
702                "FBOs with multisample texture attachments of different 'fixed sample location' "
703                "settings and with multisampled renderbuffers (of the same amount of samples)"
704                "should be considered incomplete")
705     , fbo_id(0)
706     , rbo_id(0)
707     , to_id_2d_multisample_array_color(0)
708     , to_id_2d_multisample_color(0)
709 {
710     /* Left blank on purpose */
711 }
712 
713 /** Deinitializes ES objects created during test execution */
deinit()714 void MultisampleTextureDependenciesFBOIncompleteness4Test::deinit()
715 {
716     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
717 
718     if (fbo_id != 0)
719     {
720         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
721         gl.deleteFramebuffers(1, &fbo_id);
722 
723         fbo_id = 0;
724     }
725 
726     if (rbo_id != 0)
727     {
728         gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
729         gl.deleteRenderbuffers(1, &rbo_id);
730     }
731 
732     if (to_id_2d_multisample_color != 0)
733     {
734         gl.deleteTextures(1, &to_id_2d_multisample_color);
735 
736         to_id_2d_multisample_color = 0;
737     }
738 
739     if (to_id_2d_multisample_array_color != 0)
740     {
741         gl.deleteTextures(1, &to_id_2d_multisample_array_color);
742 
743         to_id_2d_multisample_array_color = 0;
744     }
745 
746     /* Call base class' deinit() */
747     TestCase::deinit();
748 }
749 
750 /** Executes test iteration.
751  *
752  *  @return Returns STOP when test has finished executing.
753  */
iterate()754 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness4Test::iterate()
755 {
756     bool are_2d_ms_array_tos_supported =
757         m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
758     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
759 
760     /* Only execute if GL_MAX_SAMPLES pname value >= 3 */
761     glw::GLint gl_max_samples_value = 0;
762 
763     gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
764     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() generated an error for GL_MAX_SAMPLES pname");
765 
766     if (gl_max_samples_value < 3)
767     {
768         throw tcu::NotSupportedError("GL_MAX_SAMPLES pname value < 3, skipping");
769     }
770 
771     /* Set up texture objects */
772     if (are_2d_ms_array_tos_supported)
773     {
774         gl.genTextures(1, &to_id_2d_multisample_array_color);
775     }
776 
777     gl.genTextures(1, &to_id_2d_multisample_color);
778 
779     GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
780 
781     /* Set up a framebuffer object */
782     gl.genFramebuffers(1, &fbo_id);
783     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
784 
785     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
786 
787     /* Set up a renderbuffer object */
788     gl.genRenderbuffers(1, &rbo_id);
789     gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
790 
791     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
792 
793     /* Set up first GL_RGBA8 multisample texture storage */
794     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_color);
795     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
796                                GL_RGBA8, 2,                  /* width */
797                                2,                            /* height */
798                                GL_FALSE);                    /* fixedsamplelocations */
799 
800     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up GL_RGBA8 multisample texture storage.");
801 
802     if (are_2d_ms_array_tos_supported)
803     {
804         /* Set up second GL_RGBA8 multisample texture storage */
805         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_2d_multisample_array_color);
806         gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, /* samples */
807                                    GL_RGBA8, 2,                            /* width */
808                                    2,                                      /* height */
809                                    2,                                      /* depth */
810                                    GL_TRUE);                               /* fixedsamplelocations */
811 
812         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up second GL_RGBA8 multisample texture storage.");
813     }
814 
815     /* Set up renderbuffer storage */
816     gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 3, /* samples */
817                                       GL_RGBA8, 2,        /* width */
818                                       2);                 /* height */
819 
820     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up renderbuffer storage.");
821 
822     /* Set up FBO's zeroth color attachment */
823     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
824                             to_id_2d_multisample_color, 0); /* level */
825 
826     /* Make sure FBO is considered complete at this point */
827     glw::GLenum fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
828 
829     if (fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
830     {
831         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
832                            << " expected: GL_FRAMEBUFFER_COMPLETE" << tcu::TestLog::EndMessage;
833 
834         TCU_FAIL("Invalid FBO completeness status reported.");
835     }
836 
837     if (are_2d_ms_array_tos_supported)
838     {
839         /* Set up FBO's first color attachment */
840         gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_2d_multisample_array_color,
841                                    0,  /* level */
842                                    0); /* layer */
843 
844         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up FBO color attachments");
845 
846         /* FBO should now be considered incomplete */
847         fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
848 
849         if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
850         {
851             m_testCtx.getLog() << tcu::TestLog::Message
852                                << "Invalid FBO completeness status reported:" << fbo_completeness
853                                << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
854 
855             TCU_FAIL("Invalid FBO completeness status reported.");
856         }
857     }
858 
859     /* Set up FBO's second color attachment */
860     gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rbo_id);
861 
862     /* FBO should now be considered incomplete */
863     fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
864 
865     if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
866     {
867         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
868                            << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
869 
870         TCU_FAIL("Invalid FBO completeness status reported.");
871     }
872 
873     /* All done */
874     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
875 
876     return STOP;
877 }
878 
879 /** Constructor.
880  *
881  *  @param context CTS context handle.
882  **/
MultisampleTextureDependenciesFBOIncompleteness5Test(Context & context)883 MultisampleTextureDependenciesFBOIncompleteness5Test::MultisampleTextureDependenciesFBOIncompleteness5Test(
884     Context &context)
885     : TestCase(context, "fbo_with_renderbuffer_and_multisample_texture_attachments_with_different_number_of_samples",
886                "FBOs with renderbuffer and multisample texture attachments, where amount "
887                "of samples used for multisample texture attachments differs from the "
888                "amount of samples used for renderbuffer attachments, should be considered "
889                "incomplete")
890     , fbo_id(0)
891     , rbo_id(0)
892     , to_id_multisample_2d(0)
893     , to_id_multisample_2d_array(0)
894 {
895     /* Left blank on purpose */
896 }
897 
898 /** Deinitializes ES objects created during test execution */
deinit()899 void MultisampleTextureDependenciesFBOIncompleteness5Test::deinit()
900 {
901     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
902 
903     if (fbo_id != 0)
904     {
905         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
906         gl.deleteFramebuffers(1, &fbo_id);
907 
908         fbo_id = 0;
909     }
910 
911     if (rbo_id != 0)
912     {
913         gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
914         gl.deleteRenderbuffers(1, &rbo_id);
915     }
916 
917     if (to_id_multisample_2d != 0)
918     {
919         gl.deleteTextures(1, &to_id_multisample_2d);
920 
921         to_id_multisample_2d = 0;
922     }
923 
924     if (to_id_multisample_2d_array != 0)
925     {
926         gl.deleteTextures(1, &to_id_multisample_2d_array);
927 
928         to_id_multisample_2d_array = 0;
929     }
930 
931     /* Call base class' deinit() */
932     TestCase::deinit();
933 }
934 
935 /** Executes test iteration.
936  *
937  *  @return Returns STOP when test has finished executing.
938  */
iterate()939 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness5Test::iterate()
940 {
941     bool are_multisample_2d_array_tos_supported =
942         m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
943     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
944 
945     /* Retrieve GL_MAX_INTEGER_SAMPLES and GL_MAX_SAMPLES values */
946     glw::GLint gl_max_integer_samples_value = 0;
947     glw::GLint gl_max_samples_value         = 0;
948 
949     gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &gl_max_integer_samples_value);
950     gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
951     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() generated an error");
952 
953     /* Set up texture objects */
954     gl.genTextures(1, &to_id_multisample_2d);
955 
956     if (are_multisample_2d_array_tos_supported)
957     {
958         gl.genTextures(1, &to_id_multisample_2d_array);
959     }
960 
961     GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
962 
963     /* Set up a framebuffer object */
964     gl.genFramebuffers(1, &fbo_id);
965     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
966 
967     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
968 
969     /* Set up a renderbuffer object */
970     gl.genRenderbuffers(1, &rbo_id);
971     gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
972 
973     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
974 
975     /* Bind texture objects to relevant texture targets */
976     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
977 
978     if (are_multisample_2d_array_tos_supported)
979     {
980         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
981     }
982 
983     GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glBindTexture() call failed.");
984 
985     /* Iterate through internalformats. Current internalformat will be used
986      * by the 2D multisample attachment */
987     const glw::GLenum internalformats[]  = {GL_R8, GL_RGB565, GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I};
988     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
989 
990     for (unsigned int n_2d_multisample_internalformat = 0; n_2d_multisample_internalformat < n_internalformats;
991          ++n_2d_multisample_internalformat)
992     {
993         glw::GLenum internalformat_2d_multisample = internalformats[n_2d_multisample_internalformat];
994 
995         /* Query sample counts supported for 2DMS texture on given internal format */
996         glw::GLint num_sample_counts_2dms;
997 
998         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat_2d_multisample, GL_NUM_SAMPLE_COUNTS, 1,
999                                &num_sample_counts_2dms);
1000 
1001         std::vector<glw::GLint> sample_counts_2dms(num_sample_counts_2dms);
1002 
1003         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat_2d_multisample, GL_SAMPLES,
1004                                num_sample_counts_2dms, &sample_counts_2dms[0]);
1005 
1006         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve sample counts supported for 2DMS");
1007 
1008         /* Iterate again through the internalformats. This internalformat will be used
1009          * by the 2D multisample array attacmhent.
1010          *
1011          * NOTE: Under implementations which do not support 2DMS Array textures, we will
1012          *       not attach the 2DMS Array textures to the FBO at all. This fits the conformance
1013          *       test idea and does not break existing test implementation.
1014          *       However, since 2DMS Array textures are unavailable, we only run a single inner
1015          *       loop iteration. More iterations would not bring anything to the table at all.
1016          */
1017         for (unsigned int n_2d_multisample_array_internalformat = 0;
1018              n_2d_multisample_array_internalformat < ((are_multisample_2d_array_tos_supported) ? n_internalformats : 1);
1019              ++n_2d_multisample_array_internalformat)
1020         {
1021             glw::GLenum internalformat_2d_multisample_array = internalformats[n_2d_multisample_array_internalformat];
1022             glw::GLint num_sample_counts_2dms_array         = 1;
1023             std::vector<glw::GLint> sample_counts_2dms_array(num_sample_counts_2dms_array);
1024 
1025             if (are_multisample_2d_array_tos_supported)
1026             {
1027                 /* Query sample counts supported for 2DMS_ARRAY texture on given internal format */
1028                 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, internalformat_2d_multisample_array,
1029                                        GL_NUM_SAMPLE_COUNTS, 1, &num_sample_counts_2dms_array);
1030 
1031                 sample_counts_2dms_array.resize(num_sample_counts_2dms_array);
1032 
1033                 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, internalformat_2d_multisample_array,
1034                                        GL_SAMPLES, num_sample_counts_2dms_array, &sample_counts_2dms_array[0]);
1035 
1036                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve sample counts supported for 2DMS_ARRAY");
1037             }
1038             else
1039             {
1040                 /* Add a single entry to the 2d ms sample count array */
1041                 num_sample_counts_2dms_array = 1;
1042                 sample_counts_2dms_array[0]  = 0;
1043             }
1044 
1045             /* One more iteration for renderbuffer attachment */
1046             for (unsigned int n_rbo_internalformat = 0; n_rbo_internalformat < n_internalformats;
1047                  ++n_rbo_internalformat)
1048             {
1049                 glw::GLenum internalformat_rbo = internalformats[n_rbo_internalformat];
1050 
1051                 /* Query sample counts supported for RBO on given internal format */
1052                 glw::GLint num_sample_counts_rbo;
1053 
1054                 gl.getInternalformativ(GL_RENDERBUFFER, internalformat_rbo, GL_NUM_SAMPLE_COUNTS, 1,
1055                                        &num_sample_counts_rbo);
1056 
1057                 std::vector<glw::GLint> sample_counts_rbo(num_sample_counts_rbo);
1058 
1059                 gl.getInternalformativ(GL_RENDERBUFFER, internalformat_rbo, GL_SAMPLES, num_sample_counts_rbo,
1060                                        &sample_counts_rbo[0]);
1061 
1062                 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve sample counts supported for rbo");
1063 
1064                 /* Now iterate over all samples argument we will use for the 2D multisample attachment */
1065                 for (int i_2dms = 0; i_2dms < num_sample_counts_2dms; ++i_2dms)
1066                 {
1067                     int samples_2d_multisample = sample_counts_2dms[i_2dms];
1068 
1069                     /* ..and yet another iteration for the 2D multisample array attachment */
1070                     for (int i_2dms_array = 0; i_2dms_array < num_sample_counts_2dms_array; ++i_2dms_array)
1071                     {
1072                         int samples_2d_multisample_array = sample_counts_2dms_array[i_2dms_array];
1073 
1074                         /* Finally, iterate over values to be used for samples argument of
1075                          * a glRenderbufferStorageMultisample() call.
1076                          */
1077                         for (int i_rbo = 0; i_rbo < num_sample_counts_rbo; ++i_rbo)
1078                         {
1079                             int samples_rbo = sample_counts_rbo[i_rbo];
1080 
1081                             /* This is a negative test. Hence, skip an iteration where all the
1082                              * samples arguments used for the multisample 2d/multisample 2d array/rbo
1083                              * triple match.
1084                              */
1085                             if (((samples_rbo == samples_2d_multisample) &&
1086                                  (samples_rbo == samples_2d_multisample_array)) ||
1087                                 (samples_rbo == 1) || (samples_2d_multisample == 1) ||
1088                                 (samples_2d_multisample_array == 1))
1089                             {
1090                                 /* Skip the iteration */
1091                                 continue;
1092                             }
1093 
1094                             /* Set up 2D multisample texture storage. */
1095                             gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples_2d_multisample,
1096                                                        internalformat_2d_multisample, 2, /* width */
1097                                                        2,                                /* height */
1098                                                        GL_FALSE);
1099                             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed.");
1100 
1101                             if (are_multisample_2d_array_tos_supported)
1102                             {
1103                                 /* Set up 2D multisample array texture storage. */
1104                                 gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES,
1105                                                            samples_2d_multisample_array,
1106                                                            internalformat_2d_multisample_array, 2, /* width */
1107                                                            2,                                      /* height */
1108                                                            2,                                      /* depth */
1109                                                            GL_FALSE);
1110                                 GLU_EXPECT_NO_ERROR(gl.getError(), "gltexStorage3DMultisample() call failed.");
1111                             }
1112 
1113                             /* Set up renderbuffer storage */
1114                             gl.renderbufferStorageMultisample(GL_RENDERBUFFER, samples_rbo, internalformat_rbo,
1115                                                               2,  /* width */
1116                                                               2); /* height */
1117                             GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample() call failed.");
1118 
1119                             /* Set up FBO's color attachments */
1120                             gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1121                                                     GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d, 0); /* level */
1122                             GLU_EXPECT_NO_ERROR(
1123                                 gl.getError(),
1124                                 "glFramebufferTexture2D() call failed for GL_COLOR_ATTACHMENT0 color attachment.");
1125 
1126                             if (are_multisample_2d_array_tos_supported)
1127                             {
1128                                 gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
1129                                                            to_id_multisample_2d_array, 0, /* level */
1130                                                            0);                            /* layer */
1131                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed for "
1132                                                                    "GL_COLOR_ATTACHMENT1 color attachment.");
1133                             }
1134 
1135                             gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER,
1136                                                        rbo_id);
1137                             GLU_EXPECT_NO_ERROR(
1138                                 gl.getError(),
1139                                 "glFramebufferRenderbuffer() call failed for GL_COLOR_ATTACHMENT2 color attachment.");
1140 
1141                             /* Make sure the FBO is incomplete */
1142                             glw::GLenum fbo_completeness_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1143 
1144                             if (fbo_completeness_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
1145                             {
1146                                 m_testCtx.getLog()
1147                                     << tcu::TestLog::Message << "Invalid FBO completeness status reported ["
1148                                     << fbo_completeness_status
1149                                     << "]"
1150                                        " instead of expected GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE."
1151                                     << " Sample count 2D_MS:" << samples_2d_multisample
1152                                     << " Sample count 2D_MS_ARRAY:" << samples_2d_multisample_array
1153                                     << " Sample count RBO:" << samples_rbo << tcu::TestLog::EndMessage;
1154 
1155                                 TCU_FAIL("Invalid FBO completeness status reported.");
1156                             }
1157 
1158                             /* Re-create texture objects */
1159                             gl.deleteTextures(1, &to_id_multisample_2d);
1160 
1161                             if (are_multisample_2d_array_tos_supported)
1162                             {
1163                                 gl.deleteTextures(1, &to_id_multisample_2d_array);
1164                             }
1165 
1166                             GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glDeleteTextures() call failed.");
1167 
1168                             gl.genTextures(1, &to_id_multisample_2d);
1169 
1170                             if (are_multisample_2d_array_tos_supported)
1171                             {
1172                                 gl.genTextures(1, &to_id_multisample_2d_array);
1173                             }
1174 
1175                             GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed.");
1176 
1177                             gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
1178 
1179                             if (are_multisample_2d_array_tos_supported)
1180                             {
1181                                 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
1182                             }
1183 
1184                             GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glBindTexture() call failed.");
1185                         } /* for (all samples argument values to be used for renderbuffer attachment) */
1186                     }     /* for (all samples argument values to be used for 2D multisample array attachment) */
1187                 }         /* for (all samples argument values to be used for 2D multisample attachment) */
1188             }             /* for (all internalformats used by renderbuffer attachment) */
1189         }                 /* for (all internalformats used by 2D multisample array attachment) */
1190     }                     /* for (all internalformats used by 2D multisample attachment) */
1191 
1192     /* All done */
1193     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1194 
1195     return STOP;
1196 }
1197 
1198 /** Constructor.
1199  *
1200  *  @param context CTS context handle.
1201  **/
1202 MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::
MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test(Context & context)1203     MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test(Context &context)
1204     : TestCase(context, "framebuffer_texture2d_used_with_invalid_texture_target",
1205                "Checks GL_INVALID_OPERATION is reported if 2D or cube-map texture "
1206                "target is used with a multisample 2D texture for a "
1207                "glFramebufferTexture2D() call")
1208     , fbo_id(0)
1209     , to_id(0)
1210 {
1211     /* Left blank on purpose */
1212 }
1213 
1214 /** Deinitializes ES objects created during test execution */
deinit()1215 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::deinit()
1216 {
1217     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1218 
1219     if (fbo_id != 0)
1220     {
1221         gl.deleteFramebuffers(1, &fbo_id);
1222 
1223         fbo_id = 0;
1224     }
1225 
1226     if (to_id != 0)
1227     {
1228         gl.deleteTextures(1, &to_id);
1229 
1230         to_id = 0;
1231     }
1232 
1233     /* Call base class' deinit() */
1234     TestCase::deinit();
1235 }
1236 
1237 /** Initializes ES objects created during test execution */
initInternals()1238 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::initInternals()
1239 {
1240     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1241 
1242     /* Generate and bind a framebuffer object */
1243     gl.genFramebuffers(1, &fbo_id);
1244     gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1245 
1246     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1247 
1248     /* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE texture target */
1249     gl.genTextures(1, &to_id);
1250     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1251 
1252     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1253 }
1254 
1255 /** Executes test iteration.
1256  *
1257  *  @return Returns STOP when test has finished executing.
1258  */
iterate()1259 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::iterate()
1260 {
1261     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1262 
1263     initInternals();
1264 
1265     /* For storing internalformat specific maximum number of samples */
1266     glw::GLint gl_max_internalformat_samples = 0;
1267 
1268     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_INTEGER_SAMPLES and/or GL_MAX_SAMPLES values");
1269 
1270     /* Iterate through all internalformats to be used for the test */
1271     const glw::GLenum internalformats[] = {
1272         GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I};
1273 
1274     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1275 
1276     for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1277     {
1278         glw::GLenum internalformat       = internalformats[n_internalformat];
1279         bool is_color_renderable         = false;
1280         bool is_depth_stencil_renderable = false;
1281 
1282         if (internalformat == GL_DEPTH24_STENCIL8)
1283         {
1284             is_depth_stencil_renderable = true;
1285         }
1286         else if (internalformat != GL_DEPTH_COMPONENT32F)
1287         {
1288             is_color_renderable = true;
1289         }
1290 
1291         /* Determine a value to be used for samples argument in subsequent
1292          * glTexStorage2DMultisample() call. */
1293         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1294                                &gl_max_internalformat_samples);
1295 
1296         GLU_EXPECT_NO_ERROR(gl.getError(),
1297                             "Could not retrieve maximum supported amount of samples for internal format");
1298 
1299         glw::GLint samples = gl_max_internalformat_samples;
1300 
1301         /* Skip formats that are not multisampled in the implementation */
1302         if (samples <= 1)
1303         {
1304             continue;
1305         }
1306 
1307         /* Set the texture object storage up */
1308         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 1, /* width */
1309                                    1,                                                     /* height */
1310                                    GL_FALSE);                                             /* fixedsamplelocations */
1311 
1312         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call generated an unexpected error.");
1313 
1314         /* Try to issue the invalid glFramebufferTexture2D() call */
1315         glw::GLenum attachment = (is_color_renderable)         ? GL_COLOR_ATTACHMENT0 :
1316                                  (is_depth_stencil_renderable) ? GL_DEPTH_STENCIL_ATTACHMENT :
1317                                                                  GL_DEPTH_ATTACHMENT;
1318 
1319         gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, to_id, 0); /* level */
1320 
1321         /* Make sure GL_INVALID_OPERATION error was generated */
1322         glw::GLenum error_code = gl.getError();
1323 
1324         if (error_code != GL_INVALID_OPERATION)
1325         {
1326             m_testCtx.getLog()
1327                 << tcu::TestLog::Message << "An unexpected error code " << error_code
1328                 << " instead of GL_INVALID_OPERATION was generated by an invalid glFramebufferTexture2D() call"
1329                 << tcu::TestLog::EndMessage;
1330 
1331             TCU_FAIL("Invalid error code reported by glFramebufferTexture2D() call.");
1332         }
1333 
1334         /* Re-create the texture object */
1335         gl.deleteTextures(1, &to_id);
1336         gl.genTextures(1, &to_id);
1337         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1338 
1339         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1340     } /* for (all internalformats) */
1341 
1342     /* All done */
1343     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1344 
1345     return STOP;
1346 }
1347 
1348 /** Constructor.
1349  *
1350  *  @param context CTS context handle.
1351  **/
1352 MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::
MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test(Context & context)1353     MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test(Context &context)
1354     : TestCase(context, "framebuffer_texture2d_used_with_invalid_level",
1355                "Checks GL_INVALID_VALUE is reported if glFramebufferTexture2D() "
1356                "is called with invalid level argument.")
1357     , fbo_id(0)
1358     , to_id(0)
1359 {
1360     /* Left blank on purpose */
1361 }
1362 
1363 /** Deinitializes ES objects created during test execution */
deinit()1364 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::deinit()
1365 {
1366     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1367 
1368     if (fbo_id != 0)
1369     {
1370         gl.deleteFramebuffers(1, &fbo_id);
1371 
1372         fbo_id = 0;
1373     }
1374 
1375     if (to_id != 0)
1376     {
1377         gl.deleteTextures(1, &to_id);
1378 
1379         to_id = 0;
1380     }
1381 
1382     /* Call base class' deinit() */
1383     TestCase::deinit();
1384 }
1385 
1386 /** Initializes ES objects created during test execution */
initInternals()1387 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::initInternals()
1388 {
1389     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1390 
1391     /* Generate and bind a framebuffer object */
1392     gl.genFramebuffers(1, &fbo_id);
1393     gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1394 
1395     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1396 
1397     /* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE texture target */
1398     gl.genTextures(1, &to_id);
1399     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1400 
1401     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1402 }
1403 
1404 /** Executes test iteration.
1405  *
1406  *  @return Returns STOP when test has finished executing.
1407  */
iterate()1408 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::iterate()
1409 {
1410     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1411 
1412     initInternals();
1413 
1414     /* For storing format specific maximum number of samples */
1415     glw::GLint gl_max_internalformat_samples = 0;
1416 
1417     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_INTEGER_SAMPLES and/or GL_MAX_SAMPLE values");
1418 
1419     /* Iterate through all internalformats to be used for the test */
1420     const glw::GLenum internalformats[] = {
1421         GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I};
1422     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1423 
1424     for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1425     {
1426         glw::GLenum internalformat = internalformats[n_internalformat];
1427         bool is_color_renderable   = false;
1428         bool is_depth_renderable   = false;
1429 
1430         if (internalformat == GL_DEPTH_COMPONENT32F)
1431         {
1432             is_depth_renderable = true;
1433         }
1434         else if (internalformat != GL_DEPTH24_STENCIL8)
1435         {
1436             is_color_renderable = true;
1437         }
1438 
1439         /* Determine a value to be used for samples argument in subsequent
1440          * glTexStorage2DMultisample() call. */
1441         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1442                                &gl_max_internalformat_samples);
1443 
1444         GLU_EXPECT_NO_ERROR(gl.getError(),
1445                             "Could not retrieve maximum supported amount of samples for internal format");
1446 
1447         glw::GLint samples = gl_max_internalformat_samples;
1448 
1449         /* Skip formats that are not multisampled in implementation */
1450         if (samples <= 1)
1451         {
1452             continue;
1453         }
1454 
1455         /* Set the texture object storage up */
1456         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 1, /* width */
1457                                    1,                                                     /* height */
1458                                    GL_FALSE);                                             /* fixedsamplelocations */
1459 
1460         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call generated an unexpected error.");
1461 
1462         /* Try to issue the invalid glFramebufferTexture2D() call */
1463         glw::GLenum attachment = (is_color_renderable) ? GL_COLOR_ATTACHMENT0 :
1464                                  (is_depth_renderable) ? GL_DEPTH_ATTACHMENT :
1465                                                          GL_DEPTH_STENCIL_ATTACHMENT;
1466 
1467         /* From spec:
1468          *
1469          * If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero. If textarget
1470          * is one of the cube map face targets from table 3.21, then level must be greater
1471          * than or equal to zero and less than or equal to log2 of the value of MAX_CUBE_-
1472          * MAP_TEXTURE_SIZE. If textarget is TEXTURE_2D, level must be greater than or
1473          * equal to zero and no larger than log2 of the value of MAX_TEXTURE_SIZE.
1474          */
1475         gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, to_id, 1); /* level */
1476 
1477         /* Make sure GL_INVALID_VALUE error was generated */
1478         glw::GLenum error_code = gl.getError();
1479 
1480         if (error_code != GL_INVALID_VALUE)
1481         {
1482             m_testCtx.getLog()
1483                 << tcu::TestLog::Message << "An unexpected error code " << error_code
1484                 << " instead of GL_INVALID_VALUE was generated by an invalid glFramebufferTexture2D() call"
1485                 << tcu::TestLog::EndMessage;
1486 
1487             TCU_FAIL("Invalid error code reported by glFramebufferTexture2D() call.");
1488         }
1489 
1490         /* Re-create the texture object */
1491         gl.deleteTextures(1, &to_id);
1492         gl.genTextures(1, &to_id);
1493         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1494 
1495         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1496     } /* for (all internalformats) */
1497 
1498     /* All done */
1499     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1500 
1501     return STOP;
1502 }
1503 
1504 /** Constructor.
1505  *
1506  *  @param context CTS context handle.
1507  **/
1508 MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::
MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test(Context & context)1509     MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test(Context &context)
1510     : TestCase(context, "framebuffer_texture_layer_used_for_invalid_texture_target",
1511                "Checks GL_INVALID_OPERATION is reported if 2D multisample texture is used for a "
1512                "glFramebufferTextureLayer() call")
1513     , fbo_id(0)
1514     , to_id(0)
1515 {
1516     /* Left blank on purpose */
1517 }
1518 
1519 /** Deinitializes ES objects created during test execution */
deinit()1520 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::deinit()
1521 {
1522     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1523 
1524     if (fbo_id != 0)
1525     {
1526         gl.deleteFramebuffers(1, &fbo_id);
1527 
1528         fbo_id = 0;
1529     }
1530 
1531     if (to_id != 0)
1532     {
1533         gl.deleteTextures(1, &to_id);
1534 
1535         to_id = 0;
1536     }
1537 
1538     /* Call base class' deinit() */
1539     TestCase::deinit();
1540 }
1541 
1542 /** Initializes ES objects created during test execution */
initInternals()1543 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::initInternals()
1544 {
1545     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1546 
1547     /* Generate and bind a framebuffer object */
1548     gl.genFramebuffers(1, &fbo_id);
1549     gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1550 
1551     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1552 
1553     /* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE texture target */
1554     gl.genTextures(1, &to_id);
1555     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1556 
1557     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1558 }
1559 
1560 /** Executes test iteration.
1561  *
1562  *  @return Returns STOP when test has finished executing.
1563  */
iterate()1564 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::iterate()
1565 {
1566     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1567 
1568     initInternals();
1569 
1570     /* For storing format specific maximum number of samples */
1571     glw::GLint gl_max_internalformat_samples = 0;
1572 
1573     /* Iterate through all internalformats to be used for the test */
1574     const glw::GLenum internalformats[] = {
1575         GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I};
1576     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1577 
1578     for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1579     {
1580         glw::GLenum internalformat = internalformats[n_internalformat];
1581         bool is_color_renderable   = false;
1582         bool is_depth_renderable   = false;
1583 
1584         if (internalformat == GL_DEPTH_COMPONENT32F)
1585         {
1586             is_depth_renderable = true;
1587         }
1588         else if (internalformat != GL_DEPTH24_STENCIL8)
1589         {
1590             is_color_renderable = true;
1591         }
1592 
1593         /* Determine a value to be used for samples argument in subsequent
1594          * glTexStorage2DMultisample() call. */
1595         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1596                                &gl_max_internalformat_samples);
1597 
1598         GLU_EXPECT_NO_ERROR(gl.getError(),
1599                             "Could not retrieve maximum supported amount of samples for internal format");
1600 
1601         glw::GLint samples = gl_max_internalformat_samples;
1602 
1603         /* Skip formats that are not multisampled in implementation */
1604         if (samples <= 1)
1605         {
1606             continue;
1607         }
1608 
1609         /* Set the texture object storage up */
1610         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 2, /* width */
1611                                    2,                                                     /* height */
1612                                    GL_FALSE);                                             /* fixedsamplelocations */
1613 
1614         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call generated an unexpected error.");
1615 
1616         /* Try to issue the invalid glFramebufferTextureLayer() call */
1617         glw::GLenum attachment = (is_color_renderable) ? GL_COLOR_ATTACHMENT0 :
1618                                  (is_depth_renderable) ? GL_DEPTH_ATTACHMENT :
1619                                                          GL_DEPTH_STENCIL_ATTACHMENT;
1620 
1621         gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachment, to_id, 0, /* level */
1622                                    0);                                        /* layer */
1623 
1624         /* Make sure GL_INVALID_OPERATION error was generated */
1625         glw::GLenum error_code = gl.getError();
1626 
1627         if (error_code != GL_INVALID_OPERATION)
1628         {
1629             m_testCtx.getLog()
1630                 << tcu::TestLog::Message << "An unexpected error code " << error_code
1631                 << " instead of GL_INVALID_OPERATION was generated by an invalid glFramebufferTextureLayer() call"
1632                 << tcu::TestLog::EndMessage;
1633 
1634             TCU_FAIL("Invalid error code reported by glFramebufferTextureLayer() call.");
1635         }
1636 
1637         /* Re-create the texture object */
1638         gl.deleteTextures(1, &to_id);
1639         gl.genTextures(1, &to_id);
1640         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1641 
1642         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1643     } /* for (all internalformats) */
1644 
1645     /* All done */
1646     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1647 
1648     return STOP;
1649 }
1650 
1651 /** Constructor.
1652  *
1653  *  @param context CTS context handle.
1654  **/
1655 MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::
MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test(Context & context)1656     MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test(Context &context)
1657     : TestCase(context, "framebuffer_texture_layer_used_with_invalid_level_argument",
1658                "Checks GL_INVALID_VALUE error is reported if a glFramebufferTextureLayer() call"
1659                " is made with level exceeding amount of layers defined for a 2D multisample"
1660                " array texture")
1661     , fbo_id(0)
1662     , to_id(0)
1663 {
1664     /* Left blank on purpose */
1665 }
1666 
1667 /** Deinitializes ES objects created during test execution */
deinit()1668 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::deinit()
1669 {
1670     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1671 
1672     if (fbo_id != 0)
1673     {
1674         gl.deleteFramebuffers(1, &fbo_id);
1675 
1676         fbo_id = 0;
1677     }
1678 
1679     if (to_id != 0)
1680     {
1681         gl.deleteTextures(1, &to_id);
1682 
1683         to_id = 0;
1684     }
1685 
1686     /* Call base class' deinit() */
1687     TestCase::deinit();
1688 }
1689 
1690 /** Initializes ES objects created during test execution */
initInternals()1691 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::initInternals()
1692 {
1693     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1694 
1695     /* Generate and bind a framebuffer object */
1696     gl.genFramebuffers(1, &fbo_id);
1697     gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1698 
1699     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1700 
1701     /* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target */
1702     gl.genTextures(1, &to_id);
1703     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id);
1704 
1705     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1706 }
1707 
1708 /** Executes test iteration.
1709  *
1710  *  @return Returns STOP when test has finished executing.
1711  */
iterate()1712 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::iterate()
1713 {
1714     if (!m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
1715     {
1716         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "OES_texture_storage_multisample_2d_array");
1717 
1718         return STOP;
1719     }
1720 
1721     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1722 
1723     initInternals();
1724 
1725     /* For storing format specific maximum number of samples */
1726     glw::GLint gl_max_internalformat_samples = 0;
1727 
1728     /* Iterate through all internalformats to be used for the test */
1729     const glw::GLenum internalformats[] = {
1730         GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I};
1731     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1732 
1733     for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1734     {
1735         glw::GLenum internalformat = internalformats[n_internalformat];
1736         bool is_color_renderable   = false;
1737         bool is_depth_renderable   = false;
1738 
1739         if (internalformat == GL_DEPTH_COMPONENT32F)
1740         {
1741             is_depth_renderable = true;
1742         }
1743         else if (internalformat != GL_DEPTH24_STENCIL8)
1744         {
1745             is_color_renderable = true;
1746         }
1747 
1748         /* Determine a value to be used for samples argument in subsequent
1749          * glTexStorage2DMultisample() call. */
1750         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1751                                &gl_max_internalformat_samples);
1752 
1753         /* Get MAX_TEXTURE_SIZE and calculate max level */
1754         glw::GLint gl_max_texture_size = 0;
1755         gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_texture_size);
1756         const glw::GLint max_level = glw::GLint(log(double(gl_max_texture_size)) / log(2.0));
1757 
1758         GLU_EXPECT_NO_ERROR(gl.getError(),
1759                             "Could not retrieve maximum supported amount of samples for internal format");
1760 
1761         glw::GLint samples = gl_max_internalformat_samples;
1762 
1763         /* Set the texture object storage up */
1764         gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samples, internalformat, 2, /* width */
1765                                    2,                                                               /* height */
1766                                    2,                                                               /* depth */
1767                                    GL_FALSE); /* fixedsamplelocations */
1768 
1769         GLU_EXPECT_NO_ERROR(gl.getError(), "gltexStorage3DMultisample() call generated an unexpected error.");
1770 
1771         /* Try to issue the invalid glFramebufferTextureLayer() call */
1772         glw::GLenum attachment = (is_color_renderable) ? GL_COLOR_ATTACHMENT0 :
1773                                  (is_depth_renderable) ? GL_DEPTH_ATTACHMENT :
1774                                                          GL_DEPTH_STENCIL_ATTACHMENT;
1775 
1776         gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachment, to_id,
1777                                    max_level + 1, /* level - must be <= log_2(MAX_TEXTURE_SIZE) */
1778                                    0);            /* layer */
1779 
1780         /* Make sure GL_INVALID_VALUE error was generated */
1781         glw::GLenum error_code = gl.getError();
1782 
1783         if (error_code != GL_INVALID_VALUE)
1784         {
1785             m_testCtx.getLog()
1786                 << tcu::TestLog::Message << "An unexpected error code " << error_code
1787                 << " instead of GL_INVALID_VALUE was generated by an invalid glFramebufferTextureLayer() call"
1788                 << tcu::TestLog::EndMessage;
1789 
1790             TCU_FAIL("Invalid error code reported by glFramebufferTextureLayer() call.");
1791         }
1792 
1793         /* Re-create the texture object */
1794         gl.deleteTextures(1, &to_id);
1795         gl.genTextures(1, &to_id);
1796         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id);
1797 
1798         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1799     } /* for (all internalformats) */
1800 
1801     /* All done */
1802     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1803 
1804     return STOP;
1805 }
1806 
1807 /** Constructor.
1808  *
1809  *  @param context CTS context handle.
1810  **/
1811 MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::
MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test(Context & context)1812     MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test(Context &context)
1813     : TestCase(context, "renderbuffer_storage_multisample_invalid_samples_argument_for_noninteger_internalformats",
1814                "GL_INVALID_OPERATION error is reported for glRenderbufferStorageMultisample() "
1815                "calls, for which samples argument > MAX_SAMPLES for non-integer internalformats")
1816     , rbo_id(0)
1817 {
1818     /* Left blank on purpose */
1819 }
1820 
1821 /** Deinitializes ES objects created during test execution */
deinit()1822 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::deinit()
1823 {
1824     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1825 
1826     if (rbo_id != 0)
1827     {
1828         gl.deleteRenderbuffers(1, &rbo_id);
1829 
1830         rbo_id = 0;
1831     }
1832 
1833     /* Call base class' deinit() */
1834     TestCase::deinit();
1835 }
1836 
1837 /** Initializes ES objects created during test execution */
initInternals()1838 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::initInternals()
1839 {
1840     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1841 
1842     gl.genRenderbuffers(1, &rbo_id);
1843     gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
1844 
1845     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
1846 }
1847 
1848 /** Executes test iteration.
1849  *
1850  *  @return Returns STOP when test has finished executing.
1851  */
iterate()1852 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::iterate()
1853 {
1854     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1855 
1856     initInternals();
1857 
1858     /* Retrieve GL_MAX_SAMPLES pname value */
1859     glw::GLint gl_max_samples_value = 0;
1860 
1861     gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
1862     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_SAMPLES value.");
1863 
1864     /* Iterate through a set of valid non-integer internalformats */
1865     const glw::GLenum noninteger_internalformats[] = {
1866         GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_STENCIL_INDEX8};
1867     const unsigned int n_noninteger_internalformats =
1868         sizeof(noninteger_internalformats) / sizeof(noninteger_internalformats[0]);
1869 
1870     for (unsigned int n_internalformat = 0; n_internalformat < n_noninteger_internalformats; ++n_internalformat)
1871     {
1872         glw::GLenum error_code                         = GL_NO_ERROR;
1873         const glw::GLenum internalformat               = noninteger_internalformats[n_internalformat];
1874         glw::GLint gl_max_internalformat_samples_value = -1;
1875 
1876         /* Retrieve maximum amount of samples available for the texture target considered */
1877         gl.getInternalformativ(GL_RENDERBUFFER, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples_value);
1878         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed to retrieve GL_SAMPLES");
1879 
1880         /* Execute the test */
1881         gl.renderbufferStorageMultisample(GL_RENDERBUFFER, gl_max_internalformat_samples_value + 1, internalformat,
1882                                           1,  /* width */
1883                                           1); /* height */
1884 
1885         error_code = gl.getError();
1886         if (error_code != GL_INVALID_OPERATION)
1887         {
1888             m_testCtx.getLog() << tcu::TestLog::Message << "glRenderbufferStorageMultisample() generated error code "
1889                                << error_code << " when GL_INVALID_OPERATION was expected." << tcu::TestLog::EndMessage;
1890 
1891             TCU_FAIL("Invalid error code generated by glRenderbufferStorageMultisample() call.");
1892         }
1893     } /* for (all internalformats) */
1894 
1895     /* All done */
1896     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1897 
1898     return STOP;
1899 }
1900 
1901 /** Constructor.
1902  *
1903  *  @param context CTS context handle.
1904  **/
1905 MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::
MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test(Context & context)1906     MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test(Context &context)
1907     : TestCase(context, "renderbuffer_storage_multisample_invalid_samples_argument_for_integer_internalformats",
1908                "GL_INVALID_OPERATION error is reported for glRenderbufferStorageMultisample() calls, "
1909                "for which samples argument > MAX_INTEGER_SAMPLES for integer internalformats")
1910     , rbo_id(0)
1911 {
1912     /* Left blank on purpose */
1913 }
1914 
1915 /** Deinitializes ES objects created during test execution */
deinit()1916 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::deinit()
1917 {
1918     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1919 
1920     if (rbo_id != 0)
1921     {
1922         gl.deleteRenderbuffers(1, &rbo_id);
1923 
1924         rbo_id = 0;
1925     }
1926 
1927     /* Call base class' deinit() */
1928     TestCase::deinit();
1929 }
1930 
1931 /** Initializes ES objects created during test execution */
initInternals()1932 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::initInternals()
1933 {
1934     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1935 
1936     gl.genRenderbuffers(1, &rbo_id);
1937     gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
1938 
1939     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
1940 }
1941 
1942 /** Executes test iteration.
1943  *
1944  *  @return Returns STOP when test has finished executing.
1945  */
iterate()1946 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::iterate()
1947 {
1948     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1949 
1950     initInternals();
1951 
1952     /* Retrieve GL_MAX_INTEGER_SAMPLES pname value */
1953     glw::GLint gl_max_integer_samples_value = 0;
1954 
1955     gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &gl_max_integer_samples_value);
1956     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_INTEGER_SAMPLES value.");
1957 
1958     /* Iterate through a set of valid integer internalformats */
1959     const glw::GLenum integer_internalformats[]  = {GL_RG8UI, GL_RGBA32I};
1960     const unsigned int n_integer_internalformats = sizeof(integer_internalformats) / sizeof(integer_internalformats[0]);
1961 
1962     for (unsigned int n_internalformat = 0; n_internalformat < n_integer_internalformats; ++n_internalformat)
1963     {
1964         glw::GLenum error_code           = GL_NO_ERROR;
1965         const glw::GLenum internalformat = integer_internalformats[n_internalformat];
1966 
1967         /* Execute the test */
1968         gl.renderbufferStorageMultisample(GL_RENDERBUFFER, gl_max_integer_samples_value + 1, internalformat,
1969                                           1,  /* width */
1970                                           1); /* height */
1971 
1972         error_code = gl.getError();
1973         if (error_code != GL_INVALID_OPERATION)
1974         {
1975             m_testCtx.getLog() << tcu::TestLog::Message << "glRenderbufferStorageMultisample() generated error code "
1976                                << error_code << " when GL_INVALID_OPERATION was expected." << tcu::TestLog::EndMessage;
1977 
1978             TCU_FAIL("Invalid error code generated by glRenderbufferStorageMultisample() call.");
1979         }
1980     } /* for (all internalformats) */
1981 
1982     /* All done */
1983     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1984 
1985     return STOP;
1986 }
1987 
1988 /** Constructor.
1989  *
1990  *  @param context CTS context handle.
1991  **/
1992 MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::
MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest(Context & context)1993     MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest(Context &context)
1994     : TestCase(context, "no_error_generated_for_valid_framebuffer_texture2d_calls",
1995                "No error is reported for glFramebufferTexture2D() calls using "
1996                "GL_TEXTURE_2D_MULTISAMPLE texture target.")
1997     , fbo_id(0)
1998     , to_id(0)
1999 {
2000     /* Left blank on purpose */
2001 }
2002 
2003 /** Deinitializes ES objects created during test execution */
deinit()2004 void MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::deinit()
2005 {
2006     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2007 
2008     if (fbo_id != 0)
2009     {
2010         gl.deleteFramebuffers(1, &fbo_id);
2011 
2012         fbo_id = 0;
2013     }
2014 
2015     if (to_id != 0)
2016     {
2017         gl.deleteTextures(1, &to_id);
2018 
2019         to_id = 0;
2020     }
2021 
2022     /* Call base class' deinit() */
2023     TestCase::deinit();
2024 }
2025 
2026 /** Initializes ES objects created during test execution */
initInternals()2027 void MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::initInternals()
2028 {
2029     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2030 
2031     /* Set up a framebuffer object */
2032     gl.genFramebuffers(1, &fbo_id);
2033     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
2034 
2035     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
2036 }
2037 
2038 /** Executes test iteration.
2039  *
2040  *  @return Returns STOP when test has finished executing.
2041  */
2042 tcu::TestNode::IterateResult MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::
iterate()2043     iterate()
2044 {
2045     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2046 
2047     initInternals();
2048 
2049     /* For storing format specific maximum number of samples */
2050     glw::GLint gl_max_internalformat_samples = 0;
2051 
2052     /* Iterate through all internalformats */
2053     const glw::GLenum internalformats[] = {
2054         GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I};
2055     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
2056 
2057     for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
2058     {
2059         glw::GLenum internalformat = internalformats[n_internalformat];
2060 
2061         /* Determine a value to be used for samples argument in subsequent
2062          * glTexStorage2DMultisample() call. */
2063         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
2064                                &gl_max_internalformat_samples);
2065 
2066         GLU_EXPECT_NO_ERROR(gl.getError(),
2067                             "Could not retrieve maximum supported amount of samples for internal format");
2068 
2069         glw::GLint samples = gl_max_internalformat_samples;
2070 
2071         /* Skip formats that are not multisampled in implementation */
2072         if (samples <= 1)
2073         {
2074             continue;
2075         }
2076 
2077         /* Set up a texture object. */
2078         gl.genTextures(1, &to_id);
2079         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
2080 
2081         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 1, /* width */
2082                                    1,                                                     /* height */
2083                                    GL_FALSE);                                             /* fixedsamplelocations */
2084 
2085         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
2086 
2087         /* Determine attachment type for internalformat considered */
2088         glw::GLenum attachment_type = GL_COLOR_ATTACHMENT0;
2089 
2090         if (internalformat == GL_DEPTH_COMPONENT32F)
2091         {
2092             attachment_type = GL_DEPTH_ATTACHMENT;
2093         }
2094         else if (internalformat == GL_DEPTH24_STENCIL8)
2095         {
2096             attachment_type = GL_DEPTH_STENCIL_ATTACHMENT;
2097         }
2098 
2099         /* Attach it to the FBO */
2100         gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment_type, GL_TEXTURE_2D_MULTISAMPLE, to_id, 0); /* level */
2101 
2102         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
2103 
2104         /* Release the texture object */
2105         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
2106         gl.deleteTextures(1, &to_id);
2107 
2108         to_id = 0;
2109 
2110         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not release the texture object");
2111     } /* for (all internalformats) */
2112 
2113     /* All done */
2114     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2115 
2116     return STOP;
2117 }
2118 
2119 /** Constructor.
2120  *
2121  *  @param context CTS context handle.
2122  **/
2123 MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::
MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest(Context & context)2124     MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest(Context &context)
2125     : TestCase(context, "no_error_generated_for_valid_renderbuffer_storage_multisample_calls",
2126                "No error is reported for valid glRenderbufferStorageMultisample() calls.")
2127     , rbo_id(0)
2128 {
2129     /* Left blank on purpose */
2130 }
2131 
2132 /** Deinitializes ES objects created during test execution */
deinit()2133 void MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::deinit()
2134 {
2135     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2136 
2137     if (rbo_id != 0)
2138     {
2139         gl.deleteRenderbuffers(1, &rbo_id);
2140 
2141         rbo_id = 0;
2142     }
2143 
2144     /* Call base class' deinit() */
2145     TestCase::deinit();
2146 }
2147 
2148 /** Initializes ES objects created during test execution */
initInternals()2149 void MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::initInternals()
2150 {
2151     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2152 
2153     gl.genRenderbuffers(1, &rbo_id);
2154     gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
2155 
2156     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
2157 }
2158 
2159 /** Executes test iteration.
2160  *
2161  *  @return Returns STOP when test has finished executing.
2162  */
2163 tcu::TestNode::IterateResult MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::
iterate()2164     iterate()
2165 {
2166     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2167 
2168     initInternals();
2169 
2170     /* For storing format specific maximum number of samples */
2171     glw::GLint gl_max_internalformat_samples = 0;
2172 
2173     /* Iterate through a set of valid non-integer and integer
2174      internalformats and a set of all legal samples argument values */
2175     const glw::GLenum internalformats[] = {
2176         GL_RGB8,           GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8,
2177         GL_STENCIL_INDEX8, GL_RG8UI,  GL_RGBA32I};
2178     const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
2179 
2180     for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
2181     {
2182         glw::GLenum internalformat = internalformats[n_internalformat];
2183 
2184         /* Determine a value to be used for samples argument in subsequent
2185          * glTexStorage2DMultisample() call. */
2186         gl.getInternalformativ(GL_RENDERBUFFER, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples);
2187 
2188         GLU_EXPECT_NO_ERROR(gl.getError(),
2189                             "Could not retrieve maximum supported amount of samples for internal format");
2190 
2191         for (int samples = 1; samples <= gl_max_internalformat_samples; ++samples)
2192         {
2193             /* Execute the test */
2194             gl.renderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, 1, 1);
2195 
2196             GLU_EXPECT_NO_ERROR(gl.getError(),
2197                                 "A valid glRenderbufferStorageMultisample() call has reported an error.");
2198         } /* for (all legal samples argument values) */
2199     }     /* for (all internalformats) */
2200 
2201     /* All done */
2202     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2203 
2204     return STOP;
2205 }
2206 
2207 /** Constructor.
2208  *
2209  *  @param context CTS context handle.
2210  **/
MultisampleTextureDependenciesTexParameterTest(Context & context)2211 MultisampleTextureDependenciesTexParameterTest::MultisampleTextureDependenciesTexParameterTest(Context &context)
2212     : TestCase(context, "tex_parameter_support",
2213                "Verifies glTexParameter*() behavior when used against multisample texture targets")
2214     , to_id_multisample_2d(0)
2215     , to_id_multisample_2d_array(0)
2216 {
2217     /* Left blank on purpose */
2218 }
2219 
2220 /* Calls glTexParameterf(), glTexParameterfv(), glTexParameteri() and
2221  * glTexParameteriv(). For each invocation, the function checks if
2222  * the error code reported after each call matches the expected value.
2223  * If the values differ, an info message is logged and TestError exception
2224  * is thrown.
2225  *
2226  * @param expected_error_code Expected GL error code.
2227  * @param value               Integer value to use. For glTexParameterf()
2228  *                            or glTexParameterfv(), the value will be cast
2229  *                            onto a float type prior to calling.
2230  * @param pname               GL pname to use for glTexParameter*() calls.
2231  * @param texture_target      Texture target to use for glTexParameter*() calls.
2232  */
checkAllTexParameterInvocations(glw::GLenum expected_error_code,glw::GLint value,glw::GLenum pname,glw::GLenum texture_target)2233 void MultisampleTextureDependenciesTexParameterTest::checkAllTexParameterInvocations(glw::GLenum expected_error_code,
2234                                                                                      glw::GLint value,
2235                                                                                      glw::GLenum pname,
2236                                                                                      glw::GLenum texture_target)
2237 {
2238     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2239 
2240     glw::GLenum error_code         = GL_NO_ERROR;
2241     const glw::GLfloat float_value = (glw::GLfloat)value;
2242     const glw::GLint int_value     = value;
2243 
2244     /* glTexParameterf() */
2245     gl.texParameterf(texture_target, pname, float_value);
2246 
2247     error_code = gl.getError();
2248 
2249     if (error_code != expected_error_code)
2250     {
2251         m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameterf() call generated an error " << error_code
2252                            << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2253 
2254         TCU_FAIL("glTexParameterf() call generated an unexpected error.");
2255     }
2256 
2257     /* glTexParameteri() */
2258     gl.texParameteri(texture_target, pname, int_value);
2259 
2260     error_code = gl.getError();
2261 
2262     if (error_code != expected_error_code)
2263     {
2264         m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameteri() call generated an error " << error_code
2265                            << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2266 
2267         TCU_FAIL("glTexParameterf() call generated an unexpected error.");
2268     }
2269 
2270     /* glTexParameterfv() */
2271     gl.texParameterfv(texture_target, pname, &float_value);
2272 
2273     error_code = gl.getError();
2274 
2275     if (error_code != expected_error_code)
2276     {
2277         m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameterfv() call generated an error " << error_code
2278                            << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2279 
2280         TCU_FAIL("glTexParameterfv() call generated an unexpected error.");
2281     }
2282 
2283     /* glTexParameteriv() */
2284     gl.texParameteriv(texture_target, pname, &int_value);
2285 
2286     error_code = gl.getError();
2287 
2288     if (error_code != expected_error_code)
2289     {
2290         m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameteriv() call generated an error " << error_code
2291                            << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2292 
2293         TCU_FAIL("glTexParameteriv() call generated an unexpected error.");
2294     }
2295 }
2296 
2297 /** Deinitializes ES objects created during test execution */
deinit()2298 void MultisampleTextureDependenciesTexParameterTest::deinit()
2299 {
2300     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2301 
2302     if (to_id_multisample_2d != 0)
2303     {
2304         gl.deleteTextures(1, &to_id_multisample_2d);
2305 
2306         to_id_multisample_2d = 0;
2307     }
2308 
2309     if (to_id_multisample_2d_array != 0)
2310     {
2311         gl.deleteTextures(1, &to_id_multisample_2d_array);
2312 
2313         to_id_multisample_2d_array = 0;
2314     }
2315 
2316     /* Call base class' deinit() */
2317     TestCase::deinit();
2318 }
2319 
2320 /** Executes test iteration.
2321  *
2322  *  @return Returns STOP when test has finished executing.
2323  */
iterate()2324 tcu::TestNode::IterateResult MultisampleTextureDependenciesTexParameterTest::iterate()
2325 {
2326     bool are_multisample_2d_array_tos_supported =
2327         m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
2328     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2329 
2330     /* Set up texture objects */
2331     gl.genTextures(1, &to_id_multisample_2d);
2332     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
2333 
2334     if (are_multisample_2d_array_tos_supported)
2335     {
2336         gl.genTextures(1, &to_id_multisample_2d_array);
2337         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
2338     }
2339 
2340     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture objects");
2341 
2342     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, /* samples */
2343                                GL_RGBA8, 1,                  /* width */
2344                                1,                            /* height */
2345                                GL_FALSE);                    /* fixedsamplelocations */
2346 
2347     GLU_EXPECT_NO_ERROR(gl.getError(),
2348                         "glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
2349 
2350     if (are_multisample_2d_array_tos_supported)
2351     {
2352         gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 1, /* samples */
2353                                    GL_RGBA8, 1,                            /* width */
2354                                    1,                                      /* height */
2355                                    1,                                      /* depth */
2356                                    GL_FALSE);                              /* fixedsamplelocations */
2357 
2358         GLU_EXPECT_NO_ERROR(
2359             gl.getError(),
2360             "gltexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target");
2361     }
2362 
2363     /* Run the test for both multisample texture targets */
2364     const glw::GLenum texture_targets[]  = {GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES};
2365     const unsigned int n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
2366 
2367     for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2368     {
2369         glw::GLenum texture_target = texture_targets[n_texture_target];
2370 
2371         if (!are_multisample_2d_array_tos_supported && texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES)
2372         {
2373             /* Skip the iteration */
2374             continue;
2375         }
2376 
2377         /* Verify that setting GL_TEXTURE_BASE_LEVEL to 0 does not generate any 0. Using any other
2378          * value should generate GL_INVALID_OPERATION
2379          */
2380         for (int n_iteration = 0; n_iteration < 2 /* iterations */; ++n_iteration)
2381         {
2382             glw::GLenum expected_error_code = (n_iteration == 0) ? GL_NO_ERROR : GL_INVALID_OPERATION;
2383             glw::GLint int_value            = (n_iteration == 0) ? 0 : 1;
2384 
2385             checkAllTexParameterInvocations(expected_error_code, int_value, GL_TEXTURE_BASE_LEVEL, texture_target);
2386         } /* for (all iterations) */
2387     }     /* for (both texture targets) */
2388 
2389     /* Make sure that modifying sampler state information results in an error
2390      * for multisample texture targets. */
2391     const glw::GLenum sampler_pnames[]  = {GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER,   GL_TEXTURE_WRAP_S,
2392                                            GL_TEXTURE_WRAP_T,     GL_TEXTURE_WRAP_R,       GL_TEXTURE_MIN_LOD,
2393                                            GL_TEXTURE_MAX_LOD,    GL_TEXTURE_COMPARE_MODE, GL_TEXTURE_COMPARE_FUNC};
2394     const unsigned int n_sampler_pnames = sizeof(sampler_pnames) / sizeof(sampler_pnames[0]);
2395 
2396     for (unsigned int n_sampler_pname = 0; n_sampler_pname < n_sampler_pnames; ++n_sampler_pname)
2397     {
2398         glw::GLenum pname = sampler_pnames[n_sampler_pname];
2399 
2400         for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2401         {
2402             glw::GLenum texture_target = texture_targets[n_texture_target];
2403 
2404             if (!are_multisample_2d_array_tos_supported && texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES)
2405             {
2406                 /* Skip the iteration */
2407                 continue;
2408             }
2409 
2410             /* When <target> is TEXTURE_2D_MULTISAMPLE or
2411              TEXTURE_2D_MULTISAMPLE_ARRAY, certain texture parameters may not be
2412              specified. In this case, an INVALID_ENUM */
2413             checkAllTexParameterInvocations(GL_INVALID_ENUM, 0, pname, texture_target);
2414 
2415         } /* for (all texture targets) */
2416     }     /* for (all sampler properties) */
2417 
2418     /* Make sure that modifying remaining texture parameters does not result in an error for
2419      * multisample texture targets. */
2420     for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2421     {
2422         glw::GLenum texture_target = texture_targets[n_texture_target];
2423 
2424         if (!are_multisample_2d_array_tos_supported && texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES)
2425         {
2426             /* Skip the iteration */
2427             continue;
2428         }
2429 
2430         checkAllTexParameterInvocations(GL_NO_ERROR, 10, GL_TEXTURE_MAX_LEVEL, texture_target);
2431         checkAllTexParameterInvocations(GL_NO_ERROR, GL_GREEN, GL_TEXTURE_SWIZZLE_R, texture_target);
2432         checkAllTexParameterInvocations(GL_NO_ERROR, GL_BLUE, GL_TEXTURE_SWIZZLE_G, texture_target);
2433         checkAllTexParameterInvocations(GL_NO_ERROR, GL_ALPHA, GL_TEXTURE_SWIZZLE_B, texture_target);
2434         checkAllTexParameterInvocations(GL_NO_ERROR, GL_RED, GL_TEXTURE_SWIZZLE_A, texture_target);
2435     }
2436 
2437     /* All done */
2438     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2439 
2440     return STOP;
2441 }
2442 } // namespace glcts
2443