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 "esextcGeometryShaderInput.hpp"
25
26 #include "gluContextInfo.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 #include <cstring>
31
32 namespace glcts
33 {
34 /* Vertex shader for GeometryShader_gl_in_ArrayContents */
35 const char *const GeometryShader_gl_in_ArrayContentsTest::m_vertex_shader_code =
36 "${VERSION}\n"
37 "\n"
38 " out vec2 vs_gs_a;\n"
39 "flat out ivec4 vs_gs_b;\n"
40 "\n"
41 "void main()\n"
42 "{\n"
43 " vs_gs_a = vec2 (gl_VertexID, 0);\n"
44 " vs_gs_b = ivec4(0, gl_VertexID, 0, 1);\n"
45 "}\n";
46
47 /* Geometry shader for GeometryShader_gl_in_ArrayContents */
48 const char *const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_preamble_code =
49 "${VERSION}\n"
50 "\n"
51 "${GEOMETRY_SHADER_REQUIRE}\n"
52 "\n"
53 "layout(triangles) in;\n"
54 "layout(triangle_strip, max_vertices=3) out;\n"
55 "\n";
56
57 const char *const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_code =
58 "#ifdef USE_UNSIZED_ARRAYS\n"
59 " in vec2 vs_gs_a[];\n"
60 " flat in ivec4 vs_gs_b[];\n"
61 "#else\n"
62 " in vec2 vs_gs_a[3];\n"
63 " flat in ivec4 vs_gs_b[3];\n"
64 "#endif\n"
65 "\n"
66 " out vec2 gs_fs_a;\n"
67 "flat out ivec4 gs_fs_b;\n"
68 "\n"
69 "void main()\n"
70 "{\n"
71 " gl_Position = vec4(-1, -1, 0, 1);\n"
72 " gs_fs_a = vs_gs_a[0];\n"
73 " gs_fs_b = vs_gs_b[0];\n"
74 " EmitVertex();\n"
75 " \n"
76 " gl_Position = vec4(-1, 1, 0, 1);\n"
77 " gs_fs_a = vs_gs_a[1];\n"
78 " gs_fs_b = vs_gs_b[1];\n"
79 " EmitVertex();\n"
80 " \n"
81 " gl_Position = vec4(1, 1, 0, 1);\n"
82 " gs_fs_a = vs_gs_a[2];\n"
83 " gs_fs_b = vs_gs_b[2];\n"
84 " EmitVertex();\n"
85 " \n"
86 " EndPrimitive();\n"
87 "}\n";
88
89 /* Fragment shader for GeometryShader_gl_in_ArrayContents */
90 const char *const GeometryShader_gl_in_ArrayContentsTest::m_fragment_shader_code =
91 "${VERSION}\n"
92 "\n"
93 "precision highp float;\n"
94 "\n"
95 "layout(location = 0) out vec4 fs_out_color;\n"
96 "\n"
97 "void main()\n"
98 "{\n"
99 " fs_out_color = vec4(1, 1, 1, 1);\n"
100 "}\n";
101
102 /* Vertex Shader for GeometryShader_gl_in_ArrayLengthTest*/
103 const char *const GeometryShader_gl_in_ArrayLengthTest::m_vertex_shader_code =
104 "${VERSION}\n"
105 "\n"
106 "void main()\n"
107 "{\n"
108 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n"
109 "}\n";
110
111 /* Geometry shader body parts for GeometryShader_gl_in_ArrayLengthTest */
112 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_preamble = "${VERSION}\n"
113 "\n"
114 "${GEOMETRY_SHADER_REQUIRE}\n"
115 "\n";
116
117 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_points =
118 "layout(points) in;\n";
119
120 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines =
121 "layout(lines) in;\n";
122
123 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines_with_adjacency =
124 "layout(lines_adjacency) in;\n";
125
126 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles =
127 "layout(triangles) in;\n";
128
129 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles_with_adjacency =
130 "layout(triangles_adjacency) in;\n";
131
132 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_points =
133 "layout(points, max_vertices=1) out;\n"
134 "\n"
135 "#define N_OUT_VERTICES (1)\n";
136
137 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_line_strip =
138 "layout(line_strip, max_vertices=2) out;\n"
139 "\n"
140 "#define N_OUT_VERTICES (2)\n";
141
142 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_triangle_strip =
143 "layout(triangle_strip, max_vertices=3) out;\n"
144 "\n"
145 "#define N_OUT_VERTICES (3)\n";
146
147 const char *const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_main =
148 "\n"
149 "flat out int in_array_size;\n"
150 "\n"
151 "void main()\n"
152 "{\n"
153 " for (int n = 0; n < N_OUT_VERTICES; n++)\n"
154 " {\n"
155 " in_array_size = gl_in.length();\n"
156 " EmitVertex();\n"
157 " }\n"
158 "\n"
159 " EndPrimitive();\n"
160 "}\n";
161
162 /* Fragment Shader for GeometryShader_gl_in_ArrayLengthTest */
163 const char *const GeometryShader_gl_in_ArrayLengthTest::m_fragment_shader_code = "${VERSION}\n"
164 "\n"
165 "precision highp float;\n"
166 "\n"
167 "void main()\n"
168 "{\n"
169 "}\n";
170
171 /* Vertex Shader for GeometryShader_gl_PointSize_ValueTest */
172 const char *const GeometryShader_gl_PointSize_ValueTest::m_vertex_shader_code =
173 "${VERSION}\n"
174 "\n"
175 "void main()\n"
176 "{\n"
177 " // See test description for explanation of magic numbers\n"
178 " switch (gl_VertexID)\n"
179 " {\n"
180 " case 0:\n"
181 " {\n"
182 " gl_Position = vec4(-7.0/8.0, 0, 0, 1);\n"
183 "\n"
184 " break;\n"
185 " }\n"
186 "\n"
187 " case 1:\n"
188 " {\n"
189 " gl_Position = vec4(6.0/8.0, 0, 0, 1);\n"
190 "\n"
191 " break;\n"
192 " }\n"
193 " }\n"
194 "\n"
195 " gl_PointSize = float(2 * (gl_VertexID + 1));\n"
196 "}\n";
197
198 /* Geometry Shader for GeometryShader_gl_PointSize_ValueTest */
199 const char *const GeometryShader_gl_PointSize_ValueTest::m_geometry_shader_code =
200 "${VERSION}\n"
201 "\n"
202 "${GEOMETRY_SHADER_REQUIRE}\n"
203 "${GEOMETRY_POINT_SIZE_REQUIRE}\n"
204 "\n"
205 "layout(points) in;\n"
206 "layout(points, max_vertices=1) out;\n"
207 "\n"
208 "void main()\n"
209 "{\n"
210 " gl_Position = gl_in[0].gl_Position;\n"
211 " gl_PointSize = gl_in[0].gl_PointSize * 2.0;\n"
212 " EmitVertex();\n"
213 " \n"
214 " EndPrimitive();\n"
215 "}\n";
216
217 /* Fragment Shader for GeometryShader_gl_PointSize_ValueTest */
218 const char *const GeometryShader_gl_PointSize_ValueTest::m_fragment_shader_code =
219 "${VERSION}\n"
220 "\n"
221 "precision highp float;\n"
222 "\n"
223 "layout(location = 0) out vec4 fs_out_color;\n"
224 "\n"
225 "void main()\n"
226 "{\n"
227 " fs_out_color = vec4(1, 1, 1, 1);\n"
228 "}\n";
229
230 /* Vertex Shader for GeometryShader_gl_Position_ValueTest */
231 const char *const GeometryShader_gl_Position_ValueTest::m_vertex_shader_code =
232 "${VERSION}\n"
233 "\n"
234 "void main()\n"
235 "{\n"
236 " gl_Position = vec4(gl_VertexID, gl_VertexID, 0, 1);\n"
237 "\n"
238 "}\n";
239
240 /* Geometry Shader for GeometryShader_gl_Position_ValueTest */
241 const char *const GeometryShader_gl_Position_ValueTest::m_geometry_shader_code =
242 "${VERSION}\n"
243 "\n"
244 "${GEOMETRY_SHADER_REQUIRE}\n"
245 "${GEOMETRY_POINT_SIZE_REQUIRE}\n"
246 "\n"
247 "layout(points) in;\n"
248 "layout(points, max_vertices=1) out;\n"
249 "\n"
250 "void main()\n"
251 "{\n"
252 " // See test description for discussion on the magic numbers\n"
253 " gl_Position = vec4(-1.0 + 4.0/32.0 + gl_in[0].gl_Position.x / 4.0, 0, 0, 1);\n"
254 " gl_PointSize = 8.0;\n"
255 " EmitVertex();\n"
256 "\n"
257 " EndPrimitive();\n"
258 "}\n";
259
260 /* Fragment Shader for GeometryShader_gl_Position_ValueTest */
261 const char *const GeometryShader_gl_Position_ValueTest::m_fragment_shader_code =
262 "${VERSION}\n"
263 "\n"
264 "precision highp float;\n"
265 "\n"
266 "layout(location = 0) out vec4 fs_out_color;\n"
267 "\n"
268 "void main()\n"
269 "{\n"
270 " fs_out_color = vec4(1, 1, 1, 1);\n"
271 "}\n";
272
273 /* Constants for GeometryShader_gl_in_ArrayContentsTest */
274 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex =
275 2 * sizeof(glw::GLfloat) + 4 * sizeof(glw::GLint);
276 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives = 1;
277 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive = 3;
278
279 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_buffer_size =
280 GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex *
281 GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive *
282 GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives;
283
284 /* Constants for GeometryShader_gl_in_ArrayLengthTest */
285 const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_max_primitive_emitted = 6;
286 const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_buffer_size = sizeof(glw::GLint) * m_max_primitive_emitted;
287
288 /* Constants for GeometryShader_gl_PointSize_ValueTest */
289 const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_height = 16;
290 const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_pixel_size = 4;
291 const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_width = 16;
292
293 /* Constants for GeometryShader_gl_Position_ValueTest */
294 const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_height = 64;
295 const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_pixel_size = 4;
296 const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_width = 64;
297
298 /** Constructor
299 *
300 * @param context Test context
301 * @param name Test case's name
302 * @param description Test case's desricption
303 **/
GeometryShader_gl_in_ArrayContentsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)304 GeometryShader_gl_in_ArrayContentsTest::GeometryShader_gl_in_ArrayContentsTest(Context &context,
305 const ExtParameters &extParams,
306 const char *name,
307 const char *description)
308 : TestCaseBase(context, extParams, name, description)
309 , m_fragment_shader_id(0)
310 , m_geometry_shader_sized_arrays_id(0)
311 , m_geometry_shader_unsized_arrays_id(0)
312 , m_program_object_sized_arrays_id(0)
313 , m_program_object_unsized_arrays_id(0)
314 , m_vertex_shader_id(0)
315 , m_buffer_object_id(0)
316 , m_vertex_array_object_id(0)
317 {
318 /* Nothing to be done here */
319 }
320
321 /** Initializes GLES objects used during the test.
322 *
323 **/
initTest()324 void GeometryShader_gl_in_ArrayContentsTest::initTest()
325 {
326 /* Varing names */
327 const glw::GLchar *const captured_varyings[] = {
328 "gs_fs_a",
329 "gs_fs_b",
330 };
331
332 /* Number of varings */
333 const glw::GLuint n_captured_varyings_size = sizeof(captured_varyings) / sizeof(captured_varyings[0]);
334
335 /* GL */
336 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
337
338 /* Create program and shaders */
339 m_program_object_sized_arrays_id = gl.createProgram();
340 m_program_object_unsized_arrays_id = gl.createProgram();
341
342 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
343 m_geometry_shader_unsized_arrays_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
344 m_geometry_shader_sized_arrays_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
345 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
346
347 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
348
349 /* Set up transform feedback */
350 gl.transformFeedbackVaryings(m_program_object_sized_arrays_id, n_captured_varyings_size, captured_varyings,
351 GL_INTERLEAVED_ATTRIBS);
352 gl.transformFeedbackVaryings(m_program_object_unsized_arrays_id, n_captured_varyings_size, captured_varyings,
353 GL_INTERLEAVED_ATTRIBS);
354
355 /* Build programs */
356 const char *geometry_shader_unsized_arrays_code[] = {m_geometry_shader_preamble_code,
357 "#define USE_UNSIZED_ARRAYS\n", m_geometry_shader_code};
358 const char *geometry_shader_sized_arrays_code[] = {m_geometry_shader_preamble_code, m_geometry_shader_code};
359
360 if (false ==
361 buildProgram(m_program_object_unsized_arrays_id, m_fragment_shader_id, 1 /* number of fragment shader parts */,
362 &m_fragment_shader_code, m_geometry_shader_unsized_arrays_id,
363 DE_LENGTH_OF_ARRAY(geometry_shader_unsized_arrays_code), geometry_shader_unsized_arrays_code,
364 m_vertex_shader_id, 1 /* number of vertex shader parts */, &m_vertex_shader_code))
365 {
366 TCU_FAIL("Could not create a program from valid vertex/geometry (unsized arrays version)/fragment shaders");
367 }
368
369 if (false == buildProgram(m_program_object_sized_arrays_id, m_fragment_shader_id,
370 1 /* number of fragment shader parts */, &m_fragment_shader_code,
371 m_geometry_shader_sized_arrays_id, DE_LENGTH_OF_ARRAY(geometry_shader_sized_arrays_code),
372 geometry_shader_sized_arrays_code, m_vertex_shader_id,
373 1 /* number of vertex shader parts */, &m_vertex_shader_code))
374 {
375 TCU_FAIL("Could not create a program from valid vertex/geometry (sized arrays version)/fragment shaders");
376 }
377
378 /* Generate, bind and allocate buffer */
379 gl.genBuffers(1, &m_buffer_object_id);
380 gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
381 gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);
382
383 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");
384
385 /* Generate and bind VAO */
386 gl.genVertexArrays(1, &m_vertex_array_object_id);
387 gl.bindVertexArray(m_vertex_array_object_id);
388
389 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
390 }
391
392 /** Executes the test.
393 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
394 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
395 * Note the function throws exception should an error occur!
396 **/
iterate()397 tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayContentsTest::iterate()
398 {
399 /* This test should only run if EXT_geometry_shader is supported */
400 if (true != m_is_geometry_shader_extension_supported)
401 {
402 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
403 }
404
405 initTest();
406
407 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
408 unsigned char reference_data[m_buffer_size] = {0};
409 bool result = true;
410
411 /* Prepare reference data */
412 {
413 glw::GLint *ivec4_data_ptr;
414 glw::GLfloat *vec2_data_ptr;
415
416 const unsigned int ivec4_offset_from_vertex = 2 * sizeof(glw::GLfloat);
417 const unsigned int vec2_offset_from_vertex = 0;
418
419 /* Expected data for vertex:
420 * vec2 = {VertexID, 0.0f}
421 * ivec4 = {0, VertexID, 0, 1}
422 */
423 for (unsigned int vertex_id = 0; vertex_id < m_n_vertices_emitted_per_primitive * m_n_emitted_primitives;
424 ++vertex_id)
425 {
426 const unsigned int vertex_offset = vertex_id * m_n_bytes_emitted_per_vertex;
427 const unsigned int ivec4_offset = vertex_offset + ivec4_offset_from_vertex;
428 const unsigned int vec2_offset = vertex_offset + vec2_offset_from_vertex;
429
430 ivec4_data_ptr = (glw::GLint *)(reference_data + ivec4_offset);
431 vec2_data_ptr = (glw::GLfloat *)(reference_data + vec2_offset);
432
433 ivec4_data_ptr[0] = 0;
434 ivec4_data_ptr[1] = vertex_id;
435 ivec4_data_ptr[2] = 0;
436 ivec4_data_ptr[3] = 1;
437
438 vec2_data_ptr[0] = (float)vertex_id;
439 vec2_data_ptr[1] = 0.0f;
440 }
441 }
442
443 /* Setup transform feedback */
444 gl.enable(GL_RASTERIZER_DISCARD);
445 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id);
446
447 /* Draw the geometry */
448 for (int n_case = 0; n_case < 2 /* unsized/sized array cases */; ++n_case)
449 {
450 glw::GLuint po_id = (n_case == 0) ? m_program_object_unsized_arrays_id : m_program_object_sized_arrays_id;
451
452 gl.useProgram(po_id);
453 gl.beginTransformFeedback(GL_TRIANGLES);
454 {
455 gl.drawArrays(GL_TRIANGLES, 0 /* first */, 3 /* one triangle */);
456 }
457 gl.endTransformFeedback();
458
459 GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call");
460
461 /* Map buffer object storage holding XFB result into process space. */
462 glw::GLchar *transform_feedback_data = (glw::GLchar *)gl.mapBufferRange(
463 GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, m_buffer_size, GL_MAP_READ_BIT);
464
465 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");
466
467 /* Verify data extracted from transform feedback */
468 if (0 != memcmp(transform_feedback_data, reference_data, m_buffer_size))
469 {
470 m_testCtx.getLog() << tcu::TestLog::Message << "Data extracted from transform feedback is invalid."
471 << tcu::TestLog::EndMessage;
472
473 result = false;
474 }
475
476 /* Unmap the buffer object. */
477 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
478
479 GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");
480
481 /* Verify results */
482 if (true != result)
483 {
484 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
485 return STOP;
486 }
487 }
488
489 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
490 return STOP;
491 }
492
493 /** Deinitializes GLES objects created during the test.
494 *
495 */
deinit()496 void GeometryShader_gl_in_ArrayContentsTest::deinit()
497 {
498 /* GL */
499 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
500
501 /* Bind default values */
502 gl.useProgram(0);
503 gl.bindVertexArray(0);
504 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
505 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
506
507 /* Delete everything */
508 if (0 != m_vertex_array_object_id)
509 {
510 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
511 }
512
513 if (0 != m_buffer_object_id)
514 {
515 gl.deleteBuffers(1, &m_buffer_object_id);
516 }
517
518 if (0 != m_program_object_sized_arrays_id)
519 {
520 gl.deleteProgram(m_program_object_sized_arrays_id);
521 }
522
523 if (0 != m_program_object_unsized_arrays_id)
524 {
525 gl.deleteProgram(m_program_object_unsized_arrays_id);
526 }
527
528 if (0 != m_fragment_shader_id)
529 {
530 gl.deleteShader(m_fragment_shader_id);
531 }
532
533 if (0 != m_geometry_shader_sized_arrays_id)
534 {
535 gl.deleteShader(m_geometry_shader_sized_arrays_id);
536 }
537
538 if (0 != m_geometry_shader_unsized_arrays_id)
539 {
540 gl.deleteShader(m_geometry_shader_unsized_arrays_id);
541 }
542
543 if (0 != m_vertex_shader_id)
544 {
545 gl.deleteShader(m_vertex_shader_id);
546 }
547
548 /* Deinitialize Base */
549 TestCaseBase::deinit();
550 }
551
552 /** Constructor
553 *
554 * @param context Test context
555 * @param name Test case's name
556 * @param description Test case's desricption
557 **/
GeometryShader_gl_in_ArrayLengthTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)558 GeometryShader_gl_in_ArrayLengthTest::GeometryShader_gl_in_ArrayLengthTest(Context &context,
559 const ExtParameters &extParams,
560 const char *name, const char *description)
561 : TestCaseBase(context, extParams, name, description)
562 , m_buffer_object_id(0)
563 , m_vertex_array_object_id(0)
564 {
565 /* Nothing to be done here */
566 }
567
568 /** Initialize test case
569 *
570 **/
init()571 void GeometryShader_gl_in_ArrayLengthTest::init()
572 {
573 /* Initialize Base */
574 TestCaseBase::init();
575
576 /* Captured variables */
577 const char *captured_varyings[] = {"in_array_size"};
578
579 /* This test should only run if EXT_geometry_shader is supported */
580 if (true != m_is_geometry_shader_extension_supported)
581 {
582 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
583 }
584
585 /* GL */
586 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
587
588 /* Set up test descriptors */
589 initCase(m_test_lines, GL_LINES, 2, /* number of vertices */
590 2, /* as per spec */
591 GL_POINTS, m_geometry_shader_code_input_lines, m_geometry_shader_code_output_points);
592
593 m_tests.push_back(&m_test_lines);
594
595 initCase(m_test_lines_adjacency, m_glExtTokens.LINES_ADJACENCY, 4, /* number of vertices */
596 4, /* as per spec */
597 GL_POINTS, m_geometry_shader_code_input_lines_with_adjacency, m_geometry_shader_code_output_points);
598
599 m_tests.push_back(&m_test_lines_adjacency);
600
601 initCase(m_test_points, GL_POINTS, 1, /* number of vertices */
602 1, /* as per spec */
603 GL_POINTS, m_geometry_shader_code_input_points, m_geometry_shader_code_output_points);
604
605 m_tests.push_back(&m_test_points);
606
607 initCase(m_test_triangles, GL_TRIANGLES, 3, /* number of vertices */
608 3, /* as per spec */
609 GL_POINTS, m_geometry_shader_code_input_triangles, m_geometry_shader_code_output_points);
610
611 m_tests.push_back(&m_test_triangles);
612
613 initCase(m_test_triangles_adjacency, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY, 6, /* number of vertices */
614 6, /* as per spec */
615 GL_POINTS, m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_points);
616
617 m_tests.push_back(&m_test_triangles_adjacency);
618
619 initCase(m_test_lines_adjacency_to_line_strip, m_glExtTokens.LINES_ADJACENCY, 4 /* number of vertices */,
620 4 /* expected array length */, GL_LINES, m_geometry_shader_code_input_lines_with_adjacency,
621 m_geometry_shader_code_output_line_strip);
622
623 m_tests.push_back(&m_test_lines_adjacency_to_line_strip);
624
625 initCase(m_test_triangles_adjacency_to_triangle_strip, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY,
626 6 /* number of vertices */, 6 /* expected array length */, GL_TRIANGLES,
627 m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_triangle_strip);
628
629 m_tests.push_back(&m_test_triangles_adjacency_to_triangle_strip);
630
631 /* Initialize program objects */
632 for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
633 {
634 /* Case instance */
635 Case *test = *it;
636
637 /* Init program */
638 initCaseProgram(*test, captured_varyings, sizeof(captured_varyings) / sizeof(captured_varyings[0]));
639 }
640
641 /* Generate, bind and allocate buffer */
642 gl.genBuffers(1, &m_buffer_object_id);
643 gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
644 gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);
645
646 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");
647
648 /* Generate and bind VAO */
649 gl.genVertexArrays(1, &m_vertex_array_object_id);
650 gl.bindVertexArray(m_vertex_array_object_id);
651
652 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
653 }
654
655 /** Executes the test.
656 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
657 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
658 * Note the function throws exception should an error occur!
659 **/
iterate()660 tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayLengthTest::iterate()
661 {
662 /* GL */
663 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
664
665 /* This test should only run if EXT_geometry_shader is supported */
666 if (true != m_is_geometry_shader_extension_supported)
667 {
668 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
669 }
670
671 /* Setup transform feedback */
672 gl.enable(GL_RASTERIZER_DISCARD);
673 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id);
674
675 /* Execute tests */
676 for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
677 {
678 glw::GLint result_value = 0;
679 Case *test = *it;
680
681 /* Execute */
682 gl.useProgram(test->po_id);
683
684 gl.beginTransformFeedback(test->tf_mode);
685 {
686 gl.drawArrays(test->draw_call_mode, 0, /* first */
687 test->draw_call_n_vertices);
688 }
689 gl.endTransformFeedback();
690
691 GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call");
692
693 /* Map transform feedback results */
694 glw::GLint *result = (glw::GLint *)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */,
695 sizeof(glw::GLint), GL_MAP_READ_BIT);
696
697 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");
698
699 /* Extract value from transform feedback */
700 result_value = *result;
701
702 /* Unmap transform feedback buffer */
703 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
704
705 GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");
706
707 /* Verify results */
708 if (result_value != test->expected_array_length)
709 {
710 m_testCtx.getLog() << tcu::TestLog::Message << "Expected array length: " << test->expected_array_length
711 << " but found: " << result_value << tcu::TestLog::EndMessage;
712
713 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
714 return STOP;
715 }
716 }
717
718 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
719 return STOP;
720 }
721
722 /** Deinitializes test case
723 *
724 **/
deinit()725 void GeometryShader_gl_in_ArrayLengthTest::deinit()
726 {
727 /* GL */
728 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
729
730 /* Bind default values */
731 gl.useProgram(0);
732 gl.bindVertexArray(0);
733 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
734 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
735 /* Delete everything */
736 if (0 != m_vertex_array_object_id)
737 {
738 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
739 }
740
741 if (0 != m_buffer_object_id)
742 {
743 gl.deleteBuffers(1, &m_buffer_object_id);
744 }
745
746 /* Deinit test cases */
747 for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
748 {
749 Case *test = *it;
750
751 deinitCase(*test);
752 }
753
754 m_tests.clear();
755
756 /* Deinitialize Base */
757 TestCaseBase::deinit();
758 }
759
760 /** Deinitialize test case instance
761 *
762 * @param info Case instance
763 **/
deinitCase(Case & info)764 void GeometryShader_gl_in_ArrayLengthTest::deinitCase(Case &info)
765 {
766 /* GL */
767 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
768
769 /* Delete everything */
770 if (0 != info.po_id)
771 {
772 gl.deleteProgram(info.po_id);
773 }
774
775 if (0 != info.vs_id)
776 {
777 gl.deleteShader(info.vs_id);
778 }
779
780 if (0 != info.gs_id)
781 {
782 gl.deleteShader(info.gs_id);
783 }
784
785 if (0 != info.fs_id)
786 {
787 gl.deleteShader(info.fs_id);
788 }
789
790 /* Clear case */
791 resetCase(info);
792 }
793
794 /** Initialize test case instance with provided data.
795 *
796 * @param info Case instance;
797 * @param draw_call_mode Primitive type used by a draw call;
798 * @param draw_call_n_vertices Number of vertices used by a draw call;
799 * @param expected_array_length Expected size of gl_in array;
800 * @param tf_mode Primitive type used by transform feedback;
801 * @param input_body_part Part of geometry shader which specifies input layout;
802 * @param output_body_part Part of geometry shader which specifies output layout;
803 **/
initCase(Case & info,glw::GLenum draw_call_mode,glw::GLint draw_call_n_vertices,glw::GLint expected_array_length,glw::GLenum tf_mode,const glw::GLchar * input_body_part,const glw::GLchar * output_body_part)804 void GeometryShader_gl_in_ArrayLengthTest::initCase(Case &info, glw::GLenum draw_call_mode,
805 glw::GLint draw_call_n_vertices, glw::GLint expected_array_length,
806 glw::GLenum tf_mode, const glw::GLchar *input_body_part,
807 const glw::GLchar *output_body_part)
808 {
809 /* Reset case descriptor */
810 resetCase(info);
811
812 /* Set fields */
813 info.draw_call_mode = draw_call_mode;
814 info.draw_call_n_vertices = draw_call_n_vertices;
815 info.expected_array_length = expected_array_length;
816 info.input_body_part = input_body_part;
817 info.output_body_part = output_body_part;
818 info.tf_mode = tf_mode;
819 }
820
821 /** Creates and build program for given Case
822 *
823 * @param info Case instance
824 * @param captured_varyings Name of varyings captured by transform feedback
825 * @param n_captured_varyings_size Number of varyings captured by transform feedback
826 **/
initCaseProgram(Case & info,const glw::GLchar ** captured_varyings,glw::GLuint n_captured_varyings_size)827 void GeometryShader_gl_in_ArrayLengthTest::initCaseProgram(Case &info, const glw::GLchar **captured_varyings,
828 glw::GLuint n_captured_varyings_size)
829 {
830 /* GL */
831 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
832
833 /* Create program and shader objects */
834 info.po_id = gl.createProgram();
835
836 info.vs_id = gl.createShader(GL_VERTEX_SHADER);
837 info.gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
838 info.fs_id = gl.createShader(GL_FRAGMENT_SHADER);
839
840 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
841
842 /* Prepare geometry shader parts */
843 const char *const geometry_shader_parts[] = {m_geometry_shader_code_preamble, info.input_body_part,
844 info.output_body_part, m_geometry_shader_code_main};
845
846 /* Set up transform feedback */
847 gl.transformFeedbackVaryings(info.po_id, n_captured_varyings_size, captured_varyings, GL_SEPARATE_ATTRIBS);
848
849 /* Build program */
850 if (false == buildProgram(info.po_id, info.fs_id, 1 /* number of fragment shader code parts */,
851 &m_fragment_shader_code, info.gs_id, DE_LENGTH_OF_ARRAY(geometry_shader_parts),
852 geometry_shader_parts, info.vs_id, 1 /* number of vertex shader code parts */,
853 &m_vertex_shader_code))
854 {
855 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
856 }
857 }
858
859 /** Reset Case instance descriptor's contents.
860 *
861 * @param info Case instance
862 **/
resetCase(Case & info)863 void GeometryShader_gl_in_ArrayLengthTest::resetCase(Case &info)
864 {
865 memset(&info, 0, sizeof(info));
866 }
867
868 /** Constructor
869 *
870 * @param context Test context
871 * @param name Test case's name
872 * @param description Test case's desricption
873 **/
GeometryShader_gl_PointSize_ValueTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)874 GeometryShader_gl_PointSize_ValueTest::GeometryShader_gl_PointSize_ValueTest(Context &context,
875 const ExtParameters &extParams,
876 const char *name, const char *description)
877 : TestCaseBase(context, extParams, name, description)
878 , m_fragment_shader_id(0)
879 , m_geometry_shader_id(0)
880 , m_program_object_id(0)
881 , m_vertex_shader_id(0)
882 , m_vertex_array_object_id(0)
883 , m_color_texture_id(0)
884 , m_framebuffer_object_id(0)
885 {
886 /* Nothing to be done here */
887 }
888
889 /** Initialize test case
890 *
891 **/
init()892 void GeometryShader_gl_PointSize_ValueTest::init()
893 {
894 /* Initialize Base */
895 TestCaseBase::init();
896
897 /* This test should only run if EXT_geometry_shader and EXT_geometry_point_size both are supported */
898 if (true != m_is_geometry_shader_extension_supported)
899 {
900 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
901 }
902
903 if (true != m_is_geometry_shader_point_size_supported)
904 {
905 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
906 }
907
908 /* GL */
909 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
910
911 /* Verify that point size range is supported */
912 glw::GLfloat point_size_range[2] = {0};
913
914 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
915 {
916 gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
917 }
918 else
919 {
920 gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
921 }
922
923 if (8.0f > point_size_range[1])
924 {
925 m_testCtx.getLog() << tcu::TestLog::Message
926 << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
927 << point_size_range[1] << tcu::TestLog::EndMessage;
928
929 throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
930 }
931
932 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
933 {
934 gl.enable(GL_PROGRAM_POINT_SIZE);
935 }
936
937 /* Create program and shaders */
938 m_program_object_id = gl.createProgram();
939
940 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
941 m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
942 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
943
944 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
945
946 /* Build program */
947 if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
948 &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
949 &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
950 &m_vertex_shader_code))
951 {
952 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
953 }
954
955 /* Set up texture object and a FBO */
956 gl.genTextures(1, &m_color_texture_id);
957 gl.genFramebuffers(1, &m_framebuffer_object_id);
958
959 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
960
961 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
962 m_texture_width, m_texture_height))
963 {
964 TCU_FAIL("Failed to setup framebuffer");
965 }
966
967 /* Set up a vertex array object */
968 gl.genVertexArrays(1, &m_vertex_array_object_id);
969 gl.bindVertexArray(m_vertex_array_object_id);
970
971 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
972 }
973
974 /** Executes the test.
975 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
976 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
977 * Note the function throws exception should an error occur!
978 **/
iterate()979 tcu::TestCase::IterateResult GeometryShader_gl_PointSize_ValueTest::iterate()
980 {
981 /* Buffer to store results of rendering */
982 unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];
983
984 /* This test should only run if EXT_geometry_shader is supported */
985 if (true != m_is_geometry_shader_extension_supported)
986 {
987 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
988 }
989
990 if (true != m_is_geometry_shader_point_size_supported)
991 {
992 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
993 }
994
995 /* GL */
996 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
997
998 /* Render */
999 gl.useProgram(m_program_object_id);
1000
1001 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");
1002
1003 gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
1004 gl.clear(GL_COLOR_BUFFER_BIT);
1005
1006 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
1007
1008 gl.drawArrays(GL_POINTS, 0 /* first */, 2 /* count */);
1009
1010 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
1011
1012 /* Check if the data was modified during the rendering process */
1013 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
1014
1015 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
1016
1017 /* 1) pixel at (2, 8) is (255, 255, 255, 255) */
1018 unsigned int referencePixelCoordinates[2] = {2, 8};
1019
1020 if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
1021 m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
1022 255 /* blue */, 255 /* alpha */))
1023 {
1024 const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
1025 referencePixelCoordinates[0] * m_texture_pixel_size;
1026
1027 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1028 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1029 << result_image[texel_offset + 3] << "]"
1030 << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;
1031
1032 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1033 return STOP;
1034 }
1035
1036 /* 2) pixel at (14, 8) is (255, 255, 255, 255) */
1037 referencePixelCoordinates[0] = 14;
1038 referencePixelCoordinates[1] = 8;
1039
1040 if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
1041 m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
1042 255 /* blue */, 255 /* alpha */))
1043 {
1044 const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
1045 referencePixelCoordinates[0] * m_texture_pixel_size;
1046
1047 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1048 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1049 << result_image[texel_offset + 3] << "]"
1050 << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;
1051
1052 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1053 return STOP;
1054 }
1055
1056 /* 3) pixel at (6, 8) is (0, 0, 0, 0) */
1057 referencePixelCoordinates[0] = 6;
1058 referencePixelCoordinates[1] = 8;
1059
1060 if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
1061 m_texture_width, m_texture_height, m_texture_pixel_size, 0 /* red */, 0 /* green */,
1062 0 /* blue */, 0 /* alpha */))
1063 {
1064 const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
1065 referencePixelCoordinates[0] * m_texture_pixel_size;
1066
1067 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1068 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1069 << result_image[texel_offset + 3] << "]"
1070 << "is different from reference data [0, 0, 0, 0]!" << tcu::TestLog::EndMessage;
1071
1072 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1073 return STOP;
1074 }
1075
1076 /* Done */
1077 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1078 return STOP;
1079 }
1080
1081 /** Deinitializes test case
1082 *
1083 **/
deinit()1084 void GeometryShader_gl_PointSize_ValueTest::deinit()
1085 {
1086 /* GL */
1087 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1088
1089 /* Bind defaults */
1090 gl.useProgram(0);
1091 gl.bindVertexArray(0);
1092 gl.bindTexture(GL_TEXTURE_2D, 0);
1093 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1094 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1095 {
1096 gl.disable(GL_PROGRAM_POINT_SIZE);
1097 }
1098
1099 /* Delete everything */
1100 if (m_program_object_id != 0)
1101 {
1102 gl.deleteProgram(m_program_object_id);
1103 }
1104
1105 if (m_fragment_shader_id != 0)
1106 {
1107 gl.deleteShader(m_fragment_shader_id);
1108 }
1109
1110 if (m_geometry_shader_id != 0)
1111 {
1112 gl.deleteShader(m_geometry_shader_id);
1113 }
1114
1115 if (m_vertex_shader_id != 0)
1116 {
1117 gl.deleteShader(m_vertex_shader_id);
1118 }
1119
1120 if (m_vertex_array_object_id != 0)
1121 {
1122 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
1123 }
1124
1125 if (m_color_texture_id != 0)
1126 {
1127 gl.deleteTextures(1, &m_color_texture_id);
1128 }
1129
1130 if (m_framebuffer_object_id != 0)
1131 {
1132 gl.deleteFramebuffers(1, &m_framebuffer_object_id);
1133 }
1134
1135 /* Release base class */
1136 TestCaseBase::deinit();
1137 }
1138
1139 /** Constructor
1140 *
1141 * @param context Test context
1142 * @param name Test case's name
1143 * @param description Test case's desricption
1144 **/
GeometryShader_gl_Position_ValueTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1145 GeometryShader_gl_Position_ValueTest::GeometryShader_gl_Position_ValueTest(Context &context,
1146 const ExtParameters &extParams,
1147 const char *name, const char *description)
1148 : TestCaseBase(context, extParams, name, description)
1149 , m_fragment_shader_id(0)
1150 , m_geometry_shader_id(0)
1151 , m_program_object_id(0)
1152 , m_vertex_shader_id(0)
1153 , m_vertex_array_object_id(0)
1154 , m_color_texture_id(0)
1155 , m_framebuffer_object_id(0)
1156 {
1157 /* Nothing to be done here */
1158 }
1159
1160 /** Initialize test case
1161 *
1162 **/
init()1163 void GeometryShader_gl_Position_ValueTest::init()
1164 {
1165 /* Initialize base */
1166 TestCaseBase::init();
1167
1168 /* This test should only run if EXT_geometry_shader is supported */
1169 if (true != m_is_geometry_shader_extension_supported)
1170 {
1171 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1172 }
1173
1174 if (true != m_is_geometry_shader_point_size_supported)
1175 {
1176 throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
1177 }
1178
1179 /* GL */
1180 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1181
1182 /* Verify that point size range is supported */
1183 glw::GLfloat point_size_range[2] = {0};
1184
1185 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1186 {
1187 gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
1188 }
1189 else
1190 {
1191 gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
1192 }
1193
1194 if (8.0f > point_size_range[1])
1195 {
1196 m_testCtx.getLog() << tcu::TestLog::Message
1197 << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
1198 << point_size_range[1] << tcu::TestLog::EndMessage;
1199
1200 throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
1201 }
1202
1203 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1204 {
1205 gl.enable(GL_PROGRAM_POINT_SIZE);
1206 }
1207
1208 /* Create program and shaders */
1209 m_program_object_id = gl.createProgram();
1210
1211 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
1212 m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
1213 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
1214
1215 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
1216
1217 /* Build program */
1218 if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
1219 &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
1220 &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
1221 &m_vertex_shader_code))
1222 {
1223 TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
1224 }
1225
1226 /* Set up a texture object and a FBO */
1227 gl.genTextures(1, &m_color_texture_id);
1228 gl.genFramebuffers(1, &m_framebuffer_object_id);
1229
1230 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
1231
1232 if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
1233 m_texture_width, m_texture_height))
1234 {
1235 TCU_FAIL("Failed to setup framebuffer");
1236 }
1237
1238 /* Set up a vertex array object */
1239 gl.genVertexArrays(1, &m_vertex_array_object_id);
1240 gl.bindVertexArray(m_vertex_array_object_id);
1241
1242 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
1243 }
1244
1245 /** Executes the test.
1246 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1247 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1248 * Note the function throws exception should an error occur!
1249 **/
iterate()1250 tcu::TestCase::IterateResult GeometryShader_gl_Position_ValueTest::iterate()
1251 {
1252 /* Variables used for image verification purposes */
1253 unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];
1254
1255 /* This test should only run if EXT_geometry_shader is supported */
1256 if (true != m_is_geometry_shader_extension_supported)
1257 {
1258 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1259 }
1260
1261 /* GL */
1262 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1263
1264 /* Render */
1265 gl.useProgram(m_program_object_id);
1266
1267 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");
1268
1269 gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
1270 gl.clear(GL_COLOR_BUFFER_BIT);
1271
1272 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
1273
1274 gl.drawArrays(GL_POINTS, 0 /* first */, 8 /* count */);
1275
1276 GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
1277
1278 /* Check if the data was modified during the rendering process */
1279 gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
1280
1281 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
1282
1283 /* The test passes if centers of the rendered points are lit at expected locations. */
1284 for (unsigned int x = 4; x < m_texture_width; x += 8)
1285 {
1286 if (false == comparePixel(result_image, x, 32 /* y */, m_texture_width, m_texture_height, m_texture_pixel_size,
1287 255 /* red */, 255 /* green */, 255 /* blue */, 255 /* alpha */))
1288 {
1289 const unsigned int texel_offset = 32 * m_texture_width * m_texture_pixel_size + x * m_texture_pixel_size;
1290
1291 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1292 << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1293 << result_image[texel_offset + 3] << "]"
1294 << "is different from reference data [255, 255, 255, 255] !" << tcu::TestLog::EndMessage;
1295
1296 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1297 return STOP;
1298 }
1299 }
1300
1301 /* Done */
1302 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1303 return STOP;
1304 }
1305
1306 /** Deinitializes test case
1307 *
1308 **/
deinit()1309 void GeometryShader_gl_Position_ValueTest::deinit()
1310 {
1311 /* GL */
1312 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1313
1314 /* Bind default values */
1315 gl.useProgram(0);
1316 gl.bindVertexArray(0);
1317 gl.bindTexture(GL_TEXTURE_2D, 0);
1318 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1319 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1320 {
1321 gl.disable(GL_PROGRAM_POINT_SIZE);
1322 }
1323
1324 /* Delete everything */
1325 if (m_program_object_id != 0)
1326 {
1327 gl.deleteProgram(m_program_object_id);
1328 }
1329
1330 if (m_fragment_shader_id != 0)
1331 {
1332 gl.deleteShader(m_fragment_shader_id);
1333 }
1334
1335 if (m_geometry_shader_id != 0)
1336 {
1337 gl.deleteShader(m_geometry_shader_id);
1338 }
1339
1340 if (m_vertex_shader_id != 0)
1341 {
1342 gl.deleteShader(m_vertex_shader_id);
1343 }
1344
1345 if (m_vertex_array_object_id != 0)
1346 {
1347 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
1348 }
1349
1350 if (m_color_texture_id != 0)
1351 {
1352 gl.deleteTextures(1, &m_color_texture_id);
1353 }
1354
1355 if (m_framebuffer_object_id != 0)
1356 {
1357 gl.deleteFramebuffers(1, &m_framebuffer_object_id);
1358 }
1359
1360 /* Release base class */
1361 TestCaseBase::deinit();
1362 }
1363
1364 } // namespace glcts
1365