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 #include "esextcGeometryShaderLayeredFBO.hpp"
24 
25 #include "gluDefs.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuTestLog.hpp"
29 #include <cstring>
30 
31 namespace glcts
32 {
33 
34 const unsigned int GeometryShaderLayeredFBOShared::n_shared_fbo_ids = 4; /* as per test spec */
35 const unsigned int GeometryShaderLayeredFBOShared::n_shared_to_ids  = 7; /* as per test spec */
36 const glw::GLuint GeometryShaderLayeredFBOShared::shared_to_depth   = 4; /* as per test spec */
37 const glw::GLuint GeometryShaderLayeredFBOShared::shared_to_height  = 4; /* as per test spec */
38 const glw::GLuint GeometryShaderLayeredFBOShared::shared_to_width   = 4; /* as per test spec */
39 
40 /** Checks if the bound draw framebuffer's completeness status is equal to the value
41  *  specified by the caller.
42  *
43  *  @param test_context                 Test context used by the conformance test.
44  *  @param gl                           ES / GL entry-points.
45  *  @param fbo_id                       ID of the framebuffer to use for the query.
46  *  @param expected_completeness_status Expected completeness status (described by a GLenum value)
47  *
48  *  @return true if the draw framebuffer's completeness status matches the expected value,
49  *          false otherwise
50  */
checkFBOCompleteness(tcu::TestContext & test_context,const glw::Functions & gl,glw::GLenum fbo_id,glw::GLenum expected_completeness_status)51 bool GeometryShaderLayeredFBOShared::checkFBOCompleteness(tcu::TestContext &test_context, const glw::Functions &gl,
52                                                           glw::GLenum fbo_id, glw::GLenum expected_completeness_status)
53 {
54     glw::GLenum current_fbo_status = GL_NONE;
55     bool result                    = true;
56 
57     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
58     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
59 
60     current_fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
61     GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus() call failed.");
62 
63     if (current_fbo_status != expected_completeness_status)
64     {
65         /* Please check doxygen documentation of GeometryShaderIncompleteLayeredFBOTest class
66          * for more details, if you ever reach this location */
67         test_context.getLog() << tcu::TestLog::Message << "Test iteration [" << fbo_id
68                               << "] failed. "
69                                  "Expected: ["
70                               << expected_completeness_status
71                               << "], "
72                                  "got: ["
73                               << current_fbo_status << "]" << tcu::TestLog::EndMessage;
74 
75         result = false;
76     }
77 
78     return result;
79 }
80 
81 /** Deinitializes framebuffer objects, whose IDs are passed by the caller.
82  *
83  *  @param gl      ES / GL entry-points
84  *  @param fbo_ids Exactly GeometryShaderLayeredFBOShared::n_shared_fbo_ids FBO
85  *                 ids to be deinitialized.
86  */
deinitFBOs(const glw::Functions & gl,const glw::GLuint * fbo_ids)87 void GeometryShaderLayeredFBOShared::deinitFBOs(const glw::Functions &gl, const glw::GLuint *fbo_ids)
88 {
89     if (fbo_ids != DE_NULL)
90     {
91         gl.deleteFramebuffers(GeometryShaderLayeredFBOShared::n_shared_fbo_ids, fbo_ids);
92     }
93 }
94 
95 /** Deinitializes texture obejcts, whose IDs are passed by the caller.
96  *
97  *  @param gl     ES / GL entry-points
98  *  @param to_ids Exactly GeometryShaderLayeredFBOShared::n_shared_to_ids Texture
99  *                Object IDs to be deinitialized.
100  */
deinitTOs(const glw::Functions & gl,const glw::GLuint * to_ids)101 void GeometryShaderLayeredFBOShared::deinitTOs(const glw::Functions &gl, const glw::GLuint *to_ids)
102 {
103     if (to_ids != DE_NULL)
104     {
105         gl.deleteTextures(GeometryShaderLayeredFBOShared::n_shared_to_ids, to_ids);
106     }
107 }
108 
109 /** Initializes all framebuffer objects required to run layered framebufer object conformance test.
110  *
111  *  @param gl                    ES / GL entry-points
112  *  @param pGLFramebufferTexture glFramebufferTexture{EXT}() entry-point func ptr.
113  *  @param to_ids                Exactly 7 Texture Object IDs, initialized as per test spec.
114  *  @param out_fbo_ids           Deref will be used to store 4 FBO ids, initialized as per test spec.
115  **/
initFBOs(const glw::Functions & gl,glw::glFramebufferTextureFunc pGLFramebufferTexture,const glw::GLuint * to_ids,glw::GLuint * out_fbo_ids)116 void GeometryShaderLayeredFBOShared::initFBOs(const glw::Functions &gl,
117                                               glw::glFramebufferTextureFunc pGLFramebufferTexture,
118                                               const glw::GLuint *to_ids, glw::GLuint *out_fbo_ids)
119 {
120     const glw::GLuint to_id_a      = to_ids[0];
121     const glw::GLuint to_id_a_prim = to_ids[1];
122     const glw::GLuint to_id_b      = to_ids[2];
123     const glw::GLuint to_id_c      = to_ids[3];
124     const glw::GLuint to_id_d      = to_ids[4];
125     const glw::GLuint to_id_e      = to_ids[5];
126     const glw::GLuint to_id_f      = to_ids[6];
127 
128     gl.genFramebuffers(n_shared_fbo_ids, out_fbo_ids);
129     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
130 
131     /* Set up framebuffer object A */
132     const glw::GLenum fbo_a_draw_buffers[]  = {GL_COLOR_ATTACHMENT0, GL_NONE, GL_COLOR_ATTACHMENT2};
133     const glw::GLenum fbo_b_draw_buffers[]  = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
134     const glw::GLenum fbo_c_draw_buffers[]  = {GL_COLOR_ATTACHMENT0};
135     const glw::GLenum fbo_d_draw_buffers[]  = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
136     const glw::GLuint fbo_id_a              = out_fbo_ids[0];
137     const glw::GLuint fbo_id_b              = out_fbo_ids[1];
138     const glw::GLuint fbo_id_c              = out_fbo_ids[2];
139     const glw::GLuint fbo_id_d              = out_fbo_ids[3];
140     const unsigned int n_fbo_a_draw_buffers = sizeof(fbo_a_draw_buffers) / sizeof(fbo_a_draw_buffers[0]);
141     const unsigned int n_fbo_b_draw_buffers = sizeof(fbo_b_draw_buffers) / sizeof(fbo_b_draw_buffers[0]);
142     const unsigned int n_fbo_c_draw_buffers = sizeof(fbo_c_draw_buffers) / sizeof(fbo_c_draw_buffers[0]);
143     const unsigned int n_fbo_d_draw_buffers = sizeof(fbo_d_draw_buffers) / sizeof(fbo_d_draw_buffers[0]);
144 
145     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_a);
146     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
147 
148     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_a, 0);     /* level */
149     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, to_id_b, 0);     /* level */
150     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, to_id_a_prim, 0); /* level */
151     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call(s) failed.");
152 
153     gl.drawBuffers(n_fbo_a_draw_buffers, fbo_a_draw_buffers);
154     GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffers() call failed.");
155 
156     /* Set up framebuffer object B */
157     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_b);
158     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
159 
160     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_c, 0); /* level */
161     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_a, 0); /* level */
162     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call(s) failed.");
163 
164     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, to_id_d, 0); /* level */
165     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
166 
167     gl.drawBuffers(n_fbo_b_draw_buffers, fbo_b_draw_buffers);
168     GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffers() call failed.");
169 
170     /* Set up framebuffer object C */
171     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_c);
172     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
173 
174     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_d, 0); /* level */
175     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
176 
177     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, to_id_a_prim, 0); /* level */
178     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call failed.");
179 
180     gl.drawBuffers(n_fbo_c_draw_buffers, fbo_c_draw_buffers);
181     GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBufers() call failed.");
182 
183     /* Set up framebuffer object D */
184     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_d);
185     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
186 
187     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_e, 0); /* level */
188     pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_f, 0); /* level */
189     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call(s) failed.");
190 
191     gl.drawBuffers(n_fbo_d_draw_buffers, fbo_d_draw_buffers);
192     GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffers() call failed.");
193 }
194 
195 /** Initializes exactly seven texture objects, as per test spec.
196  *
197  *  @param gl                         ES / GL entry-points
198  *  @param pGLTexStorage3DMultisample glTexStorage3DMultisample{EXT}() entry-point func ptr.
199  *  @param out_to_ids                 Deref will be used to store 7 texture object IDs, initialized
200  *                                    as per test spec.
201  */
initTOs(const glw::Functions & gl,glw::glTexStorage3DMultisampleFunc pGLTexStorage3DMultisample,glw::GLuint * out_to_ids)202 void GeometryShaderLayeredFBOShared::initTOs(const glw::Functions &gl,
203                                              glw::glTexStorage3DMultisampleFunc pGLTexStorage3DMultisample,
204                                              glw::GLuint *out_to_ids)
205 {
206     gl.genTextures(n_shared_to_ids, out_to_ids);
207     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
208 
209     /* Set up texture object A */
210     const glw::GLuint to_id_a      = out_to_ids[0];
211     const glw::GLuint to_id_a_prim = out_to_ids[1];
212     const glw::GLuint to_id_b      = out_to_ids[2];
213     const glw::GLuint to_id_c      = out_to_ids[3];
214     const glw::GLuint to_id_d      = out_to_ids[4];
215     const glw::GLuint to_id_e      = out_to_ids[5];
216     const glw::GLuint to_id_f      = out_to_ids[6];
217 
218     gl.bindTexture(GL_TEXTURE_2D, to_id_a);
219     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
220 
221     gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
222                     GL_RGBA8,         /* color-renderable internalformat */
223                     shared_to_width, shared_to_height);
224     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
225 
226     /* Set up texture object A' */
227     gl.bindTexture(GL_TEXTURE_2D, to_id_a_prim);
228     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
229 
230     gl.texStorage2D(GL_TEXTURE_2D, 1,     /* levels */
231                     GL_DEPTH_COMPONENT16, /* depth-renderable internalformat */
232                     shared_to_width, shared_to_height);
233     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
234 
235     /* Set up texture object B */
236     gl.bindTexture(GL_TEXTURE_2D_ARRAY, to_id_b);
237     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
238 
239     gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, /* levels */
240                     GL_RGBA8,               /* color-renderable internalformat */
241                     shared_to_width, shared_to_height, shared_to_depth);
242     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
243 
244     /* Set up texture object C */
245     gl.bindTexture(GL_TEXTURE_3D, to_id_c);
246     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
247 
248     gl.texStorage3D(GL_TEXTURE_3D, 1, /* levels */
249                     GL_RGBA8,         /* color-renderable internalformats */
250                     shared_to_width, shared_to_height, shared_to_depth);
251     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
252 
253     /* Set up texture object D */
254     gl.bindTexture(GL_TEXTURE_CUBE_MAP, to_id_d);
255     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
256 
257     gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, /* levels */
258                     GL_RGBA8,               /* color-renderable internalformat */
259                     shared_to_width, shared_to_height);
260     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
261 
262     /* Set up texture object E */
263     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_e);
264     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
265 
266     gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,                /* samples */
267                                GL_RGBA8,                                    /* color-renderable internalformat */
268                                shared_to_width, shared_to_height, GL_TRUE); /* fixedsamplelocations */
269     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed.");
270 
271     /* Set up texture object F */
272     gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, to_id_f);
273     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
274 
275     pGLTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 2, /* samples */
276                                GL_RGBA8,                           /* color-renderable internalformat */
277                                shared_to_width, shared_to_height, shared_to_depth, GL_TRUE); /* fixedsamplelocations */
278     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed.");
279 }
280 
281 /** Constructor
282  *
283  * @param context       Test context
284  * @param extParams     Not used.
285  * @param name          Test case's name
286  * @param description   Test case's description
287  **/
GeometryShaderIncompleteLayeredFBOTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)288 GeometryShaderIncompleteLayeredFBOTest::GeometryShaderIncompleteLayeredFBOTest(Context &context,
289                                                                                const ExtParameters &extParams,
290                                                                                const char *name,
291                                                                                const char *description)
292     : TestCaseBase(context, extParams, name, description)
293     , m_fbo_ids(DE_NULL)
294     , m_to_ids(DE_NULL)
295 {
296     // left blank intentionally
297 }
298 
299 /** Deinitializes GLES objects created during the test. */
deinit()300 void GeometryShaderIncompleteLayeredFBOTest::deinit()
301 {
302     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
303 
304     /* Release framebuffer objects */
305     GeometryShaderLayeredFBOShared::deinitFBOs(gl, m_fbo_ids);
306 
307     if (m_fbo_ids != DE_NULL)
308     {
309         delete[] m_fbo_ids;
310 
311         m_fbo_ids = DE_NULL;
312     }
313 
314     /* Release texture objects */
315     GeometryShaderLayeredFBOShared::deinitTOs(gl, m_to_ids);
316 
317     if (m_to_ids != DE_NULL)
318     {
319         delete[] m_to_ids;
320 
321         m_to_ids = DE_NULL;
322     }
323 
324     /* Release base class */
325     TestCaseBase::deinit();
326 }
327 
328 /** Executes the test.
329  *
330  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
331  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
332  *  Note the function throws exception should an error occur!
333  **/
iterate()334 tcu::TestNode::IterateResult GeometryShaderIncompleteLayeredFBOTest::iterate()
335 {
336     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
337     bool result              = true;
338 
339     /* This test should only run if EXT_geometry_shader is supported. */
340     if (!m_is_geometry_shader_extension_supported)
341     {
342         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
343     }
344 
345     /* Set up texture objects */
346     m_to_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_to_ids];
347 
348     GeometryShaderLayeredFBOShared::initTOs(gl, gl.texStorage3DMultisample, m_to_ids);
349 
350     /* Set up framebuffer objects */
351     m_fbo_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_fbo_ids];
352 
353     GeometryShaderLayeredFBOShared::initFBOs(gl, gl.framebufferTexture, m_to_ids, m_fbo_ids);
354 
355     /* Verify framebuffer completeness */
356     const glw::GLuint incomplete_fbo_ids[]  = {m_fbo_ids[0], m_fbo_ids[1], m_fbo_ids[2], m_fbo_ids[3]};
357     const unsigned int n_incomplete_fbo_ids = sizeof(incomplete_fbo_ids) / sizeof(incomplete_fbo_ids[0]);
358 
359     for (unsigned int n_incomplete_fbo_id = 0; n_incomplete_fbo_id < n_incomplete_fbo_ids; ++n_incomplete_fbo_id)
360     {
361         result &= GeometryShaderLayeredFBOShared::checkFBOCompleteness(
362             m_testCtx, gl, incomplete_fbo_ids[n_incomplete_fbo_id], m_glExtTokens.FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS);
363     } /* for (all FBO ids) */
364 
365     /* All done */
366     if (result)
367     {
368         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
369     }
370     else
371     {
372         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
373     }
374 
375     return STOP;
376 }
377 
378 /** Constructor
379  *
380  * @param context       Test context
381  * @param extParams     Not used.
382  * @param name          Test case's name
383  * @param description   Test case's description
384  **/
GeometryShaderIncompleteLayeredAttachmentsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)385 GeometryShaderIncompleteLayeredAttachmentsTest::GeometryShaderIncompleteLayeredAttachmentsTest(
386     Context &context, const ExtParameters &extParams, const char *name, const char *description)
387     : TestCaseBase(context, extParams, name, description)
388     , m_fbo_ids(DE_NULL)
389     , m_to_ids(DE_NULL)
390 {
391     // left blank intentionally
392 }
393 
394 /** Deinitializes GLES objects created during the test. */
deinit()395 void GeometryShaderIncompleteLayeredAttachmentsTest::deinit()
396 {
397     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
398 
399     /* Release framebuffer objects */
400     GeometryShaderLayeredFBOShared::deinitFBOs(gl, m_fbo_ids);
401 
402     if (m_fbo_ids != DE_NULL)
403     {
404         delete[] m_fbo_ids;
405 
406         m_fbo_ids = DE_NULL;
407     }
408 
409     /* Release texture objects */
410     GeometryShaderLayeredFBOShared::deinitTOs(gl, m_to_ids);
411 
412     if (m_to_ids != DE_NULL)
413     {
414         delete[] m_to_ids;
415 
416         m_to_ids = DE_NULL;
417     }
418 
419     /* Release base class */
420     TestCaseBase::deinit();
421 }
422 
423 /** Executes the test.
424  *
425  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
426  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
427  *  Note the function throws exception should an error occur!
428  **/
iterate()429 tcu::TestNode::IterateResult GeometryShaderIncompleteLayeredAttachmentsTest::iterate()
430 {
431     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
432     bool result              = true;
433 
434     /* This test should only run if EXT_geometry_shader is supported. */
435     if (!m_is_geometry_shader_extension_supported)
436     {
437         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
438     }
439 
440     /* Set up texture objects */
441     m_to_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_to_ids];
442 
443     GeometryShaderLayeredFBOShared::initTOs(gl, gl.texStorage3DMultisample, m_to_ids);
444 
445     /* Set up framebuffer objects */
446     m_fbo_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_fbo_ids];
447 
448     GeometryShaderLayeredFBOShared::initFBOs(gl, gl.framebufferTexture, m_to_ids, m_fbo_ids);
449 
450     /* Verify query results for FBO A attachments - as per test spec */
451     glw::GLint is_fbo_color_attachment0_layered = GL_TRUE;
452     glw::GLint is_fbo_color_attachment1_layered = GL_TRUE;
453     glw::GLint is_fbo_color_attachment2_layered = GL_TRUE;
454     glw::GLint is_fbo_depth_attachment_layered  = GL_TRUE;
455 
456     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[0]);
457     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
458 
459     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
460                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
461                                            &is_fbo_color_attachment0_layered);
462     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
463                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
464                                            &is_fbo_color_attachment2_layered);
465     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
466                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
467                                            &is_fbo_depth_attachment_layered);
468     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferAttachmentParameteriv() call failed.");
469 
470     if (is_fbo_color_attachment0_layered != GL_FALSE || is_fbo_color_attachment2_layered != GL_TRUE ||
471         is_fbo_depth_attachment_layered != GL_FALSE)
472     {
473         m_testCtx.getLog() << tcu::TestLog::Message
474                            << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO A"
475                            << tcu::TestLog::EndMessage;
476 
477         result = false;
478     }
479 
480     /* Verify query results for FBO B attachments - as per test spec */
481     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[1]);
482     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
483 
484     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
485                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
486                                            &is_fbo_color_attachment0_layered);
487     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
488                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
489                                            &is_fbo_color_attachment1_layered);
490     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
491                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
492                                            &is_fbo_color_attachment2_layered);
493     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferAttachmentParameteriv() call failed.");
494 
495     if (is_fbo_color_attachment0_layered != GL_TRUE || is_fbo_color_attachment1_layered != GL_FALSE ||
496         is_fbo_color_attachment2_layered != GL_TRUE)
497     {
498         m_testCtx.getLog() << tcu::TestLog::Message
499                            << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO B"
500                            << tcu::TestLog::EndMessage;
501 
502         result = false;
503     }
504 
505     /* Verify query results for FBO C attachments - as per test spec */
506     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[2]);
507     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
508 
509     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
510                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
511                                            &is_fbo_color_attachment0_layered);
512     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
513                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
514                                            &is_fbo_depth_attachment_layered);
515     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferAttachmentParameteriv() call failed.");
516 
517     if (is_fbo_color_attachment0_layered != GL_TRUE || is_fbo_depth_attachment_layered != GL_FALSE)
518     {
519         m_testCtx.getLog() << tcu::TestLog::Message
520                            << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO C"
521                            << tcu::TestLog::EndMessage;
522 
523         result = false;
524     }
525 
526     /* Verify query results for FBO D attachments - as per test spec */
527     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[3]);
528     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
529 
530     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
531                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
532                                            &is_fbo_color_attachment0_layered);
533     gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
534                                            m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
535                                            &is_fbo_color_attachment1_layered);
536 
537     if (is_fbo_color_attachment0_layered != GL_FALSE || is_fbo_color_attachment1_layered != GL_TRUE)
538     {
539         m_testCtx.getLog() << tcu::TestLog::Message
540                            << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO D"
541                            << tcu::TestLog::EndMessage;
542 
543         result = false;
544     }
545 
546     /* All done */
547     if (result)
548     {
549         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
550     }
551     else
552     {
553         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
554     }
555 
556     return STOP;
557 }
558 
559 /** Constructor
560  *
561  * @param context       Test context
562  * @param extParams     Not used.
563  * @param name          Test case's name
564  * @param description   Test case's description
565  **/
GeometryShaderFramebufferTextureInvalidTarget(Context & context,const ExtParameters & extParams,const char * name,const char * description)566 GeometryShaderFramebufferTextureInvalidTarget::GeometryShaderFramebufferTextureInvalidTarget(
567     Context &context, const ExtParameters &extParams, const char *name, const char *description)
568     : TestCaseBase(context, extParams, name, description)
569     , m_fbo_id(0)
570     , m_to_id(0)
571 {
572 }
573 
574 /** Deinitializes GLES objects created during the test. */
deinit()575 void GeometryShaderFramebufferTextureInvalidTarget::deinit()
576 {
577     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
578 
579     if (m_fbo_id != 0)
580     {
581         gl.deleteFramebuffers(1, &m_fbo_id);
582         m_fbo_id = 0;
583     }
584 
585     if (m_to_id != 0)
586     {
587         gl.deleteTextures(1, &m_to_id);
588         m_to_id = 0;
589     }
590 
591     /* Release base class */
592     TestCaseBase::deinit();
593 }
594 
595 /** Executes the test.
596  *
597  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
598  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
599  *  Note the function throws exception should an error occur!
600  **/
iterate()601 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidTarget::iterate()
602 {
603     bool result = true;
604 
605     /* This test should only run if EXT_geometry_shader is supported. */
606     if (!m_is_geometry_shader_extension_supported)
607     {
608         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
609     }
610 
611     const glw::GLubyte pixels[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
612 
613     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
614 
615     gl.genTextures(1, &m_to_id);
616     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
617 
618     gl.bindTexture(GL_TEXTURE_2D, m_to_id);
619     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
620 
621     gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, 2 /* width */, 2 /* height */, 0 /* border */, GL_RGBA,
622                   GL_UNSIGNED_BYTE, pixels);
623     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed.");
624 
625     gl.generateMipmap(GL_TEXTURE_2D);
626     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed.");
627 
628     gl.genFramebuffers(1, &m_fbo_id);
629     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
630 
631     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
632     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed with GL_DRAW_FRAMEBUFFER pname.");
633 
634     glw::GLuint errorEnum;
635 
636     gl.framebufferTexture(GL_TEXTURE_3D, GL_COLOR_ATTACHMENT0, m_to_id /* texture */, 1 /* level */);
637     errorEnum = gl.getError();
638 
639     if (errorEnum != GL_INVALID_ENUM)
640     {
641         result = false;
642 
643         m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_ENUM was generated."
644                            << tcu::TestLog::EndMessage;
645     }
646 
647     if (result)
648     {
649         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
650     }
651     else
652     {
653         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
654     }
655 
656     return STOP;
657 }
658 
659 /** Constructor
660  *
661  * @param context       Test context
662  * @param extParams     Not used.
663  * @param name          Test case's name
664  * @param description   Test case's description
665  **/
GeometryShaderFramebufferTextureNoFBOBoundToTarget(Context & context,const ExtParameters & extParams,const char * name,const char * description)666 GeometryShaderFramebufferTextureNoFBOBoundToTarget::GeometryShaderFramebufferTextureNoFBOBoundToTarget(
667     Context &context, const ExtParameters &extParams, const char *name, const char *description)
668     : TestCaseBase(context, extParams, name, description)
669     , m_to_id(0)
670 {
671 }
672 
673 /** Deinitializes GLES objects created during the test. */
deinit()674 void GeometryShaderFramebufferTextureNoFBOBoundToTarget::deinit()
675 {
676     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
677 
678     if (m_to_id != 0)
679     {
680         gl.deleteTextures(1, &m_to_id);
681         m_to_id = 0;
682     }
683 
684     /* Release base class */
685     TestCaseBase::deinit();
686 }
687 
688 /** Executes the test.
689  *
690  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
691  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
692  *  Note the function throws exception should an error occur!
693  **/
iterate()694 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureNoFBOBoundToTarget::iterate()
695 {
696     const glw::GLuint fbEnums[] = {GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER};
697 
698     const size_t numberOfEnums = sizeof(fbEnums) / sizeof(fbEnums[0]);
699 
700     bool result = false;
701 
702     /* This test should only run if EXT_geometry_shader is supported. */
703     if (!m_is_geometry_shader_extension_supported)
704     {
705         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
706     }
707 
708     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
709 
710     gl.genTextures(1, &m_to_id);
711     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
712 
713     gl.bindTexture(GL_TEXTURE_2D, m_to_id);
714     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
715 
716     glw::GLuint errorEnum;
717 
718     for (size_t i = 0; i < numberOfEnums; ++i)
719     {
720         gl.bindFramebuffer(fbEnums[i], 0 /* framebuffer */);
721         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
722 
723         gl.framebufferTexture(fbEnums[i], GL_COLOR_ATTACHMENT0, m_to_id /* texture */, 1 /* level */);
724         errorEnum = gl.getError();
725 
726         if (errorEnum == GL_INVALID_OPERATION)
727         {
728             result = true;
729         }
730         else
731         {
732             result = false;
733 
734             m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPERATION was generated."
735                                << tcu::TestLog::EndMessage;
736 
737             break;
738         }
739     }
740 
741     if (result)
742     {
743         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
744     }
745     else
746     {
747         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
748     }
749 
750     return STOP;
751 }
752 
753 /** Constructor
754  *
755  * @param context       Test context
756  * @param extParams     Not used.
757  * @param name          Test case's name
758  * @param description   Test case's description
759  **/
GeometryShaderFramebufferTextureInvalidAttachment(Context & context,const ExtParameters & extParams,const char * name,const char * description)760 GeometryShaderFramebufferTextureInvalidAttachment::GeometryShaderFramebufferTextureInvalidAttachment(
761     Context &context, const ExtParameters &extParams, const char *name, const char *description)
762     : TestCaseBase(context, extParams, name, description)
763     , m_fbo_id(0)
764     , m_to_id(0)
765 {
766 }
767 
768 /** Deinitializes GLES objects created during the test. */
deinit()769 void GeometryShaderFramebufferTextureInvalidAttachment::deinit()
770 {
771     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
772 
773     if (m_fbo_id != 0)
774     {
775         gl.deleteFramebuffers(1, &m_fbo_id);
776         m_fbo_id = 0;
777     }
778 
779     if (m_to_id != 0)
780     {
781         gl.deleteTextures(1, &m_to_id);
782         m_to_id = 0;
783     }
784 
785     /* Release base class */
786     TestCaseBase::deinit();
787 }
788 
789 /** Executes the test.
790  *
791  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
792  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
793  *  Note the function throws exception should an error occur!
794  **/
iterate()795 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidAttachment::iterate()
796 {
797     const glw::GLuint fbEnums[] = {GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER};
798 
799     const size_t numberOfEnums = sizeof(fbEnums) / sizeof(fbEnums[0]);
800 
801     bool result = false;
802 
803     /* This test should only run if EXT_geometry_shader is supported. */
804     if (!m_is_geometry_shader_extension_supported)
805     {
806         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
807     }
808 
809     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
810 
811     glw::GLuint errorEnum;
812     glw::GLint maxColorAttachments = 0;
813 
814     gl.genFramebuffers(1, &m_fbo_id);
815     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
816 
817     gl.genTextures(1, &m_to_id);
818     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
819 
820     gl.bindTexture(GL_TEXTURE_2D, m_to_id);
821     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
822 
823     gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
824     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed with pname GL_MAX_COLOR_ATTACHMENTS.");
825 
826     for (size_t i = 0; i < numberOfEnums; ++i)
827     {
828         gl.bindFramebuffer(fbEnums[i], m_fbo_id);
829         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
830 
831         gl.framebufferTexture(fbEnums[i], GL_COLOR_ATTACHMENT0 + maxColorAttachments, m_to_id /* texture */,
832                               0 /* level */);
833         errorEnum = gl.getError();
834 
835         if (errorEnum == GL_INVALID_OPERATION)
836         {
837             result = true;
838         }
839         else
840         {
841             result = false;
842 
843             m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPERATION was generated."
844                                << tcu::TestLog::EndMessage;
845 
846             break;
847         }
848     }
849 
850     if (result)
851     {
852         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
853     }
854     else
855     {
856         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
857     }
858 
859     return STOP;
860 }
861 
862 /** Constructor
863  *
864  * @param context       Test context
865  * @param extParams     Not used.
866  * @param name          Test case's name
867  * @param description   Test case's description
868  **/
GeometryShaderFramebufferTextureInvalidValue(Context & context,const ExtParameters & extParams,const char * name,const char * description)869 GeometryShaderFramebufferTextureInvalidValue::GeometryShaderFramebufferTextureInvalidValue(
870     Context &context, const ExtParameters &extParams, const char *name, const char *description)
871     : TestCaseBase(context, extParams, name, description)
872     , m_fbo_id(0)
873 {
874 }
875 
876 /** Deinitializes GLES objects created during the test. */
deinit()877 void GeometryShaderFramebufferTextureInvalidValue::deinit()
878 {
879     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
880 
881     if (m_fbo_id != 0)
882     {
883         gl.deleteFramebuffers(1, &m_fbo_id);
884         m_fbo_id = 0;
885     }
886 
887     /* Release base class */
888     TestCaseBase::deinit();
889 }
890 
891 /** Executes the test.
892  *
893  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
894  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
895  *  Note the function throws exception should an error occur!
896  **/
iterate()897 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidValue::iterate()
898 {
899     const glw::GLuint fbEnums[] = {GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER};
900     const size_t numberOfEnums  = sizeof(fbEnums) / sizeof(fbEnums[0]);
901     bool result                 = false;
902 
903     /* This test should only run if EXT_geometry_shader is supported. */
904     if (!m_is_geometry_shader_extension_supported)
905     {
906         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
907     }
908 
909     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
910 
911     gl.genFramebuffers(1, &m_fbo_id);
912     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
913 
914     glw::GLuint errorEnum;
915     glw::GLuint invalidValue = 1;
916 
917     for (size_t i = 0; i < numberOfEnums; ++i)
918     {
919         gl.bindFramebuffer(fbEnums[i], m_fbo_id);
920         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
921 
922         gl.framebufferTexture(fbEnums[i], GL_COLOR_ATTACHMENT0, invalidValue /* texture */, 1 /* level */);
923         errorEnum = gl.getError();
924 
925         invalidValue *= 10;
926 
927         if (errorEnum == GL_INVALID_VALUE)
928         {
929             result = true;
930         }
931         else
932         {
933             result = false;
934 
935             m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_VALUE was generated."
936                                << tcu::TestLog::EndMessage;
937 
938             break;
939         }
940     }
941 
942     if (result)
943     {
944         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
945     }
946     else
947     {
948         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
949     }
950 
951     return STOP;
952 }
953 
954 /** Constructor
955  *
956  * @param context       Test context
957  * @param extParams     Not used.
958  * @param name          Test case's name
959  * @param description   Test case's description
960  **/
GeometryShaderFramebufferTextureInvalidLevelNumber(Context & context,const ExtParameters & extParams,const char * name,const char * description)961 GeometryShaderFramebufferTextureInvalidLevelNumber::GeometryShaderFramebufferTextureInvalidLevelNumber(
962     Context &context, const ExtParameters &extParams, const char *name, const char *description)
963     : TestCaseBase(context, extParams, name, description)
964     , m_fbo_id(0)
965     , m_tex_depth(4)
966     , m_tex_height(4)
967     , m_tex_width(4)
968     , m_to_2d_array_id(0)
969     , m_to_3d_id(0)
970 {
971     /* Allocate memory for m_tex_depth * m_tex_height * m_tex_width texels, with each texel being 4 GLubytes. */
972     m_texels = new glw::GLubyte[m_tex_depth * m_tex_height * m_tex_width * 4];
973 
974     memset(m_texels, 255, m_tex_depth * m_tex_height * m_tex_width * 4);
975 }
976 
977 /** Deinitializes GLES objects created during the test. */
deinit()978 void GeometryShaderFramebufferTextureInvalidLevelNumber::deinit()
979 {
980     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
981 
982     if (m_fbo_id != 0)
983     {
984         gl.deleteFramebuffers(1, &m_fbo_id);
985         m_fbo_id = 0;
986 
987         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
988     }
989 
990     if (m_texels != NULL)
991     {
992         delete[] m_texels;
993         m_texels = NULL;
994     }
995 
996     if (m_to_2d_array_id != 0)
997     {
998         gl.deleteTextures(1, &m_to_2d_array_id);
999         m_to_2d_array_id = 0;
1000     }
1001 
1002     if (m_to_3d_id != 0)
1003     {
1004         gl.deleteTextures(1, &m_to_3d_id);
1005         m_to_3d_id = 0;
1006     }
1007 
1008     /* Release base class */
1009     TestCaseBase::deinit();
1010 }
1011 
1012 /** Executes the test.
1013  *
1014  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1015  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1016  *  Note the function throws exception should an error occur!
1017  **/
iterate()1018 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidLevelNumber::iterate()
1019 {
1020     bool result = false;
1021 
1022     /* This test should only run if EXT_geometry_shader is supported. */
1023     if (!m_is_geometry_shader_extension_supported)
1024     {
1025         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1026     }
1027 
1028     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1029 
1030     /* Generate and bind framebuffer object */
1031     gl.genFramebuffers(1, &m_fbo_id);
1032     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
1033 
1034     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
1035     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
1036 
1037     /* Prepare texture 3D and generate its mipmaps */
1038     gl.genTextures(1, &m_to_3d_id);
1039     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1040 
1041     gl.bindTexture(GL_TEXTURE_3D, m_to_3d_id);
1042     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1043 
1044     gl.texStorage3D(GL_TEXTURE_3D, 2 /* levels */, GL_RGBA8, m_tex_width, m_tex_height, m_tex_depth);
1045     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
1046 
1047     gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, m_tex_width,
1048                      m_tex_height, m_tex_depth, GL_RGBA, GL_UNSIGNED_BYTE, m_texels);
1049     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
1050 
1051     gl.generateMipmap(GL_TEXTURE_3D);
1052     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed with pname GL_TEXTURE_3D.");
1053 
1054     /* Prepare texture array 2D */
1055     gl.genTextures(1, &m_to_2d_array_id);
1056     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1057 
1058     gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_2d_array_id);
1059     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1060 
1061     gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 2 /* levels */, GL_RGBA8, m_tex_width, m_tex_height,
1062                     m_tex_depth /* layerCount */);
1063     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
1064 
1065     gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, m_tex_width,
1066                      m_tex_height, m_tex_depth, GL_RGBA, GL_UNSIGNED_BYTE, m_texels);
1067     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
1068 
1069     gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1070     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed with pname GL_TEXTURE_2D_ARRAY.");
1071 
1072     glw::GLuint errorEnum;
1073 
1074     /* Test for texture 3D */
1075     gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_3d_id /* texture */, 2 /* level */);
1076     errorEnum = gl.getError();
1077 
1078     if (errorEnum == GL_INVALID_VALUE)
1079     {
1080         result = true;
1081     }
1082     else
1083     {
1084         result = false;
1085 
1086         m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_VALUE was generated."
1087                            << tcu::TestLog::EndMessage;
1088 
1089         goto end;
1090     }
1091 
1092     /* Test for texture array 2D */
1093     gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_2d_array_id /* texture */, 2 /* level */);
1094     errorEnum = gl.getError();
1095 
1096     if (errorEnum == GL_INVALID_VALUE)
1097     {
1098         result = true;
1099     }
1100     else
1101     {
1102         result = false;
1103 
1104         m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_VALUE was generated."
1105                            << tcu::TestLog::EndMessage;
1106 
1107         goto end;
1108     }
1109 
1110 end:
1111     if (result)
1112     {
1113         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1114     }
1115     else
1116     {
1117         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1118     }
1119 
1120     return STOP;
1121 }
1122 
1123 /** Constructor
1124  *
1125  * @param context       Test context
1126  * @param extParams     Not used.
1127  * @param name          Test case's name
1128  * @param description   Test case's description
1129  **/
1130 GeometryShaderFramebufferTextureArgumentRefersToBufferTexture::
GeometryShaderFramebufferTextureArgumentRefersToBufferTexture(Context & context,const ExtParameters & extParams,const char * name,const char * description)1131     GeometryShaderFramebufferTextureArgumentRefersToBufferTexture(Context &context, const ExtParameters &extParams,
1132                                                                   const char *name, const char *description)
1133     : TestCaseBase(context, extParams, name, description)
1134     , m_bo_id(0)
1135     , m_fbo_id(0)
1136     , m_tbo_id(0)
1137 {
1138     m_tex_width  = 64;
1139     m_tex_height = 64;
1140 
1141     /* Allocate memory for m_tex_height * m_tex_width texels, with each texel being 3 GLints. */
1142     m_texels = new glw::GLint[m_tex_height * m_tex_width * 3];
1143 
1144     memset(m_texels, 255, sizeof(glw::GLint) * m_tex_height * m_tex_width * 3);
1145 }
1146 
1147 /** Deinitializes GLES objects created during the test. */
deinit()1148 void GeometryShaderFramebufferTextureArgumentRefersToBufferTexture::deinit()
1149 {
1150     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1151 
1152     if (m_bo_id != 0)
1153     {
1154         gl.deleteBuffers(1, &m_bo_id);
1155         m_bo_id = 0;
1156     }
1157 
1158     if (m_fbo_id != 0)
1159     {
1160         gl.deleteFramebuffers(1, &m_fbo_id);
1161         m_fbo_id = 0;
1162 
1163         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1164     }
1165 
1166     if (m_tbo_id != 0)
1167     {
1168         gl.deleteTextures(1, &m_tbo_id);
1169         m_tbo_id = 0;
1170     }
1171 
1172     if (m_texels != NULL)
1173     {
1174         delete[] m_texels;
1175         m_texels = NULL;
1176     }
1177 
1178     /* Release base class */
1179     TestCaseBase::deinit();
1180 }
1181 
1182 /** Executes the test.
1183  *
1184  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1185  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1186  *  Note the function throws exception should an error occur!
1187  **/
iterate()1188 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureArgumentRefersToBufferTexture::iterate()
1189 {
1190     bool result = false;
1191 
1192     /* This test should only run if EXT_geometry_shader and EXT_texture_buffer are supported. */
1193     if (!m_is_geometry_shader_extension_supported)
1194     {
1195         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1196     }
1197 
1198     if (!m_is_texture_buffer_supported)
1199     {
1200         throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1201     }
1202 
1203     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1204 
1205     /* Generate buffer object */
1206     gl.genBuffers(1, &m_bo_id);
1207     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
1208 
1209     gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
1210     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
1211 
1212     gl.bufferData(GL_ARRAY_BUFFER, sizeof(m_texels), m_texels, GL_DYNAMIC_READ);
1213     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
1214 
1215     /* Generate and bind framebuffer object */
1216     gl.genFramebuffers(1, &m_fbo_id);
1217     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
1218 
1219     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
1220     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
1221 
1222     /* Prepare texture buffer */
1223     gl.genTextures(1, &m_tbo_id);
1224     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1225 
1226     gl.bindTexture(GL_TEXTURE_BUFFER, m_tbo_id);
1227     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1228 
1229     gl.texBuffer(GL_TEXTURE_BUFFER, GL_RGB32I, m_bo_id);
1230     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexBuffer() call failed.");
1231 
1232     glw::GLuint errorEnum;
1233 
1234     /* Test for texture 3D */
1235     gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_tbo_id /* texture */, 0 /* level */);
1236     errorEnum = gl.getError();
1237 
1238     if (errorEnum == GL_INVALID_OPERATION)
1239     {
1240         result = true;
1241     }
1242     else
1243     {
1244         result = false;
1245 
1246         m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPERATION was generated."
1247                            << tcu::TestLog::EndMessage;
1248 
1249         goto end;
1250     }
1251 
1252 end:
1253     if (result)
1254     {
1255         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1256     }
1257     else
1258     {
1259         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1260     }
1261 
1262     return STOP;
1263 }
1264 
1265 } // namespace glcts
1266