1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24 #include "esextcGeometryShaderBlitting.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluDefs.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 #include <cstring>
31
32 /* 3d texture layers count */
33 #define TEXTURE_DEPTH (4)
34 /* 3d texture width */
35 #define TEXTURE_WIDTH (4)
36 /* 3d texture height */
37 #define TEXTURE_HEIGHT (4)
38 /* texture texel components */
39 #define TEXTURE_TEXEL_COMPONENTS (4)
40
41 namespace glcts
42 {
43 /** Constructor
44 *
45 * @param context Test context
46 * @param name Test case's name
47 * @param description Test case's desricption
48 **/
GeometryShaderBlitting(Context & context,const ExtParameters & extParams,const char * name,const char * description)49 GeometryShaderBlitting::GeometryShaderBlitting(Context& context, const ExtParameters& extParams, const char* name,
50 const char* description)
51 : TestCaseBase(context, extParams, name, description)
52 , m_draw_fbo_completeness(GL_NONE)
53 , m_read_fbo_completeness(GL_NONE)
54 , m_fbo_draw_id(0)
55 , m_fbo_read_id(0)
56 , m_to_draw(0)
57 , m_to_read(0)
58 , m_vao_id(0)
59 {
60 /* Left blank on purpose */
61 }
62
63 /** Executes the test.
64 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
65 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
66 * Note the function throws exception should an error occur!
67 **/
iterate(void)68 tcu::TestNode::IterateResult GeometryShaderBlitting::iterate(void)
69 {
70 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
71
72 if (!m_is_geometry_shader_extension_supported)
73 {
74 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
75 }
76
77 /* Generate and bind a vertex array object */
78 gl.genVertexArrays(1, &m_vao_id);
79 gl.bindVertexArray(m_vao_id);
80
81 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up vertex array object");
82
83 /* Generate texture objects */
84 gl.genTextures(1, &m_to_draw);
85 gl.genTextures(1, &m_to_read);
86
87 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture objects");
88
89 /* Generate framebuffer objects */
90 gl.genFramebuffers(1, &m_fbo_draw_id);
91 gl.genFramebuffers(1, &m_fbo_read_id);
92
93 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up framebuffer objects");
94
95 /* Configure texture storage */
96 gl.bindTexture(GL_TEXTURE_3D, m_to_draw);
97 gl.texImage3D(GL_TEXTURE_3D, 0 /* level */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH, 0 /* border */,
98 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
99
100 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up texture objects");
101
102 gl.bindTexture(GL_TEXTURE_3D, m_to_read);
103 gl.texImage3D(GL_TEXTURE_3D, 0 /* level */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH, 0 /* border */,
104 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
105 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up texture objects");
106
107 unsigned char layer_source1[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
108 unsigned char layer_source2[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
109 unsigned char layer_source3[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
110 unsigned char layer_source4[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
111 unsigned char layer_target[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
112 unsigned char result_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
113
114 memset(layer_source1, 0, sizeof(layer_source1));
115 memset(layer_source2, 0, sizeof(layer_source2));
116 memset(layer_source3, 0, sizeof(layer_source3));
117 memset(layer_source4, 0, sizeof(layer_source4));
118 memset(layer_target, 0, sizeof(layer_target));
119
120 for (unsigned int n = 0; n < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++n)
121 {
122 layer_source1[n * TEXTURE_TEXEL_COMPONENTS + 0] = 255;
123 layer_source2[n * TEXTURE_TEXEL_COMPONENTS + 1] = 255;
124 layer_source3[n * TEXTURE_TEXEL_COMPONENTS + 2] = 255;
125 layer_source4[n * TEXTURE_TEXEL_COMPONENTS + 3] = 255;
126 } /* for (all pixels) */
127
128 /* Set up draw FBO */
129 setUpFramebuffersForRendering(m_fbo_draw_id, m_fbo_read_id, m_to_draw, m_to_read);
130
131 /* Fill texture objects with data */
132 gl.bindTexture(GL_TEXTURE_3D, m_to_read);
133 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* layer */, TEXTURE_WIDTH,
134 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_source1);
135 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* layer */, TEXTURE_WIDTH,
136 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_source2);
137 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* layer */, TEXTURE_WIDTH,
138 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_source3);
139 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* layer */, TEXTURE_WIDTH,
140 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_source4);
141
142 gl.bindTexture(GL_TEXTURE_3D, m_to_draw);
143 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* layer */, TEXTURE_WIDTH,
144 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_target);
145 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* layer */, TEXTURE_WIDTH,
146 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_target);
147 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* layer */, TEXTURE_WIDTH,
148 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_target);
149 gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* layer */, TEXTURE_WIDTH,
150 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, layer_target);
151
152 /* Check FB completeness */
153 m_draw_fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
154 m_read_fbo_completeness = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
155
156 if (m_draw_fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
157 {
158 TCU_FAIL("Draw framebuffer is reported as incomplete, though expected it to be complete");
159 }
160
161 if (m_read_fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
162 {
163 TCU_FAIL("Read framebuffer is reported as incomplete, though expected it to be complete");
164 }
165
166 /* Blit! */
167 gl.blitFramebuffer(0 /* srcX0 */, 0 /* srcY0 */, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0 /* dstX0 */, 0 /* dstY0 */,
168 TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
169
170 GLU_EXPECT_NO_ERROR(gl.getError(), "Error blitting");
171
172 for (unsigned int n = 0; n < TEXTURE_DEPTH /* layers */; ++n)
173 {
174 unsigned char expected_result_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS];
175 memset(expected_result_data, 0, sizeof(expected_result_data));
176
177 if (n == 0)
178 {
179 memcpy(expected_result_data, layer_source1, sizeof(expected_result_data));
180 }
181
182 /* Set up read FBO */
183 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_draw_id);
184
185 gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_draw, 0, n);
186 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up FBOs setUpFramebuffersForReading");
187
188 /* Read the rendered data */
189 gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, result_data);
190
191 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to read rendered pixel data");
192
193 /* Compare the rendered data with reference data */
194 for (unsigned int index = 0; index < TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_TEXEL_COMPONENTS;
195 index += TEXTURE_TEXEL_COMPONENTS)
196 {
197 if (memcmp(&expected_result_data[index], &result_data[index], TEXTURE_TEXEL_COMPONENTS) != 0)
198 {
199 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << (int)result_data[index + 0] << ", "
200 << (int)result_data[index + 1] << ", " << (int)result_data[index + 2] << ", "
201 << (int)result_data[index + 3] << "] is different from reference data ["
202 << (int)expected_result_data[index + 0] << ", "
203 << (int)expected_result_data[index + 1] << ", "
204 << (int)expected_result_data[index + 2] << ", "
205 << (int)expected_result_data[index + 3] << "] !" << tcu::TestLog::EndMessage;
206
207 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
208 return STOP;
209 }
210 } /* for (each index) */
211 } /* for (all layers) */
212
213 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
214 return STOP;
215 }
216
217 /** Deinitializes GLES objects created during the test.
218 *
219 */
deinit(void)220 void GeometryShaderBlitting::deinit(void)
221 {
222 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
223
224 /* Reset OpenGL ES state */
225 gl.bindTexture(GL_TEXTURE_3D, 0);
226 gl.bindVertexArray(0);
227 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
228 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
229
230 /* Clean up */
231 if (m_fbo_draw_id != 0)
232 {
233 gl.deleteFramebuffers(1, &m_fbo_draw_id);
234 }
235
236 if (m_fbo_read_id != 0)
237 {
238 gl.deleteFramebuffers(1, &m_fbo_read_id);
239 }
240
241 if (m_to_draw != 0)
242 {
243 gl.deleteTextures(1, &m_to_draw);
244 }
245
246 if (m_to_read != 0)
247 {
248 gl.deleteTextures(1, &m_to_read);
249 }
250
251 if (m_vao_id != 0)
252 {
253 gl.deleteVertexArrays(1, &m_vao_id);
254 }
255
256 /* Release base class */
257 TestCaseBase::deinit();
258 }
259
260 /** Constructor
261 *
262 * @param context Test context
263 * @param name Test case's name
264 * @param description Test case's desricption
265 **/
GeometryShaderBlittingLayeredToNonLayered(Context & context,const ExtParameters & extParams,const char * name,const char * description)266 GeometryShaderBlittingLayeredToNonLayered::GeometryShaderBlittingLayeredToNonLayered(Context& context,
267 const ExtParameters& extParams,
268 const char* name,
269 const char* description)
270 : GeometryShaderBlitting(context, extParams, name, description)
271 {
272 /* Left blank on purpose */
273 }
274
275 /** Setup framebuffers for rendering
276 *
277 */
setUpFramebuffersForRendering(glw::GLuint fbo_draw_id,glw::GLuint fbo_read_id,glw::GLint to_draw,glw::GLint to_read)278 void GeometryShaderBlittingLayeredToNonLayered::setUpFramebuffersForRendering(glw::GLuint fbo_draw_id,
279 glw::GLuint fbo_read_id,
280 glw::GLint to_draw, glw::GLint to_read)
281 {
282 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
283
284 /* Bind framebuffers */
285 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo_read_id);
286 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_draw_id);
287
288 /* Blitting from a layered read framebuffer to a non-layered draw framebuffer*/
289 gl.framebufferTexture(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_read, 0 /* level */);
290 gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_draw, 0, 0);
291 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up FBOs setUpFramebuffersForRendering");
292 }
293
294 /** Constructor
295 *
296 * @param context Test context
297 * @param name Test case's name
298 * @param description Test case's desricption
299 **/
GeometryShaderBlittingNonLayeredToLayered(Context & context,const ExtParameters & extParams,const char * name,const char * description)300 GeometryShaderBlittingNonLayeredToLayered::GeometryShaderBlittingNonLayeredToLayered(Context& context,
301 const ExtParameters& extParams,
302 const char* name,
303 const char* description)
304 : GeometryShaderBlitting(context, extParams, name, description)
305 {
306 /* Left blank on purpose */
307 }
308
309 /** Setup framebuffers for rendering
310 *
311 */
setUpFramebuffersForRendering(glw::GLuint fbo_draw_id,glw::GLuint fbo_read_id,glw::GLint to_draw,glw::GLint to_read)312 void GeometryShaderBlittingNonLayeredToLayered::setUpFramebuffersForRendering(glw::GLuint fbo_draw_id,
313 glw::GLuint fbo_read_id,
314 glw::GLint to_draw, glw::GLint to_read)
315 {
316 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
317
318 /* Bind framebuffers */
319 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo_read_id);
320 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_draw_id);
321
322 /* Blitting from a non-layered read framebuffer to a layered draw framebuffer */
323 gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_read, 0, 0);
324 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_draw, 0 /* level */);
325 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up FBOs setUpFramebuffersForRendering");
326 }
327
328 /** Constructor
329 *
330 * @param context Test context
331 * @param name Test case's name
332 * @param description Test case's desricption
333 **/
GeometryShaderBlittingLayeredToLayered(Context & context,const ExtParameters & extParams,const char * name,const char * description)334 GeometryShaderBlittingLayeredToLayered::GeometryShaderBlittingLayeredToLayered(Context& context,
335 const ExtParameters& extParams,
336 const char* name,
337 const char* description)
338 : GeometryShaderBlitting(context, extParams, name, description)
339 {
340 /* Left blank on purpose */
341 }
342
343 /** Setup framebuffers for rendering
344 *
345 */
setUpFramebuffersForRendering(glw::GLuint fbo_draw_id,glw::GLuint fbo_read_id,glw::GLint to_draw,glw::GLint to_read)346 void GeometryShaderBlittingLayeredToLayered::setUpFramebuffersForRendering(glw::GLuint fbo_draw_id,
347 glw::GLuint fbo_read_id, glw::GLint to_draw,
348 glw::GLint to_read)
349 {
350 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
351
352 /* Bind framebuffers */
353 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo_read_id);
354 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_draw_id);
355
356 /* Blitting from a layered read framebuffer to a layered draw framebuffer */
357 gl.framebufferTexture(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_read, 0 /* level */);
358 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_draw, 0 /* level */);
359 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up FBOs setUpFramebuffersForRendering");
360 }
361
362 } // namespace glcts
363