xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cShaderTextureImageSamplesTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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  gl4cShaderTextureImageSamplesTests.cpp
27  * \brief Implements conformance tests for GL_ARB_shader_texture_image_samples functionality
28  */ /*-------------------------------------------------------------------*/
29 
30 #include "gl4cShaderTextureImageSamplesTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35 #include "tcuRenderTarget.hpp"
36 #include "tcuTestLog.hpp"
37 
38 #include <string>
39 #include <vector>
40 
41 namespace glcts
42 {
43 /** Constructor.
44  *
45  *  @param context     Rendering context
46  *  @param name        Test name
47  *  @param description Test description
48  */
ShaderTextureImageSamplesTestBase(deqp::Context & context,const char * name,const char * description)49 ShaderTextureImageSamplesTestBase::ShaderTextureImageSamplesTestBase(deqp::Context &context, const char *name,
50                                                                      const char *description)
51     : deqp::TestCase(context, name, description)
52     , m_internalformat_n_samples_count(0)
53     , m_internalformat_n_samples_data(DE_NULL)
54     , m_bo_id(0)
55     , m_cs_id(0)
56     , m_po_id(0)
57     , m_to_id(0)
58     , m_to_depth(3)
59     , m_to_height(4)
60     , m_to_width(8)
61 {
62     /* Left blank intentionally */
63 }
64 
65 /** Compiles a compute shader and optionally attaches it to a program object, which the
66  *  method can then try to link.
67  *
68  *  Shader object ID will be stored in m_cs_id.
69  *  Program object ID will be stored in m_po_id.
70  *
71  *  @param cs_body        Source code of the compute shader to use for compilation.
72  *  @param should_link_po true if the method should also attempt to link the program object.
73  *  @param should_succeed true if the compilation and linking (depending on @param should_link_po)
74  *                        processes should succeed, false otherwise. If GL implementation
75  *                        is found not to accept a valid compute shader, the method will
76  *                        throw a TestError exception.
77  *
78  *   Upon failure, the method *does not* delete the program & shader objects.
79  *
80  *  @return true if the compilation / linking process was successful, false otherwise.
81  **/
buildComputeProgram(const char * cs_body,bool should_link_po,bool should_succeed)82 bool ShaderTextureImageSamplesTestBase::buildComputeProgram(const char *cs_body, bool should_link_po,
83                                                             bool should_succeed)
84 {
85     bool result = false;
86 
87     /* Deinitialize any program / shader objects that may have already been initialized
88      * for this test instance.
89      */
90     deinitProgramAndShaderObjects();
91 
92     /* Create the objects */
93     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
94 
95     m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
96     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
97 
98     m_po_id = gl.createProgram();
99     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
100 
101     /* Set up the shader object */
102     gl.shaderSource(m_cs_id, 1,         /* count */
103                     &cs_body, DE_NULL); /* length */
104     GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
105 
106     /* Compile the shader object */
107     glw::GLint compile_status = GL_FALSE;
108 
109     gl.compileShader(m_cs_id);
110     GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
111 
112     gl.getShaderiv(m_cs_id, GL_COMPILE_STATUS, &compile_status);
113     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
114 
115     if (compile_status != GL_TRUE)
116     {
117         if (should_succeed)
118         {
119             TCU_FAIL("Shader compilation failed.");
120         }
121 
122         goto end;
123     }
124     else
125     {
126         if (!should_succeed)
127         {
128             TCU_FAIL("Shader compilation has succeeded, even though it should not have.");
129         }
130     }
131 
132     if (should_link_po)
133     {
134         /* Prepare the program object for linking */
135         gl.attachShader(m_po_id, m_cs_id);
136         GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
137 
138         /* Link the program object */
139         glw::GLint link_status = GL_FALSE;
140 
141         gl.linkProgram(m_po_id);
142         GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
143 
144         gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
145         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
146 
147         if (link_status != GL_TRUE)
148         {
149             if (should_succeed)
150             {
151                 TCU_FAIL("Program linking failed.");
152             }
153 
154             goto end;
155         }
156     }
157 
158     result = true;
159 end:
160     return result;
161 }
162 
163 /** Deinitializes all GL objects that may have been created during test execution. */
deinit()164 void ShaderTextureImageSamplesTestBase::deinit()
165 {
166     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
167 
168     deinitProgramAndShaderObjects();
169 
170     if (m_bo_id != 0)
171     {
172         gl.deleteBuffers(1, &m_bo_id);
173 
174         m_bo_id = 0;
175     }
176 
177     if (m_internalformat_n_samples_data != DE_NULL)
178     {
179         delete[] m_internalformat_n_samples_data;
180 
181         m_internalformat_n_samples_data = DE_NULL;
182     }
183 
184     if (m_to_id != 0)
185     {
186         gl.deleteTextures(1, &m_to_id);
187         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
188 
189         m_to_id = 0;
190     }
191 }
192 
193 /** Deinitializes program & shader objects that may have been created
194  *  during test execution.
195  **/
deinitProgramAndShaderObjects()196 void ShaderTextureImageSamplesTestBase::deinitProgramAndShaderObjects()
197 {
198     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
199 
200     if (m_cs_id != 0)
201     {
202         gl.deleteShader(m_cs_id);
203 
204         m_cs_id = 0;
205     }
206 
207     if (m_po_id != 0)
208     {
209         gl.deleteProgram(m_po_id);
210 
211         m_po_id = 0;
212     }
213 }
214 
215 /** Executes the functional test as described in CTS_ARB_shader_texture_image_samples.
216  *
217  *  This method throws a TestError exception if OpenGL implementation reports any
218  *  error OR the "samples" value reported by OpenGL is found to be incorrect.
219  *
220  *  @param sampler_type Tells which sampler type should be used for the test. Note that
221  *                      even though sampler type enum values are named after texture samplers,
222  *                      the actual ES SL types used during the test will depend on whether
223  *                      the caller requested images or textures to be used (see @param test_type)
224  *  @param test_type    Tells whether the test should verify image or texture samplers.
225  **/
executeFunctionalTest(const _sampler_type & sampler_type,const _test_type & test_type)226 void ShaderTextureImageSamplesTestBase::executeFunctionalTest(const _sampler_type &sampler_type,
227                                                               const _test_type &test_type)
228 {
229     std::string cs_body;
230     const char *cs_template_code = "#version 430\n"
231                                    "\n"
232                                    "#extension GL_ARB_shader_texture_image_samples : require\n"
233                                    "\n"
234                                    "layout(local_size_x = 1) in;\n"
235                                    "\n"
236                                    "buffer Result\n"
237                                    "{\n"
238                                    "    int samples;\n"
239                                    "};\n"
240                                    "\n"
241                                    "SAMPLER_TYPE data;\n"
242                                    "\n"
243                                    "void main()\n"
244                                    "{\n"
245                                    "    samples = SAMPLES_MODIFIER\n"
246                                    "}\n";
247 
248     /* Any program or shader objects lying around at this point? If so, release them
249      * before we proceed.
250      */
251     deinitProgramAndShaderObjects();
252 
253     /* Construct the shader body */
254     const std::string samples_modifier_token = "SAMPLES_MODIFIER";
255     size_t samples_modifier_token_location   = std::string::npos;
256     std::string samples_modifier_token_value;
257     std::string sampler_type_string;
258     const std::string sampler_type_token = "SAMPLER_TYPE";
259     size_t sampler_type_token_location   = std::string::npos;
260     std::string sampler_type_token_value;
261 
262     switch (test_type)
263     {
264     case TEST_TYPE_IMAGE:
265     {
266         samples_modifier_token_value = "imageSamples(data);\n";
267 
268         switch (sampler_type)
269         {
270         case SAMPLER_TYPE_ISAMPLER2DMS:
271         {
272             sampler_type_string      = "iimage2DMS";
273             sampler_type_token_value = "layout(rgba8i) uniform iimage2DMS";
274 
275             break;
276         }
277 
278         case SAMPLER_TYPE_ISAMPLER2DMSARRAY:
279         {
280             sampler_type_string      = "iimage2DMSArray";
281             sampler_type_token_value = "layout(rgba8i) uniform iimage2DMSArray";
282 
283             break;
284         }
285 
286         case SAMPLER_TYPE_SAMPLER2DMS:
287         {
288             sampler_type_string      = "image2DMS";
289             sampler_type_token_value = "layout(rgba8) uniform image2DMS";
290 
291             break;
292         }
293 
294         case SAMPLER_TYPE_SAMPLER2DMSARRAY:
295         {
296             sampler_type_string      = "image2DMSArray";
297             sampler_type_token_value = "layout(rgba8) uniform image2DMSArray";
298 
299             break;
300         }
301 
302         case SAMPLER_TYPE_USAMPLER2DMS:
303         {
304             sampler_type_string      = "uimage2DMS";
305             sampler_type_token_value = "layout(rgba8ui) uniform uimage2DMS";
306 
307             break;
308         }
309 
310         case SAMPLER_TYPE_USAMPLER2DMSARRAY:
311         {
312             sampler_type_string      = "uimage2DMSArray";
313             sampler_type_token_value = "layout(rgba8ui) uniform uimage2DMSArray";
314 
315             break;
316         }
317 
318         default:
319         {
320             TCU_FAIL("Unrecognized sampler type");
321         }
322         } /* switch (sampler_type) */
323 
324         break;
325     } /* case TEST_TYPE_IMAGE: */
326 
327     case TEST_TYPE_TEXTURE:
328     {
329         samples_modifier_token_value = "textureSamples(data);\n";
330 
331         switch (sampler_type)
332         {
333         case SAMPLER_TYPE_ISAMPLER2DMS:
334         {
335             sampler_type_string      = "isampler2DMS";
336             sampler_type_token_value = "uniform isampler2DMS";
337 
338             break;
339         }
340 
341         case SAMPLER_TYPE_ISAMPLER2DMSARRAY:
342         {
343             sampler_type_string      = "isampler2DMSArray";
344             sampler_type_token_value = "uniform isampler2DMSArray";
345 
346             break;
347         }
348 
349         case SAMPLER_TYPE_SAMPLER2DMS:
350         {
351             sampler_type_string      = "sampler2DMS";
352             sampler_type_token_value = "uniform sampler2DMS";
353 
354             break;
355         }
356 
357         case SAMPLER_TYPE_SAMPLER2DMSARRAY:
358         {
359             sampler_type_string      = "sampler2DMSArray";
360             sampler_type_token_value = "uniform sampler2DMSArray";
361 
362             break;
363         }
364 
365         case SAMPLER_TYPE_USAMPLER2DMS:
366         {
367             sampler_type_string      = "usampler2DMS";
368             sampler_type_token_value = "uniform usampler2DMS";
369 
370             break;
371         }
372 
373         case SAMPLER_TYPE_USAMPLER2DMSARRAY:
374         {
375             sampler_type_string      = "usampler2DMSArray";
376             sampler_type_token_value = "uniform usampler2DMSArray";
377 
378             break;
379         }
380 
381         default:
382         {
383             TCU_FAIL("Unrecognized sampler type");
384         }
385         } /* switch (sampler_type) */
386 
387         break;
388     } /* case TEST_TYPE_TEXTURE: */
389 
390     default:
391     {
392         TCU_FAIL("Unrecognized test type");
393     }
394     } /* switch (test_type) */
395 
396     cs_body = cs_template_code;
397 
398     while ((samples_modifier_token_location = cs_body.find(samples_modifier_token)) != std::string::npos)
399     {
400         cs_body.replace(samples_modifier_token_location, samples_modifier_token.length(), samples_modifier_token_value);
401     }
402 
403     while ((sampler_type_token_location = cs_body.find(sampler_type_token)) != std::string::npos)
404     {
405         cs_body.replace(sampler_type_token_location, sampler_type_token.length(), sampler_type_token_value);
406     }
407 
408     /* Build the compute program */
409     if (!buildComputeProgram(cs_body.c_str(), true, /* should_link_po */
410                              true))                 /* should_succeed */
411     {
412         TCU_FAIL("Could not link a test program");
413     }
414 
415     /* Set up SSBO */
416     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
417 
418     gl.shaderStorageBlockBinding(m_po_id, 0, /* storageBlockIndex */
419                                  0);         /* storageBlockBinding */
420     GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderStorageBlockBinding() call failed.");
421 
422     gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, /* index */
423                       m_bo_id);
424     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
425 
426     /* Determine what numbers of samples we can use for GL_RGBA8, GL_RGBA8I
427      * or GL_RGBA8UI internalformats. Specific choice depends on the sampler type
428      * requested bty the caller.
429      */
430     glw::GLenum texture_internalformat = GL_NONE;
431     glw::GLenum texture_target         = GL_NONE;
432 
433     if (sampler_type == SAMPLER_TYPE_ISAMPLER2DMS || sampler_type == SAMPLER_TYPE_ISAMPLER2DMSARRAY)
434     {
435         texture_internalformat = GL_RGBA8I;
436     }
437     else if (sampler_type == SAMPLER_TYPE_SAMPLER2DMS || sampler_type == SAMPLER_TYPE_SAMPLER2DMSARRAY)
438     {
439         texture_internalformat = GL_RGBA8;
440     }
441     else
442     {
443         texture_internalformat = GL_RGBA8UI;
444     }
445 
446     if (sampler_type == SAMPLER_TYPE_ISAMPLER2DMS || sampler_type == SAMPLER_TYPE_SAMPLER2DMS ||
447         sampler_type == SAMPLER_TYPE_USAMPLER2DMS)
448     {
449         texture_target = GL_TEXTURE_2D_MULTISAMPLE;
450     }
451     else
452     {
453         texture_target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
454     }
455 
456     gl.getInternalformativ(texture_target, texture_internalformat, GL_NUM_SAMPLE_COUNTS, 1, /* bufSize */
457                            &m_internalformat_n_samples_count);
458     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() call failed.");
459 
460     if (m_internalformat_n_samples_count < 1)
461     {
462         TCU_FAIL("Invalid value returned by glGetInternalformativ() for a GL_NUM_SAMPLE_COUNTS query");
463     }
464 
465     m_internalformat_n_samples_data = new glw::GLint[m_internalformat_n_samples_count];
466 
467     gl.getInternalformativ(texture_target, texture_internalformat, GL_SAMPLES, m_internalformat_n_samples_count,
468                            m_internalformat_n_samples_data);
469     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() call failed.");
470 
471     /* Iterate over all sample counts. For each iteration, set up texture storage,
472      * run one work-item which will store the value retrieved by one of the two new
473      * ES SL functions into the buffer object. Once that happens, map the buffer
474      * object storage contents into process space and validate the value */
475     for (int n_value = 0; n_value < m_internalformat_n_samples_count; ++n_value)
476     {
477         if (test_type == TEST_TYPE_IMAGE)
478         {
479             /* Shader images do not necessarily support all sample counts. */
480             int max_image_samples;
481 
482             gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples);
483             GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_IMAGE_SAMPLES) call failed.");
484 
485             if (m_internalformat_n_samples_data[n_value] > max_image_samples)
486                 continue;
487         }
488 
489         gl.genTextures(1, &m_to_id);
490         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
491 
492         gl.bindTexture(texture_target, m_to_id);
493         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
494 
495         if (texture_target == GL_TEXTURE_2D_MULTISAMPLE)
496         {
497             gl.texStorage2DMultisample(texture_target, m_internalformat_n_samples_data[n_value], texture_internalformat,
498                                        m_to_width, m_to_height, GL_FALSE); /* fixedsamplelocations */
499             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed");
500         }
501         else
502         {
503             DE_ASSERT(texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
504 
505             gl.texStorage3DMultisample(texture_target, m_internalformat_n_samples_data[n_value], texture_internalformat,
506                                        m_to_width, m_to_height, m_to_depth, GL_TRUE); /* fixedsamplelocations */
507             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed");
508         }
509 
510         /* If we're running the "image" test, bind the texture to zeroth image unit */
511         if (test_type == TEST_TYPE_IMAGE)
512         {
513             gl.bindImageTexture(0,          /* unit */
514                                 m_to_id, 0, /* level */
515                                 GL_FALSE,   /* layered */
516                                 0,          /* lyer */
517                                 GL_READ_ONLY, texture_internalformat);
518             GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed.");
519         }
520 
521         /* Dispatch a compute request */
522         gl.useProgram(m_po_id);
523         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
524 
525         gl.dispatchCompute(1,  /* num_groups_x */
526                            1,  /* num_groups_y */
527                            1); /* num_groups_z */
528         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute() call failed.");
529 
530         gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
531         GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier() call failed.");
532 
533         /* Map the buffer object storage into process space */
534         const void *bo_ptr        = gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
535         glw::GLint expected_value = 0;
536 
537         GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed");
538 
539         expected_value = m_internalformat_n_samples_data[n_value];
540 
541         if (*(int *)bo_ptr != expected_value)
542         {
543             m_testCtx.getLog() << tcu::TestLog::Message << "Value reported for the " << sampler_type_string << " test ["
544                                << *(int *)bo_ptr
545                                << "] "
546                                   " is different from the expected one ["
547                                << expected_value << "]." << tcu::TestLog::EndMessage;
548 
549             TCU_FAIL("Invalid value reported by ES SL function");
550         }
551 
552         /* Safe to unmap the BO at this point */
553         gl.unmapBuffer(GL_ARRAY_BUFFER);
554 
555         gl.deleteTextures(1, &m_to_id);
556         m_to_id = 0;
557         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
558     } /* for (all "n samples" values) */
559 }
560 
561 /** Initializes all GL objects required to run the test. Also throws a
562  *  NotSupportedError exception if GL_ARB_shader_texture_image_samples is not
563  *  reported as a supported extension.
564  **/
init()565 void ShaderTextureImageSamplesTestBase::init()
566 {
567     /* Make sure GL_ARB_shader_texture_image_samples is supported before continuing */
568     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_texture_image_samples"))
569     {
570         throw tcu::NotSupportedError("GL_ARB_shader_texture_image_samples extension is not supported.");
571     }
572 
573     /* Allocate BO storage to hold the result int value */
574     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
575 
576     gl.genBuffers(1, &m_bo_id);
577     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
578 
579     gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
580     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
581 
582     gl.bufferData(GL_ARRAY_BUFFER, sizeof(int), DE_NULL, /* data */
583                   GL_STATIC_DRAW);                       /* usage */
584     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
585 }
586 
587 /** Constructor.
588  *
589  *  @param context Rendering context handle.
590  **/
ShaderTextureImageSampleFunctionalTest(deqp::Context & context,const char * test_name)591 ShaderTextureImageSampleFunctionalTest::ShaderTextureImageSampleFunctionalTest(deqp::Context &context,
592                                                                                const char *test_name)
593     : ShaderTextureImageSamplesTestBase(context, test_name,
594                                         "Verifies that the new ES SL functions (imageSamples() and "
595                                         "textureSamples() ) work as per spec for all supported "
596                                         "numbers of samples + texture target combinations.")
597 {
598     type_to_test = test_name[0] == 'i' ? TEST_TYPE_IMAGE : TEST_TYPE_TEXTURE;
599 }
600 
601 /** Initializes all GL objects required to run the test.  Also throws a
602  *  NotSupportedError exception if testing images and GL_MAX_IMAGE_SAMPLES = 0.
603  **/
init()604 void ShaderTextureImageSampleFunctionalTest::init()
605 {
606     ShaderTextureImageSamplesTestBase::init();
607 
608     if (type_to_test == TEST_TYPE_IMAGE)
609     {
610         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
611 
612         glw::GLint max_image_samples;
613         gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples);
614         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");
615 
616         if (max_image_samples == 0)
617         {
618             throw tcu::NotSupportedError("GL_MAX_IMAGE_SAMPLES == 0");
619         }
620     }
621 }
622 
623 /** Executes test iteration.
624  *
625  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
626  */
iterate()627 tcu::TestNode::IterateResult ShaderTextureImageSampleFunctionalTest::iterate()
628 {
629     for (unsigned int n_sampler_type = 0; n_sampler_type < SAMPLER_TYPE_COUNT; ++n_sampler_type)
630     {
631         _sampler_type sampler_type = (_sampler_type)n_sampler_type;
632 
633         for (unsigned int n_test_type = 0; n_test_type < TEST_TYPE_COUNT; ++n_test_type)
634         {
635             _test_type test_type = (_test_type)n_test_type;
636 
637             if (test_type == type_to_test)
638             {
639                 executeFunctionalTest(sampler_type, test_type);
640             }
641         } /* for (all test types) */
642     }     /* for (all sampler types) */
643 
644     /* Test case passed */
645     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
646 
647     return STOP;
648 }
649 
650 /** Constructor.
651  *
652  *  @param context Rendering context handle.
653  **/
ShaderTextureImageSamplesGLSLExtensionEnableTest(deqp::Context & context)654 ShaderTextureImageSamplesGLSLExtensionEnableTest::ShaderTextureImageSamplesGLSLExtensionEnableTest(
655     deqp::Context &context)
656     : ShaderTextureImageSamplesTestBase(
657           context, "glsl_extension_enable",
658           "Verifies a shader with \"#extension GL_ARB_shader_texture_image_samples : enable\" "
659           "line defines a corresponding pre-processor macro.")
660 {
661     /* Left blank on purpose */
662 }
663 
664 /** Executes test iteration.
665  *
666  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
667  */
iterate()668 tcu::TestNode::IterateResult ShaderTextureImageSamplesGLSLExtensionEnableTest::iterate()
669 {
670     const char *cs_body = "#version 440\n"
671                           "\n"
672                           "#extension GL_ARB_shader_texture_image_samples : enable\n"
673                           "\n"
674                           "void main()\n"
675                           "{\n"
676                           "#ifndef GL_ARB_shader_texture_image_samples\n"
677                           "    force_compilation_error\n"
678                           "#endif\n"
679                           "}\n";
680 
681     if (!buildComputeProgram(cs_body, false, /* should_link_po */
682                              true))          /* should_succeed */
683     {
684         TCU_FAIL("GL_ARB_shader_image_load_store preprocessor #define is not set to the value of 1");
685     }
686 
687     /* Test case passed */
688     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
689 
690     return STOP;
691 }
692 
693 /** Constructor.
694  *
695  *  @param context Rendering context handle.
696  **/
ShaderTextureImageSamplesGLSLExtensionRequireTest(deqp::Context & context)697 ShaderTextureImageSamplesGLSLExtensionRequireTest::ShaderTextureImageSamplesGLSLExtensionRequireTest(
698     deqp::Context &context)
699     : ShaderTextureImageSamplesTestBase(
700           context, "glsl_extension_require",
701           "Verifies a shader with \"#extension GL_ARB_shader_texture_image_samples : require\" "
702           "line compiles without error.")
703 {
704     /* Left blank on purpose */
705 }
706 
707 /** Executes test iteration.
708  *
709  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
710  */
iterate()711 tcu::TestNode::IterateResult ShaderTextureImageSamplesGLSLExtensionRequireTest::iterate()
712 {
713     const char *cs_body = "#version 440\n"
714                           "\n"
715                           "#extension GL_ARB_shader_texture_image_samples : require\n"
716                           "\n"
717                           "void main()\n"
718                           "{\n"
719                           "}\n";
720 
721     if (!buildComputeProgram(cs_body, false, /* should_link_po */
722                              true))          /* should_succeed */
723     {
724         TCU_FAIL("A valid compute program has failed to build");
725     }
726 
727     /* Test case passed */
728     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
729 
730     return STOP;
731 }
732 
733 /** Constructor.
734  *
735  *  @param context Rendering context.
736  */
ShaderTextureImageSamplesTests(deqp::Context & context)737 ShaderTextureImageSamplesTests::ShaderTextureImageSamplesTests(deqp::Context &context)
738     : TestCaseGroup(context, "shader_texture_image_samples_tests",
739                     "Contains conformance tests that verify GL implementation's support "
740                     "for GL_ARB_shader_texture_image_samples extension.")
741 {
742 }
743 
744 /** Initializes the test group contents. */
init()745 void ShaderTextureImageSamplesTests::init()
746 {
747     addChild(new ShaderTextureImageSampleFunctionalTest(m_context, "image_functional_test"));
748     addChild(new ShaderTextureImageSampleFunctionalTest(m_context, "texture_functional_test"));
749     addChild(new ShaderTextureImageSamplesGLSLExtensionEnableTest(m_context));
750     addChild(new ShaderTextureImageSamplesGLSLExtensionRequireTest(m_context));
751 }
752 
753 } // namespace glcts
754