• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  **/
createAndBuildProgram(deqp::Context & context,const GLchar * cs_code,const GLchar * fs_code,const GLchar * gs_code,const GLchar * tcs_code,const GLchar * tes_code,const GLchar * vs_code)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  **/
createAndCompileShader(deqp::Context & context,const GLenum type,const GLchar * code)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  **/
createAndFill2DTexture(deqp::Context & context,GLuint width,GLuint height,GLenum internal_format,GLenum format,GLenum type,const GLvoid * data)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  **/
deleteProgram(deqp::Context & context,const GLuint id)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  **/
deleteShader(deqp::Context & context,const GLuint id)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  **/
deleteTexture(deqp::Context & context,const GLuint id)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  **/
isExtensionSupported(deqp::Context & context,const GLchar * extension_name)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  **/
replaceToken(const GLchar * token,size_t & search_position,const GLchar * text,std::string & string)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  **/
FunctionalTest(deqp::Context & context)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  **/
iterate()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  **/
dispatch(GLuint program_id,bool is_stencil,GLuint dst_texture_id,GLuint src_texture_id)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  **/
draw(GLuint program_id,GLuint dst_texture_id,GLuint src_texture_id)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  **/
prepareDestinationTexture(bool is_stencil)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  **/
prepareProgram(bool is_draw,bool is_stencil)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  **/
prepareSourceTexture(GLenum internal_format,bool is_stencil,const std::vector<glw::GLubyte> & texture_data)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 	}
964 
965 	/* Create texture */
966 	texture_id = Utils::createAndFill2DTexture(m_context, m_width, m_height, internal_format, GL_DEPTH_STENCIL, type,
967 											   &texture_data[0]);
968 
969 	/* Set DS texture mode */
970 	gl.bindTexture(GL_TEXTURE_2D, texture_id);
971 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
972 
973 	if (true == is_stencil)
974 	{
975 		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
976 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
977 	}
978 	else
979 	{
980 		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
981 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
982 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
983 	}
984 
985 	/* Set nearest filtering */
986 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
987 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
988 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
989 
990 	/* Unbind */
991 	gl.bindTexture(GL_TEXTURE_2D, 0);
992 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
993 
994 	/* Done */
995 	return texture_id;
996 }
997 
998 /** Prepare data for source texture
999  *
1000  * @param internal_format Internal format of texture
1001  * @param texture_data    Texture contents
1002  *
1003  * @return ID of texture
1004  **/
prepareSourceTextureData(GLenum internal_format,std::vector<GLubyte> & texture_data)1005 void FunctionalTest::prepareSourceTextureData(GLenum internal_format, std::vector<GLubyte>& texture_data)
1006 {
1007 	static const GLfloat depth_step_h   = -0.5f / ((GLfloat)(m_width - 1));
1008 	static const GLfloat depth_step_v   = -0.5f / ((GLfloat)(m_height - 1));
1009 	static const GLuint  stencil_step_h = 1;
1010 	static const GLuint  stencil_step_v = 1;
1011 	static const GLuint  n_pixels		= m_width * m_height;
1012 	GLuint				 pixel_size		= 0;
1013 	GLuint				 line_size		= 0;
1014 	GLuint				 texture_size   = 0;
1015 
1016 	/* Select size of pixel */
1017 	switch (internal_format)
1018 	{
1019 	case GL_DEPTH24_STENCIL8:
1020 		pixel_size = 4;
1021 		break;
1022 	case GL_DEPTH32F_STENCIL8:
1023 		pixel_size = 8;
1024 		break;
1025 	default:
1026 		TCU_FAIL("Invalid enum");
1027 	}
1028 
1029 	line_size	= pixel_size * m_width;
1030 	texture_size = pixel_size * n_pixels;
1031 
1032 	/* Allocate storage */
1033 	texture_data.resize(texture_size);
1034 
1035 	/* Fill texture data */
1036 	for (GLuint y = 0; y < m_height; ++y)
1037 	{
1038 		const GLfloat depth_v	 = depth_step_v * (GLfloat)y;
1039 		const GLuint  line_offset = line_size * y;
1040 		const GLuint  stencil_v   = stencil_step_v * y;
1041 
1042 		for (GLuint x = 0; x < m_width; ++x)
1043 		{
1044 			const GLfloat depth_h	  = depth_step_h * (GLfloat)x;
1045 			const GLfloat depth_f	  = 1 + depth_h + depth_v;
1046 			const GLuint  depth_i	  = (GLuint)(((GLfloat)0xffffff) * depth_f);
1047 			const GLuint  pixel_offset = pixel_size * x;
1048 			const GLuint  stencil_h	= stencil_step_h * x;
1049 			const GLuint  stencil	  = 1 + stencil_h + stencil_v;
1050 
1051 			GLubyte* depth_f_data = (GLubyte*)&depth_f;
1052 			GLubyte* depth_i_data = (GLubyte*)&depth_i;
1053 			GLubyte* pixel_data   = &texture_data[0] + line_offset + pixel_offset;
1054 			GLubyte* stencil_data = (GLubyte*)&stencil;
1055 
1056 			switch (pixel_size)
1057 			{
1058 			case 4:
1059 				memcpy(pixel_data, stencil_data, 1);
1060 				memcpy(pixel_data + 1, depth_i_data, 3);
1061 				break;
1062 			case 8:
1063 				memcpy(pixel_data, depth_f_data, 4);
1064 				memcpy(pixel_data + 4, stencil_data, 1);
1065 				break;
1066 			default:
1067 				TCU_FAIL("Invalid value");
1068 			}
1069 		}
1070 	}
1071 }
1072 
1073 /** Verifies that destination texture contents match expectations
1074  *
1075  * @param id                     ID of destination texture
1076  * @param source_internal_format Internal format of source texture
1077  * @param is_stencil             Selects if stencil of depth channel is sampled
1078  * @param src_texture_data       Contents of source texture
1079  *
1080  * @return true if everything is fine, false otherwise
1081  **/
verifyTexture(GLuint id,GLenum source_internal_format,bool is_stencil,const std::vector<GLubyte> & src_texture_data)1082 bool FunctionalTest::verifyTexture(GLuint id, GLenum source_internal_format, bool is_stencil,
1083 								   const std::vector<GLubyte>& src_texture_data)
1084 {
1085 	static const GLuint  n_pixels		= m_width * m_height;
1086 	const Functions&	 gl				= m_context.getRenderContext().getFunctions();
1087 	GLuint				 dst_pixel_size = 0;
1088 	std::vector<GLubyte> dst_texture_data;
1089 	GLuint				 dst_texture_size = 0;
1090 	GLenum				 format			  = 0;
1091 	GLuint				 src_pixel_size   = 0;
1092 	GLuint				 src_stencil_off  = 0;
1093 	GLenum				 type			  = 0;
1094 
1095 	/* Select size of pixel */
1096 	if (true == is_stencil)
1097 	{
1098 		format		   = GL_RED_INTEGER;
1099 		dst_pixel_size = 1;
1100 		type		   = GL_UNSIGNED_BYTE;
1101 	}
1102 	else
1103 	{
1104 		format		   = GL_RED;
1105 		dst_pixel_size = 4;
1106 		type		   = GL_FLOAT;
1107 	}
1108 
1109 	if (GL_DEPTH24_STENCIL8 == source_internal_format)
1110 	{
1111 		src_pixel_size = 4;
1112 	}
1113 	else
1114 	{
1115 		src_pixel_size  = 8;
1116 		src_stencil_off = 4;
1117 	}
1118 
1119 	/* Allocate storage */
1120 	dst_texture_size = dst_pixel_size * n_pixels;
1121 	dst_texture_data.resize(dst_texture_size);
1122 
1123 	/* Get texture contents */
1124 	gl.bindTexture(GL_TEXTURE_2D, id);
1125 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
1126 
1127 	gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, format, type, &dst_texture_data[0]);
1128 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
1129 
1130 	gl.bindTexture(GL_TEXTURE_2D, 0);
1131 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
1132 
1133 	/* For each pixel */
1134 	for (GLuint i = 0; i < n_pixels; ++i)
1135 	{
1136 		const GLuint dst_pixel_offset = dst_pixel_size * i;
1137 		const GLuint src_pixel_offset = src_pixel_size * i;
1138 
1139 		const GLubyte* dst_pixel_data = &dst_texture_data[0] + dst_pixel_offset;
1140 		const GLubyte* src_pixel_data = &src_texture_data[0] + src_pixel_offset;
1141 
1142 		if (true == is_stencil) /* Stencil channel */
1143 		{
1144 			const GLubyte dst_stencil = dst_pixel_data[0];
1145 			const GLubyte src_stencil = src_pixel_data[src_stencil_off];
1146 
1147 			if (src_stencil != dst_stencil)
1148 			{
1149 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel [" << i
1150 													<< "], got: " << (GLuint)dst_stencil
1151 													<< " expected: " << (GLuint)src_stencil << tcu::TestLog::EndMessage;
1152 
1153 				return false;
1154 			}
1155 		}
1156 		else /* Depth channel */
1157 		{
1158 			if (GL_DEPTH24_STENCIL8 == source_internal_format) /* DEPTH24 */
1159 			{
1160 				GLfloat dst_depth   = 0.0f;
1161 				GLuint  src_depth_i = 0;
1162 				GLfloat src_depth_f = 0.0f;
1163 
1164 				memcpy(&dst_depth, dst_pixel_data, 4);
1165 				memcpy(&src_depth_i, src_pixel_data + 1, 3);
1166 
1167 				src_depth_f = ((GLfloat)src_depth_i) / ((GLfloat)0xffffff);
1168 
1169 				if (de::abs(src_depth_f - dst_depth) > 0.0001f)
1170 				{
1171 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel [" << i
1172 														<< "], got: " << dst_depth << " expected: " << src_depth_f
1173 														<< tcu::TestLog::EndMessage;
1174 
1175 					return false;
1176 				}
1177 			}
1178 			else /* DEPTH32F */
1179 			{
1180 				GLfloat dst_depth = 0.0f;
1181 				GLfloat src_depth = 0.0f;
1182 
1183 				memcpy(&dst_depth, dst_pixel_data, 4);
1184 				memcpy(&src_depth, src_pixel_data, 4);
1185 
1186 				if (de::abs(src_depth - dst_depth) > 0.0001f)
1187 				{
1188 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel [" << i
1189 														<< "], got: " << dst_depth << " expected: " << src_depth
1190 														<< tcu::TestLog::EndMessage;
1191 
1192 					return false;
1193 				}
1194 			}
1195 		}
1196 	}
1197 
1198 	return true;
1199 }
1200 
1201 /** Test given internal format and channel
1202  *
1203  * @param internal_format Internal fromat of source texture
1204  * @param is_stencil      Selects if stencil or depth channel is sampled
1205  *
1206  * @return true if results from compute and draw programs are positive, false otherwise
1207  **/
test(GLenum internal_format,bool is_stencil)1208 bool FunctionalTest::test(GLenum internal_format, bool is_stencil)
1209 {
1210 	GLuint				 compute_dst_tex_id = 0;
1211 	GLuint				 compute_program_id = 0;
1212 	GLuint				 compute_src_tex_id = 0;
1213 	GLuint				 draw_dst_tex_id	= 0;
1214 	GLuint				 draw_program_id	= 0;
1215 	GLuint				 draw_src_tex_id	= 0;
1216 	const Functions&	 gl					= m_context.getRenderContext().getFunctions();
1217 	bool				 test_result		= true;
1218 	std::vector<GLubyte> texture_data;
1219 
1220 	prepareSourceTextureData(internal_format, texture_data);
1221 
1222 	try
1223 	{
1224 		if (true == Utils::isExtensionSupported(m_context, "GL_ARB_compute_shader"))
1225 		{
1226 			compute_dst_tex_id = prepareDestinationTexture(is_stencil);
1227 			compute_program_id = prepareProgram(false, is_stencil);
1228 			compute_src_tex_id = prepareSourceTexture(internal_format, is_stencil, texture_data);
1229 
1230 			dispatch(compute_program_id, is_stencil, compute_dst_tex_id, compute_src_tex_id);
1231 
1232 			if (false == verifyTexture(compute_dst_tex_id, internal_format, is_stencil, texture_data))
1233 			{
1234 				test_result = false;
1235 			}
1236 		}
1237 
1238 		{
1239 			draw_dst_tex_id = prepareDestinationTexture(is_stencil);
1240 			draw_program_id = prepareProgram(true, is_stencil);
1241 			draw_src_tex_id = prepareSourceTexture(internal_format, is_stencil, texture_data);
1242 
1243 			draw(draw_program_id, draw_dst_tex_id, draw_src_tex_id);
1244 
1245 			if (false == verifyTexture(draw_dst_tex_id, internal_format, is_stencil, texture_data))
1246 			{
1247 				test_result = false;
1248 			}
1249 		}
1250 	}
1251 	catch (std::exception& exc)
1252 	{
1253 		gl.bindVertexArray(0);
1254 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1255 		gl.useProgram(0);
1256 
1257 		Utils::deleteProgram(m_context, compute_program_id);
1258 		Utils::deleteProgram(m_context, draw_program_id);
1259 
1260 		Utils::deleteTexture(m_context, compute_dst_tex_id);
1261 		Utils::deleteTexture(m_context, compute_src_tex_id);
1262 		Utils::deleteTexture(m_context, draw_dst_tex_id);
1263 		Utils::deleteTexture(m_context, draw_src_tex_id);
1264 
1265 		TCU_FAIL(exc.what());
1266 	}
1267 
1268 	gl.bindVertexArray(0);
1269 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1270 	gl.useProgram(0);
1271 
1272 	Utils::deleteProgram(m_context, compute_program_id);
1273 	Utils::deleteProgram(m_context, draw_program_id);
1274 
1275 	Utils::deleteTexture(m_context, compute_dst_tex_id);
1276 	Utils::deleteTexture(m_context, compute_src_tex_id);
1277 	Utils::deleteTexture(m_context, draw_dst_tex_id);
1278 	Utils::deleteTexture(m_context, draw_src_tex_id);
1279 
1280 	/* Done */
1281 	return test_result;
1282 }
1283 } /* namespace StencilTexturing */
1284 
StencilTexturingTests(deqp::Context & context)1285 StencilTexturingTests::StencilTexturingTests(deqp::Context& context) : TestCaseGroup(context, "stencil_texturing", "")
1286 {
1287 }
1288 
~StencilTexturingTests(void)1289 StencilTexturingTests::~StencilTexturingTests(void)
1290 {
1291 }
1292 
init()1293 void StencilTexturingTests::init()
1294 {
1295 	addChild(new StencilTexturing::FunctionalTest(m_context));
1296 }
1297 } /* namespace gl4cts */
1298