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
PrepareFramebuffer()329 void SamplerTest::PrepareFramebuffer()
330 {
331 /* Shortcut for GL functionality. */
332 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
333
334 /* Sanity checks. */
335 if (m_fbo || m_rbo)
336 {
337 throw 0;
338 }
339
340 /* Framebuffer creation. */
341 gl.genFramebuffers(1, &m_fbo);
342 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
343
344 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
345 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
346
347 gl.genRenderbuffers(1, &m_rbo);
348 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
349
350 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
351 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
352
353 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1 /* x size */, 1 /* y size */);
354 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
355
356 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
357 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
358
359 /* Sanity checks. */
360 if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
361 {
362 throw 0;
363 }
364 }
365
PrepareVertexArrays()366 void SamplerTest::PrepareVertexArrays()
367 {
368 /* Shortcut for GL functionality. */
369 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
370
371 /* Sanity checks.*/
372 if (m_vao)
373 {
374 throw 0;
375 }
376
377 /* Empty vao creation. */
378 gl.genVertexArrays(1, &m_vao);
379 GLU_EXPECT_NO_ERROR(gl.getError(), "gGenVertexArrays has failed");
380
381 gl.bindVertexArray(m_vao);
382 GLU_EXPECT_NO_ERROR(gl.getError(), "gBindVertexArrays has failed");
383 }
384
Draw()385 void SamplerTest::Draw()
386 {
387 /* Shortcut for GL functionality. */
388 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
389
390 /* Draw setup. */
391 gl.activeTexture(GL_TEXTURE0);
392 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
393
394 gl.uniform1i(gl.getUniformLocation(m_po, "texture_input"), 0);
395 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i has failed");
396
397 /* Draw. */
398 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
399 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
400 }
401
Check(Configuration configuration)402 bool SamplerTest::Check(Configuration configuration)
403 {
404 /* Shortcut for GL functionality. */
405 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
406
407 /* Return storage. */
408 glw::GLfloat result[4] = { 7.f, 7.f, 7.f, 7.f };
409
410 /* Fetch. */
411 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, result);
412 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
413
414 /* Comparison. */
415 for (glw::GLuint i = 0; i < 4 /* # components */; ++i)
416 {
417 if (de::abs(configuration.expected_result[i] - result[i]) > 0.0125 /* precision */)
418 {
419 /* Fail.*/
420 return false;
421 }
422 }
423
424 /* Comparsion passed.*/
425 return true;
426 }
427
CleanCase()428 void SamplerTest::CleanCase()
429 {
430 /* Shortcut for GL functionality. */
431 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
432
433 /* Program cleanup. */
434 if (m_po)
435 {
436 gl.deleteProgram(m_po);
437
438 m_po = 0;
439 }
440
441 /* Texture cleanup. */
442 if (m_to)
443 {
444 gl.deleteTextures(1, &m_to);
445
446 m_to = 0;
447 }
448
449 /* Errors cleanup. */
450 while (gl.getError())
451 ;
452 }
453
CleanTest()454 void SamplerTest::CleanTest()
455 {
456 /* Shortcut for GL functionality. */
457 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
458
459 /* Framebuffer cleanup. */
460 if (m_fbo)
461 {
462 gl.deleteFramebuffers(1, &m_fbo);
463
464 m_fbo = 0;
465 }
466
467 /* Renderbuffer cleanup. */
468 if (m_rbo)
469 {
470 gl.deleteRenderbuffers(1, &m_rbo);
471
472 m_rbo = 0;
473 }
474
475 /* Vertex arrays cleanup. */
476 if (m_vao)
477 {
478 gl.deleteVertexArrays(1, &m_vao);
479
480 m_vao = 0;
481 }
482
483 /* Errors cleanup. */
484 while (gl.getError())
485 ;
486 }
487
488 const struct SamplerTest::Configuration SamplerTest::s_configurations[] = {
489 /* regular floating point sampling */
490 { GL_TEXTURE_1D, "sampler1D", "texture(texture_input, 0.0)", { 0.f, 0.f, 0.f, 1.f } },
491 { GL_TEXTURE_2D, "sampler2D", "texture(texture_input, vec2(0.0))", { 0.f, 0.f, 0.f, 1.f } },
492 { GL_TEXTURE_3D, "sampler3D", "texture(texture_input, vec3(0.0))", { 0.f, 0.f, 0.f, 1.f } },
493 { GL_TEXTURE_CUBE_MAP, "samplerCube", "texture(texture_input, vec3(0.0))", { 0.f, 0.f, 0.f, 1.f } },
494 { GL_TEXTURE_RECTANGLE, "sampler2DRect", "texture(texture_input, vec2(0.0))", { 0.f, 0.f, 0.f, 1.f } },
495 { GL_TEXTURE_1D_ARRAY, "sampler1DArray", "texture(texture_input, vec2(0.0))", { 0.f, 0.f, 0.f, 1.f } },
496 { GL_TEXTURE_2D_ARRAY, "sampler2DArray", "texture(texture_input, vec3(0.0))", { 0.f, 0.f, 0.f, 1.f } },
497 { GL_TEXTURE_CUBE_MAP_ARRAY, "samplerCubeArray", "texture(texture_input, vec4(0.0))", { 0.f, 0.f, 0.f, 1.f } },
498
499 /* Shadow textures. */
500 { GL_TEXTURE_1D,
501 "sampler1DShadow",
502 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
503 { 0.f, 0.f, 0.f, 0.f } },
504 { GL_TEXTURE_2D,
505 "sampler2DShadow",
506 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
507 { 0.f, 0.f, 0.f, 0.f } },
508 { GL_TEXTURE_CUBE_MAP,
509 "samplerCubeShadow",
510 "vec4(texture(texture_input, vec4(0.0)), 0.0, 0.0, 0.0)",
511 { 0.f, 0.f, 0.f, 0.f } },
512 { GL_TEXTURE_RECTANGLE,
513 "sampler2DRectShadow",
514 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
515 { 0.f, 0.f, 0.f, 0.f } },
516 { GL_TEXTURE_1D_ARRAY,
517 "sampler1DArrayShadow",
518 "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
519 { 0.f, 0.f, 0.f, 0.f } },
520 { GL_TEXTURE_2D_ARRAY,
521 "sampler2DArrayShadow",
522 "vec4(texture(texture_input, vec4(0.0)), 0.0, 0.0, 0.0)",
523 { 0.f, 0.f, 0.f, 0.f } },
524 { GL_TEXTURE_CUBE_MAP_ARRAY,
525 "samplerCubeArrayShadow",
526 "vec4(texture(texture_input, vec4(0.0), 1.0), 0.0, 0.0, 0.0)",
527 { 0.f, 0.f, 0.f, 0.f } }
528 };
529
530 const glw::GLuint SamplerTest::s_configurations_count = sizeof(s_configurations) / sizeof(s_configurations[0]);
531
532 const glw::GLchar* SamplerTest::s_vertex_shader = "#version 450\n"
533 "\n"
534 "void main()\n"
535 "{\n"
536 " switch(gl_VertexID)\n"
537 " {\n"
538 " case 0:\n"
539 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
540 " break;\n"
541 " case 1:\n"
542 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
543 " break;\n"
544 " case 2:\n"
545 " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
546 " break;\n"
547 " case 3:\n"
548 " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
549 " break;\n"
550 " }\n"
551 "}\n";
552
553 const glw::GLchar* SamplerTest::s_fragment_shader_head = "#version 450\n"
554 "\n"
555 "uniform ";
556
557 const glw::GLchar* SamplerTest::s_fragment_shader_body = " texture_input;\n"
558 "out vec4 texture_output;\n"
559 "\n"
560 "void main()\n"
561 "{\n"
562 " texture_output = ";
563
564 const glw::GLchar* SamplerTest::s_fragment_shader_tail = ";\n"
565 "}\n";
566
567 } /* IncompleteTextureAccess namespace */
568 } /* gl4cts namespace */
569