Home | History | Annotate | Download | only in gl
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2015-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 #include "gl4cStencilTexturingTests.hpp"
     25 
     26 #include "gluContextInfo.hpp"
     27 #include "gluDefs.hpp"
     28 #include "gluStrUtil.hpp"
     29 #include "glwEnums.hpp"
     30 #include "glwFunctions.hpp"
     31 #include "tcuTestLog.hpp"
     32 
     33 #include <algorithm>
     34 #include <string>
     35 #include <vector>
     36 
     37 #define DEBUG_REPLACE_TOKEN 0
     38 
     39 using namespace glw;
     40 
     41 namespace gl4cts
     42 {
     43 namespace StencilTexturing
     44 {
     45 class Utils
     46 {
     47 public:
     48 	static GLuint createAndBuildProgram(deqp::Context& context, const GLchar* cs_code, const GLchar* fs_code,
     49 										const GLchar* gs_code, const GLchar* tcs_code, const GLchar* tes_code,
     50 										const GLchar* vs_code);
     51 
     52 	static GLuint createAndCompileShader(deqp::Context& context, const GLenum type, const GLchar* code);
     53 
     54 	static GLuint createAndFill2DTexture(deqp::Context& context, GLuint width, GLuint height, GLenum internal_format,
     55 										 GLenum format, GLenum type, const GLvoid* data);
     56 
     57 	static void deleteProgram(deqp::Context& context, const GLuint id);
     58 	static void deleteShader(deqp::Context& context, const GLuint id);
     59 	static void deleteTexture(deqp::Context& context, const GLuint id);
     60 	static bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name);
     61 
     62 	static void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string);
     63 };
     64 
     65 /** Create and build program from provided sources
     66  *
     67  * @param context  Test context
     68  * @param cs_code  Source code for compute shader stage
     69  * @param fs_code  Source code for fragment shader stage
     70  * @param gs_code  Source code for geometry shader stage
     71  * @param tcs_code Source code for tesselation control shader stage
     72  * @param tes_code Source code for tesselation evaluation shader stage
     73  * @param vs_code  Source code for vertex shader stage
     74  *
     75  * @return ID of program object
     76  **/
     77 GLuint Utils::createAndBuildProgram(deqp::Context& context, const GLchar* cs_code, const GLchar* fs_code,
     78 									const GLchar* gs_code, const GLchar* tcs_code, const GLchar* tes_code,
     79 									const GLchar* vs_code)
     80 {
     81 #define N_SHADER_STAGES 6
     82 
     83 	const Functions& gl							 = context.getRenderContext().getFunctions();
     84 	GLuint			 id							 = 0;
     85 	GLuint			 shader_ids[N_SHADER_STAGES] = { 0 };
     86 
     87 	const GLchar* shader_sources[N_SHADER_STAGES] = { cs_code, fs_code, gs_code, tcs_code, tes_code, vs_code };
     88 
     89 	const GLenum shader_types[N_SHADER_STAGES] = { GL_COMPUTE_SHADER,		  GL_FRAGMENT_SHADER,
     90 												   GL_GEOMETRY_SHADER,		  GL_TESS_CONTROL_SHADER,
     91 												   GL_TESS_EVALUATION_SHADER, GL_VERTEX_SHADER };
     92 	GLint status = GL_FALSE;
     93 
     94 	/* Compile all shaders */
     95 	try
     96 	{
     97 		for (GLuint i = 0; i < N_SHADER_STAGES; ++i)
     98 		{
     99 			if (0 != shader_sources[i])
    100 			{
    101 				shader_ids[i] = createAndCompileShader(context, shader_types[i], shader_sources[i]);
    102 			}
    103 		}
    104 
    105 		/* Check compilation */
    106 		for (GLuint i = 0; i < N_SHADER_STAGES; ++i)
    107 		{
    108 			if ((0 != shader_sources[i]) && (0 == shader_ids[i]))
    109 			{
    110 				context.getTestContext().getLog() << tcu::TestLog::Message
    111 												  << "Failed to build program due to compilation problems"
    112 												  << tcu::TestLog::EndMessage;
    113 
    114 				/* Delete shaders */
    115 				for (GLuint j = 0; j < N_SHADER_STAGES; ++j)
    116 				{
    117 					deleteShader(context, shader_ids[j]);
    118 				}
    119 
    120 				/* Done */
    121 				return 0;
    122 			}
    123 		}
    124 
    125 		/* Create program */
    126 		id = gl.createProgram();
    127 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
    128 
    129 		/* Attach shaders */
    130 		for (GLuint i = 0; i < N_SHADER_STAGES; ++i)
    131 		{
    132 			if (0 != shader_ids[i])
    133 			{
    134 				gl.attachShader(id, shader_ids[i]);
    135 				GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    136 			}
    137 		}
    138 
    139 		/* Link program */
    140 		gl.linkProgram(id);
    141 		GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
    142 
    143 		/* Clean shaders */
    144 		for (GLuint j = 0; j < N_SHADER_STAGES; ++j)
    145 		{
    146 			deleteShader(context, shader_ids[j]);
    147 		}
    148 
    149 		/* Get link status */
    150 		gl.getProgramiv(id, GL_LINK_STATUS, &status);
    151 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    152 
    153 		/* Log link error */
    154 		if (GL_TRUE != status)
    155 		{
    156 			glw::GLint  length = 0;
    157 			std::string message;
    158 
    159 			/* Get error log length */
    160 			gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
    161 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    162 
    163 			message.resize(length, 0);
    164 
    165 			/* Get error log */
    166 			gl.getProgramInfoLog(id, length, 0, &message[0]);
    167 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
    168 
    169 			context.getTestContext().getLog() << tcu::TestLog::Message << "Program linking failed: " << message
    170 											  << tcu::TestLog::EndMessage;
    171 
    172 			/* Clean program */
    173 			deleteProgram(context, id);
    174 
    175 			/* Done */
    176 			return 0;
    177 		}
    178 	}
    179 	catch (std::exception& exc)
    180 	{
    181 		/* Delete shaders */
    182 		for (GLuint j = 0; j < N_SHADER_STAGES; ++j)
    183 		{
    184 			deleteShader(context, shader_ids[j]);
    185 		}
    186 
    187 		throw exc;
    188 	}
    189 
    190 	return id;
    191 }
    192 
    193 /** Create and compile shader
    194  *
    195  * @param context Test context
    196  * @param type    Type of shader
    197  * @param code    Source code for shader
    198  *
    199  * @return ID of shader object
    200  **/
    201 GLuint Utils::createAndCompileShader(deqp::Context& context, const GLenum type, const GLchar* code)
    202 {
    203 	const Functions& gl		= context.getRenderContext().getFunctions();
    204 	GLuint			 id		= gl.createShader(type);
    205 	GLint			 status = GL_FALSE;
    206 
    207 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    208 
    209 	try
    210 	{
    211 		gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
    212 		GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
    213 
    214 		/* Compile */
    215 		gl.compileShader(id);
    216 		GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
    217 
    218 		/* Get compilation status */
    219 		gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
    220 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    221 
    222 		/* Log compilation error */
    223 		if (GL_TRUE != status)
    224 		{
    225 			glw::GLint  length = 0;
    226 			std::string message;
    227 
    228 			/* Error log length */
    229 			gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
    230 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    231 
    232 			/* Prepare storage */
    233 			message.resize(length, 0);
    234 
    235 			/* Get error log */
    236 			gl.getShaderInfoLog(id, length, 0, &message[0]);
    237 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
    238 
    239 			context.getTestContext().getLog() << tcu::TestLog::Message << "Shader (" << glu::getShaderTypeStr(type)
    240 											  << ") compilation failed: " << message << tcu::TestLog::EndMessage;
    241 
    242 			deleteShader(context, id);
    243 			id = 0;
    244 		}
    245 	}
    246 	catch (std::exception& exc)
    247 	{
    248 		deleteShader(context, id);
    249 		throw exc;
    250 	}
    251 
    252 	return id;
    253 }
    254 
    255 /** Generate and fill 2d texture
    256  *
    257  * @param context         Test context
    258  * @param width           Width of texture
    259  * @param height          Height of texture
    260  * @param internal_format Internal format of texture
    261  * @param format          Format of data
    262  * @param type            Type of data
    263  * @param data            Data
    264  *
    265  * @return ID of texture object
    266  **/
    267 GLuint Utils::createAndFill2DTexture(deqp::Context& context, GLuint width, GLuint height, GLenum internal_format,
    268 									 GLenum format, GLenum type, const GLvoid* data)
    269 {
    270 	const Functions& gl = context.getRenderContext().getFunctions();
    271 	GLuint			 id = 0;
    272 
    273 	gl.genTextures(1, &id);
    274 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
    275 
    276 	try
    277 	{
    278 		gl.bindTexture(GL_TEXTURE_2D, id);
    279 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    280 
    281 		gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, internal_format, width, height, 0 /* border */, format, type, data);
    282 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
    283 
    284 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    285 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    286 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
    287 
    288 		gl.bindTexture(GL_TEXTURE_2D, 0);
    289 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    290 	}
    291 	catch (std::exception& exc)
    292 	{
    293 		gl.deleteTextures(1, &id);
    294 		id = 0;
    295 
    296 		throw exc;
    297 	}
    298 
    299 	return id;
    300 }
    301 
    302 /** Delete program
    303  *
    304  * @param context Test context
    305  * @param id      ID of program
    306  **/
    307 void Utils::deleteProgram(deqp::Context& context, const GLuint id)
    308 {
    309 	const glw::Functions& gl = context.getRenderContext().getFunctions();
    310 
    311 	if (0 != id)
    312 	{
    313 		gl.deleteProgram(id);
    314 	}
    315 }
    316 
    317 /** Delete shader
    318  *
    319  * @param context Test context
    320  * @param id      ID of shader
    321  **/
    322 void Utils::deleteShader(deqp::Context& context, const GLuint id)
    323 {
    324 	const glw::Functions& gl = context.getRenderContext().getFunctions();
    325 
    326 	if (0 != id)
    327 	{
    328 		gl.deleteShader(id);
    329 	}
    330 }
    331 
    332 /** Delete texture
    333  *
    334  * @param context Test context
    335  * @param id      ID of texture
    336  **/
    337 void Utils::deleteTexture(deqp::Context& context, const GLuint id)
    338 {
    339 	const glw::Functions& gl = context.getRenderContext().getFunctions();
    340 
    341 	if (0 != id)
    342 	{
    343 		gl.deleteTextures(1, &id);
    344 	}
    345 }
    346 
    347 /** Checks if extensions is not available.
    348  *
    349  * @param context        Test context
    350  * @param extension_name Name of extension
    351  *
    352  * @return true if extension is reported as available, false otherwise
    353  **/
    354 bool Utils::isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
    355 {
    356 	const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
    357 
    358 	if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
    359 	{
    360 		std::string message = "Required extension is not supported: ";
    361 		message.append(extension_name);
    362 
    363 		return false;
    364 	}
    365 
    366 	return true;
    367 }
    368 
    369 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
    370  *
    371  * @param token           Token string
    372  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
    373  * @param text            String that will be used as replacement for <token>
    374  * @param string          String to work on
    375  **/
    376 void Utils::replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
    377 {
    378 	const size_t text_length	= strlen(text);
    379 	const size_t token_length   = strlen(token);
    380 	const size_t token_position = string.find(token, search_position);
    381 
    382 #if DEBUG_REPLACE_TOKEN
    383 	if (std::string::npos == token_position)
    384 	{
    385 		string.append("\n\nInvalid token: ");
    386 		string.append(token);
    387 
    388 		TCU_FAIL(string.c_str());
    389 	}
    390 #endif /* DEBUG_REPLACE_TOKEN */
    391 
    392 	string.replace(token_position, token_length, text, text_length);
    393 
    394 	search_position = token_position + text_length;
    395 }
    396 
    397 /* FunctionalTest */
    398 /* Shader sources */
    399 const GLchar* FunctionalTest::m_compute_shader_code =
    400 	"#version 430 core\n"
    401 	"\n"
    402 	"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
    403 	"\n"
    404 	"IMAGE_DEFINITION;\n"
    405 	"SAMPLER_DEFINITION;\n"
    406 	"\n"
    407 	"void main()\n"
    408 	"{\n"
    409 	"    vec2 tex_coord = vec2(gl_GlobalInvocationID.xy) / 8.0;\n"
    410 	"\n"
    411 	"    imageStore(uni_image,\n"
    412 	"               ivec2(gl_GlobalInvocationID.xy),\n"
    413 	"               TYPE(texture(uni_sampler, tex_coord).r, 0, 0, 0));\n"
    414 	"}\n"
    415 	"\n";
    416 
    417 const GLchar* FunctionalTest::m_fragment_shader_code =
    418 	"#version 430 core\n"
    419 	"\n"
    420 	"     in  vec2 gs_fs_tex_coord;\n"
    421 	"flat in  uint gs_fs_result;\n"
    422 	"     out TYPE fs_out_result;\n"
    423 	"\n"
    424 	"SAMPLER_DEFINITION;\n"
    425 	"\n"
    426 	"void main()\n"
    427 	"{\n"
    428 	"    if (1 != gs_fs_result)\n"
    429 	"    {\n"
    430 	"        fs_out_result = texture(uni_sampler, vec2(0.9375, 0.9375));\n"
    431 	"    }\n"
    432 	"    else\n"
    433 	"    {\n"
    434 	"        fs_out_result = texture(uni_sampler, gs_fs_tex_coord);\n"
    435 	"    }\n"
    436 	"}\n"
    437 	"\n";
    438 
    439 const GLchar* FunctionalTest::m_geometry_shader_code =
    440 	"#version 430 core\n"
    441 	"\n"
    442 	"layout(points)                           in;\n"
    443 	"layout(triangle_strip, max_vertices = 4) out;\n"
    444 	"\n"
    445 	"     in  uint tes_gs_result[];\n"
    446 	"flat out uint gs_fs_result;\n"
    447 	"     out vec2 gs_fs_tex_coord;\n"
    448 	"\n"
    449 	"SAMPLER_DEFINITION;\n"
    450 	"\n"
    451 	"void main()\n"
    452 	"{\n"
    453 	"    uint result = 1u;\n"
    454 	"\n"
    455 	"    if (1 != tes_gs_result[0])\n"
    456 	"    {\n"
    457 	"        result = 0u;\n"
    458 	"    }\n"
    459 	"\n"
    460 	"    if (EXPECTED_VALUE != texture(uni_sampler, vec2(0.9375, 0.9375)).r)\n"
    461 	"    {\n"
    462 	"        result = 0u;\n"
    463 	"    }\n"
    464 	"\n"
    465 	"    gs_fs_result    = result;\n"
    466 	"    gs_fs_tex_coord = vec2(0, 0);\n"
    467 	"    gl_Position     = vec4(-1, -1, 0, 1);\n"
    468 	"    EmitVertex();\n"
    469 	"    gs_fs_result    = result;\n"
    470 	"    gs_fs_tex_coord = vec2(0, 1);\n"
    471 	"    gl_Position     = vec4(-1, 1, 0, 1);\n"
    472 	"    EmitVertex();\n"
    473 	"    gs_fs_result    = result;\n"
    474 	"    gs_fs_tex_coord = vec2(1, 0);\n"
    475 	"    gl_Position     = vec4(1, -1, 0, 1);\n"
    476 	"    EmitVertex();\n"
    477 	"    gs_fs_result    = result;\n"
    478 	"    gs_fs_tex_coord = vec2(1, 1);\n"
    479 	"    gl_Position     = vec4(1, 1, 0, 1);\n"
    480 	"    EmitVertex();\n"
    481 	"}\n"
    482 	"\n";
    483 
    484 const GLchar* FunctionalTest::m_tesselation_control_shader_code =
    485 	"#version 430 core\n"
    486 	"\n"
    487 	"layout(vertices = 1) out;\n"
    488 	"\n"
    489 	"in  uint vs_tcs_result[];\n"
    490 	"out uint tcs_tes_result[];\n"
    491 	"\n"
    492 	"SAMPLER_DEFINITION;\n"
    493 	"\n"
    494 	"void main()\n"
    495 	"{\n"
    496 	"    uint result = 1u;\n"
    497 	"\n"
    498 	"    if (1u != vs_tcs_result[gl_InvocationID])\n"
    499 	"    {\n"
    500 	"        result = 0u;\n"
    501 	"    }\n"
    502 	"\n"
    503 	"    if (EXPECTED_VALUE != texture(uni_sampler, vec2(0.9375, 0.9375)).r)\n"
    504 	"    {\n"
    505 	"        result = 0u;\n"
    506 	"    }\n"
    507 	"\n"
    508 	"    tcs_tes_result[gl_InvocationID] = result;\n"
    509 	"\n"
    510 	"    gl_TessLevelOuter[0] = 1.0;\n"
    511 	"    gl_TessLevelOuter[1] = 1.0;\n"
    512 	"    gl_TessLevelOuter[2] = 1.0;\n"
    513 	"    gl_TessLevelOuter[3] = 1.0;\n"
    514 	"    gl_TessLevelInner[0] = 1.0;\n"
    515 	"    gl_TessLevelInner[1] = 1.0;\n"
    516 	"}\n"
    517 	"\n";
    518 
    519 const GLchar* FunctionalTest::m_tesselation_evaluation_shader_code =
    520 	"#version 430 core\n"
    521 	"\n"
    522 	"layout(isolines, point_mode) in;\n"
    523 	"\n"
    524 	"in  uint tcs_tes_result[];\n"
    525 	"out uint tes_gs_result;\n"
    526 	"\n"
    527 	"SAMPLER_DEFINITION;\n"
    528 	"\n"
    529 	"void main()\n"
    530 	"{\n"
    531 	"    uint result = 1u;\n"
    532 	"\n"
    533 	"    if (1u != tcs_tes_result[0])\n"
    534 	"    {\n"
    535 	"        result = 0u;\n"
    536 	"    }\n"
    537 	"\n"
    538 	"    if (EXPECTED_VALUE != texture(uni_sampler, vec2(0.9375, 0.9375)).r)\n"
    539 	"    {\n"
    540 	"        result = 0u;\n"
    541 	"    }\n"
    542 	"\n"
    543 	"    tes_gs_result = result;\n"
    544 	"}\n"
    545 	"\n";
    546 
    547 const GLchar* FunctionalTest::m_vertex_shader_code =
    548 	"#version 430 core\n"
    549 	"\n"
    550 	"out uint vs_tcs_result;\n"
    551 	"\n"
    552 	"SAMPLER_DEFINITION;\n"
    553 	"\n"
    554 	"void main()\n"
    555 	"{\n"
    556 	"    uint result = 1u;\n"
    557 	"\n"
    558 	"    if (EXPECTED_VALUE != texture(uni_sampler, vec2(0.9375, 0.9375)).r)\n"
    559 	"    {\n"
    560 	"        result = 0u;\n"
    561 	"    }\n"
    562 	"\n"
    563 	"    vs_tcs_result = result;\n"
    564 	"}\n"
    565 	"\n";
    566 
    567 const GLchar* FunctionalTest::m_expected_value_depth = "0.0";
    568 
    569 const GLchar* FunctionalTest::m_expected_value_stencil = "15u";
    570 
    571 const GLchar* FunctionalTest::m_image_definition_depth = "writeonly uniform image2D uni_image";
    572 
    573 const GLchar* FunctionalTest::m_image_definition_stencil = "writeonly uniform uimage2D uni_image";
    574 
    575 const GLchar* FunctionalTest::m_output_type_depth = "vec4";
    576 
    577 const GLchar* FunctionalTest::m_output_type_stencil = "uvec4";
    578 
    579 const GLchar* FunctionalTest::m_sampler_definition_depth = "uniform sampler2D uni_sampler";
    580 
    581 const GLchar* FunctionalTest::m_sampler_definition_stencil = "uniform usampler2D uni_sampler";
    582 
    583 /* Constants */
    584 const GLuint FunctionalTest::m_height		= 8;
    585 const GLint  FunctionalTest::m_image_unit   = 1;
    586 const GLint  FunctionalTest::m_texture_unit = 1;
    587 const GLuint FunctionalTest::m_width		= 8;
    588 
    589 /** Constructor
    590  *
    591  * @param context Test context
    592  **/
    593 FunctionalTest::FunctionalTest(deqp::Context& context)
    594 	: TestCase(context, "functional", "Checks if sampling stencil texture gives expected results")
    595 {
    596 	/* Nothing to be done here */
    597 }
    598 
    599 /** Execute test
    600  *
    601  * @return tcu::TestNode::STOP
    602  **/
    603 tcu::TestNode::IterateResult FunctionalTest::iterate()
    604 {
    605 	bool test_result = true;
    606 
    607 	if (false == test(GL_DEPTH24_STENCIL8, true))
    608 	{
    609 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    610 											<< "Test failed. Case format: GL_DEPTH24_STENCIL8, channel: S"
    611 											<< tcu::TestLog::EndMessage;
    612 		test_result = false;
    613 	}
    614 
    615 	if (false == test(GL_DEPTH24_STENCIL8, false))
    616 	{
    617 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    618 											<< "Test failed. Case format: GL_DEPTH24_STENCIL8, channel: D"
    619 											<< tcu::TestLog::EndMessage;
    620 		test_result = false;
    621 	}
    622 
    623 	if (false == test(GL_DEPTH32F_STENCIL8, true))
    624 	{
    625 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    626 											<< "Test failed. Case format: GL_DEPTH32F_STENCIL8, channel: S"
    627 											<< tcu::TestLog::EndMessage;
    628 		test_result = false;
    629 	}
    630 
    631 	if (false == test(GL_DEPTH32F_STENCIL8, false))
    632 	{
    633 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    634 											<< "Test failed. Case format: GL_DEPTH32F_STENCIL8, channel: D"
    635 											<< tcu::TestLog::EndMessage;
    636 		test_result = false;
    637 	}
    638 
    639 	/* Set result */
    640 	if (true == test_result)
    641 	{
    642 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
    643 	}
    644 	else
    645 	{
    646 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    647 	}
    648 
    649 	/* Done */
    650 	return tcu::TestNode::STOP;
    651 }
    652 
    653 /** Execute compute program
    654  *
    655  * @param program_id     ID of program
    656  * @param is_stencil     Selects if stencil or depth channel is sampled
    657  * @param dst_texture_id ID of destination texture
    658  * @param src_texture_id ID of source texture
    659  **/
    660 void FunctionalTest::dispatch(GLuint program_id, bool is_stencil, GLuint dst_texture_id, GLuint src_texture_id)
    661 {
    662 	const Functions& gl				 = m_context.getRenderContext().getFunctions();
    663 	GLenum			 internal_format = GL_R8UI;
    664 	GLint			 uni_image_loc   = -1;
    665 	GLint			 uni_sampler_loc = -1;
    666 
    667 	if (false == is_stencil)
    668 	{
    669 		internal_format = GL_R32F;
    670 	}
    671 
    672 	/* Set program */
    673 	gl.useProgram(program_id);
    674 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
    675 
    676 	/* Get uniform location and bind texture to proper image unit */
    677 	uni_image_loc = gl.getUniformLocation(program_id, "uni_image");
    678 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
    679 
    680 	gl.bindImageTexture(m_image_unit, dst_texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
    681 						GL_WRITE_ONLY, internal_format);
    682 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
    683 
    684 	gl.uniform1i(uni_image_loc, m_image_unit);
    685 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
    686 
    687 	/* Get uniform location and bind texture to proper texture unit */
    688 	uni_sampler_loc = gl.getUniformLocation(program_id, "uni_sampler");
    689 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
    690 
    691 	gl.activeTexture(GL_TEXTURE0 + m_texture_unit);
    692 	GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
    693 
    694 	gl.bindTexture(GL_TEXTURE_2D, src_texture_id);
    695 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    696 
    697 	gl.uniform1i(uni_sampler_loc, m_texture_unit);
    698 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
    699 
    700 	/* Dispatch program */
    701 	gl.dispatchCompute(m_width, m_height, 1);
    702 	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
    703 
    704 	/* Sync */
    705 	gl.memoryBarrier(GL_ALL_BARRIER_BITS);
    706 	GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
    707 }
    708 
    709 /** Execute draw program
    710  *
    711  * @param program_id     ID of program
    712  * @param dst_texture_id ID of destination texture
    713  * @param src_texture_id ID of source texture
    714  **/
    715 void FunctionalTest::draw(GLuint program_id, GLuint dst_texture_id, GLuint src_texture_id)
    716 {
    717 	GLuint			 fb_id			 = 0;
    718 	const Functions& gl				 = m_context.getRenderContext().getFunctions();
    719 	GLint			 uni_sampler_loc = -1;
    720 	GLuint			 vao_id			 = 0;
    721 
    722 	try
    723 	{
    724 		/* Tesselation patch set up */
    725 		gl.patchParameteri(GL_PATCH_VERTICES, 1);
    726 		GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
    727 
    728 		/* Prepare VAO */
    729 		gl.genVertexArrays(1, &vao_id);
    730 		GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
    731 
    732 		gl.bindVertexArray(vao_id);
    733 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
    734 
    735 		/* Prepare FBO */
    736 		gl.genFramebuffers(1, &fb_id);
    737 		GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
    738 
    739 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_id);
    740 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
    741 
    742 		gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dst_texture_id, 0 /* level */);
    743 		GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
    744 
    745 		gl.viewport(0 /* x */, 0 /* y */, m_width, m_height);
    746 		GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
    747 
    748 		/* Set program */
    749 		gl.useProgram(program_id);
    750 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
    751 
    752 		/* Get uniform location and bind texture to proper texture unit */
    753 		uni_sampler_loc = gl.getUniformLocation(program_id, "uni_sampler");
    754 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
    755 
    756 		gl.activeTexture(GL_TEXTURE0 + m_texture_unit);
    757 		GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
    758 
    759 		gl.bindTexture(GL_TEXTURE_2D, src_texture_id);
    760 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    761 
    762 		gl.uniform1i(uni_sampler_loc, m_texture_unit);
    763 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
    764 
    765 		/* Draw */
    766 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
    767 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
    768 
    769 		/* Sync */
    770 		gl.memoryBarrier(GL_ALL_BARRIER_BITS);
    771 		GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
    772 	}
    773 	catch (std::exception& exc)
    774 	{
    775 		gl.bindVertexArray(0);
    776 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    777 		gl.bindTexture(GL_TEXTURE_2D, 0);
    778 
    779 		if (0 != vao_id)
    780 		{
    781 			gl.deleteVertexArrays(1, &vao_id);
    782 		}
    783 
    784 		if (0 != fb_id)
    785 		{
    786 			gl.deleteFramebuffers(1, &fb_id);
    787 		}
    788 
    789 		throw exc;
    790 	}
    791 
    792 	gl.bindVertexArray(0);
    793 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    794 	gl.bindTexture(GL_TEXTURE_2D, 0);
    795 
    796 	if (0 != vao_id)
    797 	{
    798 		gl.deleteVertexArrays(1, &vao_id);
    799 	}
    800 
    801 	if (0 != fb_id)
    802 	{
    803 		gl.deleteFramebuffers(1, &fb_id);
    804 	}
    805 }
    806 
    807 /** Prepare destination texture
    808  *
    809  * @param is_stencil Selects if stencil or depth channel is sampled
    810  *
    811  * @return ID of texture
    812  **/
    813 GLuint FunctionalTest::prepareDestinationTexture(bool is_stencil)
    814 {
    815 	static const GLuint  n_pixels		 = m_width * m_height;
    816 	GLenum				 format			 = 0;
    817 	GLenum				 internal_format = 0;
    818 	GLuint				 pixel_size		 = 0;
    819 	std::vector<GLubyte> texture_data;
    820 	GLuint				 texture_id   = 0;
    821 	GLuint				 texture_size = 0;
    822 	GLenum				 type		  = 0;
    823 
    824 	/* Select size of pixel */
    825 	if (true == is_stencil)
    826 	{
    827 		format			= GL_RED_INTEGER;
    828 		internal_format = GL_R8UI;
    829 		pixel_size		= 1;
    830 		type			= GL_UNSIGNED_BYTE;
    831 	}
    832 	else
    833 	{
    834 		format			= GL_RED;
    835 		internal_format = GL_R32F;
    836 		pixel_size		= 4;
    837 		type			= GL_FLOAT;
    838 	}
    839 
    840 	/* Allocate storage */
    841 	texture_size = pixel_size * n_pixels;
    842 	texture_data.resize(texture_size);
    843 
    844 	/* Fill texture data */
    845 	memset(&texture_data[0], 0, texture_size);
    846 
    847 	/* Create texture */
    848 	texture_id =
    849 		Utils::createAndFill2DTexture(m_context, m_width, m_height, internal_format, format, type, &texture_data[0]);
    850 
    851 	/* Done */
    852 	return texture_id;
    853 }
    854 
    855 /** Prepare program
    856  *
    857  * @param is_draw    Selects if draw or compute program is prepared
    858  * @param is_stencil Selects if stencil or depth channel is sampled
    859  *
    860  * @return ID of texture
    861  **/
    862 GLuint FunctionalTest::prepareProgram(bool is_draw, bool is_stencil)
    863 {
    864 	GLuint program_id = 0;
    865 
    866 	if (true != is_draw)
    867 	{
    868 		std::string   cs_code			 = m_compute_shader_code;
    869 		const GLchar* image_definition   = m_image_definition_stencil;
    870 		size_t		  position			 = 0;
    871 		const GLchar* sampler_definition = m_sampler_definition_stencil;
    872 		const GLchar* type				 = m_output_type_stencil;
    873 
    874 		if (false == is_stencil)
    875 		{
    876 			image_definition   = m_image_definition_depth;
    877 			sampler_definition = m_sampler_definition_depth;
    878 			type			   = m_output_type_depth;
    879 		}
    880 
    881 		Utils::replaceToken("IMAGE_DEFINITION", position, image_definition, cs_code);
    882 		Utils::replaceToken("SAMPLER_DEFINITION", position, sampler_definition, cs_code);
    883 		Utils::replaceToken("TYPE", position, type, cs_code);
    884 
    885 		program_id = Utils::createAndBuildProgram(m_context, cs_code.c_str(), 0 /* fs_code */, 0 /* gs_code */,
    886 												  0 /* tcs_code */, 0 /* tes_code */, 0 /* vs_code */);
    887 	}
    888 	else
    889 	{
    890 #define N_FUNCTIONAL_TEST_SHADER_STAGES 5
    891 
    892 		const GLchar* expected_value	 = m_expected_value_stencil;
    893 		const GLchar* sampler_definition = m_sampler_definition_stencil;
    894 		std::string   shader_code[N_FUNCTIONAL_TEST_SHADER_STAGES];
    895 		const GLchar* shader_templates[N_FUNCTIONAL_TEST_SHADER_STAGES] = {
    896 			m_fragment_shader_code, m_geometry_shader_code, m_tesselation_control_shader_code,
    897 			m_tesselation_evaluation_shader_code, m_vertex_shader_code
    898 		};
    899 		const GLchar* type = m_output_type_stencil;
    900 
    901 		if (false == is_stencil)
    902 		{
    903 			expected_value	 = m_expected_value_depth;
    904 			sampler_definition = m_sampler_definition_depth;
    905 			type			   = m_output_type_depth;
    906 		}
    907 
    908 		for (GLuint i = 0; i < N_FUNCTIONAL_TEST_SHADER_STAGES; ++i)
    909 		{
    910 			size_t position = 0;
    911 
    912 			shader_code[i] = shader_templates[i];
    913 
    914 			if (0 == i)
    915 			{
    916 				Utils::replaceToken("TYPE", position, type, shader_code[i]);
    917 				Utils::replaceToken("SAMPLER_DEFINITION", position, sampler_definition, shader_code[i]);
    918 				//Utils::replaceToken("TYPE",               position, type,               shader_code[i]);
    919 			}
    920 			else
    921 			{
    922 				Utils::replaceToken("SAMPLER_DEFINITION", position, sampler_definition, shader_code[i]);
    923 				Utils::replaceToken("EXPECTED_VALUE", position, expected_value, shader_code[i]);
    924 			}
    925 		}
    926 
    927 		program_id =
    928 			Utils::createAndBuildProgram(m_context, 0 /* cs_code */, shader_code[0].c_str() /* fs_code  */,
    929 										 shader_code[1].c_str() /* gs_code  */, shader_code[2].c_str() /* tcs_code */,
    930 										 shader_code[3].c_str() /* tes_code */, shader_code[4].c_str() /* vs_code  */);
    931 	}
    932 
    933 	/* Done */
    934 	return program_id;
    935 }
    936 
    937 /** Prepare source texture
    938  *
    939  * @param internal_format Internal format of texture
    940  * @param is_stencil      Selects if stencil or depth channel is sampled
    941  * @param texture_data    Texture contents
    942  *
    943  * @return ID of texture
    944  **/
    945 GLuint FunctionalTest::prepareSourceTexture(GLenum internal_format, bool is_stencil,
    946 											const std::vector<glw::GLubyte>& texture_data)
    947 {
    948 	const Functions& gl			= m_context.getRenderContext().getFunctions();
    949 	GLuint			 texture_id = 0;
    950 	GLenum			 type		= 0;
    951 
    952 	/* Select size of pixel */
    953 	switch (internal_format)
    954 	{
    955 	case GL_DEPTH24_STENCIL8:
    956 		type = GL_UNSIGNED_INT_24_8;
    957 		break;
    958 	case GL_DEPTH32F_STENCIL8:
    959 		type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
    960 		break;
    961 	default:
    962 		TCU_FAIL("Invalid enum");
    963 		break;
    964 	}
    965 
    966 	/* Create texture */
    967 	texture_id = Utils::createAndFill2DTexture(m_context, m_width, m_height, internal_format, GL_DEPTH_STENCIL, type,
    968 											   &texture_data[0]);
    969 
    970 	/* Set DS texture mode */
    971 	gl.bindTexture(GL_TEXTURE_2D, texture_id);
    972 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    973 
    974 	if (true == is_stencil)
    975 	{
    976 		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
    977 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
    978 	}
    979 	else
    980 	{
    981 		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
    982 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
    983 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
    984 	}
    985 
    986 	/* Set nearest filtering */
    987 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    988 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    989 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
    990 
    991 	/* Unbind */
    992 	gl.bindTexture(GL_TEXTURE_2D, 0);
    993 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    994 
    995 	/* Done */
    996 	return texture_id;
    997 }
    998 
    999 /** Prepare data for source texture
   1000  *
   1001  * @param internal_format Internal format of texture
   1002  * @param texture_data    Texture contents
   1003  *
   1004  * @return ID of texture
   1005  **/
   1006 void FunctionalTest::prepareSourceTextureData(GLenum internal_format, std::vector<GLubyte>& texture_data)
   1007 {
   1008 	static const GLfloat depth_step_h   = -0.5f / ((GLfloat)(m_width - 1));
   1009 	static const GLfloat depth_step_v   = -0.5f / ((GLfloat)(m_height - 1));
   1010 	static const GLuint  stencil_step_h = 1;
   1011 	static const GLuint  stencil_step_v = 1;
   1012 	static const GLuint  n_pixels		= m_width * m_height;
   1013 	GLuint				 pixel_size		= 0;
   1014 	GLuint				 line_size		= 0;
   1015 	GLuint				 texture_size   = 0;
   1016 
   1017 	/* Select size of pixel */
   1018 	switch (internal_format)
   1019 	{
   1020 	case GL_DEPTH24_STENCIL8:
   1021 		pixel_size = 4;
   1022 		break;
   1023 	case GL_DEPTH32F_STENCIL8:
   1024 		pixel_size = 8;
   1025 		break;
   1026 	default:
   1027 		TCU_FAIL("Invalid enum");
   1028 		break;
   1029 	}
   1030 
   1031 	line_size	= pixel_size * m_width;
   1032 	texture_size = pixel_size * n_pixels;
   1033 
   1034 	/* Allocate storage */
   1035 	texture_data.resize(texture_size);
   1036 
   1037 	/* Fill texture data */
   1038 	for (GLuint y = 0; y < m_height; ++y)
   1039 	{
   1040 		const GLfloat depth_v	 = depth_step_v * (GLfloat)y;
   1041 		const GLuint  line_offset = line_size * y;
   1042 		const GLuint  stencil_v   = stencil_step_v * y;
   1043 
   1044 		for (GLuint x = 0; x < m_width; ++x)
   1045 		{
   1046 			const GLfloat depth_h	  = depth_step_h * (GLfloat)x;
   1047 			const GLfloat depth_f	  = 1 + depth_h + depth_v;
   1048 			const GLuint  depth_i	  = (GLuint)(((GLfloat)0xffffff) * depth_f);
   1049 			const GLuint  pixel_offset = pixel_size * x;
   1050 			const GLuint  stencil_h	= stencil_step_h * x;
   1051 			const GLuint  stencil	  = 1 + stencil_h + stencil_v;
   1052 
   1053 			GLubyte* depth_f_data = (GLubyte*)&depth_f;
   1054 			GLubyte* depth_i_data = (GLubyte*)&depth_i;
   1055 			GLubyte* pixel_data   = &texture_data[0] + line_offset + pixel_offset;
   1056 			GLubyte* stencil_data = (GLubyte*)&stencil;
   1057 
   1058 			switch (pixel_size)
   1059 			{
   1060 			case 4:
   1061 				memcpy(pixel_data, stencil_data, 1);
   1062 				memcpy(pixel_data + 1, depth_i_data, 3);
   1063 				break;
   1064 			case 8:
   1065 				memcpy(pixel_data, depth_f_data, 4);
   1066 				memcpy(pixel_data + 4, stencil_data, 1);
   1067 				break;
   1068 			default:
   1069 				TCU_FAIL("Invalid value");
   1070 				break;
   1071 			}
   1072 		}
   1073 	}
   1074 }
   1075 
   1076 /** Verifies that destination texture contents match expectations
   1077  *
   1078  * @param id                     ID of destination texture
   1079  * @param source_internal_format Internal format of source texture
   1080  * @param is_stencil             Selects if stencil of depth channel is sampled
   1081  * @param src_texture_data       Contents of source texture
   1082  *
   1083  * @return true if everything is fine, false otherwise
   1084  **/
   1085 bool FunctionalTest::verifyTexture(GLuint id, GLenum source_internal_format, bool is_stencil,
   1086 								   const std::vector<GLubyte>& src_texture_data)
   1087 {
   1088 	static const GLuint  n_pixels		= m_width * m_height;
   1089 	const Functions&	 gl				= m_context.getRenderContext().getFunctions();
   1090 	GLuint				 dst_pixel_size = 0;
   1091 	std::vector<GLubyte> dst_texture_data;
   1092 	GLuint				 dst_texture_size = 0;
   1093 	GLenum				 format			  = 0;
   1094 	GLuint				 src_pixel_size   = 0;
   1095 	GLuint				 src_stencil_off  = 0;
   1096 	GLenum				 type			  = 0;
   1097 
   1098 	/* Select size of pixel */
   1099 	if (true == is_stencil)
   1100 	{
   1101 		format		   = GL_RED_INTEGER;
   1102 		dst_pixel_size = 1;
   1103 		type		   = GL_UNSIGNED_BYTE;
   1104 	}
   1105 	else
   1106 	{
   1107 		format		   = GL_RED;
   1108 		dst_pixel_size = 4;
   1109 		type		   = GL_FLOAT;
   1110 	}
   1111 
   1112 	if (GL_DEPTH24_STENCIL8 == source_internal_format)
   1113 	{
   1114 		src_pixel_size = 4;
   1115 	}
   1116 	else
   1117 	{
   1118 		src_pixel_size  = 8;
   1119 		src_stencil_off = 4;
   1120 	}
   1121 
   1122 	/* Allocate storage */
   1123 	dst_texture_size = dst_pixel_size * n_pixels;
   1124 	dst_texture_data.resize(dst_texture_size);
   1125 
   1126 	/* Get texture contents */
   1127 	gl.bindTexture(GL_TEXTURE_2D, id);
   1128 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1129 
   1130 	gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, format, type, &dst_texture_data[0]);
   1131 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
   1132 
   1133 	gl.bindTexture(GL_TEXTURE_2D, 0);
   1134 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   1135 
   1136 	/* For each pixel */
   1137 	for (GLuint i = 0; i < n_pixels; ++i)
   1138 	{
   1139 		const GLuint dst_pixel_offset = dst_pixel_size * i;
   1140 		const GLuint src_pixel_offset = src_pixel_size * i;
   1141 
   1142 		const GLubyte* dst_pixel_data = &dst_texture_data[0] + dst_pixel_offset;
   1143 		const GLubyte* src_pixel_data = &src_texture_data[0] + src_pixel_offset;
   1144 
   1145 		if (true == is_stencil) /* Stencil channel */
   1146 		{
   1147 			const GLubyte dst_stencil = dst_pixel_data[0];
   1148 			const GLubyte src_stencil = src_pixel_data[src_stencil_off];
   1149 
   1150 			if (src_stencil != dst_stencil)
   1151 			{
   1152 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel [" << i
   1153 													<< "], got: " << (GLuint)dst_stencil
   1154 													<< " expected: " << (GLuint)src_stencil << tcu::TestLog::EndMessage;
   1155 
   1156 				return false;
   1157 			}
   1158 		}
   1159 		else /* Depth channel */
   1160 		{
   1161 			if (GL_DEPTH24_STENCIL8 == source_internal_format) /* DEPTH24 */
   1162 			{
   1163 				GLfloat dst_depth   = 0.0f;
   1164 				GLuint  src_depth_i = 0;
   1165 				GLfloat src_depth_f = 0.0f;
   1166 
   1167 				memcpy(&dst_depth, dst_pixel_data, 4);
   1168 				memcpy(&src_depth_i, src_pixel_data + 1, 3);
   1169 
   1170 				src_depth_f = ((GLfloat)src_depth_i) / ((GLfloat)0xffffff);
   1171 
   1172 				if (de::abs(src_depth_f - dst_depth) > 0.0001f)
   1173 				{
   1174 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel [" << i
   1175 														<< "], got: " << dst_depth << " expected: " << src_depth_f
   1176 														<< tcu::TestLog::EndMessage;
   1177 
   1178 					return false;
   1179 				}
   1180 			}
   1181 			else /* DEPTH32F */
   1182 			{
   1183 				GLfloat dst_depth = 0.0f;
   1184 				GLfloat src_depth = 0.0f;
   1185 
   1186 				memcpy(&dst_depth, dst_pixel_data, 4);
   1187 				memcpy(&src_depth, src_pixel_data, 4);
   1188 
   1189 				if (de::abs(src_depth - dst_depth) > 0.0001f)
   1190 				{
   1191 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel [" << i
   1192 														<< "], got: " << dst_depth << " expected: " << src_depth
   1193 														<< tcu::TestLog::EndMessage;
   1194 
   1195 					return false;
   1196 				}
   1197 			}
   1198 		}
   1199 	}
   1200 
   1201 	return true;
   1202 }
   1203 
   1204 /** Test given internal format and channel
   1205  *
   1206  * @param internal_format Internal fromat of source texture
   1207  * @param is_stencil      Selects if stencil or depth channel is sampled
   1208  *
   1209  * @return true if results from compute and draw programs are positive, false otherwise
   1210  **/
   1211 bool FunctionalTest::test(GLenum internal_format, bool is_stencil)
   1212 {
   1213 	GLuint				 compute_dst_tex_id = 0;
   1214 	GLuint				 compute_program_id = 0;
   1215 	GLuint				 compute_src_tex_id = 0;
   1216 	GLuint				 draw_dst_tex_id	= 0;
   1217 	GLuint				 draw_program_id	= 0;
   1218 	GLuint				 draw_src_tex_id	= 0;
   1219 	const Functions&	 gl					= m_context.getRenderContext().getFunctions();
   1220 	bool				 test_result		= true;
   1221 	std::vector<GLubyte> texture_data;
   1222 
   1223 	prepareSourceTextureData(internal_format, texture_data);
   1224 
   1225 	try
   1226 	{
   1227 		if (true == Utils::isExtensionSupported(m_context, "GL_ARB_compute_shader"))
   1228 		{
   1229 			compute_dst_tex_id = prepareDestinationTexture(is_stencil);
   1230 			compute_program_id = prepareProgram(false, is_stencil);
   1231 			compute_src_tex_id = prepareSourceTexture(internal_format, is_stencil, texture_data);
   1232 
   1233 			dispatch(compute_program_id, is_stencil, compute_dst_tex_id, compute_src_tex_id);
   1234 
   1235 			if (false == verifyTexture(compute_dst_tex_id, internal_format, is_stencil, texture_data))
   1236 			{
   1237 				test_result = false;
   1238 			}
   1239 		}
   1240 
   1241 		{
   1242 			draw_dst_tex_id = prepareDestinationTexture(is_stencil);
   1243 			draw_program_id = prepareProgram(true, is_stencil);
   1244 			draw_src_tex_id = prepareSourceTexture(internal_format, is_stencil, texture_data);
   1245 
   1246 			draw(draw_program_id, draw_dst_tex_id, draw_src_tex_id);
   1247 
   1248 			if (false == verifyTexture(draw_dst_tex_id, internal_format, is_stencil, texture_data))
   1249 			{
   1250 				test_result = false;
   1251 			}
   1252 		}
   1253 	}
   1254 	catch (std::exception& exc)
   1255 	{
   1256 		gl.bindVertexArray(0);
   1257 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
   1258 		gl.useProgram(0);
   1259 
   1260 		Utils::deleteProgram(m_context, compute_program_id);
   1261 		Utils::deleteProgram(m_context, draw_program_id);
   1262 
   1263 		Utils::deleteTexture(m_context, compute_dst_tex_id);
   1264 		Utils::deleteTexture(m_context, compute_src_tex_id);
   1265 		Utils::deleteTexture(m_context, draw_dst_tex_id);
   1266 		Utils::deleteTexture(m_context, draw_src_tex_id);
   1267 
   1268 		TCU_FAIL(exc.what());
   1269 	}
   1270 
   1271 	gl.bindVertexArray(0);
   1272 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
   1273 	gl.useProgram(0);
   1274 
   1275 	Utils::deleteProgram(m_context, compute_program_id);
   1276 	Utils::deleteProgram(m_context, draw_program_id);
   1277 
   1278 	Utils::deleteTexture(m_context, compute_dst_tex_id);
   1279 	Utils::deleteTexture(m_context, compute_src_tex_id);
   1280 	Utils::deleteTexture(m_context, draw_dst_tex_id);
   1281 	Utils::deleteTexture(m_context, draw_src_tex_id);
   1282 
   1283 	/* Done */
   1284 	return test_result;
   1285 }
   1286 } /* namespace StencilTexturing */
   1287 
   1288 StencilTexturingTests::StencilTexturingTests(deqp::Context& context) : TestCaseGroup(context, "stencil_texturing", "")
   1289 {
   1290 }
   1291 
   1292 StencilTexturingTests::~StencilTexturingTests(void)
   1293 {
   1294 }
   1295 
   1296 void StencilTexturingTests::init()
   1297 {
   1298 	addChild(new StencilTexturing::FunctionalTest(m_context));
   1299 }
   1300 } /* namespace gl4cts */
   1301