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
34namespace glcts
35{
36/* Configure constant values */
37const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_width			   = 4;
38const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_height			   = 4;
39const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_max_depth		   = 4;
40const 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 **/
48GeometryShaderLayeredRenderingBoundaryCondition::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
78GeometryShaderLayeredRenderingBoundaryCondition::~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 **/
117bool 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 */
150void 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 **/
213const 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 **/
221const 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 **/
241const 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 **/
260void 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 **/
307tcu::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 **/
473GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::
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 **/
503const 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 **/
534const 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 **/
587void 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 **/
611GeometryShaderLayeredRenderingBoundaryConditionNoGS::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 **/
634void 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 **/
651const 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 **/
680GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::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 **/
701const 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 **/
746void 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 **/
766GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO::
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 **/
788const 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 **/
835void 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