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