Home | History | Annotate | Download | only in gl
      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  */
     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  **/
     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. */
    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  **/
    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  **/
    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 												   " is different from the expected one ["
    546 							   << expected_value << "]." << tcu::TestLog::EndMessage;
    547 
    548 			TCU_FAIL("Invalid value reported by ES SL function");
    549 		}
    550 
    551 		/* Safe to unmap the BO at this point */
    552 		gl.unmapBuffer(GL_ARRAY_BUFFER);
    553 
    554 		gl.deleteTextures(1, &m_to_id);
    555 		m_to_id = 0;
    556 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
    557 	} /* for (all "n samples" values) */
    558 }
    559 
    560 /** Initializes all GL objects required to run the test. Also throws a
    561  *  NotSupportedError exception if GL_ARB_shader_texture_image_samples is not
    562  *  reported as a supported extension.
    563  **/
    564 void ShaderTextureImageSamplesTestBase::init()
    565 {
    566 	/* Make sure GL_ARB_shader_texture_image_samples is supported before continuing */
    567 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_texture_image_samples"))
    568 	{
    569 		throw tcu::NotSupportedError("GL_ARB_shader_texture_image_samples extension is not supported.");
    570 	}
    571 
    572 	/* Allocate BO storage to hold the result int value */
    573 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    574 
    575 	gl.genBuffers(1, &m_bo_id);
    576 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
    577 
    578 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
    579 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
    580 
    581 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(int), DE_NULL, /* data */
    582 				  GL_STATIC_DRAW);						 /* usage */
    583 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
    584 }
    585 
    586 /** Constructor.
    587  *
    588  *  @param context Rendering context handle.
    589  **/
    590 ShaderTextureImageSampleFunctionalTest::ShaderTextureImageSampleFunctionalTest(deqp::Context& context,
    591 																			   const char*	test_name)
    592 	: ShaderTextureImageSamplesTestBase(context, test_name, "Verifies that the new ES SL functions (imageSamples() and "
    593 															"textureSamples() ) work as per spec for all supported "
    594 															"numbers of samples + texture target combinations.")
    595 {
    596 	type_to_test = test_name[0] == 'i' ? TEST_TYPE_IMAGE : TEST_TYPE_TEXTURE;
    597 }
    598 
    599 /** Initializes all GL objects required to run the test.  Also throws a
    600  *  NotSupportedError exception if testing images and GL_MAX_IMAGE_SAMPLES = 0.
    601  **/
    602 void ShaderTextureImageSampleFunctionalTest::init()
    603 {
    604 	ShaderTextureImageSamplesTestBase::init();
    605 
    606 	if (type_to_test == TEST_TYPE_IMAGE)
    607 	{
    608 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    609 
    610 		glw::GLint max_image_samples;
    611 		gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples);
    612 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");
    613 
    614 		if (max_image_samples == 0)
    615 		{
    616 			throw tcu::NotSupportedError("GL_MAX_IMAGE_SAMPLES == 0");
    617 		}
    618 	}
    619 }
    620 
    621 /** Executes test iteration.
    622  *
    623  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
    624  */
    625 tcu::TestNode::IterateResult ShaderTextureImageSampleFunctionalTest::iterate()
    626 {
    627 	for (unsigned int n_sampler_type = 0; n_sampler_type < SAMPLER_TYPE_COUNT; ++n_sampler_type)
    628 	{
    629 		_sampler_type sampler_type = (_sampler_type)n_sampler_type;
    630 
    631 		for (unsigned int n_test_type = 0; n_test_type < TEST_TYPE_COUNT; ++n_test_type)
    632 		{
    633 			_test_type test_type = (_test_type)n_test_type;
    634 
    635 			if (test_type == type_to_test)
    636 			{
    637 				executeFunctionalTest(sampler_type, test_type);
    638 			}
    639 		} /* for (all test types) */
    640 	}	 /* for (all sampler types) */
    641 
    642 	/* Test case passed */
    643 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    644 
    645 	return STOP;
    646 }
    647 
    648 /** Constructor.
    649  *
    650  *  @param context Rendering context handle.
    651  **/
    652 ShaderTextureImageSamplesGLSLExtensionEnableTest::ShaderTextureImageSamplesGLSLExtensionEnableTest(
    653 	deqp::Context& context)
    654 	: ShaderTextureImageSamplesTestBase(
    655 		  context, "glsl_extension_enable",
    656 		  "Verifies a shader with \"#extension GL_ARB_shader_texture_image_samples : enable\" "
    657 		  "line defines a corresponding pre-processor macro.")
    658 {
    659 	/* Left blank on purpose */
    660 }
    661 
    662 /** Executes test iteration.
    663  *
    664  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
    665  */
    666 tcu::TestNode::IterateResult ShaderTextureImageSamplesGLSLExtensionEnableTest::iterate()
    667 {
    668 	const char* cs_body = "#version 440\n"
    669 						  "\n"
    670 						  "#extension GL_ARB_shader_texture_image_samples : enable\n"
    671 						  "\n"
    672 						  "void main()\n"
    673 						  "{\n"
    674 						  "#ifndef GL_ARB_shader_texture_image_samples\n"
    675 						  "    force_compilation_error\n"
    676 						  "#endif\n"
    677 						  "}\n";
    678 
    679 	if (!buildComputeProgram(cs_body, false, /* should_link_po */
    680 							 true))			 /* should_succeed */
    681 	{
    682 		TCU_FAIL("GL_ARB_shader_image_load_store preprocessor #define is not set to the value of 1");
    683 	}
    684 
    685 	/* Test case passed */
    686 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    687 
    688 	return STOP;
    689 }
    690 
    691 /** Constructor.
    692  *
    693  *  @param context Rendering context handle.
    694  **/
    695 ShaderTextureImageSamplesGLSLExtensionRequireTest::ShaderTextureImageSamplesGLSLExtensionRequireTest(
    696 	deqp::Context& context)
    697 	: ShaderTextureImageSamplesTestBase(
    698 		  context, "glsl_extension_require",
    699 		  "Verifies a shader with \"#extension GL_ARB_shader_texture_image_samples : require\" "
    700 		  "line compiles without error.")
    701 {
    702 	/* Left blank on purpose */
    703 }
    704 
    705 /** Executes test iteration.
    706  *
    707  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
    708  */
    709 tcu::TestNode::IterateResult ShaderTextureImageSamplesGLSLExtensionRequireTest::iterate()
    710 {
    711 	const char* cs_body = "#version 440\n"
    712 						  "\n"
    713 						  "#extension GL_ARB_shader_texture_image_samples : require\n"
    714 						  "\n"
    715 						  "void main()\n"
    716 						  "{\n"
    717 						  "}\n";
    718 
    719 	if (!buildComputeProgram(cs_body, false, /* should_link_po */
    720 							 true))			 /* should_succeed */
    721 	{
    722 		TCU_FAIL("A valid compute program has failed to build");
    723 	}
    724 
    725 	/* Test case passed */
    726 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    727 
    728 	return STOP;
    729 }
    730 
    731 /** Constructor.
    732  *
    733  *  @param context Rendering context.
    734  */
    735 ShaderTextureImageSamplesTests::ShaderTextureImageSamplesTests(deqp::Context& context)
    736 	: TestCaseGroup(context, "shader_texture_image_samples_tests",
    737 					"Contains conformance tests that verify GL implementation's support "
    738 					"for GL_ARB_shader_texture_image_samples extension.")
    739 {
    740 }
    741 
    742 /** Initializes the test group contents. */
    743 void ShaderTextureImageSamplesTests::init()
    744 {
    745 	addChild(new ShaderTextureImageSampleFunctionalTest(m_context, "image_functional_test"));
    746 	addChild(new ShaderTextureImageSampleFunctionalTest(m_context, "texture_functional_test"));
    747 	addChild(new ShaderTextureImageSamplesGLSLExtensionEnableTest(m_context));
    748 	addChild(new ShaderTextureImageSamplesGLSLExtensionRequireTest(m_context));
    749 }
    750 
    751 } /* glcts namespace */
    752