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 #include "esextcGeometryShaderLayeredRenderingBoundaryCondition.hpp"
25 
26 #include "gluDefs.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 #include <cstring>
31 #include <sstream>
32 #include <string>
33 
34 namespace glcts
35 {
36 /* Configure constant values */
37 const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_width			   = 4;
38 const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_height			   = 4;
39 const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_max_depth		   = 4;
40 const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_texture_components = 4;
41 
42 /** Constructor
43  *
44  * @param context       Test context
45  * @param name          Test case's name
46  * @param description   Test case's desricption
47  **/
GeometryShaderLayeredRenderingBoundaryCondition(Context & context,const ExtParameters & extParams,const char * name,const char * description)48 GeometryShaderLayeredRenderingBoundaryCondition::GeometryShaderLayeredRenderingBoundaryCondition(
49 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
50 	: TestCaseBase(context, extParams, name, description)
51 	, m_draw_mode(GL_TEXTURE_3D)
52 	, m_n_points(0)
53 	, m_is_fbo_layered(false)
54 	, m_fbo_draw_id(0)
55 	, m_fbo_read_id(0)
56 	, m_fs_id(0)
57 	, m_gs_id(0)
58 	, m_po_id(0)
59 	, m_vao_id(0)
60 	, m_vs_id(0)
61 {
62 	unsigned char blue[]  = { 0, 0, 255, 255 };
63 	unsigned char green[] = { 0, 255, 0, 255 };
64 	unsigned char red[]   = { 255, 0, 0, 255 };
65 	unsigned char white[] = { 255, 255, 255, 255 };
66 
67 	m_blue_color  = new unsigned char[m_texture_components];
68 	m_green_color = new unsigned char[m_texture_components];
69 	m_red_color   = new unsigned char[m_texture_components];
70 	m_white_color = new unsigned char[m_texture_components];
71 
72 	memcpy(m_blue_color, blue, sizeof(blue));
73 	memcpy(m_green_color, green, sizeof(green));
74 	memcpy(m_red_color, red, sizeof(red));
75 	memcpy(m_white_color, white, sizeof(white));
76 }
77 
~GeometryShaderLayeredRenderingBoundaryCondition(void)78 GeometryShaderLayeredRenderingBoundaryCondition::~GeometryShaderLayeredRenderingBoundaryCondition(void)
79 {
80 	if (m_blue_color)
81 	{
82 		delete[] m_blue_color;
83 		m_blue_color = 0;
84 	}
85 
86 	if (m_green_color)
87 	{
88 		delete[] m_green_color;
89 		m_green_color = 0;
90 	}
91 
92 	if (m_red_color)
93 	{
94 		delete[] m_red_color;
95 		m_red_color = 0;
96 	}
97 	if (m_white_color)
98 	{
99 		delete[] m_white_color;
100 		m_white_color = 0;
101 	}
102 }
103 
104 /** Check if given data contains the same values as reference pixel
105  *
106  *   @param width          Texture width
107  *   @param height         Texture height
108  *   @param pixelSize      Size of pixel
109  *   @param textureData    buffer with data read from texture
110  *   @param referencePixel contains expected color value
111  *   @param attachment     Attachment number (written to log on failure)
112  *   @param layer          Layer number (written to log on failure)
113  *
114  *   @return  true    If all data in scope from textureData contains the same color as in referencePixel
115  *            false   in other case
116  **/
comparePixels(glw::GLint width,glw::GLint height,glw::GLint pixelSize,const unsigned char * textureData,const unsigned char * referencePixel,int attachment,int layer)117 bool GeometryShaderLayeredRenderingBoundaryCondition::comparePixels(glw::GLint width, glw::GLint height,
118 																	glw::GLint			 pixelSize,
119 																	const unsigned char* textureData,
120 																	const unsigned char* referencePixel, int attachment,
121 																	int layer)
122 {
123 	unsigned int rowWidth = pixelSize * width;
124 
125 	for (int y = 0; y < height; ++y)
126 	{
127 		for (int x = 0; x < width; ++x)
128 		{
129 			const unsigned char* renderedData = textureData + y * rowWidth + x * m_texture_components;
130 
131 			if (memcmp(referencePixel, renderedData, m_texture_components) != 0)
132 			{
133 				m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data for [x=" << x << " y=" << y
134 								   << " attachment=" << attachment << " layer=" << layer << "] "
135 								   << "[" << (int)renderedData[0] << ", " << (int)renderedData[1] << ", "
136 								   << (int)renderedData[2] << ", " << (int)renderedData[3] << "]"
137 								   << " are different from reference data [" << (int)referencePixel[0] << ", "
138 								   << (int)referencePixel[1] << ", " << (int)referencePixel[2] << ", "
139 								   << (int)referencePixel[3] << "] !" << tcu::TestLog::EndMessage;
140 				return false;
141 			} /* if (data comparison failed) */
142 		}	 /* for (all columns) */
143 	}		  /* for (all rows) */
144 	return true;
145 }
146 
147 /** Deinitializes GLES objects created during the test.
148  *
149  */
deinit(void)150 void GeometryShaderLayeredRenderingBoundaryCondition::deinit(void)
151 {
152 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
153 
154 	/* Reset OpenGL ES state */
155 	gl.useProgram(0);
156 	gl.bindVertexArray(0);
157 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
158 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
159 
160 	for (unsigned int i = 0; i < m_textures_info.size(); i++)
161 	{
162 		gl.bindTexture(m_textures_info[i].m_texture_target, 0);
163 	}
164 
165 	if (m_po_id != 0)
166 	{
167 		gl.deleteProgram(m_po_id);
168 	}
169 
170 	if (m_fs_id != 0)
171 	{
172 		gl.deleteShader(m_fs_id);
173 	}
174 
175 	if (m_gs_id != 0)
176 	{
177 		gl.deleteShader(m_gs_id);
178 	}
179 
180 	if (m_vs_id != 0)
181 	{
182 		gl.deleteShader(m_vs_id);
183 	}
184 
185 	for (unsigned int i = 0; i < m_textures_info.size(); i++)
186 	{
187 		gl.deleteTextures(1, &m_textures_info[i].m_id);
188 	}
189 
190 	if (m_fbo_read_id != 0)
191 	{
192 		gl.deleteFramebuffers(1, &m_fbo_read_id);
193 	}
194 
195 	if (m_fbo_draw_id != 0)
196 	{
197 		gl.deleteFramebuffers(1, &m_fbo_draw_id);
198 	}
199 
200 	if (m_vao_id != 0)
201 	{
202 		gl.deleteVertexArrays(1, &m_vao_id);
203 	}
204 
205 	/* Release base class */
206 	TestCaseBase::deinit();
207 }
208 
209 /** Returns code for Geometry Shader.
210  *
211  *  @return NULL
212  **/
getGeometryShaderCode()213 const char* GeometryShaderLayeredRenderingBoundaryCondition::getGeometryShaderCode()
214 {
215 	return 0;
216 }
217 
218 /** Returns code for Fragment Shader
219  * @return pointer to literal with Fragment Shader code
220  **/
getFragmentShaderCode()221 const char* GeometryShaderLayeredRenderingBoundaryCondition::getFragmentShaderCode()
222 {
223 	static const char* result = "${VERSION}\n"
224 								"\n"
225 								"precision highp float;\n"
226 								"\n"
227 								"flat in  int  layer_id;\n"
228 								"     out vec4 color;\n"
229 								"\n"
230 								"void main()\n"
231 								"{\n"
232 								"    color = vec4(1, 1, 1, 1);\n"
233 								"}\n";
234 	return result;
235 }
236 
237 /** Returns code for Vertex Shader
238  *
239  * @return pointer to literal with Vertex Shader code
240  **/
getVertexShaderCode()241 const char* GeometryShaderLayeredRenderingBoundaryCondition::getVertexShaderCode()
242 {
243 	static const char* result = "${VERSION}\n"
244 								"\n"
245 								"precision highp float;\n"
246 								"\n"
247 								"flat out int layer_id;\n"
248 								"\n"
249 								"void main()\n"
250 								"{\n"
251 								"    layer_id = 0;\n"
252 								"}\n";
253 
254 	return result;
255 }
256 
257 /** Initializes GLES objects used during the test.
258  *
259  **/
initTest(void)260 void GeometryShaderLayeredRenderingBoundaryCondition::initTest(void)
261 {
262 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
263 
264 	/* Create shader and program objects */
265 	const char* fsCode = getFragmentShaderCode();
266 	const char* gsCode = getGeometryShaderCode();
267 	const char* vsCode = getVertexShaderCode();
268 
269 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
270 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
271 	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
272 	m_po_id = gl.createProgram();
273 
274 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program/shader objects.");
275 
276 	if (!buildProgram(m_po_id, (fsCode) ? m_fs_id : 0, (fsCode) ? 1 : 0 /* part */, (fsCode) ? &fsCode : 0,
277 					  (gsCode) ? m_gs_id : 0, (gsCode) ? 1 : 0 /* part */, (gsCode) ? &gsCode : 0,
278 					  (vsCode) ? m_vs_id : 0, (vsCode) ? 1 : 0 /* part */, (vsCode) ? &vsCode : 0))
279 	{
280 		TCU_FAIL("Could not create a program object from a valid vertex/geometry/fragment shader!");
281 	}
282 
283 	/* Set up framebuffer objects */
284 	gl.genFramebuffers(1, &m_fbo_read_id);
285 	gl.genFramebuffers(1, &m_fbo_draw_id);
286 
287 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating framebuffer objects!");
288 
289 	/* Set up vertex array object */
290 	gl.genVertexArrays(1, &m_vao_id);
291 
292 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating vertex array object!");
293 
294 	for (unsigned int i = 0; i < m_textures_info.size(); i++)
295 	{
296 		gl.genTextures(1, &m_textures_info[i].m_id);
297 	}
298 
299 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating texture objects!");
300 }
301 
302 /** Executes the test.
303  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
304  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
305  *  Note the function throws exception should an error occur!
306  **/
iterate(void)307 tcu::TestNode::IterateResult GeometryShaderLayeredRenderingBoundaryCondition::iterate(void)
308 {
309 	/* check if EXT_geometry_shader extension is supported */
310 	if (!m_is_geometry_shader_extension_supported)
311 	{
312 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
313 	}
314 
315 	initTest();
316 
317 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
318 
319 	/* Bind draw framebuffer */
320 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_draw_id);
321 
322 	/* Set up all textures */
323 	unsigned char buffer[m_width * m_height * m_max_depth * m_texture_components];
324 
325 	memset(buffer, 0, sizeof(buffer));
326 
327 	for (unsigned int i = 0; i < m_textures_info.size(); i++)
328 	{
329 		gl.bindTexture(m_textures_info[i].m_texture_target, m_textures_info[i].m_id);
330 		gl.texStorage3D(m_textures_info[i].m_texture_target, 1, GL_RGBA8, m_width, m_height,
331 						m_textures_info[i].m_depth);
332 		gl.texSubImage3D(m_textures_info[i].m_texture_target, 0, 0, 0, 0, m_width, m_height, m_textures_info[i].m_depth,
333 						 GL_RGBA, GL_UNSIGNED_BYTE, buffer);
334 
335 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring a texture object!");
336 	}
337 
338 	/* Set up draw buffers */
339 	{
340 		glw::GLenum* drawBuffers = new glw::GLenum[m_textures_info.size()];
341 
342 		for (unsigned int i = 0; i < m_textures_info.size(); i++)
343 		{
344 			drawBuffers[i] = m_textures_info[i].m_draw_buffer;
345 		}
346 
347 		gl.drawBuffers((glw::GLsizei)m_textures_info.size(), drawBuffers);
348 
349 		delete[] drawBuffers;
350 		drawBuffers = 0;
351 	}
352 
353 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting draw buffers!");
354 
355 	/* Configure draw FBO so that it uses texture attachments */
356 	for (unsigned int i = 0; i < m_textures_info.size(); i++)
357 	{
358 		if (m_is_fbo_layered)
359 		{
360 			gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, m_textures_info[i].m_draw_buffer, m_textures_info[i].m_id,
361 								  0 /* level */);
362 		}
363 		else
364 		{
365 			gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, m_textures_info[i].m_draw_buffer, m_textures_info[i].m_id,
366 									   0 /* level */, i /* layer */);
367 		}
368 
369 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring framebuffer objects!");
370 	} /* for (all textures considered) */
371 
372 	/* Verify draw framebuffer is considered complete */
373 	glw::GLenum fboCompleteness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
374 
375 	if (fboCompleteness != GL_FRAMEBUFFER_COMPLETE)
376 	{
377 		m_testCtx.getLog() << tcu::TestLog::Message << "Draw FBO is incomplete: "
378 						   << "[" << fboCompleteness << "]" << tcu::TestLog::EndMessage;
379 
380 		TCU_FAIL("Draw FBO is incomplete.");
381 	}
382 
383 	/* Set up viewport */
384 	gl.viewport(0, 0, m_width, m_height);
385 
386 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up viewport!");
387 
388 	/** Bind a vertex array object */
389 	gl.bindVertexArray(m_vao_id);
390 
391 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring vertex array object!");
392 
393 	/* Render */
394 	gl.useProgram(m_po_id);
395 
396 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error using program object!");
397 
398 	gl.drawArrays(m_draw_mode, 0, m_n_points);
399 
400 	GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
401 
402 	/* Bind read framebuffer object. */
403 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read_id);
404 
405 	/* Compare the rendered data against reference representation */
406 	unsigned int min_depth = 0;
407 
408 	if (m_textures_info.size() > 0)
409 	{
410 		min_depth = m_textures_info[0].m_depth;
411 
412 		for (unsigned int nTexture = 1; nTexture < m_textures_info.size(); nTexture++)
413 		{
414 			if (min_depth > (unsigned)m_textures_info[nTexture].m_depth)
415 			{
416 				min_depth = m_textures_info[nTexture].m_depth;
417 			}
418 		}
419 	}
420 
421 	for (unsigned int nTexture = 0; nTexture < m_textures_info.size(); nTexture++)
422 	{
423 		for (unsigned int nLayer = 0; nLayer < min_depth; nLayer++)
424 		{
425 			/* Configure read FBO's color attachment */
426 			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_textures_info[nTexture].m_id, 0,
427 									   nLayer);
428 
429 			GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up read framebuffer!");
430 
431 			/* Verify read framebuffer is considered complete */
432 			glw::GLenum _fboCompleteness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
433 
434 			if (_fboCompleteness != GL_FRAMEBUFFER_COMPLETE)
435 			{
436 				m_testCtx.getLog() << tcu::TestLog::Message << "Read FBO is incomplete: "
437 								   << "[" << _fboCompleteness << "]" << tcu::TestLog::EndMessage;
438 
439 				TCU_FAIL("Read FBO is incomplete.");
440 			}
441 			gl.viewport(0, 0, m_width, m_height);
442 
443 			/* Read the rendered data */
444 			gl.readPixels(0 /* x */, 0 /* y */, m_width /* width */, m_height /* height */, GL_RGBA, GL_UNSIGNED_BYTE,
445 						  buffer);
446 
447 			GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read pixels using glReadPixels()");
448 
449 			/* Retrieve reference color for layer */
450 			unsigned char expectedData[m_texture_components];
451 
452 			getReferenceColor(nLayer, expectedData, m_texture_components);
453 
454 			/* Compare the retrieved data with reference data */
455 			if (!comparePixels(m_width, m_height, m_texture_components, buffer, expectedData, nTexture, nLayer))
456 			{
457 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
458 				return STOP;
459 			} /* if (data comparison failed) */
460 		}	 /* for (all layers) */
461 	}		  /* for (all texture objects) */
462 
463 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
464 	return STOP;
465 }
466 
467 /** Constructor
468  *
469  * @param context       Test context
470  * @param name          Test case's name
471  * @param description   Test case's desricption
472  **/
473 GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::
GeometryShaderLayeredRenderingBoundaryConditionVariousTextures(Context & context,const ExtParameters & extParams,const char * name,const char * description)474 	GeometryShaderLayeredRenderingBoundaryConditionVariousTextures(Context& context, const ExtParameters& extParams,
475 																   const char* name, const char* description)
476 	: GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description)
477 {
478 	TextureInfo texInfo;
479 
480 	texInfo.m_depth			 = 2;
481 	texInfo.m_draw_buffer	= GL_COLOR_ATTACHMENT0;
482 	texInfo.m_id			 = 0;
483 	texInfo.m_texture_target = GL_TEXTURE_3D;
484 
485 	m_textures_info.push_back(texInfo);
486 
487 	texInfo.m_depth			 = 4;
488 	texInfo.m_draw_buffer	= GL_COLOR_ATTACHMENT1;
489 	texInfo.m_id			 = 0;
490 	texInfo.m_texture_target = GL_TEXTURE_3D;
491 
492 	m_textures_info.push_back(texInfo);
493 
494 	m_draw_mode		 = GL_POINTS;
495 	m_n_points		 = 1;
496 	m_is_fbo_layered = true;
497 }
498 
499 /** Returns code for Fragment Shader
500  *
501  * @return pointer to literal with Fragment Shader code
502  **/
getFragmentShaderCode()503 const char* GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::getFragmentShaderCode()
504 {
505 	static const char* result = "${VERSION}\n"
506 								"\n"
507 								"precision highp float;\n"
508 								"\n"
509 								"flat in  int  layer_id;\n"
510 								"layout(location=0) out vec4 color0;\n"
511 								"layout(location=1) out vec4 color1;\n"
512 								"\n"
513 								"void main()\n"
514 								"{\n"
515 								"    vec4 color;\n"
516 								"    switch (layer_id)\n"
517 								"    {\n"
518 								"        case 0:  color = vec4(1, 0, 0, 1); break;\n"
519 								"        case 1:  color = vec4(0, 1, 0, 1); break;\n"
520 								"        case 2:  color = vec4(0, 0, 1, 1); break;\n"
521 								"        case 3:  color = vec4(1, 1, 1, 1); break;\n"
522 								"        default: color = vec4(0, 0, 0, 0); break;\n"
523 								"    }\n"
524 								"    color0 = color;\n"
525 								"    color1 = color;\n"
526 								"}\n";
527 	return result;
528 }
529 
530 /** Returns code for Geometry Shader
531  *
532  * @return pointer to literal with Geometry Shader code
533  **/
getGeometryShaderCode()534 const char* GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::getGeometryShaderCode()
535 {
536 	static const char* result = "${VERSION}\n"
537 								"\n"
538 								"${GEOMETRY_SHADER_REQUIRE}\n"
539 								"\n"
540 								"precision highp float;\n"
541 								"\n"
542 								"#define MAX_VERTICES 16\n"
543 								"#define N_LAYERS     2\n"
544 								"\n"
545 								"layout(points)                                    in;\n"
546 								"layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n"
547 								"\n"
548 								"precision highp float;\n"
549 								"\n"
550 								"flat out int layer_id;\n"
551 								"\n"
552 								"void main()\n"
553 								"{\n"
554 								"    for (int n = 0;n < N_LAYERS;++n)\n"
555 								"    {\n"
556 								"        gl_Layer    = n;\n"
557 								"        layer_id    = gl_Layer;\n"
558 								"        gl_Position = vec4(1, 1, 0, 1);\n"
559 								"        EmitVertex();\n"
560 								"\n"
561 								"        gl_Layer    = n;\n"
562 								"        layer_id    = gl_Layer;\n"
563 								"        gl_Position = vec4(1, -1, 0, 1);\n"
564 								"        EmitVertex();\n"
565 								"\n"
566 								"        gl_Layer    = n;\n"
567 								"        layer_id    = gl_Layer;\n"
568 								"        gl_Position = vec4(-1, 1, 0, 1);\n"
569 								"        EmitVertex();\n"
570 								"\n"
571 								"        gl_Layer    = n;\n"
572 								"        layer_id    = gl_Layer;\n"
573 								"        gl_Position = vec4(-1, -1, 0, 1);\n"
574 								"        EmitVertex();\n"
575 								"\n"
576 								"        EndPrimitive();\n"
577 								"    }\n"
578 								"}\n";
579 	return result;
580 }
581 
582 /** Get reference color for test result verification
583  * @param layerIndex      index of layer
584  * @param colorBuffer     will be used to store the requested data(buffor size should be greater than or equal colorBufferSize)
585  * @param colorBufferSize components number
586  **/
getReferenceColor(glw::GLint layerIndex,unsigned char * colorBuffer,int colorBufferSize)587 void GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::getReferenceColor(glw::GLint	 layerIndex,
588 																					   unsigned char* colorBuffer,
589 																					   int			  colorBufferSize)
590 {
591 	if (layerIndex == 0)
592 	{
593 		memcpy(colorBuffer, m_red_color, colorBufferSize);
594 	}
595 	else if (layerIndex == 1)
596 	{
597 		memcpy(colorBuffer, m_green_color, colorBufferSize);
598 	}
599 	else
600 	{
601 		memset(colorBuffer, 0, colorBufferSize);
602 	}
603 }
604 
605 /** Constructor
606  *
607  * @param context     Test context
608  * @param name        Test case's name
609  * @param description Test case's description
610  **/
GeometryShaderLayeredRenderingBoundaryConditionNoGS(Context & context,const ExtParameters & extParams,const char * name,const char * description)611 GeometryShaderLayeredRenderingBoundaryConditionNoGS::GeometryShaderLayeredRenderingBoundaryConditionNoGS(
612 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
613 	: GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description)
614 {
615 	TextureInfo texInfo;
616 
617 	texInfo.m_depth			 = 4;
618 	texInfo.m_draw_buffer	= GL_COLOR_ATTACHMENT0;
619 	texInfo.m_id			 = 0;
620 	texInfo.m_texture_target = GL_TEXTURE_3D;
621 
622 	m_textures_info.push_back(texInfo);
623 
624 	m_draw_mode		 = GL_TRIANGLE_FAN;
625 	m_n_points		 = 4;
626 	m_is_fbo_layered = true;
627 }
628 
629 /** Get reference color for test result verification
630  * @param layerIndex      index of layer
631  * @param colorBuffer     will be used to store the requested data(buffer size should be greater than or equal colorBufferSize)
632  * @param colorBufferSize components number
633  **/
getReferenceColor(glw::GLint layerIndex,unsigned char * colorBuffer,int colorBufferSize)634 void GeometryShaderLayeredRenderingBoundaryConditionNoGS::getReferenceColor(glw::GLint	 layerIndex,
635 																			unsigned char* colorBuffer,
636 																			int			   colorBufferSize)
637 {
638 	if (layerIndex == 0)
639 	{
640 		memcpy(colorBuffer, m_white_color, colorBufferSize);
641 	}
642 	else
643 	{
644 		memset(colorBuffer, 0, colorBufferSize);
645 	}
646 }
647 
648 /** Returns code for Vertex Shader
649  * @return pointer to literal with Vertex Shader code
650  **/
getVertexShaderCode()651 const char* GeometryShaderLayeredRenderingBoundaryConditionNoGS::getVertexShaderCode()
652 {
653 	static const char* result = "${VERSION}\n"
654 								"\n"
655 								"precision highp float;\n"
656 								"\n"
657 								"flat out int layer_id;\n"
658 								"\n"
659 								"void main()\n"
660 								"{\n"
661 								"    layer_id = 0;\n"
662 								"\n"
663 								"    switch (gl_VertexID)\n"
664 								"    {\n"
665 								"        case 0:  gl_Position = vec4(-1, -1, 0, 1); break;\n"
666 								"        case 1:  gl_Position = vec4(-1,  1, 0, 1); break;\n"
667 								"        case 2:  gl_Position = vec4( 1,  1, 0, 1); break;\n"
668 								"        default: gl_Position = vec4( 1, -1, 0, 1); break;\n"
669 								"    }\n"
670 								"}\n";
671 	return result;
672 }
673 
674 /** Constructor
675  *
676  * @param context       Test context
677  * @param name          Test case's name
678  * @param description   Test case's desricption
679  **/
GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet(Context & context,const ExtParameters & extParams,const char * name,const char * description)680 GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet(
681 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
682 	: GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description)
683 {
684 	TextureInfo texInfo;
685 
686 	texInfo.m_depth			 = 4;
687 	texInfo.m_draw_buffer	= GL_COLOR_ATTACHMENT0;
688 	texInfo.m_id			 = 0;
689 	texInfo.m_texture_target = GL_TEXTURE_3D;
690 
691 	m_textures_info.push_back(texInfo);
692 
693 	m_draw_mode		 = GL_POINTS;
694 	m_n_points		 = 1;
695 	m_is_fbo_layered = true;
696 }
697 
698 /** Returns code for Geometry Shader
699  * @return pointer to literal with Geometry Shader code
700  **/
getGeometryShaderCode()701 const char* GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::getGeometryShaderCode()
702 {
703 	static const char* result = "${VERSION}\n"
704 								"\n"
705 								"${GEOMETRY_SHADER_REQUIRE}\n"
706 								"\n"
707 								"precision highp float;\n"
708 								"\n"
709 								"#define MAX_VERTICES 4\n"
710 								"\n"
711 								"layout(points)                                    in;\n"
712 								"layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n"
713 								"\n"
714 								"precision highp float;\n"
715 								"\n"
716 								"flat out int layer_id;\n"
717 								"\n"
718 								"void main()\n"
719 								"{\n"
720 								"    layer_id    = 0;\n"
721 								"    gl_Position = vec4(1, 1, 0, 1);\n"
722 								"    EmitVertex();\n"
723 								"\n"
724 								"    layer_id    = 0;\n"
725 								"    gl_Position = vec4(1, -1, 0, 1);\n"
726 								"    EmitVertex();\n"
727 								"\n"
728 								"    layer_id    = 0;\n"
729 								"    gl_Position = vec4(-1, 1, 0, 1);\n"
730 								"    EmitVertex();\n"
731 								"\n"
732 								"    layer_id    = 0;\n"
733 								"    gl_Position = vec4(-1, -1, 0, 1);\n"
734 								"    EmitVertex();\n"
735 								"\n"
736 								"    EndPrimitive();\n"
737 								"}\n";
738 	return result;
739 }
740 
741 /** Get reference color for test result verification
742  * @param layerIndex      index of layer
743  * @param colorBuffer     will be used to store the requested data(buffer size should be greater than or equal colorBufferSize)
744  * @param colorBufferSize components number
745  **/
getReferenceColor(glw::GLint layerIndex,unsigned char * colorBuffer,int colorBufferSize)746 void GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::getReferenceColor(glw::GLint	 layerIndex,
747 																				  unsigned char* colorBuffer,
748 																				  int			 colorBufferSize)
749 {
750 	if (layerIndex == 0)
751 	{
752 		memcpy(colorBuffer, m_white_color, colorBufferSize);
753 	}
754 	else
755 	{
756 		memset(colorBuffer, 0, colorBufferSize);
757 	}
758 }
759 
760 /** Constructor
761  *
762  * @param context       Test context
763  * @param name          Test case's name
764  * @param description   Test case's desricption
765  **/
766 GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO::
GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO(Context & context,const ExtParameters & extParams,const char * name,const char * description)767 	GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO(Context& context, const ExtParameters& extParams,
768 																const char* name, const char* description)
769 	: GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description)
770 {
771 	TextureInfo texInfo;
772 
773 	texInfo.m_depth			 = 4;
774 	texInfo.m_draw_buffer	= GL_COLOR_ATTACHMENT0;
775 	texInfo.m_id			 = 0;
776 	texInfo.m_texture_target = GL_TEXTURE_3D;
777 
778 	m_textures_info.push_back(texInfo);
779 
780 	m_draw_mode		 = GL_POINTS;
781 	m_n_points		 = 1;
782 	m_is_fbo_layered = false;
783 }
784 
785 /** Returns code for Geometry Shader
786  * @return pointer to literal with Geometry Shader code
787  **/
getGeometryShaderCode()788 const char* GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO::getGeometryShaderCode()
789 {
790 	static const char* result = "${VERSION}\n"
791 								"\n"
792 								"${GEOMETRY_SHADER_REQUIRE}\n"
793 								"\n"
794 								"precision highp float;\n"
795 								"\n"
796 								"#define MAX_VERTICES 4\n"
797 								"\n"
798 								"layout(points)                                    in;\n"
799 								"layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n"
800 								"\n"
801 								"precision highp float;\n"
802 								"\n"
803 								"flat out int layer_id;\n"
804 								"\n"
805 								"void main()\n"
806 								"{\n"
807 								"    gl_Layer = 1;\n"
808 								"\n"
809 								"    layer_id    = gl_Layer;\n"
810 								"    gl_Position = vec4(1, 1, 0, 1);\n"
811 								"    EmitVertex();\n"
812 								"\n"
813 								"    layer_id    = gl_Layer;\n"
814 								"    gl_Position = vec4(1, -1, 0, 1);\n"
815 								"    EmitVertex();\n"
816 								"\n"
817 								"    layer_id    = gl_Layer;\n"
818 								"    gl_Position = vec4(-1, 1, 0, 1);\n"
819 								"    EmitVertex();\n"
820 								"\n"
821 								"    layer_id    = gl_Layer;\n"
822 								"    gl_Position = vec4(-1, -1, 0, 1);\n"
823 								"    EmitVertex();\n"
824 								"\n"
825 								"    EndPrimitive();\n"
826 								"}\n";
827 	return result;
828 }
829 
830 /** Get reference color for test result verification
831  * @param layerIndex      index of layer
832  * @param colorBuffer     will be used to store the requested data(buffer size should be greater than or equal colorBufferSize)
833  * @param colorBufferSize components number
834  **/
getReferenceColor(glw::GLint layerIndex,unsigned char * colorBuffer,int colorBufferSize)835 void GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO::getReferenceColor(glw::GLint	 layerIndex,
836 																					unsigned char* colorBuffer,
837 																					int			   colorBufferSize)
838 {
839 	if (layerIndex == 0)
840 	{
841 		memcpy(colorBuffer, m_white_color, colorBufferSize);
842 	}
843 	else
844 	{
845 		memset(colorBuffer, 0, colorBufferSize);
846 	}
847 }
848 
849 } // namespace glcts
850