1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24 /**
25 * \file gl4cSyncTests.cpp
26 * \brief Declares test classes for synchronization functionality.
27 */ /*-------------------------------------------------------------------*/
28
29 #include "gl4cIncompleteTextureAccessTests.hpp"
30
31 #include "deSharedPtr.hpp"
32
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "gluPixelTransfer.hpp"
36 #include "gluStrUtil.hpp"
37
38 #include "tcuFuzzyImageCompare.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "tcuRenderTarget.hpp"
41 #include "tcuSurface.hpp"
42 #include "tcuTestLog.hpp"
43
44 #include "glw.h"
45 #include "glwFunctions.hpp"
46
47 namespace gl4cts
48 {
49 namespace IncompleteTextureAccess
50 {
51 /****************************************** Incomplete Texture Access Tests Group ***********************************************/
52
53 /** @brief Incomplete Texture Access Tests Group constructor.
54 *
55 * @param [in] context OpenGL context.
56 */
Tests(deqp::Context & context)57 Tests::Tests(deqp::Context &context)
58 : TestCaseGroup(context, "incomplete_texture_access", "Incomplete Texture Access Tests Suite")
59 {
60 }
61
62 /** @brief Incomplete Texture Access Tests initializer. */
init()63 void Tests::init()
64 {
65 addChild(new IncompleteTextureAccess::SamplerTest(m_context));
66 }
67
68 /*************************************** Sampler Incomplete Texture Access Test Test *******************************************/
69
70 /** @brief Sampler Incomplete Texture Access Test constructor.
71 *
72 * @param [in] context OpenGL context.
73 */
SamplerTest(deqp::Context & context)74 SamplerTest::SamplerTest(deqp::Context &context)
75 : deqp::TestCase(context, "sampler", "Fetch using sampler test")
76 , m_po(0)
77 , m_to(0)
78 , m_fbo(0)
79 , m_rbo(0)
80 , m_vao(0)
81 {
82 /* Intentionally left blank. */
83 }
84
85 /** @brief Iterate Incomplete Texture Access Test cases.
86 *
87 * @return Iteration result.
88 */
iterate()89 tcu::TestNode::IterateResult SamplerTest::iterate()
90 {
91 /* Get context setup. */
92 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
93
94 if (!is_at_least_gl_45)
95 {
96 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
97
98 return STOP;
99 }
100
101 /* Running tests. */
102 bool is_ok = true;
103 bool is_error = false;
104
105 try
106 {
107 PrepareFramebuffer();
108 PrepareVertexArrays();
109
110 for (glw::GLuint i = 0; i < s_configurations_count; ++i)
111 {
112 PrepareProgram(s_configurations[i]);
113 PrepareTexture(s_configurations[i]);
114
115 Draw();
116
117 if (!Check(s_configurations[i]))
118 {
119 m_context.getTestContext().getLog()
120 << tcu::TestLog::Message << "Incomplete texture sampler access test failed with sampler "
121 << s_configurations[i].sampler_template << "." << tcu::TestLog::EndMessage;
122
123 is_ok = false;
124 }
125
126 CleanCase();
127 }
128 }
129 catch (...)
130 {
131 is_ok = false;
132 is_error = true;
133 }
134
135 /* Cleanup. */
136 CleanCase();
137 CleanTest();
138
139 /* Result's setup. */
140 if (is_ok)
141 {
142 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
143 }
144 else
145 {
146 if (is_error)
147 {
148 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
149 }
150 else
151 {
152 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
153 }
154 }
155
156 return STOP;
157 }
158
PrepareProgram(Configuration configuration)159 void SamplerTest::PrepareProgram(Configuration configuration)
160 {
161 /* Shortcut for GL functionality */
162 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
163
164 struct Shader
165 {
166 glw::GLchar const *source[5];
167 glw::GLsizei const count;
168 glw::GLenum const type;
169 glw::GLuint id;
170 } shader[] = {{{s_vertex_shader, NULL, NULL, NULL, NULL}, 1, GL_VERTEX_SHADER, 0},
171 {{s_fragment_shader_head, configuration.sampler_template, s_fragment_shader_body,
172 configuration.fetch_template, s_fragment_shader_tail},
173 5,
174 GL_FRAGMENT_SHADER,
175 0}};
176
177 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
178
179 try
180 {
181 /* Create program. */
182 m_po = gl.createProgram();
183 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
184
185 /* Shader compilation. */
186
187 for (glw::GLuint i = 0; i < shader_count; ++i)
188 {
189 {
190 shader[i].id = gl.createShader(shader[i].type);
191
192 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
193
194 gl.attachShader(m_po, shader[i].id);
195
196 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
197
198 gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
199
200 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
201
202 gl.compileShader(shader[i].id);
203
204 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
205
206 glw::GLint status = GL_FALSE;
207
208 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
209 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
210
211 if (GL_FALSE == status)
212 {
213 glw::GLint log_size = 0;
214 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
215 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
216
217 glw::GLchar *log_text = new glw::GLchar[log_size];
218
219 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
220
221 m_context.getTestContext().getLog()
222 << tcu::TestLog::Message << "Shader compilation has failed.\n"
223 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
224 << "Shader compilation error log:\n"
225 << log_text << "\n"
226 << "Shader source code:\n"
227 << shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
228 << (shader[i].source[2] ? shader[i].source[2] : "")
229 << (shader[i].source[3] ? shader[i].source[3] : "")
230 << (shader[i].source[4] ? shader[i].source[4] : "") << "\n"
231 << tcu::TestLog::EndMessage;
232
233 delete[] log_text;
234
235 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
236
237 throw 0;
238 }
239 }
240 }
241
242 /* Link. */
243 gl.linkProgram(m_po);
244
245 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
246
247 glw::GLint status = GL_FALSE;
248
249 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
250
251 if (GL_TRUE == status)
252 {
253 for (glw::GLuint i = 0; i < shader_count; ++i)
254 {
255 if (shader[i].id)
256 {
257 gl.detachShader(m_po, shader[i].id);
258
259 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
260 }
261 }
262 }
263 else
264 {
265 glw::GLint log_size = 0;
266
267 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
268
269 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
270
271 glw::GLchar *log_text = new glw::GLchar[log_size];
272
273 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
274
275 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
276 << log_text << "\n"
277 << tcu::TestLog::EndMessage;
278
279 delete[] log_text;
280
281 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
282
283 throw 0;
284 }
285 }
286 catch (...)
287 {
288 if (m_po)
289 {
290 gl.deleteProgram(m_po);
291
292 m_po = 0;
293 }
294 }
295
296 for (glw::GLuint i = 0; i < shader_count; ++i)
297 {
298 if (0 != shader[i].id)
299 {
300 gl.deleteShader(shader[i].id);
301
302 shader[i].id = 0;
303 }
304 }
305
306 if (0 == m_po)
307 {
308 throw 0;
309 }
310 else
311 {
312 gl.useProgram(m_po);
313 GLU_EXPECT_NO_ERROR(gl.getError(), "glUsePrograms has failed");
314 }
315 }
316
PrepareTexture(Configuration configuration)317 void SamplerTest::PrepareTexture(Configuration configuration)
318 {
319 /* Shortcut for GL functionality. */
320 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
321
322 if (m_to)
323 {
324 throw 0;
325 }
326
327 gl.genTextures(1, &m_to);
328 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
329
330 gl.bindTexture(configuration.texture_target, m_to);
331 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
332
333 if (configuration.is_shadow)
334 {
335 gl.texParameteri(configuration.texture_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
336 gl.texParameteri(configuration.texture_target, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
337 }
338 else
339 {
340 gl.texParameteri(configuration.texture_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
341 }
342 }
343
PrepareFramebuffer()344 void SamplerTest::PrepareFramebuffer()
345 {
346 /* Shortcut for GL functionality. */
347 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
348
349 /* Quick checks. */
350 if (m_fbo || m_rbo)
351 {
352 throw 0;
353 }
354
355 /* Framebuffer creation. */
356 gl.genFramebuffers(1, &m_fbo);
357 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
358
359 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
360 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
361
362 gl.genRenderbuffers(1, &m_rbo);
363 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
364
365 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
366 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
367
368 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1 /* x size */, 1 /* y size */);
369 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
370
371 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
372 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
373
374 /* Quick checks. */
375 if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
376 {
377 throw 0;
378 }
379 }
380
PrepareVertexArrays()381 void SamplerTest::PrepareVertexArrays()
382 {
383 /* Shortcut for GL functionality. */
384 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
385
386 /* Quick checks.*/
387 if (m_vao)
388 {
389 throw 0;
390 }
391
392 /* Empty vao creation. */
393 gl.genVertexArrays(1, &m_vao);
394 GLU_EXPECT_NO_ERROR(gl.getError(), "gGenVertexArrays has failed");
395
396 gl.bindVertexArray(m_vao);
397 GLU_EXPECT_NO_ERROR(gl.getError(), "gBindVertexArrays has failed");
398 }
399
Draw()400 void SamplerTest::Draw()
401 {
402 /* Shortcut for GL functionality. */
403 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
404
405 /* Draw setup. */
406 gl.activeTexture(GL_TEXTURE0);
407 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
408
409 gl.uniform1i(gl.getUniformLocation(m_po, "texture_input"), 0);
410 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i has failed");
411
412 /* Draw. */
413 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
414 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
415 }
416
Check(Configuration configuration)417 bool SamplerTest::Check(Configuration configuration)
418 {
419 /* Shortcut for GL functionality. */
420 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
421
422 /* Return storage. */
423 glw::GLfloat result[4] = {7.f, 7.f, 7.f, 7.f};
424
425 /* Fetch. */
426 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, result);
427 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
428
429 /* Comparison. */
430 for (glw::GLuint i = 0; i < 4 /* # components */; ++i)
431 {
432 if (de::abs(configuration.expected_result[i] - result[i]) > 0.0125 /* precision */)
433 {
434 /* Fail.*/
435 return false;
436 }
437 }
438
439 /* Comparsion passed.*/
440 return true;
441 }
442
CleanCase()443 void SamplerTest::CleanCase()
444 {
445 /* Shortcut for GL functionality. */
446 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
447
448 /* Program cleanup. */
449 if (m_po)
450 {
451 gl.deleteProgram(m_po);
452
453 m_po = 0;
454 }
455
456 /* Texture cleanup. */
457 if (m_to)
458 {
459 gl.deleteTextures(1, &m_to);
460
461 m_to = 0;
462 }
463
464 /* Errors cleanup. */
465 while (gl.getError())
466 ;
467 }
468
CleanTest()469 void SamplerTest::CleanTest()
470 {
471 /* Shortcut for GL functionality. */
472 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
473
474 /* Framebuffer cleanup. */
475 if (m_fbo)
476 {
477 gl.deleteFramebuffers(1, &m_fbo);
478
479 m_fbo = 0;
480 }
481
482 /* Renderbuffer cleanup. */
483 if (m_rbo)
484 {
485 gl.deleteRenderbuffers(1, &m_rbo);
486
487 m_rbo = 0;
488 }
489
490 /* Vertex arrays cleanup. */
491 if (m_vao)
492 {
493 gl.deleteVertexArrays(1, &m_vao);
494
495 m_vao = 0;
496 }
497
498 /* Errors cleanup. */
499 while (gl.getError())
500 ;
501 }
502
503 const struct SamplerTest::Configuration SamplerTest::s_configurations[] = {
504 /* regular floating point sampling */
505 {GL_TEXTURE_1D, "sampler1D", "texture(texture_input, 0.0)", {0.f, 0.f, 0.f, 1.f}, false},
506 {GL_TEXTURE_2D, "sampler2D", "texture(texture_input, vec2(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
507 {GL_TEXTURE_3D, "sampler3D", "texture(texture_input, vec3(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
508 {GL_TEXTURE_CUBE_MAP, "samplerCube", "texture(texture_input, vec3(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
509 {GL_TEXTURE_RECTANGLE, "sampler2DRect", "texture(texture_input, vec2(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
510 {GL_TEXTURE_1D_ARRAY, "sampler1DArray", "texture(texture_input, vec2(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
511 {GL_TEXTURE_2D_ARRAY, "sampler2DArray", "texture(texture_input, vec3(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
512 {GL_TEXTURE_CUBE_MAP_ARRAY, "samplerCubeArray", "texture(texture_input, vec4(0.0))", {0.f, 0.f, 0.f, 1.f}, false},
513
514 /* Shadow textures. */
515 {GL_TEXTURE_1D,
516 "sampler1DShadow",
517 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
518 {0.f, 0.f, 0.f, 0.f},
519 true},
520 {GL_TEXTURE_2D,
521 "sampler2DShadow",
522 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
523 {0.f, 0.f, 0.f, 0.f},
524 true},
525 {GL_TEXTURE_CUBE_MAP,
526 "samplerCubeShadow",
527 "vec4(texture(texture_input, vec4(0.0)), 0.0, 0.0, 0.0)",
528 {0.f, 0.f, 0.f, 0.f},
529 true},
530 {GL_TEXTURE_RECTANGLE,
531 "sampler2DRectShadow",
532 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
533 {0.f, 0.f, 0.f, 0.f},
534 true},
535 {GL_TEXTURE_1D_ARRAY,
536 "sampler1DArrayShadow",
537 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
538 {0.f, 0.f, 0.f, 0.f},
539 true},
540 {GL_TEXTURE_2D_ARRAY,
541 "sampler2DArrayShadow",
542 "vec4(texture(texture_input, vec4(0.0)), 0.0, 0.0, 0.0)",
543 {0.f, 0.f, 0.f, 0.f},
544 true},
545 {GL_TEXTURE_CUBE_MAP_ARRAY,
546 "samplerCubeArrayShadow",
547 "vec4(texture(texture_input, vec4(0.0), 1.0), 0.0, 0.0, 0.0)",
548 {0.f, 0.f, 0.f, 0.f},
549 true}};
550
551 const glw::GLuint SamplerTest::s_configurations_count = sizeof(s_configurations) / sizeof(s_configurations[0]);
552
553 const glw::GLchar *SamplerTest::s_vertex_shader = "#version 450\n"
554 "\n"
555 "void main()\n"
556 "{\n"
557 " switch(gl_VertexID)\n"
558 " {\n"
559 " case 0:\n"
560 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
561 " break;\n"
562 " case 1:\n"
563 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
564 " break;\n"
565 " case 2:\n"
566 " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
567 " break;\n"
568 " case 3:\n"
569 " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
570 " break;\n"
571 " }\n"
572 "}\n";
573
574 const glw::GLchar *SamplerTest::s_fragment_shader_head = "#version 450\n"
575 "\n"
576 "uniform ";
577
578 const glw::GLchar *SamplerTest::s_fragment_shader_body = " texture_input;\n"
579 "out vec4 texture_output;\n"
580 "\n"
581 "void main()\n"
582 "{\n"
583 " texture_output = ";
584
585 const glw::GLchar *SamplerTest::s_fragment_shader_tail = ";\n"
586 "}\n";
587
588 } // namespace IncompleteTextureAccess
589 } // namespace gl4cts
590