1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2024 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 */ /*!
26 * \file glcFramebufferBlitTests.cpp
27 * \brief Conformance tests for the framebuffer blit functionality.
28 */ /*-------------------------------------------------------------------*/
29
30 #include "deMath.h"
31
32 #include "glcFramebufferBlitTests.hpp"
33 #include "glcMisc.hpp"
34 #include "gluContextInfo.hpp"
35 #include "gluDefs.hpp"
36 #include "gluTextureUtil.hpp"
37 #include "gluTextureUtil.hpp"
38 #include "gluStrUtil.hpp"
39 #include "glwEnums.hpp"
40 #include "glwFunctions.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuRenderTarget.hpp"
43 #include "tcuStringTemplate.hpp"
44
45 #include <cmath>
46 #include <memory>
47
48 #define CHECK(actual, expected, info) \
49 { \
50 result &= ((actual) != (expected)) ? false : true; \
51 if (!result) \
52 { \
53 m_testCtx.getLog() << tcu::TestLog::Message << #info << ": " << __FILE__ << ":" << __LINE__ << ":" \
54 << "expected " << getEnumName((GLenum)(expected)) << "but got " \
55 << getEnumName((GLenum)(actual)) << tcu::TestLog::EndMessage; \
56 } \
57 }
58
59 #define CHECK_COLOR(actual, expected, info) \
60 { \
61 result &= ((actual) != (expected)) ? false : true; \
62 if (!result) \
63 { \
64 m_testCtx.getLog() << tcu::TestLog::Message << #info << ": " << __FILE__ << ":" << __LINE__ \
65 << tcu::TestLog::EndMessage; \
66 TCU_CHECK(result); \
67 } \
68 }
69
70 #define CHECK_CONTINUE(actual, expected, info) \
71 { \
72 result &= ((actual) != (expected)) ? false : true; \
73 if (!result) \
74 { \
75 m_testCtx.getLog() << tcu::TestLog::Message << #info << ": " << __FILE__ << ":" << __LINE__ << ":" \
76 << "expected " << getEnumName((GLenum)(expected)) << "but got " \
77 << getEnumName((GLenum)(actual)) << tcu::TestLog::EndMessage; \
78 continue; \
79 } \
80 }
81
82 #define CHECK_RET(actual, expected, info) \
83 CHECK((actual), (expected), info); \
84 TCU_CHECK(result);
85
86 using namespace glw;
87 using namespace glu;
88 using namespace glcts;
89 using namespace blt;
90
91 namespace
92 {
93 /* Get epsilon based on format precision
94 */
GetEpsilon(GLuint resultPreBits,GLuint sourcePreBits)95 GLfloat GetEpsilon(GLuint resultPreBits, GLuint sourcePreBits)
96 {
97 GLuint tolerance = std::min(resultPreBits, sourcePreBits);
98 tolerance = std::min(tolerance, (GLuint)23); // don't exceed the amount of mantissa bits in a float
99 return (GLfloat)1.0 / (1 << tolerance);
100 }
101
102 /* multicolor pattern values */
103 const tcu::Vec4 RED = {1.0f, 0.0f, 0.0f, 1.0f};
104 const tcu::Vec4 GREEN = {0.0f, 1.0f, 0.0f, 1.0f};
105 const tcu::Vec4 BLUE = {0.0f, 0.0f, 1.0f, 1.0f};
106 const tcu::Vec4 WHITE = {1.0f, 1.0f, 1.0f, 1.0f};
107 const tcu::Vec4 BLACK = {0.0f, 0.0f, 0.0f, 1.0f};
108 const Depth Q0 = 0.0f;
109 const Depth Q1 = 0.25f;
110 const Depth Q2 = 0.5f;
111 const Depth Q3 = 0.75f;
112 const Depth Q4 = 1.0f;
113 const Stencil ZERO = 0;
114 const Stencil ONE = 1;
115 const Stencil TWO = 2;
116 const Stencil THREE = 3;
117 const Stencil FOUR = 4;
118
119 const GLuint DEFAULT = 0x12345678;
120 const GLuint RED_CHANNEL = 1 << 13;
121 const GLuint GREEN_CHANNEL = 1 << 14;
122 const GLuint BLUE_CHANNEL = 1 << 15;
123 const GLuint ALPHA_CHANNEL = 1 << 16;
124 const GLuint MAX_BUF_OBJECTS = 256;
125 const GLuint DEFAULT_COLOR_CHANNEL_BITS = RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL | ALPHA_CHANNEL;
126
127 char STR_BUF[256];
128
129 const Color DST_COLOR = {0.0f, 0.0f, 0.0f, 1.0f};
130 const Depth DST_DEPTH = 0.0f;
131 const Stencil DST_STCIL = 0;
132
getEnumName(const GLenum e)133 const char *getEnumName(const GLenum e)
134 {
135 if (glu::getUncompressedTextureFormatName(e) != nullptr)
136 return glu::getUncompressedTextureFormatName(e);
137 else if (glu::getFaceName(e) != nullptr)
138 return glu::getFaceName(e);
139 else if (glu::getFramebufferAttachmentName(e) != nullptr)
140 return glu::getFramebufferAttachmentName(e);
141 else if (glu::getBooleanName((int)e) != nullptr)
142 return glu::getBooleanName((int)e);
143 else if (glu::getFramebufferStatusName(e) != nullptr)
144 return glu::getFramebufferStatusName(e);
145 else if (glu::getInternalFormatTargetName(e) != nullptr)
146 return glu::getInternalFormatTargetName(e);
147 else if (glu::getFramebufferTargetName(e) != nullptr)
148 return glu::getFramebufferTargetName(e);
149 else if (glu::getErrorName(e) != nullptr)
150 return glu::getErrorName(e);
151 else
152 {
153 switch (e)
154 {
155 case GL_LEFT:
156 return "GL_LEFT";
157 case RED_CHANNEL:
158 return "RED_CHANNEL";
159 case GREEN_CHANNEL:
160 return "GREEN_CHANNEL";
161 case BLUE_CHANNEL:
162 return "BLUE_CHANNEL";
163 case RED_CHANNEL | GREEN_CHANNEL:
164 return "RG_CHANNELS";
165 case RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL:
166 return "RGB_CHANNELS";
167 case RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL | ALPHA_CHANNEL:
168 return "ALL_CHANNELS";
169 case DEFAULT:
170 return "DEFAULT";
171 default:
172 break;
173 }
174 snprintf(STR_BUF, sizeof(STR_BUF) - 1, "0x%04x", e);
175 return STR_BUF;
176 }
177 }
178 } // namespace
179
180 namespace glcts
181 {
182 // clang-format off
183
184 /** @brief Vertex shader source code to test framebuffer blit of color buffers. */
185 const glw::GLchar* glcts::FramebufferBlitBaseTestCase::m_default_vert_shader =
186 R"(${VERSION}
187 ${EXTENSION}
188 in vec4 pos;
189 in vec2 UV;
190 out vec2 vUV;
191 void main()
192 {
193 gl_Position = pos;
194 vUV = UV;
195 }
196 )";
197
198 /** @brief Fragment shader source code to test framebuffer blit of color buffers. */
199 const glw::GLchar* glcts::FramebufferBlitBaseTestCase::m_default_frag_shader =
200 R"(${VERSION}
201 ${PRECISION}
202 in vec2 vUV;
203 out vec4 color;
204 uniform highp sampler2D tex;
205 void main()
206 {
207 color = texture(tex, vUV);
208 }
209 )";
210
211 /** @brief Vertex shader source code to test framebuffer blit of depth buffers. */
212 const glw::GLchar* glcts::FramebufferBlitBaseTestCase::m_render_vert_shader =
213 R"(${VERSION}
214 ${EXTENSION}
215 in vec4 pos;
216 void main()
217 {
218 gl_Position = pos;
219 }
220 )";
221
222 /** @brief Fragment shader source code to test framebuffer blit of depth buffers. */
223 const glw::GLchar* glcts::FramebufferBlitBaseTestCase::m_render_frag_shader =
224 R"(${VERSION}
225 ${PRECISION}
226 out vec4 color;
227 uniform vec4 uColor;
228 void main()
229 {
230 color = uColor;
231 }
232 )";
233
234 // clang-format on
235
FramebufferBlitBaseTestCase(deqp::Context & context,const char * name,const char * desc)236 FramebufferBlitBaseTestCase::FramebufferBlitBaseTestCase(deqp::Context &context, const char *name, const char *desc)
237 : TestCase(context, name, desc)
238 , m_fbos{0, 0}
239 , m_color_tbos{0, 0}
240 , m_depth_tbos{0, 0}
241 , m_stcil_tbos{0, 0}
242 , m_color_rbos{0, 0}
243 , m_depth_rbos{0, 0}
244 , m_stcil_rbos{0, 0}
245 , m_dflt(0)
246 , m_defaultCoord(0, 0)
247 , m_defaultProg(nullptr)
248 , m_renderProg(nullptr)
249 , m_isContextES(false)
250 , m_cbfTestSupported(false)
251 , m_msTbosSupported(false)
252 , m_minDrawBuffers(0)
253 , m_minColorAttachments(0)
254 , m_depth_internalFormat(0)
255 , m_depth_type(0)
256 , m_depth_format(0)
257 , m_stcil_internalFormat(0)
258 , m_stcil_type(0)
259 , m_stcil_format(0)
260 {
261 }
262
263 /** Stub deinit method. */
deinit()264 void FramebufferBlitBaseTestCase::deinit()
265 {
266 if (m_renderProg)
267 {
268 delete m_renderProg;
269 m_renderProg = nullptr;
270 }
271
272 if (m_defaultProg)
273 {
274 delete m_defaultProg;
275 m_defaultProg = nullptr;
276 }
277 }
278
279 /** Stub init method */
init()280 void FramebufferBlitBaseTestCase::init()
281 {
282 const glu::RenderContext &renderContext = m_context.getRenderContext();
283 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(renderContext.getType());
284 m_isContextES = glu::isContextTypeES(renderContext.getType());
285
286 specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
287 if (m_isContextES)
288 {
289 specializationMap["EXTENSION"] = "#extension GL_EXT_clip_cull_distance : enable";
290 specializationMap["PRECISION"] = "precision highp float;";
291 }
292 else
293 {
294 specializationMap["EXTENSION"] = "";
295 specializationMap["PRECISION"] = "";
296 }
297
298 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
299
300 auto contextType = m_context.getRenderContext().getType();
301 if (m_isContextES)
302 {
303 m_cbfTestSupported = m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float") ||
304 glu::contextSupports(contextType, glu::ApiType::es(3, 2));
305
306 m_msTbosSupported = glu::contextSupports(contextType, glu::ApiType::es(3, 1));
307 m_minDrawBuffers = 4;
308 m_minColorAttachments = 4;
309 }
310 else
311 {
312 m_cbfTestSupported = true;
313 m_msTbosSupported = true;
314 m_minDrawBuffers = 8;
315 m_minColorAttachments = 8;
316 }
317
318 /* Building programs. */
319 auto setup_shaders = [&](const std::string &vert, const std::string &frag)
320 {
321 std::string vert_shader = tcu::StringTemplate(vert).specialize(specializationMap);
322 std::string frag_shader = tcu::StringTemplate(frag).specialize(specializationMap);
323
324 ProgramSources sources = makeVtxFragSources(vert_shader, frag_shader);
325 auto prog = new ShaderProgram(gl, sources);
326
327 if (!prog->isOk())
328 {
329 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
330 << "Vertex: " << prog->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
331 << prog->getShader(glu::SHADERTYPE_VERTEX) << "\n"
332 << "Fragment: " << prog->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
333 << prog->getShader(glu::SHADERTYPE_FRAGMENT) << "\n"
334 << "Program: " << prog->getProgramInfo().infoLog << tcu::TestLog::EndMessage;
335 TCU_FAIL("FramebufferBlitMultiToSingleSampledTestCase::init: shader build failed");
336 };
337 return prog;
338 };
339
340 m_defaultProg = setup_shaders(m_default_vert_shader, m_default_frag_shader);
341 m_renderProg = setup_shaders(m_render_vert_shader, m_render_frag_shader);
342
343 m_defaultFBO = m_context.getRenderContext().getDefaultFramebuffer();
344 int bufWidth = m_context.getRenderTarget().getWidth();
345 int bufHeight = m_context.getRenderTarget().getHeight();
346
347 m_fullRect = {0, 0, bufWidth, bufHeight};
348 m_defaultCoord = {bufWidth / 2, bufHeight / 2};
349
350 // /* multicolor pattern rectangles for all quadrants */
351 m_setup.ul_rect = {0, bufHeight / 2, bufWidth / 2,
352 bufHeight - bufHeight / 2}; /* upper left (x, y, width, height) */
353 m_setup.ur_rect = {bufWidth / 2, bufHeight / 2, bufWidth - bufWidth / 2,
354 bufHeight - bufHeight / 2}; /* upper right (x, y, width, height) */
355 m_setup.ll_rect = {0, 0, bufWidth / 2, bufHeight / 2}; /* lower left (x, y, width, height) */
356 m_setup.lr_rect = {bufWidth / 2, 0, bufWidth - bufWidth / 2, bufHeight / 2}; /* lower right (x, y, width, height) */
357 m_setup.blt_src_rect = m_fullRect;
358 m_setup.negative_src_width = false;
359 m_setup.negative_src_height = false;
360 m_setup.blt_dst_rect = m_fullRect;
361 m_setup.negative_dst_width = false;
362 m_setup.negative_dst_height = false;
363 m_setup.scissor_rect = m_fullRect;
364 // /* corner coordinates */
365 m_setup.ul_coord = {0, bufHeight - 1}; /* upper left corner */
366 m_setup.ur_coord = {bufWidth - 1, bufHeight - 1}; /* upper right corner */
367 m_setup.ll_coord = {0, 0}; /* lower left corner */
368 m_setup.lr_coord = {bufWidth - 1, 0}; /* lower right corner */
369 m_setup.ul_color = RED;
370 m_setup.ur_color = GREEN;
371 m_setup.ll_color = BLUE;
372 m_setup.lr_color = WHITE;
373 m_setup.ul_depth = Q1;
374 m_setup.ur_depth = Q2;
375 m_setup.ll_depth = Q3;
376 m_setup.lr_depth = Q4;
377 m_setup.ul_stcil = ONE;
378 m_setup.ur_stcil = TWO;
379 m_setup.ll_stcil = THREE;
380 m_setup.lr_stcil = FOUR;
381
382 // clang-format off
383 /* buffer configs used in functionality tests */
384 m_bufferCfg = {
385 /* src_fbo dst_fbo src_type dst_type src_color_buf src_depth_buf src_stcil_buf dst_color_buf dst_depth_buf dst_stcil_buf same_read_and_draw_buffer */
386 { &m_fbos[0], &m_fbos[1], GL_TEXTURE_2D, GL_TEXTURE_2D, &m_color_tbos[0], &m_depth_tbos[0], &m_stcil_tbos[0], &m_color_tbos[1], &m_depth_tbos[1], &m_stcil_tbos[1], false }, /* texture READ_BUFFER, texture DRAW_BUFFER */
387 { &m_fbos[0], &m_fbos[1], GL_RENDERBUFFER, GL_TEXTURE_2D, &m_color_rbos[0], &m_depth_rbos[0], &m_stcil_rbos[0], &m_color_tbos[1], &m_depth_tbos[1], &m_stcil_tbos[1], false }, /* renderbuffer READ_BUFFER, texture DRAW_BUFFER */
388 { &m_fbos[0], &m_fbos[1], GL_TEXTURE_2D, GL_RENDERBUFFER, &m_color_tbos[0], &m_depth_tbos[0], &m_stcil_tbos[0], &m_color_rbos[1], &m_depth_rbos[1], &m_stcil_rbos[1], false }, /* texture READ_BUFFER, renderbuffer DRAW_BUFFER */
389 { &m_fbos[0], &m_fbos[1], GL_RENDERBUFFER, GL_RENDERBUFFER, &m_color_rbos[0], &m_depth_rbos[0], &m_stcil_rbos[0], &m_color_rbos[1], &m_depth_rbos[1], &m_stcil_rbos[1], false }, /* renderbuffer READ_BUFFER, renderbuffer DRAW_BUFFER */
390 { &m_dflt, &m_fbos[1], 0, GL_TEXTURE_2D, &m_dflt, &m_dflt, &m_dflt, &m_color_tbos[1], &m_depth_tbos[1], &m_stcil_tbos[1], false }, /* default READ_BUFFER, texture DRAW_BUFFER */
391 { &m_dflt, &m_fbos[1], 0, GL_RENDERBUFFER, &m_dflt, &m_dflt, &m_dflt, &m_color_rbos[1], &m_depth_rbos[1], &m_stcil_rbos[1], false }, /* default READ_BUFFER, renderbuffer DRAW_BUFFER */
392 { &m_fbos[0], &m_dflt, GL_TEXTURE_2D, 0, &m_color_tbos[0], &m_depth_tbos[0], &m_stcil_tbos[0], &m_dflt, &m_dflt, &m_dflt, false }, /* texture READ_BUFFER, default DRAW_BUFFER */
393 { &m_fbos[0], &m_dflt, GL_RENDERBUFFER, 0, &m_color_rbos[0], &m_depth_rbos[0], &m_stcil_rbos[0], &m_dflt, &m_dflt, &m_dflt, false } /* renderbuffer READ_BUFFER, default DRAW_BUFFER */
394 };
395
396 if (!m_isContextES)
397 {
398 m_bufferCfg.push_back({ &m_fbos[0], &m_fbos[1], GL_TEXTURE_2D, GL_TEXTURE_2D, &m_color_tbos[0], &m_depth_tbos[0],
399 &m_stcil_tbos[0], &m_color_tbos[1], &m_depth_tbos[1], &m_stcil_tbos[1],
400 true }); /* same texture in READ_BUFFER and DRAW_BUFFER */
401 m_bufferCfg.push_back({ &m_fbos[0], &m_fbos[1], GL_RENDERBUFFER, GL_RENDERBUFFER, &m_color_rbos[0], &m_depth_rbos[0],
402 &m_stcil_rbos[0], &m_color_rbos[1], &m_depth_rbos[1], &m_stcil_rbos[1],
403 true }); /* same renderbuffer in READ_BUFFER and DRAW_BUFFER */
404 m_bufferCfg.push_back({ &m_dflt, &m_dflt, 0, 0, &m_dflt, &m_dflt, &m_dflt, &m_dflt, &m_dflt, &m_dflt,
405 true }); /* default READ_BUFFER and DRAW_BUFFER */
406 }
407
408 m_depthCfg = {
409 /* From table 3.13 */
410 /* internal format, format, type, attachment, depth bits */
411 { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_ATTACHMENT, 24 },
412 { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_ATTACHMENT, 16 },
413 { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_ATTACHMENT, 32 },
414 { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL_ATTACHMENT, 24 },
415 { GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH_STENCIL_ATTACHMENT, 32 },
416 };
417
418 if (!m_isContextES)
419 {
420 m_depthCfg.push_back({ GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_ATTACHMENT, 32 });
421 }
422 // clang-format on
423 }
424
425 template <typename... Args>
tcu_fail_msg(const std::string & format,Args...args)426 inline void FramebufferBlitBaseTestCase::tcu_fail_msg(const std::string &format, Args... args)
427 {
428 int str_size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1;
429 if (str_size <= 0)
430 throw std::runtime_error("Formatting error.");
431 size_t s = static_cast<size_t>(str_size);
432 std::unique_ptr<char[]> buffer(new char[s]);
433 std::snprintf(buffer.get(), s, format.c_str(), args...);
434 m_testCtx.getLog() << tcu::TestLog::Message << buffer.get() << tcu::TestLog::EndMessage;
435 }
436
437 /* Get default frame buffer's compatible bliting format */
GetDefaultFramebufferBlitFormat(bool * noDepth,bool * noStencil)438 bool FramebufferBlitBaseTestCase::GetDefaultFramebufferBlitFormat(bool *noDepth, bool *noStencil)
439 {
440 int depthBits = 0, stencilBits = 0;
441
442 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
443 gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
444 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
445
446 getBits(gl, m_isContextES, GL_DRAW_FRAMEBUFFER, GL_DEPTH_BITS, &depthBits);
447 getBits(gl, m_isContextES, GL_DRAW_FRAMEBUFFER, GL_STENCIL_BITS, &stencilBits);
448
449 m_depth_internalFormat = 0;
450 m_depth_type = 0;
451 m_depth_format = 0;
452
453 m_stcil_internalFormat = 0;
454 m_stcil_type = 0;
455 m_stcil_format = 0;
456
457 *noDepth = (depthBits == 0);
458 *noStencil = (stencilBits == 0);
459
460 /* Check if running under FBO config */
461 if (m_defaultFBO != 0)
462 {
463 m_stcil_internalFormat = m_depth_internalFormat = GL_DEPTH24_STENCIL8;
464 m_stcil_type = m_depth_type = GL_UNSIGNED_INT_24_8;
465 m_stcil_format = m_depth_format = GL_DEPTH_STENCIL;
466
467 return true;
468 }
469
470 if (depthBits == 16)
471 {
472 if (stencilBits == 0)
473 {
474 m_depth_internalFormat = GL_DEPTH_COMPONENT16;
475 m_depth_type = GL_UNSIGNED_SHORT;
476 m_depth_format = GL_DEPTH_COMPONENT;
477
478 return true;
479 }
480 }
481 else if (depthBits == 24)
482 {
483 if (stencilBits == 0)
484 {
485 m_depth_internalFormat = GL_DEPTH_COMPONENT24;
486 m_depth_type = GL_UNSIGNED_INT;
487 m_depth_format = GL_DEPTH_COMPONENT;
488
489 return true;
490 }
491 else if (stencilBits == 8)
492 {
493 m_stcil_internalFormat = m_depth_internalFormat = GL_DEPTH24_STENCIL8;
494 m_stcil_type = m_depth_type = GL_UNSIGNED_INT_24_8;
495 m_stcil_format = m_depth_format = GL_DEPTH_STENCIL;
496
497 return true;
498 }
499 }
500 else if (depthBits == 32)
501 {
502 if (stencilBits == 0)
503 {
504 GLint type = 0;
505 GetDrawbuffer32DepthComponentType(&type);
506 if (type == GL_FLOAT)
507 {
508 m_depth_internalFormat = GL_DEPTH_COMPONENT32F;
509 m_depth_type = GL_FLOAT;
510 }
511 else
512 {
513 m_depth_internalFormat = GL_DEPTH_COMPONENT32;
514 m_depth_type = GL_UNSIGNED_INT;
515 }
516 m_depth_format = GL_DEPTH_COMPONENT;
517
518 return true;
519 }
520 else if (stencilBits == 8)
521 {
522 m_stcil_internalFormat = m_depth_internalFormat = GL_DEPTH32F_STENCIL8;
523 m_stcil_type = m_depth_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
524 m_stcil_format = m_depth_format = GL_DEPTH_STENCIL;
525
526 return true;
527 }
528 }
529
530 return false;
531 }
532
GetDrawbuffer32DepthComponentType(glw::GLint * value)533 bool FramebufferBlitBaseTestCase::GetDrawbuffer32DepthComponentType(glw::GLint *value)
534 {
535 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
536 if (!m_isContextES)
537 {
538 GLenum target = GL_DRAW_FRAMEBUFFER;
539 GLenum depthAttachment = GL_DEPTH;
540 GLint fbo = 0;
541 gl.getIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
542 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
543
544 if (fbo)
545 {
546 depthAttachment = GL_DEPTH_ATTACHMENT;
547 }
548
549 /*
550 * OPENGL SPECS 4.5: Paragraph 9.2. BINDING AND MANAGING FRAMEBUFFER OBJECTS p.335
551 * If the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE, then either no framebuffer is bound to target;
552 * or a default framebuffer is queried, attachment is GL_DEPTH or GL_STENCIL,
553 * and the number of depth or stencil bits, respectively, is zero....
554 * and all other queries will generate an INVALID_OPERATION error.
555 * */
556 if (fbo == 0)
557 { //default framebuffer
558 gl.getFramebufferAttachmentParameteriv(target, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, value);
559 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
560
561 if (*value == GL_NONE)
562 {
563 *value = GL_FLOAT;
564 return false;
565 }
566 }
567 gl.getFramebufferAttachmentParameteriv(target, depthAttachment, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
568 value);
569 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
570 }
571 else
572 {
573 *value = GL_FLOAT;
574 }
575
576 return true;
577 }
578
579 ///* Initialize textures or renderbuffers. Return true if succeed, false otherwise.
580 // *
581 // * count: number of textures to init
582 // * buf: pointer to tex objects
583 // * internal_format: tex internal format
584 // */
585 template <GLenum E, GLuint samples, typename F>
init_gl_objs(F f,const GLuint count,const GLuint * buf,const GLint format)586 bool FramebufferBlitBaseTestCase::init_gl_objs(F f, const GLuint count, const GLuint *buf, const GLint format)
587 {
588 if (!check_param(buf != NULL, "invalid buf pointer"))
589 return false;
590 if (!check_param(count < MAX_BUF_OBJECTS, "invalid count"))
591 return false;
592
593 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
594 for (GLuint i = 0; i < count; i++)
595 {
596 f(E, buf[i]);
597 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
598 if (E == GL_TEXTURE_2D)
599 {
600 gl.texStorage2D(E, 1, format, m_fullRect.w, m_fullRect.h);
601 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
602 }
603 else if (E == GL_TEXTURE_2D_MULTISAMPLE)
604 {
605 gl.texStorage2DMultisample(E, samples, format, m_fullRect.w, m_fullRect.h, GL_TRUE);
606 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2DMultisample");
607 }
608 else if (E == GL_RENDERBUFFER)
609 {
610 if (samples == 0)
611 {
612 gl.renderbufferStorage(E, format, m_fullRect.w, m_fullRect.h);
613 GLU_EXPECT_NO_ERROR(gl.getError(), "renderbufferStorage");
614 }
615 else
616 {
617 gl.renderbufferStorageMultisample(E, samples, format, m_fullRect.w, m_fullRect.h);
618 GLU_EXPECT_NO_ERROR(gl.getError(), "renderbufferStorageMultisample");
619 }
620 }
621 }
622 return true;
623 }
624
check_param(glw::GLboolean expr,const char * str)625 bool FramebufferBlitBaseTestCase::check_param(glw::GLboolean expr, const char *str)
626 {
627 if (!expr)
628 {
629 m_testCtx.getLog() << tcu::TestLog::Message << ":" << __FILE__ << ":" << __LINE__ << str
630 << tcu::TestLog::EndMessage;
631 return false;
632 }
633 return true;
634 }
635
636 /* Clear the color buffer to given color. Prior to return, unbind all
637 * used attachments and setup default read and draw framebuffers.
638 * Return true if succeed, false otherwise.
639 *
640 * fbo: framebuffer to use
641 * attachment: framebuffer attachment to attach buffer
642 * type: buffer type
643 * buf: colorbuffer to be cleared
644 * color: clear color
645 * rect: region of colorbuffer to be cleared
646 * check_coord: coord to verify buffer value after clearing
647 * check_channels: channels to be verified
648 */
clearColorBuffer(const GLuint fbo,const GLenum attachment,const GLenum type,const GLuint buf,const Color & color,const Rectangle & rect,const Coord & check_coord,const GLuint check_channels,const bool bFloatInternalFormat)649 bool FramebufferBlitBaseTestCase::clearColorBuffer(const GLuint fbo, const GLenum attachment, const GLenum type,
650 const GLuint buf, const Color &color, const Rectangle &rect,
651 const Coord &check_coord, const GLuint check_channels,
652 const bool bFloatInternalFormat)
653 {
654 bool result = true;
655 Color tmp_color = {0.5f, 0.5f, 0.5f, 0.5f};
656 GLint sample_buffers = 0;
657
658 if (!check_param(
659 (type == 0 || type == GL_TEXTURE_2D || type == GL_TEXTURE_2D_MULTISAMPLE || type == GL_RENDERBUFFER),
660 "invalid type"))
661 return false;
662
663 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
664
665 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
666 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
667
668 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
669 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
670
671 if (fbo && (fbo != m_defaultFBO))
672 {
673 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, attachment, type, buf);
674 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, type, buf);
675 gl.readBuffer(attachment);
676 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
677
678 gl.drawBuffers(1, &attachment);
679 GLU_EXPECT_NO_ERROR(gl.getError(), "drawBuffers");
680 }
681
682 // clear color rectangle
683 gl.scissor(rect.x, rect.y, rect.w, rect.h);
684 GLU_EXPECT_NO_ERROR(gl.getError(), "scissor");
685
686 gl.enable(GL_SCISSOR_TEST);
687 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
688
689 GLuint status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
690 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
691 if (status != GL_FRAMEBUFFER_COMPLETE)
692 m_testCtx.getLog() << tcu::TestLog::Message << "checkFramebufferStatus unexpected status"
693 << tcu::TestLog::EndMessage;
694
695 gl.clearColor(color[0], color[1], color[2], color[3]);
696 GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
697
698 m_testCtx.getLog() << tcu::TestLog::Message << "clearing color to [" << color[0] << "," << color[1] << ","
699 << color[2] << "," << color[3] << "]" << tcu::TestLog::EndMessage;
700
701 gl.clear(GL_COLOR_BUFFER_BIT);
702 GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
703
704 gl.disable(GL_SCISSOR_TEST);
705 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
706
707 /* Verify the color in cleared buffer in case of single-sampled
708 * buffers. Don't verify in case of multisampled buffer since
709 * glReadPixels generates GL_INVALID_OPERATION if
710 * GL_SAMPLE_BUFFERS is greater than zero. */
711 gl.getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
712 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
713
714 if (sample_buffers == 0)
715 {
716 if (fbo && (fbo != m_defaultFBO))
717 {
718 m_testCtx.getLog() << tcu::TestLog::Message << "verifying initial "
719 << ((type == GL_RENDERBUFFER) ? "ren" : "tex") << "buf" << buf << " color [" << color[0]
720 << "," << color[1] << "," << color[2] << "," << color[3] << "]"
721 << tcu::TestLog::EndMessage;
722 }
723 else
724 {
725 m_testCtx.getLog() << tcu::TestLog::Message << "verifying initial default buf color [" << color[0] << ","
726 << color[1] << "," << color[2] << "," << color[3] << "]" << tcu::TestLog::EndMessage;
727 }
728
729 getColor(check_coord, &tmp_color, bFloatInternalFormat);
730 bool ret = checkColor(tmp_color, color, check_channels);
731 CHECK(ret, true, checkColor);
732 }
733 else
734 {
735 if (fbo && (fbo != m_defaultFBO))
736 {
737 m_testCtx.getLog() << tcu::TestLog::Message << "no verification of multisampled "
738 << ((type == GL_RENDERBUFFER) ? "ren" : "tex") << "buf" << buf
739 << tcu::TestLog::EndMessage;
740 }
741 else
742 {
743 m_testCtx.getLog() << tcu::TestLog::Message << "no verification of multisampled dfltbuf"
744 << tcu::TestLog::EndMessage;
745 }
746 }
747
748 if (fbo && (fbo != m_defaultFBO))
749 {
750 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, attachment, type, 0);
751 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, type, 0);
752 }
753
754 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultFBO);
755 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
756 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_defaultFBO);
757 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
758
759 return result;
760 }
761
762 /* Attach a buffer object to framebuffer. Return true if succeed,
763 * false otherwise.
764 *
765 * target: fbo target
766 * attachment: color/depth/stencil attachment
767 * type: buf type
768 * buf: buf to attach
769 */
attachBufferToFramebuffer(GLenum target,GLenum attachment,GLenum type,GLuint buf)770 bool FramebufferBlitBaseTestCase::attachBufferToFramebuffer(GLenum target, GLenum attachment, GLenum type, GLuint buf)
771 {
772 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
773 if (type == GL_TEXTURE_2D || type == GL_TEXTURE_2D_MULTISAMPLE)
774 {
775 gl.framebufferTexture2D(target, attachment, type, buf, 0);
776 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
777
778 if (buf)
779 {
780 m_testCtx.getLog() << tcu::TestLog::Message << "attaching texbuf" << buf << " to "
781 << getEnumName(attachment) << " of " << getEnumName(target) << tcu::TestLog::EndMessage;
782 }
783 else
784 {
785 m_testCtx.getLog() << tcu::TestLog::Message << "detaching " << getEnumName(attachment) << " of "
786 << getEnumName(target) << tcu::TestLog::EndMessage;
787 }
788 }
789 else if (type == GL_RENDERBUFFER)
790 {
791 gl.framebufferRenderbuffer(target, attachment, type, buf);
792 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
793
794 if (buf)
795 {
796 m_testCtx.getLog() << tcu::TestLog::Message << "attaching renbuf" << buf << " to "
797 << getEnumName(attachment) << " of " << getEnumName(target) << tcu::TestLog::EndMessage;
798 }
799 else
800 {
801 m_testCtx.getLog() << tcu::TestLog::Message << "detaching " << getEnumName(attachment) << " of "
802 << getEnumName(target) << tcu::TestLog::EndMessage;
803 }
804 }
805 return true;
806 }
807
808 /* Get the color value from the given coordinates. Return true if
809 * succeed, false otherwise.
810 */
getColor(const Coord & coord,Color * color,const bool bFloatInternalFormat)811 bool FramebufferBlitBaseTestCase::getColor(const Coord &coord, Color *color, const bool bFloatInternalFormat)
812 {
813 bool result = true;
814
815 GLuint status;
816 GLint x = coord.x();
817 GLint y = coord.y();
818
819 if (!check_param(color != NULL, "invalid color pointer"))
820 return false;
821
822 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
823
824 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
825 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
826 if (status != GL_FRAMEBUFFER_COMPLETE)
827 m_testCtx.getLog() << tcu::TestLog::Message << "checkFramebufferStatus unexpected status"
828 << tcu::TestLog::EndMessage;
829
830 if (bFloatInternalFormat)
831 {
832 GLfloat tmp_fcolor[4] = {0.6f, 0.6f, 0.6f, 0.6f};
833 gl.readPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, &tmp_fcolor[0]);
834 GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
835
836 color->x() = tmp_fcolor[0];
837 color->y() = tmp_fcolor[1];
838 color->z() = tmp_fcolor[2];
839 color->w() = tmp_fcolor[3];
840 }
841 else
842 {
843 GLubyte tmp_color[4] = {100, 100, 100, 100};
844 gl.readPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &tmp_color[0]);
845 GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
846
847 color->x() = tmp_color[0] / 255.0f;
848 color->y() = tmp_color[1] / 255.0f;
849 color->z() = tmp_color[2] / 255.0f;
850 color->w() = tmp_color[3] / 255.0f;
851 }
852
853 m_testCtx.getLog() << tcu::TestLog::Message << "getColor: XY=[" << x << "," << y << "] RGBA=[" << color->x() << ","
854 << color->y() << "," << color->z() << "," << color->w() << "]" << tcu::TestLog::EndMessage;
855
856 return result;
857 }
858
859 /* Verify the actual color and the expected color match in given
860 * channels. Return true if succeed, false otherwise.
861 *
862 * actual: actual color to be checked
863 * expect: expected color
864 * channels: bitfield combination of RED_CHANNEL, GREEN_CHANNEL,
865 * BLUE_CHANNEL, and ALPHA_CHANNEL
866 */
checkColor(const Color & actual,const Color & expect,const GLuint channels)867 bool FramebufferBlitBaseTestCase::checkColor(const Color &actual, const Color &expect, const GLuint channels)
868 {
869 GLubyte expect_r = 0, expect_g = 0, expect_b = 0, expect_a = 0;
870 GLubyte actual_r = 0, actual_g = 0, actual_b = 0, actual_a = 0;
871
872 if (channels & RED_CHANNEL)
873 {
874 expect_r = floatToByte(expect.x());
875 actual_r = floatToByte(actual.x());
876 }
877 if (channels & GREEN_CHANNEL)
878 {
879 expect_g = floatToByte(expect.y());
880 actual_g = floatToByte(actual.y());
881 }
882 if (channels & BLUE_CHANNEL)
883 {
884 expect_b = floatToByte(expect.z());
885 actual_b = floatToByte(actual.z());
886 }
887 if (channels & ALPHA_CHANNEL)
888 {
889 expect_a = floatToByte(expect.w());
890 actual_a = floatToByte(actual.w());
891 }
892
893 if (actual_r != expect_r || actual_g != expect_g || actual_b != expect_b || actual_a != expect_a)
894 {
895 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: expected RGBA=[" << expect_r << "," << expect_g << ","
896 << expect_b << "," << expect_a << "] but got RGBA[" << actual_r << "," << actual_g << ","
897 << actual_b << "," << actual_a << "]" << tcu::TestLog::EndMessage;
898 return false;
899 }
900 return true;
901 }
902
903 /* Convert float [0,1] to byte [0,255].
904 */
floatToByte(GLfloat f)905 GLubyte FramebufferBlitBaseTestCase::floatToByte(GLfloat f)
906 {
907 if (f < 0.0f || f > 1.0f)
908 {
909 m_testCtx.getLog() << tcu::TestLog::Message << ":" << __FILE__ << ":" << __LINE__
910 << "float not in range [0.0f, 1.0f]" << tcu::TestLog::EndMessage;
911 return 0;
912 }
913 return (GLubyte)std::floor(f == 1.0f ? 255 : f * 255.0);
914 }
915
916 /* Clear the depth buffer to given depth. Prior to return, unbind all
917 * used attachments and setup default read and draw framebuffers.
918 * Return true if succeed, false otherwise.
919 *
920 * fbo: framebuffer to use
921 * attachment: framebuffer attachment to attach buffer
922 * type: buffer type
923 * buf: depthbuffer to be cleared
924 * depth: clear depth
925 * rect: region of depthbuffer to be cleared
926 * check_coord: coord to verify buffer value after clearing
927 */
clearDepthBuffer(const GLuint fbo,const GLenum attachment,const GLenum type,const GLuint buf,const GLuint internalFormat,const Depth depth,const Rectangle & rect,const Coord & check_coord)928 bool FramebufferBlitBaseTestCase::clearDepthBuffer(const GLuint fbo, const GLenum attachment, const GLenum type,
929 const GLuint buf, const GLuint internalFormat, const Depth depth,
930 const Rectangle &rect, const Coord &check_coord)
931 {
932 bool result = true;
933 Depth tmp_depth = 0.2f;
934 GLint sample_buffers;
935
936 /* Get epsilon based on format precision */
937 auto get_epsilon = [](const GLuint resultPreBits, const GLuint sourcePreBits)
938 {
939 GLuint tolerance = std::min(resultPreBits, sourcePreBits);
940 tolerance = std::min(tolerance, GLuint(23)); // don't exceed the amount of mantissa bits in a float
941 return (float)1.0 / (1 << tolerance);
942 };
943
944 if (!check_param(
945 (type == 0 || type == GL_TEXTURE_2D || type == GL_TEXTURE_2D_MULTISAMPLE || type == GL_RENDERBUFFER),
946 "invalid type"))
947 return false;
948
949 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
950
951 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
952 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
953
954 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
955 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
956
957 if (fbo && (fbo != m_defaultFBO))
958 {
959 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, attachment, type, buf);
960 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, type, buf);
961 }
962
963 // clear depth rectangle
964 gl.scissor(rect.x, rect.y, rect.w, rect.h);
965 GLU_EXPECT_NO_ERROR(gl.getError(), "scissor");
966 gl.enable(GL_SCISSOR_TEST);
967 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
968
969 GLuint status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
970 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
971 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
972
973 if (!m_isContextES)
974 {
975 gl.clearDepth(depth);
976 GLU_EXPECT_NO_ERROR(gl.getError(), "clearDepth");
977 }
978 else
979 {
980 gl.clearDepthf(depth);
981 GLU_EXPECT_NO_ERROR(gl.getError(), "clearDepthf");
982 }
983
984 m_testCtx.getLog() << tcu::TestLog::Message << "clearing depth to [" << depth << "]" << tcu::TestLog::EndMessage;
985
986 gl.clear(GL_DEPTH_BUFFER_BIT);
987 GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
988 gl.disable(GL_SCISSOR_TEST);
989 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
990
991 /* Verify the depth in cleared depth in case of single-sampled
992 * buffers. Don't verify in case of multisampled buffer since
993 * glReadPixels generates GL_INVALID_OPERATION if
994 * GL_SAMPLE_BUFFERS is greater than zero. */
995 gl.getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
996
997 if (sample_buffers == 0)
998 {
999 if (fbo && (fbo != m_defaultFBO))
1000 {
1001 m_testCtx.getLog() << tcu::TestLog::Message << "verifying initial "
1002 << ((type == GL_TEXTURE_2D) ? "tex" : "ren") << "buf" << buf << " depth [" << depth
1003 << "]" << tcu::TestLog::EndMessage;
1004 }
1005 else
1006 {
1007 m_testCtx.getLog() << tcu::TestLog::Message << "verifying initial dfltbuf depth [" << depth << "]"
1008 << tcu::TestLog::EndMessage;
1009 }
1010
1011 GLuint precisionBits[2] = {0, 0};
1012 getDepth(check_coord, &tmp_depth, &precisionBits[0], fbo, internalFormat, rect);
1013
1014 /* Calculate precision */
1015 precisionBits[1] = GetDepthPrecisionBits(internalFormat);
1016 GLfloat epsilon = get_epsilon(precisionBits[0], precisionBits[1]);
1017
1018 result = checkDepth(tmp_depth, depth, epsilon);
1019 CHECK(result, true, checkDepth);
1020 }
1021 else
1022 {
1023 if (fbo && (fbo != m_defaultFBO))
1024 {
1025 m_testCtx.getLog() << tcu::TestLog::Message << "no verification of multisampled "
1026 << ((type == GL_RENDERBUFFER) ? "ren" : "tex") << "buf" << buf
1027 << tcu::TestLog::EndMessage;
1028 }
1029 else
1030 {
1031 m_testCtx.getLog() << tcu::TestLog::Message << "no verification of multisampled dfltbuf"
1032 << tcu::TestLog::EndMessage;
1033 }
1034 }
1035
1036 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultFBO);
1037 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1038
1039 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_defaultFBO);
1040 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1041
1042 return result;
1043 }
1044
1045 /* Get the depth value from the given coordinates. Return true if
1046 * succeed, false otherwise.
1047 */
getDepth(const Coord & coord,Depth * depth,GLuint * precisionBits,const GLuint fbo,const GLuint internalFormat,const Rectangle & rect)1048 bool FramebufferBlitBaseTestCase::getDepth(const Coord &coord, Depth *depth, GLuint *precisionBits, const GLuint fbo,
1049 const GLuint internalFormat, const Rectangle &rect)
1050 {
1051 bool result = true;
1052 GLuint status = 0;
1053 GLint x = coord.x(), y = coord.y();
1054
1055 if (!check_param(depth != NULL, "invalid depth pointer"))
1056 return false;
1057
1058 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1059 if (m_isContextES)
1060 {
1061 GLuint fbo_0, tex_0 = 0, tex_1;
1062 const GLenum attachment_0 = GL_COLOR_ATTACHMENT0;
1063 GLubyte dataColor[4];
1064
1065 {
1066 /* Blit to a depth texture for later sampling in the shader to get the depth value */
1067 const auto psInternalFormat = glu::getTransferFormat(glu::mapGLInternalFormat(internalFormat));
1068
1069 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1070 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1071
1072 gl.genFramebuffers(1, &fbo_0);
1073 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
1074 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_0);
1075 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1076 gl.genTextures(1, &tex_0);
1077 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1078 gl.bindTexture(GL_TEXTURE_2D, tex_0);
1079 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
1080 gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, rect.w, rect.h, 0, psInternalFormat.format,
1081 psInternalFormat.dataType, 0);
1082 GLU_EXPECT_NO_ERROR(gl.getError(), "texImage2D");
1083 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex_0, 0);
1084 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
1085
1086 status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1087 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1088 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1089 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1090 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1091 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1092
1093 gl.blitFramebuffer(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h, 0, 0, rect.w, rect.h,
1094 GL_DEPTH_BUFFER_BIT, GL_NEAREST);
1095 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
1096
1097 gl.deleteFramebuffers(1, &fbo_0);
1098 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
1099 }
1100
1101 gl.genFramebuffers(1, &fbo_0);
1102 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
1103 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_0);
1104 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1105
1106 gl.genTextures(1, &tex_1);
1107 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1108 gl.bindTexture(GL_TEXTURE_2D, tex_1);
1109 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
1110 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.w, rect.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1111 GLU_EXPECT_NO_ERROR(gl.getError(), "texImage2D");
1112 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_1, 0);
1113 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
1114 gl.drawBuffers(1, &attachment_0);
1115 GLU_EXPECT_NO_ERROR(gl.getError(), "drawBuffers");
1116 gl.readBuffer(attachment_0);
1117 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
1118 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1119 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1120 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1121
1122 GLuint vao = 0, vbo = 0;
1123 if (!setupDefaultShader(vao, vbo))
1124 return false;
1125
1126 gl.activeTexture(GL_TEXTURE0);
1127 GLU_EXPECT_NO_ERROR(gl.getError(), "activeTexture");
1128 gl.bindTexture(GL_TEXTURE_2D, tex_0);
1129 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
1130 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1131 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
1132 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1133 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
1134 gl.disable(GL_DEPTH_TEST);
1135 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
1136 gl.depthMask(GL_FALSE);
1137 GLU_EXPECT_NO_ERROR(gl.getError(), "depthMask");
1138 gl.disable(GL_STENCIL_TEST);
1139 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
1140 gl.viewport(0, 0, rect.w, rect.h);
1141 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
1142 gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
1143 GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
1144 gl.clear(GL_COLOR_BUFFER_BIT);
1145 GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1146 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
1147 GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
1148
1149 gl.readPixels(x - rect.x, y - rect.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dataColor);
1150 GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
1151
1152 gl.deleteFramebuffers(1, &fbo_0);
1153 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
1154 gl.deleteTextures(1, &tex_0);
1155 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
1156 gl.deleteTextures(1, &tex_1);
1157 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
1158
1159 gl.depthMask(GL_TRUE);
1160 GLU_EXPECT_NO_ERROR(gl.getError(), "depthMask");
1161 // restore viewport
1162 gl.viewport(m_fullRect.x, m_fullRect.y, m_fullRect.w, m_fullRect.h);
1163 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
1164
1165 gl.disableVertexAttribArray(0);
1166 GLU_EXPECT_NO_ERROR(gl.getError(), "disableVertexAttribArray");
1167 gl.disableVertexAttribArray(1);
1168 GLU_EXPECT_NO_ERROR(gl.getError(), "disableVertexAttribArray");
1169
1170 if (vbo)
1171 {
1172 gl.deleteBuffers(1, &vbo);
1173 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteBuffers");
1174 }
1175
1176 if (vao)
1177 {
1178 gl.deleteVertexArrays(1, &vao);
1179 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteVertexArrays");
1180 }
1181
1182 *depth = dataColor[0] / 255.0f;
1183 *precisionBits = 8;
1184
1185 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1186 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1187 }
1188 else
1189 {
1190 GLfloat tmp_depth = 0.2f;
1191 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1192 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1193 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1194 gl.readPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &tmp_depth);
1195 GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
1196
1197 *depth = tmp_depth;
1198 *precisionBits = 24;
1199 }
1200
1201 m_testCtx.getLog() << tcu::TestLog::Message << "getDepth: XY[" << x << "," << y << "] DEPTH_COMPONENT[" << *depth
1202 << "]" << tcu::TestLog::EndMessage;
1203
1204 return result;
1205 }
1206
1207 /* Get depth precision bit from a depth internal format
1208 */
GetDepthPrecisionBits(const GLenum depthInternalFormat)1209 GLuint FramebufferBlitBaseTestCase::GetDepthPrecisionBits(const GLenum depthInternalFormat)
1210 {
1211 for (GLuint i = 0; i < m_depthCfg.size(); ++i)
1212 if (m_depthCfg[i].internal_format == depthInternalFormat)
1213 return m_depthCfg[i].precisionBits;
1214 return 0;
1215 }
1216
1217 /* Verify the actual and the expected depth match. Return true if
1218 * succeed, false otherwise.
1219 */
checkDepth(const Depth actual,const Depth expected,const GLfloat eps)1220 bool FramebufferBlitBaseTestCase::checkDepth(const Depth actual, const Depth expected, const GLfloat eps)
1221 {
1222 if (std::fabs(actual - expected) > eps)
1223 {
1224 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: expected DEPTH[" << expected << "] but got DEPTH["
1225 << actual << "], epsilon[" << eps << "]" << tcu::TestLog::EndMessage;
1226 return false;
1227 }
1228 return true;
1229 }
1230
setupDefaultShader(GLuint & vao,GLuint & vbo)1231 bool FramebufferBlitBaseTestCase::setupDefaultShader(GLuint &vao, GLuint &vbo)
1232 {
1233 bool result = true;
1234
1235 // clang-format off
1236 const std::vector <GLfloat> vboData =
1237 {
1238 -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1239 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1240 -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1241 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1242 };
1243 // clang-format on
1244
1245 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1246
1247 gl.genVertexArrays(1, &vao);
1248 GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
1249 gl.bindVertexArray(vao);
1250 GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
1251
1252 gl.genBuffers(1, &vbo);
1253 GLU_EXPECT_NO_ERROR(gl.getError(), "genBuffers");
1254 gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
1255 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
1256
1257 gl.bufferData(GL_ARRAY_BUFFER, vboData.size() * sizeof(GLfloat), (GLvoid *)vboData.data(), GL_DYNAMIC_DRAW);
1258 GLU_EXPECT_NO_ERROR(gl.getError(), "bufferData");
1259
1260 gl.useProgram(m_defaultProg->getProgram());
1261 GLU_EXPECT_NO_ERROR(gl.getError(), "useProgram");
1262
1263 // Setup shader attributes
1264 GLint attribPos = gl.getAttribLocation(m_defaultProg->getProgram(), "pos");
1265 GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation");
1266 CHECK_RET((attribPos != -1), true, getAttribLocation);
1267
1268 GLint attribUV = gl.getAttribLocation(m_defaultProg->getProgram(), "UV");
1269 GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation");
1270 CHECK_RET((attribUV != -1), true, getAttribLocation);
1271
1272 const GLsizei vertSize = (vboData.size() / 4) * sizeof(GLfloat);
1273 const GLsizei uvOffset = (4 * sizeof(GLfloat));
1274
1275 gl.vertexAttribPointer(attribPos, 4, GL_FLOAT, GL_FALSE, vertSize, nullptr);
1276 GLU_EXPECT_NO_ERROR(gl.getError(), "vertexAttribPointer");
1277 gl.enableVertexAttribArray(attribPos);
1278 GLU_EXPECT_NO_ERROR(gl.getError(), "enableVertexAttribArray");
1279
1280 gl.vertexAttribPointer(attribUV, 2, GL_FLOAT, GL_FALSE, vertSize, (const GLvoid *)uvOffset);
1281 GLU_EXPECT_NO_ERROR(gl.getError(), "vertexAttribPointer");
1282 gl.enableVertexAttribArray(attribUV);
1283 GLU_EXPECT_NO_ERROR(gl.getError(), "enableVertexAttribArray");
1284
1285 // Setup shader uniform
1286 GLint uniformTex = gl.getUniformLocation(m_defaultProg->getProgram(), "tex");
1287 GLU_EXPECT_NO_ERROR(gl.getError(), "getUniformLocation");
1288 CHECK_RET((uniformTex != -1), true, getUniformLocation);
1289 gl.uniform1i(uniformTex, 0);
1290 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
1291
1292 return result;
1293 }
1294
1295 /* Get the stencil value from the given coordinates. Return true if
1296 * succeed, false otherwise.
1297 */
getStencil(const Coord & coord,Stencil * stcil,const GLuint fbo,const GLuint internalFormat,const Rectangle & rect)1298 bool FramebufferBlitBaseTestCase::getStencil(const Coord &coord, Stencil *stcil, const GLuint fbo,
1299 const GLuint internalFormat, const Rectangle &rect)
1300 {
1301 bool result = true;
1302 GLuint status = 0;
1303 GLint x = coord.x(), y = coord.y();
1304
1305 if (!check_param(stcil != NULL, "invalid stcil pointer"))
1306 return false;
1307
1308 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1309 if (m_isContextES)
1310 {
1311 GLuint fbo_0 = 0, stencil_buf = 0, tex_0 = 0;
1312 GLint uColor = 0;
1313 const GLenum attachment_0 = GL_COLOR_ATTACHMENT0;
1314 GLubyte dataColor[4] = {50, 50, 50, 50};
1315
1316 {
1317 /* Blit to a stencil renderbuffer anyway to prevent buf is multisampled and to use this whole stencil renderbuffer for rendering */
1318 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1319 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1320
1321 gl.genFramebuffers(1, &fbo_0);
1322 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
1323 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_0);
1324 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1325
1326 gl.genRenderbuffers(1, &stencil_buf);
1327 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
1328 gl.bindRenderbuffer(GL_RENDERBUFFER, stencil_buf);
1329 GLU_EXPECT_NO_ERROR(gl.getError(), "bindRenderbuffer");
1330 gl.renderbufferStorage(GL_RENDERBUFFER, internalFormat, rect.w, rect.h);
1331 GLU_EXPECT_NO_ERROR(gl.getError(), "renderbufferStorage");
1332 gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buf);
1333 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
1334
1335 status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1336 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1337 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1338 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1339 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1340 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1341
1342 gl.blitFramebuffer(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h, 0, 0, rect.w, rect.h,
1343 GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1344 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
1345
1346 gl.deleteFramebuffers(1, &fbo_0);
1347 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
1348 }
1349
1350 gl.genFramebuffers(1, &fbo_0);
1351 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
1352 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_0);
1353 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1354
1355 gl.genTextures(1, &tex_0);
1356 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1357 gl.bindTexture(GL_TEXTURE_2D, tex_0);
1358 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
1359 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.w, rect.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1360 GLU_EXPECT_NO_ERROR(gl.getError(), "texImage2D");
1361 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_0, 0);
1362 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
1363 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buf);
1364 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
1365
1366 gl.drawBuffers(1, &attachment_0);
1367 GLU_EXPECT_NO_ERROR(gl.getError(), "drawBuffers");
1368 gl.readBuffer(attachment_0);
1369 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
1370 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1371 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1372
1373 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1374
1375 GLuint vao = 0, vbo = 0;
1376 if (!setupRenderShader(vao, vbo, &uColor))
1377 return false;
1378
1379 gl.viewport(0, 0, rect.w, rect.h);
1380 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
1381 gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
1382 GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
1383 gl.clear(GL_COLOR_BUFFER_BIT);
1384 GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1385
1386 gl.enable(GL_STENCIL_TEST);
1387 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
1388 gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1389 GLU_EXPECT_NO_ERROR(gl.getError(), "stencilOp");
1390 for (GLuint i = 0; i < 256; i++)
1391 {
1392 float v = i / 255.0f;
1393 gl.uniform4f(uColor, v, v, v, 1.0f);
1394 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform4f");
1395 gl.stencilFunc(GL_EQUAL, i, 0xFF);
1396 GLU_EXPECT_NO_ERROR(gl.getError(), "stencilFunc");
1397 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
1398 GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
1399 }
1400
1401 gl.disable(GL_STENCIL_TEST);
1402 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
1403 gl.readPixels(x - rect.x, y - rect.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dataColor);
1404 GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
1405
1406 // restore viewport
1407 gl.viewport(m_fullRect.x, m_fullRect.y, m_fullRect.w, m_fullRect.h);
1408 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
1409
1410 gl.deleteFramebuffers(1, &fbo_0);
1411 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
1412 gl.deleteRenderbuffers(1, &stencil_buf);
1413 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteRenderbuffers");
1414 gl.deleteTextures(1, &tex_0);
1415 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
1416
1417 gl.disableVertexAttribArray(0);
1418 GLU_EXPECT_NO_ERROR(gl.getError(), "disableVertexAttribArray");
1419
1420 if (vbo)
1421 {
1422 gl.deleteBuffers(1, &vbo);
1423 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteBuffers");
1424 }
1425
1426 if (vao)
1427 {
1428 gl.deleteVertexArrays(1, &vao);
1429 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
1430 }
1431
1432 *stcil = dataColor[0];
1433
1434 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1435 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1436 }
1437 else
1438 {
1439 GLuint tmp_stcil = 50;
1440
1441 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1442 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1443 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1444 gl.readPixels(x, y, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_INT, &tmp_stcil);
1445 GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
1446
1447 *stcil = tmp_stcil;
1448 }
1449
1450 m_testCtx.getLog() << tcu::TestLog::Message << "getStencil: XY[" << x << "," << y << "] STENCIL_INDEX[" << *stcil
1451 << "]" << tcu::TestLog::EndMessage;
1452
1453 return result;
1454 }
1455
1456 /* Verify the actual and the expected stencil match. Return true if
1457 * succeed, false otherwise.
1458 */
checkStencil(const Stencil actual,const Stencil expected)1459 bool FramebufferBlitBaseTestCase::checkStencil(const Stencil actual, const Stencil expected)
1460 {
1461 if (actual != expected)
1462 {
1463 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: expected STENCIL[" << expected << "] but got STENCIL["
1464 << actual << "]" << tcu::TestLog::EndMessage;
1465 return false;
1466 }
1467 return true;
1468 }
1469
1470 /* Clear the stencil buffer to given stencil. Prior to return, unbind
1471 * all used attachments and setup default read and draw framebuffers.
1472 * Return true if succeed, false otherwise.
1473 *
1474 * fbo: framebuffer to use
1475 * attachment: framebuffer attachment to attach buffer
1476 * type: buffer type
1477 * buf: stencilbuffer to be cleared
1478 * stcil: clear stcil
1479 * rect: region of stencilbuffer to be cleared
1480 * check_coord: coord to verify buffer value after clearing
1481 */
clearStencilBuffer(const GLuint fbo,const GLenum attachment,const GLenum type,const GLuint buf,const GLuint internalFormat,const Stencil stcil,const Rectangle & rect,const Coord & check_coord)1482 bool FramebufferBlitBaseTestCase::clearStencilBuffer(const GLuint fbo, const GLenum attachment, const GLenum type,
1483 const GLuint buf, const GLuint internalFormat, const Stencil stcil,
1484 const Rectangle &rect, const Coord &check_coord)
1485 {
1486 bool result = true;
1487 Stencil tmp_stcil = 50;
1488 GLint sample_buffers = 0;
1489
1490 if (!check_param(
1491 (type == 0 || type == GL_TEXTURE_2D || type == GL_TEXTURE_2D_MULTISAMPLE || type == GL_RENDERBUFFER),
1492 "invalid type"))
1493 return false;
1494
1495 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1496
1497 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1498 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1499 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
1500 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1501 if (fbo && (fbo != m_defaultFBO))
1502 {
1503 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, attachment, type, buf);
1504 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, type, buf);
1505 }
1506
1507 // clear stencil rectangle
1508 gl.scissor(rect.x, rect.y, rect.w, rect.h);
1509 GLU_EXPECT_NO_ERROR(gl.getError(), "scissor");
1510 gl.enable(GL_SCISSOR_TEST);
1511 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
1512
1513 GLuint status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1514 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
1515 CHECK_RET(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
1516
1517 gl.clearStencil(stcil);
1518 GLU_EXPECT_NO_ERROR(gl.getError(), "clearStencil");
1519
1520 m_testCtx.getLog() << tcu::TestLog::Message << "clearing stencil to [" << stcil << "]" << tcu::TestLog::EndMessage;
1521
1522 gl.clear(GL_STENCIL_BUFFER_BIT);
1523 GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1524 gl.disable(GL_SCISSOR_TEST);
1525 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
1526
1527 /* Verify the stencil in cleared stencil in case of single-sampled
1528 * buffers. Don't verify in case of multisampled buffer since
1529 * glReadPixels generates GL_INVALID_OPERATION if
1530 * GL_SAMPLE_BUFFERS is greater than zero. */
1531 gl.getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
1532 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
1533 if (sample_buffers == 0)
1534 {
1535 if (fbo && (fbo != m_defaultFBO))
1536 {
1537 m_testCtx.getLog() << tcu::TestLog::Message << "verifying initial "
1538 << ((type == GL_TEXTURE_2D) ? "tex" : "ren") << "buf" << buf << " stencil [" << stcil
1539 << "]" << tcu::TestLog::EndMessage;
1540 }
1541 else
1542 {
1543 m_testCtx.getLog() << tcu::TestLog::Message << "verifying initial dfltbuf stencil [" << stcil << "]"
1544 << tcu::TestLog::EndMessage;
1545 }
1546
1547 getStencil(check_coord, &tmp_stcil, fbo, internalFormat, rect);
1548 result = checkStencil(tmp_stcil, stcil);
1549 CHECK(result, true, checkStencil);
1550 }
1551 else
1552 {
1553 if (fbo && (fbo != m_defaultFBO))
1554 {
1555 m_testCtx.getLog() << tcu::TestLog::Message << "no verification of multisampled "
1556 << ((type == GL_RENDERBUFFER) ? "ren" : "tex") << "buf" << buf
1557 << tcu::TestLog::EndMessage;
1558 }
1559 else
1560 {
1561 m_testCtx.getLog() << tcu::TestLog::Message << "no verification of multisampled dfltbuf"
1562 << tcu::TestLog::EndMessage;
1563 }
1564 }
1565
1566 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultFBO);
1567 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1568 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_defaultFBO);
1569 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1570
1571 return result;
1572 }
1573
setupRenderShader(GLuint & vao,GLuint & vbo,GLint * uColor)1574 bool FramebufferBlitBaseTestCase::setupRenderShader(GLuint &vao, GLuint &vbo, GLint *uColor)
1575 {
1576 bool result = true;
1577
1578 // clang-format off
1579 const std::vector<GLfloat> vboData = {
1580 -1.0f, -1.0f, 0.0f, 1.0f,
1581 1.0f, -1.0f, 0.0f, 1.0f,
1582 -1.0f, 1.0f, 0.0f, 1.0f,
1583 1.0f, 1.0f, 0.0f, 1.0f,
1584 };
1585 // clang-format on
1586
1587 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1588
1589 gl.genVertexArrays(1, &vao);
1590 GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
1591 gl.bindVertexArray(vao);
1592 GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
1593
1594 gl.genBuffers(1, &vbo);
1595 GLU_EXPECT_NO_ERROR(gl.getError(), "genBuffers");
1596 gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
1597 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
1598
1599 gl.bufferData(GL_ARRAY_BUFFER, vboData.size() * sizeof(GLfloat), (GLvoid *)vboData.data(), GL_DYNAMIC_DRAW);
1600 GLU_EXPECT_NO_ERROR(gl.getError(), "bufferData");
1601
1602 // setup shader
1603 gl.useProgram(m_renderProg->getProgram());
1604 GLU_EXPECT_NO_ERROR(gl.getError(), "useProgram");
1605
1606 GLint attribPos = gl.getAttribLocation(m_renderProg->getProgram(), "pos");
1607 GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation");
1608 CHECK_RET((attribPos != -1), true, getAttribLocation);
1609
1610 gl.vertexAttribPointer(attribPos, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
1611 GLU_EXPECT_NO_ERROR(gl.getError(), "vertexAttribPointer");
1612
1613 // Setup shader attributes
1614 gl.enableVertexAttribArray(attribPos);
1615 GLU_EXPECT_NO_ERROR(gl.getError(), "enableVertexAttribArray");
1616
1617 // Setup shader uniform
1618 *uColor = gl.getUniformLocation(m_renderProg->getProgram(), "uColor");
1619 GLU_EXPECT_NO_ERROR(gl.getError(), "getUniformLocation");
1620 CHECK_RET((*uColor != -1), true, getUniformLocation);
1621 gl.uniform4f(*uColor, 1.0f, 1.0f, 1.0f, 1.0f);
1622 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform4f");
1623
1624 return result;
1625 }
1626
1627 /* print values in global variables
1628 */
printGlobalBufferInfo()1629 void FramebufferBlitBaseTestCase::printGlobalBufferInfo()
1630 {
1631 auto print_info = [&](GLuint h0, GLuint h1, const char *str)
1632 {
1633 m_testCtx.getLog() << tcu::TestLog::Message << "CONFIG: " << str << "[0]=" << h0 << ", " << str << "[1]=" << h1
1634 << tcu::TestLog::EndMessage;
1635 };
1636
1637 print_info(m_fbos[0], m_fbos[1], "fbos");
1638 print_info(m_color_tbos[0], m_color_tbos[1], "color_tbos");
1639 print_info(m_depth_tbos[0], m_depth_tbos[1], "depth_tbos");
1640 print_info(m_stcil_tbos[0], m_stcil_tbos[1], "stcil_tbos");
1641 print_info(m_color_rbos[0], m_color_rbos[1], "color_rbos");
1642 print_info(m_depth_rbos[0], m_depth_rbos[1], "depth_rbos");
1643 print_info(m_stcil_rbos[0], m_stcil_rbos[1], "stcil_rbos");
1644
1645 m_testCtx.getLog() << tcu::TestLog::Message
1646 << "\nCONFIG: depth_internalFormat=" << getEnumName(m_depth_internalFormat)
1647 << "\nCONFIG: stcil_internalFormat=" << getEnumName(m_stcil_internalFormat)
1648 << tcu::TestLog::EndMessage;
1649 }
1650
1651 /** Constructor.
1652 *
1653 * @param context Rendering context
1654 */
FramebufferBlitMultiToSingleSampledTestCase(deqp::Context & context)1655 FramebufferBlitMultiToSingleSampledTestCase::FramebufferBlitMultiToSingleSampledTestCase(deqp::Context &context)
1656 : FramebufferBlitBaseTestCase(
1657 context, "multisampled_to_singlesampled_blit",
1658 "Confirm that blits from multisampled to single sampled framebuffers of various types are properly resolved.")
1659 {
1660 }
1661
FramebufferBlitMultiToSingleSampledTestCase(deqp::Context & context,const char * name,const char * desc)1662 FramebufferBlitMultiToSingleSampledTestCase::FramebufferBlitMultiToSingleSampledTestCase(deqp::Context &context,
1663 const char *name,
1664 const char *desc)
1665 : FramebufferBlitBaseTestCase(context, name, desc)
1666 {
1667 }
1668
1669 /** Stub deinit method. */
deinit()1670 void FramebufferBlitMultiToSingleSampledTestCase::deinit()
1671 {
1672 FramebufferBlitBaseTestCase::deinit();
1673 }
1674
1675 /** Stub init method */
init()1676 void FramebufferBlitMultiToSingleSampledTestCase::init()
1677 {
1678 FramebufferBlitBaseTestCase::init();
1679
1680 // clang-format off
1681 /* buffer configs used in functionality tests */
1682 m_multisampleColorCfg = {
1683 /* internal format, format, type, color channel bits */
1684 { GL_R8, GL_RED, GL_UNSIGNED_BYTE, RED_CHANNEL, false },
1685 { GL_RG8, GL_RG, GL_UNSIGNED_BYTE, RED_CHANNEL|GREEN_CHANNEL, false },
1686 { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RED_CHANNEL|GREEN_CHANNEL|BLUE_CHANNEL|ALPHA_CHANNEL, false },
1687 { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, RED_CHANNEL|GREEN_CHANNEL|BLUE_CHANNEL|ALPHA_CHANNEL, false },
1688 { GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, RED_CHANNEL|GREEN_CHANNEL|BLUE_CHANNEL|ALPHA_CHANNEL, false },
1689 { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, RED_CHANNEL|GREEN_CHANNEL|BLUE_CHANNEL|ALPHA_CHANNEL, false },
1690 { GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, RED_CHANNEL|GREEN_CHANNEL|BLUE_CHANNEL, true },
1691 { GL_RG16F, GL_RG, GL_HALF_FLOAT, RED_CHANNEL|GREEN_CHANNEL, true },
1692 { GL_R16F, GL_RED, GL_HALF_FLOAT, RED_CHANNEL, true },
1693 { GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, RED_CHANNEL|GREEN_CHANNEL|BLUE_CHANNEL, false }, /* Texture only format */
1694 };
1695
1696 if (!m_isContextES)
1697 {
1698 m_multisampleColorCfg.push_back({ GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_10_10_10_2,
1699 RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL | ALPHA_CHANNEL, false });
1700 }
1701 else
1702 {
1703 m_multisampleColorCfg.push_back({ GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
1704 RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL | ALPHA_CHANNEL, false });
1705 m_multisampleColorCfg.push_back(
1706 { GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL, false });
1707 }
1708 // clang-format on
1709 }
1710
FramebufferBlitMultiToSingleSampledColorConfigTestCase(deqp::Context & context)1711 FramebufferBlitMultiToSingleSampledColorConfigTestCase::FramebufferBlitMultiToSingleSampledColorConfigTestCase(
1712 deqp::Context &context)
1713 : FramebufferBlitMultiToSingleSampledTestCase(context, "multisampled_to_singlesampled_blit_color_config_test",
1714 "Confirm that blits from multisampled to single sampled framebuffers "
1715 "of various types are properly resolved using color config.")
1716 {
1717 }
1718
1719 /** Executes color configuration framebuffer blit tests.
1720 *
1721 * @return Returns false if test went wrong.
1722 */
1723 template <GLuint samples>
testColorBlitConfig(const tcu::IVec2 & ul_center,const tcu::IVec2 & ur_center,const tcu::IVec2 & ll_center,const tcu::IVec2 & lr_center,const glw::GLint max_color_attachments)1724 bool FramebufferBlitMultiToSingleSampledColorConfigTestCase::testColorBlitConfig(const tcu::IVec2 &ul_center,
1725 const tcu::IVec2 &ur_center,
1726 const tcu::IVec2 &ll_center,
1727 const tcu::IVec2 &lr_center,
1728 const glw::GLint max_color_attachments)
1729 {
1730 bool result = true;
1731 GLint status = 0;
1732 tcu::Vec4 tmp_color(0.0f, 0.0f, 0.0f, 0.0f);
1733 /* default color for multicolor pattern */
1734 tcu::Vec4 ul_color = RED, ur_color = GREEN, ll_color = BLUE, lr_color = WHITE;
1735 GLuint bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1736 GLuint filter = GL_NEAREST;
1737
1738 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1739 /* test buffer combinations (texture to texture, texture to
1740 * renderbuffer, etc.) */
1741 for (GLuint i = 0; i < m_bufferCfg.size(); i++)
1742 {
1743 /* test color attachments */
1744 for (GLint j = 0; j < max_color_attachments; j++)
1745 {
1746 /* test color formats */
1747 for (GLuint k = 0; k < m_multisampleColorCfg.size(); k++)
1748 {
1749 const GLenum &attachment = GL_COLOR_ATTACHMENT0 + j;
1750 const BufferConfig &buf_config = m_bufferCfg[i];
1751 const MultisampleColorConfig &color_config = m_multisampleColorCfg[k];
1752
1753 if (m_isContextES)
1754 {
1755 /* If the format is FP, skip if the extension is not present */
1756 if (color_config.bIsFloat && !m_cbfTestSupported)
1757 {
1758 continue;
1759 }
1760 }
1761
1762 // Check default framebuffer
1763 if ((buf_config.src_type == 0) || (buf_config.dst_type == 0))
1764 {
1765 GLint sample_buffers = 0;
1766 GLint red_bits = 0, green_bits = 0, blue_bits = 0, alpha_bits = 0;
1767
1768 gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
1769 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
1770 gl.getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
1771 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
1772
1773 // Skip if default is used as src but not multisampled
1774 // or if default is used as dst but multisampled
1775 if (((buf_config.src_type == 0) && (sample_buffers == 0)) ||
1776 ((buf_config.dst_type == 0) && (sample_buffers != 0)))
1777 {
1778 continue;
1779 }
1780
1781 if (m_isContextES)
1782 {
1783 // check if default framebuffer supports GL_SRGB encoding
1784 if (GL_SRGB8_ALPHA8 == color_config.internal_format)
1785 {
1786 int encoding = GL_NONE;
1787
1788 gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER,
1789 m_defaultFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK,
1790 GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding);
1791 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1792
1793 if (GL_SRGB != encoding)
1794 {
1795 continue;
1796 }
1797 }
1798
1799 {
1800 // Multisample color format and type must match that of the default framebuffer when blitting
1801 GLint format = 0;
1802 // framebuffer_blit_functionality_multisampled_to_singlesampled_blit was attempting to
1803 // match the format and type of a framebuffer by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and
1804 // GL_IMPLEMENTATION_COLOR_READ_TYPE, which could return anything the implementation
1805 // chooses, not necessarily the actual format and type of the framebuffer.
1806 // Currently there is no api to determine format and type of the default (EGL) framebuffer id 0
1807 if (m_defaultFBO)
1808 {
1809 // defaultFBO is bound to both read and draw framebuffers, so there is no need to specify.
1810 GLint object_type = 0;
1811
1812 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1813 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
1814 &object_type);
1815 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1816 if (object_type == GL_RENDERBUFFER)
1817 {
1818 GLint renderbuffer = 0;
1819 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1820 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
1821 &renderbuffer);
1822 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1823 gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
1824 GLU_EXPECT_NO_ERROR(gl.getError(), "bindRenderbuffer");
1825 gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT,
1826 &format);
1827 GLU_EXPECT_NO_ERROR(gl.getError(), "getRenderbufferParameteriv");
1828 if (color_config.internal_format != format)
1829 {
1830 continue;
1831 }
1832 }
1833 else
1834 {
1835
1836 m_testCtx.getLog() << tcu::TestLog::Message
1837 << "Could not read default FBO type and format because color "
1838 "attachment 0 is not a renderbuffer."
1839 << tcu::TestLog::EndMessage;
1840 continue;
1841 }
1842 }
1843 else
1844 {
1845 m_testCtx.getLog() << tcu::TestLog::Message
1846 << "Could not read default FBO type and format because FBO ID is 0."
1847 << tcu::TestLog::EndMessage;
1848 continue;
1849 }
1850 }
1851
1852 // Check that the default framebuffer has all the channels we will need.
1853 gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER,
1854 m_defaultFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK,
1855 GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &red_bits);
1856 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1857
1858 gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER,
1859 m_defaultFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK,
1860 GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, &green_bits);
1861 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1862 gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER,
1863 m_defaultFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK,
1864 GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, &blue_bits);
1865 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1866 gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER,
1867 m_defaultFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK,
1868 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
1869 GLU_EXPECT_NO_ERROR(gl.getError(), "getFramebufferAttachmentParameteriv");
1870
1871 if (((color_config.color_channel_bits & RED_CHANNEL) && red_bits == 0) ||
1872 ((color_config.color_channel_bits & GREEN_CHANNEL) && green_bits == 0) ||
1873 ((color_config.color_channel_bits & BLUE_CHANNEL) && blue_bits == 0) ||
1874 ((color_config.color_channel_bits & ALPHA_CHANNEL) && alpha_bits == 0))
1875 {
1876 m_testCtx.getLog()
1877 << tcu::TestLog::Message << "Required channel for "
1878 << getEnumName(color_config.internal_format)
1879 << " not present in default framebuffer. Skipping." << tcu::TestLog::EndMessage;
1880 continue;
1881 }
1882 }
1883 }
1884
1885 /* skip the configs where same buffer is used as a
1886 * read and draw buffer (different samplings) */
1887 if (buf_config.same_read_and_draw_buffer)
1888 continue;
1889
1890 if (m_isContextES)
1891 {
1892 /* ES3.0 does not support multi-sample texture */
1893 if (!m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
1894 {
1895 continue;
1896 }
1897 }
1898
1899 m_testCtx.getLog() << tcu::TestLog::Message
1900 << "BEGIN ------------------------------------------------------------------"
1901 << "BLITTING in " << getEnumName(attachment) << " from "
1902 << ((!buf_config.src_type) ? getEnumName(DEFAULT) : getEnumName(buf_config.src_type))
1903 << " to "
1904 << ((!buf_config.dst_type) ? getEnumName(DEFAULT) : getEnumName(buf_config.dst_type))
1905 << "[" << getEnumName(color_config.internal_format) << "] buffers"
1906 << tcu::TestLog::EndMessage;
1907
1908 if (!m_isContextES)
1909 {
1910 gl.enable(GL_MULTISAMPLE);
1911 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
1912 }
1913
1914 gl.genFramebuffers(2, m_fbos);
1915 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
1916
1917 gl.genTextures(2, m_color_tbos);
1918 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1919
1920 /* init multisampled texture for reading and
1921 * single-sampled texture for drawing */
1922 if (m_msTbosSupported)
1923 result &= init_gl_objs<GL_TEXTURE_2D_MULTISAMPLE, samples>(gl.bindTexture, 1, &m_color_tbos[0],
1924 color_config.internal_format);
1925
1926 result &=
1927 init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, &m_color_tbos[1], color_config.internal_format);
1928
1929 gl.genRenderbuffers(2, m_color_rbos);
1930 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
1931
1932 result &= init_gl_objs<GL_RENDERBUFFER, samples>(gl.bindRenderbuffer, 1, &m_color_rbos[0],
1933 color_config.internal_format);
1934
1935 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, &m_color_rbos[1],
1936 color_config.internal_format);
1937
1938 /* multicolor pattern to the source */
1939 if (m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
1940 {
1941 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1942 m_color_tbos[0], ul_color, m_setup.ul_rect, ul_center,
1943 color_config.color_channel_bits, color_config.bIsFloat);
1944 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1945 m_color_tbos[0], ur_color, m_setup.ur_rect, ur_center,
1946 color_config.color_channel_bits, color_config.bIsFloat);
1947 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1948 m_color_tbos[0], ll_color, m_setup.ll_rect, ll_center,
1949 color_config.color_channel_bits, color_config.bIsFloat);
1950 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1951 m_color_tbos[0], lr_color, m_setup.lr_rect, lr_center,
1952 color_config.color_channel_bits, color_config.bIsFloat);
1953 }
1954 else if (buf_config.src_type == GL_RENDERBUFFER)
1955 {
1956 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rbos[0],
1957 ul_color, m_setup.ul_rect, ul_center, color_config.color_channel_bits,
1958 color_config.bIsFloat);
1959 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rbos[0],
1960 ur_color, m_setup.ur_rect, ur_center, color_config.color_channel_bits,
1961 color_config.bIsFloat);
1962 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rbos[0],
1963 ll_color, m_setup.ll_rect, ll_center, color_config.color_channel_bits,
1964 color_config.bIsFloat);
1965 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rbos[0],
1966 lr_color, m_setup.lr_rect, lr_center, color_config.color_channel_bits,
1967 color_config.bIsFloat);
1968 }
1969 else
1970 {
1971 result &=
1972 clearColorBuffer(m_defaultFBO, GL_NONE, 0, 0, ul_color, m_setup.ul_rect, ul_center,
1973 color_config.color_channel_bits, color_config.bIsFloat); /* default buffer */
1974 result &=
1975 clearColorBuffer(m_defaultFBO, GL_NONE, 0, 0, ur_color, m_setup.ur_rect, ur_center,
1976 color_config.color_channel_bits, color_config.bIsFloat); /* default buffer */
1977 result &=
1978 clearColorBuffer(m_defaultFBO, GL_NONE, 0, 0, ll_color, m_setup.ll_rect, ll_center,
1979 color_config.color_channel_bits, color_config.bIsFloat); /* default buffer */
1980 result &=
1981 clearColorBuffer(m_defaultFBO, GL_NONE, 0, 0, lr_color, m_setup.lr_rect, lr_center,
1982 color_config.color_channel_bits, color_config.bIsFloat); /* default buffer */
1983 }
1984
1985 /* initial destination color to the destination */
1986 if (buf_config.dst_type == GL_TEXTURE_2D)
1987 {
1988 result &= clearColorBuffer(m_fbos[1], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_tbos[1],
1989 DST_COLOR, m_fullRect, m_defaultCoord, color_config.color_channel_bits,
1990 color_config.bIsFloat);
1991 }
1992 else if (buf_config.dst_type == GL_RENDERBUFFER)
1993 {
1994 result &= clearColorBuffer(m_fbos[1], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rbos[1],
1995 DST_COLOR, m_fullRect, m_defaultCoord, color_config.color_channel_bits,
1996 color_config.bIsFloat);
1997 }
1998 else
1999 {
2000 result &= clearColorBuffer(m_defaultFBO, GL_NONE, 0, 0, DST_COLOR, m_fullRect, m_defaultCoord,
2001 color_config.color_channel_bits, color_config.bIsFloat);
2002 }
2003
2004 printGlobalBufferInfo();
2005
2006 /* bind framebuffer objects */
2007 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, buf_config.src_type == 0 ? m_defaultFBO : *buf_config.src_fbo);
2008 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2009
2010 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo);
2011 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2012
2013 /* attach color buffers */
2014 if (m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
2015 {
2016 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE,
2017 *buf_config.src_cbuf);
2018 }
2019 else
2020 {
2021 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, buf_config.src_type,
2022 *buf_config.src_cbuf);
2023 }
2024 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, attachment, buf_config.dst_type,
2025 *buf_config.dst_cbuf);
2026
2027 if (buf_config.src_type != 0)
2028 {
2029 gl.readBuffer(attachment);
2030 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
2031 }
2032
2033 if (buf_config.dst_type != 0)
2034 {
2035 if (m_isContextES)
2036 {
2037 std::vector<GLenum> draw_attachments(max_color_attachments, GL_NONE);
2038 draw_attachments[j] = attachment;
2039 gl.drawBuffers(j + 1, draw_attachments.data());
2040 }
2041 else
2042 {
2043 gl.drawBuffers(1, &attachment);
2044 }
2045 GLU_EXPECT_NO_ERROR(gl.getError(), "drawBuffers");
2046 }
2047
2048 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
2049 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
2050 CHECK_CONTINUE(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
2051 status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
2052 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
2053 CHECK_CONTINUE(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
2054
2055 m_testCtx.getLog() << tcu::TestLog::Message
2056 << "BLIT -------------------------------------------------------------------"
2057 << "BLIT SRC_RECT=[" << m_setup.blt_src_rect.x << "," << m_setup.blt_src_rect.y
2058 << "," << m_setup.blt_src_rect.w << "," << m_setup.blt_src_rect.h << "] DST_RECT=["
2059 << m_setup.blt_dst_rect.x << "," << m_setup.blt_dst_rect.y << ","
2060 << m_setup.blt_dst_rect.w << "," << m_setup.blt_dst_rect.h << "]"
2061 << tcu::TestLog::EndMessage;
2062
2063 /* blit */
2064 gl.blitFramebuffer(m_setup.blt_src_rect.x, m_setup.blt_src_rect.y,
2065 m_setup.blt_src_rect.x + m_setup.blt_src_rect.w,
2066 m_setup.blt_src_rect.y + m_setup.blt_src_rect.h, m_setup.blt_dst_rect.x,
2067 m_setup.blt_dst_rect.y, m_setup.blt_dst_rect.x + m_setup.blt_dst_rect.w,
2068 m_setup.blt_dst_rect.y + m_setup.blt_dst_rect.h, bits, filter);
2069 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
2070
2071 /* bind dst_fbo to GL_READ_FRAMEBUFFER */
2072 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo);
2073 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2074
2075 /* setup the read color buffer again if the destination
2076 * buffer is an user fbo */
2077 if (buf_config.dst_type != 0)
2078 {
2079 gl.readBuffer(attachment);
2080 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
2081 }
2082
2083 std::ostringstream sstr;
2084 sstr << "BITS [" << std::hex << color_config.color_channel_bits << "]=["
2085 << getEnumName(color_config.color_channel_bits) << "]";
2086 m_testCtx.getLog() << tcu::TestLog::Message << sstr.str() << tcu::TestLog::EndMessage;
2087
2088 /* read and verify color values */
2089 getColor(m_setup.ul_coord, &tmp_color, color_config.bIsFloat);
2090 result &= checkColor(tmp_color, ul_color, color_config.color_channel_bits);
2091 CHECK_COLOR(result, true, checkColor);
2092
2093 getColor(m_setup.ur_coord, &tmp_color, color_config.bIsFloat);
2094 result &= checkColor(tmp_color, ur_color, color_config.color_channel_bits);
2095 CHECK_COLOR(result, true, checkColor);
2096
2097 getColor(m_setup.ll_coord, &tmp_color, color_config.bIsFloat);
2098 result &= checkColor(tmp_color, ll_color, color_config.color_channel_bits);
2099 CHECK_COLOR(result, true, checkColor);
2100
2101 getColor(m_setup.lr_coord, &tmp_color, color_config.bIsFloat);
2102 result &= checkColor(tmp_color, lr_color, color_config.color_channel_bits);
2103 CHECK_COLOR(result, true, checkColor);
2104
2105 gl.deleteTextures(2, m_color_tbos);
2106 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
2107
2108 m_color_tbos[0] = 0;
2109 m_color_tbos[1] = 0;
2110 gl.deleteRenderbuffers(2, m_color_rbos);
2111 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteRenderbuffers");
2112
2113 m_color_rbos[0] = 0;
2114 m_color_rbos[1] = 0;
2115 gl.deleteFramebuffers(2, m_fbos);
2116 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
2117
2118 m_fbos[0] = 0;
2119 m_fbos[1] = 0;
2120
2121 if (!m_isContextES)
2122 {
2123 gl.disable(GL_MULTISAMPLE);
2124 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
2125 }
2126
2127 m_testCtx.getLog() << tcu::TestLog::Message
2128 << "END --------------------------------------------------------------------"
2129 << tcu::TestLog::EndMessage;
2130 }
2131 }
2132 }
2133 return result;
2134 }
2135
FramebufferBlitMultiToSingleSampledDepthConfigTestCase(deqp::Context & context)2136 FramebufferBlitMultiToSingleSampledDepthConfigTestCase::FramebufferBlitMultiToSingleSampledDepthConfigTestCase(
2137 deqp::Context &context)
2138 : FramebufferBlitMultiToSingleSampledTestCase(context, "multisampled_to_singlesampled_blit_depth_config_test",
2139 "Confirm that blits from multisampled to single sampled framebuffers "
2140 "of various types are properly resolved using depth config.")
2141 {
2142 }
2143
2144 /** Executes depth configuration framebuffer blit tests.
2145 *
2146 * @return Returns false if test went wrong.
2147 */
2148 template <GLuint samples>
testDepthBlitConfig(const tcu::IVec2 & ul_center,const tcu::IVec2 & ur_center,const tcu::IVec2 & ll_center,const tcu::IVec2 & lr_center)2149 bool FramebufferBlitMultiToSingleSampledDepthConfigTestCase::testDepthBlitConfig(const tcu::IVec2 &ul_center,
2150 const tcu::IVec2 &ur_center,
2151 const tcu::IVec2 &ll_center,
2152 const tcu::IVec2 &lr_center)
2153 {
2154 bool result = true;
2155 GLint status = 0;
2156 GLfloat tmp_depth = 0.0f;
2157 /* default depth for multicolor pattern */
2158 GLfloat ul_depth = Q1, ur_depth = Q2, ll_depth = Q3, lr_depth = Q4;
2159 /* default stcil for multicolor pattern */
2160 GLuint ul_stcil = ONE, ur_stcil = TWO, ll_stcil = THREE, lr_stcil = FOUR;
2161 GLuint bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
2162 GLuint filter = GL_NEAREST;
2163
2164 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2165
2166 auto get_blit_epsilon = [](const GLuint srcPreBits, const GLuint resultPreBits, const GLuint dstPreBits)
2167 {
2168 GLuint tolerance = std::min(srcPreBits, std::min(resultPreBits, dstPreBits));
2169 tolerance = std::min(tolerance, GLuint(23)); // don't exceed the amount of mantissa bits in a float
2170 return (GLfloat)1.0 / (1 << tolerance);
2171 };
2172
2173 /* test buffer combinations (texture to texture, texture to
2174 * renderbuffer, etc.) */
2175 for (GLuint i = 0; i < m_bufferCfg.size(); i++)
2176 {
2177 /* test depth formats */
2178 for (GLuint j = 0; j < m_depthCfg.size(); j++)
2179 {
2180 BufferConfig buf_config = m_bufferCfg[i];
2181 DepthConfig depth_config = m_depthCfg[j];
2182
2183 // Check default framebuffer
2184 if ((buf_config.src_type == 0) || (buf_config.dst_type == 0))
2185 {
2186 GLint sample_buffers = 0;
2187 gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2188 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2189
2190 gl.getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
2191 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
2192
2193 // Skip if default is used as src but not multisampled
2194 // or if default is used as dst but multisampled
2195 if (((buf_config.src_type == 0) && (sample_buffers == 0)) ||
2196 ((buf_config.dst_type == 0) && (sample_buffers != 0)))
2197 {
2198 continue;
2199 }
2200
2201 {
2202 // Check format
2203 bool noDefaultDepth, noDefaultStcil;
2204
2205 if (!GetDefaultFramebufferBlitFormat(&noDefaultDepth, &noDefaultStcil))
2206 {
2207 continue;
2208 }
2209
2210 if (noDefaultDepth || (depth_config.internal_format != m_depth_internalFormat))
2211 {
2212 continue;
2213 }
2214 }
2215 }
2216
2217 /* skip the configs where same buffer is used as a
2218 * read and draw buffer (different samplings) */
2219 if (buf_config.same_read_and_draw_buffer)
2220 continue;
2221
2222 if (m_isContextES)
2223 {
2224 /* ES3.0 does not support multi-sample texture */
2225 if (!m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
2226 {
2227 continue;
2228 }
2229 }
2230
2231 m_testCtx.getLog() << tcu::TestLog::Message
2232 << "BEGIN ------------------------------------------------------------------"
2233 << "[" << getEnumName(depth_config.internal_format) << "] buffers"
2234 << tcu::TestLog::EndMessage;
2235
2236 if (!m_isContextES)
2237 {
2238 gl.enable(GL_MULTISAMPLE);
2239 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
2240 }
2241
2242 gl.genFramebuffers(2, m_fbos);
2243 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
2244
2245 gl.genTextures(2, m_depth_tbos);
2246 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2247
2248 /* init multisampled texture for reading and
2249 * single-sampled texture for drawing */
2250 if (m_msTbosSupported)
2251 result &= init_gl_objs<GL_TEXTURE_2D_MULTISAMPLE, samples>(gl.bindTexture, 1, &m_depth_tbos[0],
2252 depth_config.internal_format);
2253
2254 result &= init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, &m_depth_tbos[1], depth_config.internal_format);
2255
2256 gl.genRenderbuffers(2, m_depth_rbos);
2257 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
2258
2259 result &= init_gl_objs<GL_RENDERBUFFER, samples>(gl.bindRenderbuffer, 1, &m_depth_rbos[0],
2260 depth_config.internal_format);
2261
2262 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, &m_depth_rbos[1],
2263 depth_config.internal_format);
2264
2265 /* prepare depth-only buffers */
2266
2267 /* multicolor pattern to the source texture */
2268 if (m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
2269 {
2270 result &=
2271 clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE, m_depth_tbos[0],
2272 depth_config.internal_format, ul_depth, m_setup.ul_rect, ul_center);
2273 result &=
2274 clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE, m_depth_tbos[0],
2275 depth_config.internal_format, ur_depth, m_setup.ur_rect, ur_center);
2276 result &=
2277 clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE, m_depth_tbos[0],
2278 depth_config.internal_format, ll_depth, m_setup.ll_rect, ll_center);
2279 result &=
2280 clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE, m_depth_tbos[0],
2281 depth_config.internal_format, lr_depth, m_setup.lr_rect, lr_center);
2282 }
2283 else if (buf_config.src_type == GL_RENDERBUFFER)
2284 {
2285 result &= clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2286 depth_config.internal_format, ul_depth, m_setup.ul_rect, ul_center);
2287 result &= clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2288 depth_config.internal_format, ur_depth, m_setup.ur_rect, ur_center);
2289 result &= clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2290 depth_config.internal_format, ll_depth, m_setup.ll_rect, ll_center);
2291 result &= clearDepthBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2292 depth_config.internal_format, lr_depth, m_setup.lr_rect, lr_center);
2293 }
2294 else
2295 {
2296 /* multicolor pattern to the default buffer */
2297 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, ul_depth,
2298 m_setup.ul_rect, ul_center); /* default buffer */
2299 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, ur_depth,
2300 m_setup.ur_rect, ur_center); /* default buffer */
2301 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, ll_depth,
2302 m_setup.ll_rect, ll_center); /* default buffer */
2303 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, lr_depth,
2304 m_setup.lr_rect, lr_center); /* default buffer */
2305 }
2306
2307 /* initial destination depth to the destination */
2308 if (buf_config.dst_type == GL_TEXTURE_2D)
2309 {
2310 result &= clearDepthBuffer(m_fbos[1], depth_config.attachment, GL_TEXTURE_2D, m_depth_tbos[1],
2311 depth_config.internal_format, DST_DEPTH, m_fullRect, m_defaultCoord);
2312 }
2313 else if (buf_config.dst_type == GL_RENDERBUFFER)
2314 {
2315 result &= clearDepthBuffer(m_fbos[1], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[1],
2316 depth_config.internal_format, DST_DEPTH, m_fullRect, m_defaultCoord);
2317 }
2318 else
2319 {
2320 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, DST_DEPTH, m_fullRect,
2321 m_defaultCoord);
2322 }
2323
2324 /* prepare depth-stencil buffers */
2325 if (depth_config.attachment == GL_DEPTH_STENCIL_ATTACHMENT)
2326 {
2327 if (m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
2328 {
2329 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE,
2330 m_depth_tbos[0], depth_config.internal_format, ul_stcil,
2331 m_setup.ul_rect, ul_center);
2332 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE,
2333 m_depth_tbos[0], depth_config.internal_format, ur_stcil,
2334 m_setup.ur_rect, ur_center);
2335 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE,
2336 m_depth_tbos[0], depth_config.internal_format, ll_stcil,
2337 m_setup.ll_rect, ll_center);
2338 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_TEXTURE_2D_MULTISAMPLE,
2339 m_depth_tbos[0], depth_config.internal_format, lr_stcil,
2340 m_setup.lr_rect, lr_center);
2341 }
2342 else if (buf_config.src_type == GL_RENDERBUFFER)
2343 {
2344 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2345 depth_config.internal_format, ul_stcil, m_setup.ul_rect, ul_center);
2346 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2347 depth_config.internal_format, ur_stcil, m_setup.ur_rect, ur_center);
2348 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2349 depth_config.internal_format, ll_stcil, m_setup.ll_rect, ll_center);
2350 result &= clearStencilBuffer(m_fbos[0], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[0],
2351 depth_config.internal_format, lr_stcil, m_setup.lr_rect, lr_center);
2352 }
2353 else
2354 {
2355 /* multicolor pattern to the default buffer */
2356 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, ul_stcil,
2357 m_setup.ul_rect, ul_center);
2358 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, ur_stcil,
2359 m_setup.ur_rect, ur_center);
2360 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, ll_stcil,
2361 m_setup.ll_rect, ll_center);
2362 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, lr_stcil,
2363 m_setup.lr_rect, lr_center);
2364 }
2365
2366 /* initial destination stencil to the destination texture */
2367 if (buf_config.dst_type == GL_TEXTURE_2D)
2368 {
2369 result &= clearStencilBuffer(m_fbos[1], depth_config.attachment, GL_TEXTURE_2D, m_depth_tbos[1],
2370 depth_config.internal_format, DST_STCIL, m_fullRect, m_defaultCoord);
2371 }
2372 else if (buf_config.dst_type == GL_RENDERBUFFER)
2373 {
2374 result &= clearStencilBuffer(m_fbos[1], depth_config.attachment, GL_RENDERBUFFER, m_depth_rbos[1],
2375 depth_config.internal_format, DST_STCIL, m_fullRect, m_defaultCoord);
2376 }
2377 else
2378 {
2379 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, depth_config.internal_format, DST_STCIL,
2380 m_fullRect, m_defaultCoord);
2381 }
2382 }
2383
2384 printGlobalBufferInfo();
2385
2386 /* bind and attach */
2387 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, buf_config.src_type == 0 ? m_defaultFBO : *buf_config.src_fbo);
2388 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2389 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo);
2390 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2391
2392 if (m_msTbosSupported && buf_config.src_type == GL_TEXTURE_2D)
2393 {
2394 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, depth_config.attachment,
2395 GL_TEXTURE_2D_MULTISAMPLE, *buf_config.src_dbuf);
2396 }
2397 else
2398 {
2399 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, depth_config.attachment, buf_config.src_type,
2400 *buf_config.src_dbuf);
2401 }
2402 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, depth_config.attachment, buf_config.dst_type,
2403 *buf_config.dst_dbuf);
2404
2405 /* check status */
2406 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
2407 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
2408 CHECK_CONTINUE(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
2409 status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
2410 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
2411 CHECK_CONTINUE(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
2412
2413 m_testCtx.getLog() << tcu::TestLog::Message << "BLITTING in " << getEnumName(depth_config.attachment)
2414 << " from "
2415 << ((!buf_config.src_type) ? getEnumName(DEFAULT) : getEnumName(buf_config.src_type))
2416 << " to "
2417 << ((!buf_config.dst_type) ? getEnumName(DEFAULT) : getEnumName(buf_config.dst_type))
2418 << tcu::TestLog::EndMessage;
2419
2420 m_testCtx.getLog() << tcu::TestLog::Message
2421 << "BLIT -------------------------------------------------------------------"
2422 << tcu::TestLog::EndMessage;
2423
2424 m_testCtx.getLog() << tcu::TestLog::Message << "BLIT SRC_RECT=[" << m_setup.blt_src_rect.x << ","
2425 << m_setup.blt_src_rect.y << "," << m_setup.blt_src_rect.x + m_setup.blt_src_rect.w
2426 << "," << m_setup.blt_src_rect.y + m_setup.blt_src_rect.h << "] DST_RECT=["
2427 << m_setup.blt_dst_rect.x << "," << m_setup.blt_dst_rect.y << ","
2428 << m_setup.blt_dst_rect.x + m_setup.blt_dst_rect.w << ","
2429 << m_setup.blt_dst_rect.y + m_setup.blt_dst_rect.h << "]" << tcu::TestLog::EndMessage;
2430
2431 /* blit */
2432 gl.blitFramebuffer(m_setup.blt_src_rect.x, m_setup.blt_src_rect.y,
2433 m_setup.blt_src_rect.x + m_setup.blt_src_rect.w,
2434 m_setup.blt_src_rect.y + m_setup.blt_src_rect.h, m_setup.blt_dst_rect.x,
2435 m_setup.blt_dst_rect.y, m_setup.blt_dst_rect.x + m_setup.blt_dst_rect.w,
2436 m_setup.blt_dst_rect.y + m_setup.blt_dst_rect.h, bits, filter);
2437 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
2438
2439 /* bind destination framebuffer for reading */
2440 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo);
2441 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2442
2443 /* read and verify depth values */
2444 {
2445 GLuint resultPreBits = 0;
2446 GLint srcPreBits = 0, dstPreBits = 0;
2447 GLfloat epsilon = 0.f;
2448
2449 if (buf_config.src_type)
2450 srcPreBits = GetDepthPrecisionBits(depth_config.internal_format);
2451 else
2452 getBits(gl, m_isContextES, GL_READ_FRAMEBUFFER, GL_DEPTH_BITS, &srcPreBits);
2453
2454 if (buf_config.dst_type)
2455 dstPreBits = GetDepthPrecisionBits(depth_config.internal_format);
2456 else
2457 getBits(gl, m_isContextES, GL_READ_FRAMEBUFFER, GL_DEPTH_BITS, &dstPreBits);
2458
2459 getDepth(m_setup.ul_coord, &tmp_depth, &resultPreBits,
2460 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, depth_config.internal_format,
2461 m_setup.ul_rect);
2462 epsilon = get_blit_epsilon(srcPreBits, resultPreBits, dstPreBits);
2463 result &= checkDepth(tmp_depth, ul_depth, epsilon);
2464 CHECK_COLOR(result, true, checkDepth);
2465
2466 getDepth(m_setup.ur_coord, &tmp_depth, &resultPreBits,
2467 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, depth_config.internal_format,
2468 m_setup.ur_rect);
2469 epsilon = get_blit_epsilon(srcPreBits, resultPreBits, dstPreBits);
2470 result &= checkDepth(tmp_depth, ur_depth, epsilon);
2471 CHECK_COLOR(result, true, checkDepth);
2472
2473 getDepth(m_setup.ll_coord, &tmp_depth, &resultPreBits,
2474 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, depth_config.internal_format,
2475 m_setup.ll_rect);
2476 epsilon = get_blit_epsilon(srcPreBits, resultPreBits, dstPreBits);
2477 result &= checkDepth(tmp_depth, ll_depth, epsilon);
2478 CHECK_COLOR(result, true, checkDepth);
2479
2480 getDepth(m_setup.lr_coord, &tmp_depth, &resultPreBits,
2481 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, depth_config.internal_format,
2482 m_setup.lr_rect);
2483 epsilon = get_blit_epsilon(srcPreBits, resultPreBits, dstPreBits);
2484 result &= checkDepth(tmp_depth, lr_depth, epsilon);
2485 CHECK_COLOR(result, true, checkDepth);
2486 }
2487
2488 /* read and verify stencil values */
2489 if (depth_config.attachment == GL_DEPTH_STENCIL_ATTACHMENT)
2490 {
2491 Stencil tmp_stcil = 0;
2492 getStencil(m_setup.ul_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
2493 depth_config.internal_format, m_setup.ul_rect);
2494 result &= checkStencil(tmp_stcil, ul_stcil);
2495 CHECK_COLOR(result, true, checkStencil);
2496
2497 getStencil(m_setup.ur_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
2498 depth_config.internal_format, m_setup.ur_rect);
2499 result &= checkStencil(tmp_stcil, ur_stcil);
2500 CHECK_COLOR(result, true, checkStencil);
2501
2502 getStencil(m_setup.ll_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
2503 depth_config.internal_format, m_setup.ll_rect);
2504 result &= checkStencil(tmp_stcil, ll_stcil);
2505 CHECK_COLOR(result, true, checkStencil);
2506
2507 getStencil(m_setup.lr_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
2508 depth_config.internal_format, m_setup.lr_rect);
2509 result &= checkStencil(tmp_stcil, lr_stcil);
2510 CHECK_COLOR(result, true, checkStencil);
2511 }
2512
2513 gl.deleteTextures(2, m_depth_tbos);
2514 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
2515 m_color_tbos[0] = 0;
2516 m_color_tbos[1] = 0;
2517 gl.deleteRenderbuffers(2, m_depth_rbos);
2518 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteRenderbuffers");
2519 m_depth_rbos[0] = 0;
2520 m_depth_rbos[1] = 0;
2521 m_color_rbos[0] = 0;
2522 m_color_rbos[1] = 0;
2523 gl.deleteFramebuffers(2, m_fbos);
2524 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
2525 m_fbos[0] = 0;
2526 m_fbos[1] = 0;
2527
2528 if (!m_isContextES)
2529 {
2530 gl.disable(GL_MULTISAMPLE);
2531 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
2532 }
2533
2534 m_testCtx.getLog() << tcu::TestLog::Message
2535 << "END --------------------------------------------------------------------"
2536 << tcu::TestLog::EndMessage;
2537 }
2538 }
2539
2540 return result;
2541 }
2542
2543 /** Executes test iteration.
2544 *
2545 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2546 */
iterate()2547 tcu::TestNode::IterateResult FramebufferBlitMultiToSingleSampledTestCase::iterate()
2548 {
2549 bool result = true;
2550 /* quadrant centers for verifying initial colors */
2551 tcu::IVec2 ul_center, ur_center, ll_center, lr_center;
2552 constexpr GLuint samples = 4;
2553
2554 /* quadrant centers to verify initial colors */
2555 ul_center[0] = m_setup.ul_rect.x + m_setup.ul_rect.w / 2;
2556 ul_center[1] = m_setup.ul_rect.y + m_setup.ul_rect.h / 2;
2557 ur_center[0] = m_setup.ur_rect.x + m_setup.ur_rect.w / 2;
2558 ur_center[1] = m_setup.ur_rect.y + m_setup.ur_rect.h / 2;
2559 ll_center[0] = m_setup.ll_rect.x + m_setup.ll_rect.w / 2;
2560 ll_center[1] = m_setup.ll_rect.y + m_setup.ll_rect.h / 2;
2561 lr_center[0] = m_setup.lr_rect.x + m_setup.lr_rect.w / 2;
2562 lr_center[1] = m_setup.lr_rect.y + m_setup.lr_rect.h / 2;
2563
2564 FramebufferBlitMultiToSingleSampledColorConfigTestCase *colorTestCaseConfig =
2565 dynamic_cast<FramebufferBlitMultiToSingleSampledColorConfigTestCase *>(this);
2566 if (colorTestCaseConfig != nullptr)
2567 {
2568 GLint max_color_attachments = 0;
2569 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2570
2571 gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
2572 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
2573
2574 CHECK_RET(max_color_attachments >= m_minColorAttachments, GL_TRUE, glGetIntegerv);
2575
2576 if (m_isContextES)
2577 {
2578 GLint max_draw_buffers = 0;
2579 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
2580 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
2581
2582 CHECK_RET(max_draw_buffers >= m_minDrawBuffers, GL_TRUE, glGetIntegerv);
2583 if (max_draw_buffers < max_color_attachments)
2584 {
2585 max_color_attachments = max_draw_buffers;
2586 }
2587 }
2588
2589 /* 1. Test all color buffer formats, no depth or stencil buffers
2590 * attached here */
2591 CHECK_RET(colorTestCaseConfig->testColorBlitConfig<samples>(ul_center, ur_center, ll_center, lr_center,
2592 max_color_attachments),
2593 true, "color blit test failed");
2594 }
2595 else
2596 {
2597 FramebufferBlitMultiToSingleSampledDepthConfigTestCase *depthTestCaseConfig =
2598 dynamic_cast<FramebufferBlitMultiToSingleSampledDepthConfigTestCase *>(this);
2599 if (depthTestCaseConfig != nullptr)
2600 {
2601 /* 2. Test all depth buffer formats, no color or stencil buffers
2602 * attached here */
2603 CHECK_RET(depthTestCaseConfig->testDepthBlitConfig<samples>(ul_center, ur_center, ll_center, lr_center),
2604 true, "depth blit test failed");
2605 }
2606 }
2607
2608 if (result)
2609 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2610 else
2611 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2612 return STOP;
2613 }
2614
2615 /** Constructor.
2616 *
2617 * @param context Rendering context
2618 */
FramebufferBlitScissorTestCase(deqp::Context & context)2619 FramebufferBlitScissorTestCase::FramebufferBlitScissorTestCase(deqp::Context &context)
2620 : FramebufferBlitBaseTestCase(context, "scissor_blit", "Confirm that the scissor test is properly respected")
2621 {
2622 }
2623
2624 /** Stub deinit method. */
deinit()2625 void FramebufferBlitScissorTestCase::deinit()
2626 {
2627 FramebufferBlitBaseTestCase::deinit();
2628 }
2629
2630 /** Stub init method */
init()2631 void FramebufferBlitScissorTestCase::init()
2632 {
2633 FramebufferBlitBaseTestCase::init();
2634
2635 int bufWidth = m_context.getRenderTarget().getWidth();
2636 int bufHeight = m_context.getRenderTarget().getHeight();
2637
2638 /* setup specific for scissor test */
2639 /* rectangle */
2640 m_setup.scissor_rect = {0, 0, bufWidth / 2, bufHeight / 2}; /* lower left (x, y, width, height) */
2641
2642 /* expected values */
2643 m_setup.ul_color = BLACK;
2644 m_setup.ur_color = BLACK;
2645 m_setup.ll_color = GREEN;
2646 m_setup.lr_color = BLACK;
2647 m_setup.ul_depth = Q0;
2648 m_setup.ur_depth = Q0;
2649 m_setup.ll_depth = Q1;
2650 m_setup.lr_depth = Q0;
2651 m_setup.ul_stcil = ZERO;
2652 m_setup.ur_stcil = ZERO;
2653 m_setup.ll_stcil = ONE;
2654 m_setup.lr_stcil = ZERO;
2655 }
2656
runMultiColorPatternTest(const GLint max_color_attachments)2657 bool FramebufferBlitScissorTestCase::runMultiColorPatternTest(const GLint max_color_attachments)
2658 {
2659 bool result = true;
2660 GLint status = 0;
2661 GLuint bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
2662 blt::Color tmp_color = {0.0f, 0.0f, 0.0f, 0.0f};
2663 GLfloat tmp_depth = 0.0f;
2664
2665 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2666 int bufWidth = m_context.getRenderTarget().getWidth();
2667
2668 for (GLuint i = 0; i < m_bufferCfg.size(); i++)
2669 {
2670 /* test buffer combinations (texture to texture, texture to
2671 * renderbuffer, etc.) */
2672 GLuint effective_bits = bits;
2673
2674 /* test color attachments */
2675 /* test color attachments */
2676 for (GLint j = 0; j < max_color_attachments; j++)
2677 {
2678 const BufferConfig &buf_config = m_bufferCfg[i];
2679 GLenum attachment = GL_COLOR_ATTACHMENT0 + j;
2680
2681 /* default color, depth and stencil values for multicolor pattern */
2682 blt::Color ul_color = RED;
2683 blt::Color ur_color = GREEN;
2684 blt::Color ll_color = BLUE;
2685 blt::Color lr_color = WHITE;
2686 blt::Depth ul_depth = Q1;
2687 blt::Depth ur_depth = Q2;
2688 blt::Depth ll_depth = Q3;
2689 blt::Depth lr_depth = Q4;
2690 blt::Stencil ul_stcil = ONE;
2691 blt::Stencil ur_stcil = TWO;
2692 blt::Stencil ll_stcil = THREE;
2693 blt::Stencil lr_stcil = FOUR;
2694
2695 /* source quadrant rects */
2696 blt::Rectangle src_ul_rect = m_setup.ul_rect;
2697 blt::Rectangle src_ur_rect = m_setup.ur_rect;
2698 blt::Rectangle src_ll_rect = m_setup.ll_rect;
2699 blt::Rectangle src_lr_rect = m_setup.lr_rect;
2700
2701 /* destination quadrant rects */
2702 blt::Rectangle dst_ul_rect;
2703 blt::Rectangle dst_ur_rect;
2704 blt::Rectangle dst_ll_rect;
2705 blt::Rectangle dst_lr_rect;
2706
2707 /* destination rect, no quadrants */
2708 blt::Rectangle dst_rect = m_setup.blt_dst_rect;
2709
2710 /* quadrant centers to verify initial colors */
2711 blt::Coord src_ul_center = {src_ul_rect.x + src_ul_rect.w / 2, src_ul_rect.y + src_ul_rect.h / 2};
2712 blt::Coord src_ur_center = {src_ur_rect.x + src_ur_rect.w / 2, src_ur_rect.y + src_ur_rect.h / 2};
2713 blt::Coord src_ll_center = {src_ll_rect.x + src_ll_rect.w / 2, src_ll_rect.y + src_ll_rect.h / 2};
2714 blt::Coord src_lr_center = {src_lr_rect.x + src_lr_rect.w / 2, src_lr_rect.y + src_lr_rect.h / 2};
2715 blt::Coord dst_center = {dst_rect.x + dst_rect.w / 2, dst_rect.y + dst_rect.h / 2};
2716
2717 /* end coords to verify final color */
2718 blt::Coord end_ul_coord = m_setup.ul_coord;
2719 blt::Coord end_ur_coord = m_setup.ur_coord;
2720 blt::Coord end_ll_coord = m_setup.ll_coord;
2721 blt::Coord end_lr_coord = m_setup.lr_coord;
2722
2723 /* blit rectangles */
2724 blt::Rectangle blt_src_rect = m_setup.blt_src_rect;
2725 blt::Rectangle blt_dst_rect = m_setup.blt_dst_rect;
2726
2727 /* special case for 4.14 test, when scissoring is enabled,
2728 it is not suitable to test same_read_and_draw_buffer config */
2729 if (m_setup.scissor_rect.w != m_fullRect.w && m_setup.scissor_rect.h != m_fullRect.h)
2730 {
2731 if (buf_config.same_read_and_draw_buffer)
2732 {
2733 continue;
2734 }
2735 }
2736
2737 m_depth_internalFormat = 0;
2738 m_depth_type = 0;
2739 m_depth_format = 0;
2740
2741 m_stcil_internalFormat = 0;
2742 m_stcil_type = 0;
2743 m_stcil_format = 0;
2744
2745 // When default FB is involved
2746 // Check the format of default FB
2747 if ((buf_config.src_type == 0) || (buf_config.dst_type == 0))
2748 {
2749 GLint sample_buffers;
2750 bool noDefaultDepth, noDefaultStcil;
2751
2752 // Multisample is not tested here
2753 gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2754 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2755
2756 gl.getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
2757 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
2758
2759 if (sample_buffers != 0)
2760 {
2761 m_testCtx.getLog() << tcu::TestLog::Message
2762 << "SKIP --------------------------------------------------------------------"
2763 << tcu::TestLog::EndMessage;
2764 continue;
2765 }
2766
2767 if (!GetDefaultFramebufferBlitFormat(&noDefaultDepth, &noDefaultStcil))
2768 {
2769 // No matched format can be found for blit depth and stencil
2770 if ((effective_bits & GL_COLOR_BUFFER_BIT) == 0)
2771 {
2772 m_testCtx.getLog()
2773 << tcu::TestLog::Message
2774 << "SKIP --------------------------------------------------------------------"
2775 << tcu::TestLog::EndMessage;
2776 continue;
2777 }
2778 else
2779 {
2780 // Just check color
2781 effective_bits &= ~GL_DEPTH_BUFFER_BIT;
2782 effective_bits &= ~GL_STENCIL_BUFFER_BIT;
2783 }
2784 }
2785
2786 if (noDefaultDepth)
2787 {
2788 effective_bits &= ~GL_DEPTH_BUFFER_BIT;
2789 }
2790
2791 if (noDefaultStcil)
2792 {
2793 effective_bits &= ~GL_STENCIL_BUFFER_BIT;
2794 }
2795 }
2796
2797 /* prepare read rectangles (to the left part of buffer)
2798 * and draw rectangles (to the right part of buffer) when
2799 * same buffer used for reading and drawing */
2800 if (buf_config.same_read_and_draw_buffer)
2801 {
2802 m_testCtx.getLog() << tcu::TestLog::Message
2803 << "........................................................................"
2804 << tcu::TestLog::EndMessage;
2805
2806 tcu_fail_msg("from src_ul_rect [x,y,w,h]=[%d,%d,%d,%d]", src_ul_rect.x, src_ul_rect.y, src_ul_rect.w,
2807 src_ul_rect.h);
2808 tcu_fail_msg("from src_ur_rect [x,y,w,h]=[%d,%d,%d,%d]", src_ur_rect.x, src_ur_rect.y, src_ur_rect.w,
2809 src_ur_rect.h);
2810 tcu_fail_msg("from src_ll_rect [x,y,w,h]=[%d,%d,%d,%d]", src_ll_rect.x, src_ll_rect.y, src_ll_rect.w,
2811 src_ll_rect.h);
2812 tcu_fail_msg("from src_lr_rect [x,y,w,h]=[%d,%d,%d,%d]", src_lr_rect.x, src_lr_rect.y, src_lr_rect.w,
2813 src_lr_rect.h);
2814
2815 /* src quadrants to the left side of buffer */
2816 src_ll_rect.x = src_ll_rect.x / 2; /* lower-left src */
2817 src_ll_rect.w = src_ll_rect.w / 2; /* lower-left src */
2818 src_lr_rect.x = src_ll_rect.w; /* lower-right src */
2819 src_lr_rect.w = bufWidth / 2 - src_ll_rect.w; /* lower-right src */
2820 src_ul_rect.x = src_ul_rect.x / 2; /* upper-left src */
2821 src_ul_rect.w = src_ul_rect.w / 2; /* upper-left src */
2822 src_ur_rect.x = src_ul_rect.w; /* upper-right src */
2823 src_ur_rect.w = bufWidth / 2 - src_ul_rect.w; /* upper-right src */
2824
2825 tcu_fail_msg("to src_ul_rect [x,y,w,h]=[%d,%d,%d,%d]", src_ul_rect.x, src_ul_rect.y, src_ul_rect.w,
2826 src_ul_rect.h);
2827 tcu_fail_msg("to src_ur_rect [x,y,w,h]=[%d,%d,%d,%d]", src_ur_rect.x, src_ur_rect.y, src_ur_rect.w,
2828 src_ur_rect.h);
2829 tcu_fail_msg("to src_ll_rect [x,y,w,h]=[%d,%d,%d,%d]", src_ll_rect.x, src_ll_rect.y, src_ll_rect.w,
2830 src_ll_rect.h);
2831 tcu_fail_msg("to src_lr_rect [x,y,w,h]=[%d,%d,%d,%d]", src_lr_rect.x, src_lr_rect.y, src_lr_rect.w,
2832 src_lr_rect.h);
2833 tcu_fail_msg("from dst_rect [x,y,w,h]=[%d,%d,%d,%d]", dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
2834
2835 /* dst rectangle to the right side of buffer */
2836 dst_rect.x = bufWidth / 2 + dst_rect.x / 2;
2837 dst_rect.w = bufWidth / 2;
2838
2839 tcu_fail_msg("to dst_rect [x,y,w,h]=[%d,%d,%d,%d]", dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
2840 tcu_fail_msg("from src_ul_center [x,y]=[%d,%d]", src_ul_center.x(), src_ul_center.y());
2841 tcu_fail_msg("from src_ur_center [x,y]=[%d,%d]", src_ur_center.x(), src_ur_center.y());
2842 tcu_fail_msg("from src_ll_center [x,y]=[%d,%d]", src_ll_center.x(), src_ll_center.y());
2843 tcu_fail_msg("from src_lr_center [x,y]=[%d,%d]", src_lr_center.x(), src_lr_center.y());
2844
2845 /* src quadrant centers to verify initial colors */
2846 src_ul_center = blt::Coord(src_ul_rect.x + src_ul_rect.w / 2, src_ul_rect.y + src_ul_rect.h / 2);
2847 src_ur_center = blt::Coord(src_ur_rect.x + src_ur_rect.w / 2, src_ur_rect.y + src_ur_rect.h / 2);
2848 src_ll_center = blt::Coord(src_ll_rect.x + src_ll_rect.w / 2, src_ll_rect.y + src_ll_rect.h / 2);
2849 src_lr_center = blt::Coord(src_lr_rect.x + src_lr_rect.w / 2, src_lr_rect.y + src_lr_rect.h / 2);
2850
2851 tcu_fail_msg("to src_ul_center [x,y]=[%d,%d]", src_ul_center.x(), src_ul_center.y());
2852 tcu_fail_msg("to src_ur_center [x,y]=[%d,%d]", src_ur_center.x(), src_ur_center.y());
2853 tcu_fail_msg("to src_ll_center [x,y]=[%d,%d]", src_ll_center.x(), src_ll_center.y());
2854 tcu_fail_msg("to src_lr_center [x,y]=[%d,%d]", src_lr_center.x(), src_lr_center.y());
2855 tcu_fail_msg("from dst_center [x,y]=[%d,%d]", dst_center.x(), dst_center.y());
2856
2857 /* dst center to verify initial color */
2858 dst_center = blt::Coord(dst_rect.x + dst_rect.w / 2, dst_rect.y + dst_rect.h / 2);
2859
2860 tcu_fail_msg("to dst_center [x,y]=[%d,%d]", dst_center.x(), dst_center.y());
2861 tcu_fail_msg("from end_ul_coord [x,y]=[%d,%d]", end_ul_coord.x(), end_ul_coord.y());
2862 tcu_fail_msg("from end_ur_coord [x,y]=[%d,%d]", end_ur_coord.x(), end_ur_coord.y());
2863 tcu_fail_msg("from end_ll_coord [x,y]=[%d,%d]", end_ll_coord.x(), end_ll_coord.y());
2864 tcu_fail_msg("from end_lr_coord [x,y]=[%d,%d]", end_lr_coord.x(), end_lr_coord.y());
2865
2866 /* end coords to verify final colors */
2867 end_ul_coord = blt::Coord(dst_rect.x, end_ul_coord.y());
2868 end_ur_coord = blt::Coord(dst_rect.x + dst_rect.w - 1, end_ur_coord.y());
2869 end_ll_coord = blt::Coord(dst_rect.x, end_ll_coord.y());
2870 end_lr_coord = blt::Coord(dst_rect.x + dst_rect.w - 1, end_lr_coord.y());
2871
2872 tcu_fail_msg("to end_ul_coord [x,y]=[%d,%d]", end_ul_coord.x(), end_ul_coord.y());
2873 tcu_fail_msg("to end_ur_coord [x,y]=[%d,%d]", end_ur_coord.x(), end_ur_coord.y());
2874 tcu_fail_msg("to end_ll_coord [x,y]=[%d,%d]", end_ll_coord.x(), end_ll_coord.y());
2875 tcu_fail_msg("to end_lr_coord [x,y]=[%d,%d]", end_lr_coord.x(), end_lr_coord.y());
2876 tcu_fail_msg("from blt_src_rect [x,y,w,h]=[%d,%d,%d,%d]", blt_src_rect.x, blt_src_rect.y,
2877 blt_src_rect.w, blt_src_rect.h);
2878 tcu_fail_msg("from blt_dst_rect [x,y,w,h]=[%d,%d,%d,%d]", blt_dst_rect.x, blt_dst_rect.y,
2879 blt_dst_rect.w, blt_dst_rect.h);
2880
2881 /* blit rectangles */
2882 blt_src_rect.x = src_ll_rect.x;
2883 blt_src_rect.w = src_ll_rect.w + src_lr_rect.w;
2884 blt_dst_rect.x = dst_rect.x;
2885 blt_dst_rect.w = dst_rect.w;
2886
2887 tcu_fail_msg("to blt_src_rect [x,y,w,h]=[%d,%d,%d,%d]", blt_src_rect.x, blt_src_rect.y, blt_src_rect.w,
2888 blt_src_rect.h);
2889 tcu_fail_msg("to blt_dst_rect [x,y,w,h]=[%d,%d,%d,%d]", blt_dst_rect.x, blt_dst_rect.y, blt_dst_rect.w,
2890 blt_dst_rect.h);
2891 m_testCtx.getLog() << tcu::TestLog::Message
2892 << "........................................................................"
2893 << tcu::TestLog::EndMessage;
2894 }
2895
2896 /* dest quadrant rects */
2897 dst_ul_rect = blt::Rectangle(blt_dst_rect.x, blt_dst_rect.y + blt_dst_rect.h / 2, blt_dst_rect.w / 2,
2898 blt_dst_rect.h - blt_dst_rect.h / 2);
2899 dst_ur_rect = blt::Rectangle(blt_dst_rect.x + blt_dst_rect.w / 2, blt_dst_rect.y + blt_dst_rect.h / 2,
2900 blt_dst_rect.w - blt_dst_rect.w / 2, blt_dst_rect.h - blt_dst_rect.h / 2);
2901 dst_ll_rect = blt::Rectangle(blt_dst_rect.x, blt_dst_rect.y, blt_dst_rect.w / 2, blt_dst_rect.h / 2);
2902 dst_lr_rect = blt::Rectangle(blt_dst_rect.x + blt_dst_rect.w / 2, blt_dst_rect.y,
2903 blt_dst_rect.w - blt_dst_rect.w / 2, blt_dst_rect.h / 2);
2904
2905 /* special case for 4.14 test, clear whole buffer to
2906 * green color, depth one and stcil zero */
2907 if (m_setup.scissor_rect.w != m_fullRect.w && m_setup.scissor_rect.h != m_fullRect.h)
2908 {
2909 ul_color = ur_color = ll_color = lr_color = GREEN;
2910 ul_depth = ur_depth = ll_depth = lr_depth = Q1;
2911 ul_stcil = ur_stcil = ll_stcil = lr_stcil = ONE;
2912 }
2913
2914 gl.genFramebuffers(2, m_fbos);
2915 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
2916
2917 m_testCtx.getLog() << tcu::TestLog::Message
2918 << "BEGIN ------------------------------------------------------------------"
2919 << tcu::TestLog::EndMessage;
2920 tcu_fail_msg("BLITTING in %s from %s to %s %s", getEnumName(attachment),
2921 (!buf_config.src_type) ? getEnumName(DEFAULT) : getEnumName(buf_config.src_type),
2922 (!buf_config.dst_type) ? getEnumName(DEFAULT) : getEnumName(buf_config.dst_type),
2923 (buf_config.dst_type) ?
2924 (buf_config.same_read_and_draw_buffer) ? "(same buffer)" : "(different buffers)" :
2925 "");
2926
2927 *buf_config.src_cbuf = 0;
2928 *buf_config.src_dbuf = 0;
2929 *buf_config.src_sbuf = 0;
2930 *buf_config.dst_cbuf = 0;
2931 *buf_config.dst_dbuf = 0;
2932 *buf_config.dst_sbuf = 0;
2933
2934 /* prepare color buffers */
2935 if (effective_bits & GL_COLOR_BUFFER_BIT)
2936 {
2937 /* multicolor pattern to the source buffer */
2938 if (buf_config.src_type == GL_TEXTURE_2D)
2939 {
2940 gl.genTextures(1, buf_config.src_cbuf);
2941 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2942
2943 result &= init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, buf_config.src_cbuf, GL_RGBA8);
2944
2945 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *buf_config.src_cbuf,
2946 ul_color, src_ul_rect, src_ul_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2947 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *buf_config.src_cbuf,
2948 ur_color, src_ur_rect, src_ur_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2949 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *buf_config.src_cbuf,
2950 ll_color, src_ll_rect, src_ll_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2951 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *buf_config.src_cbuf,
2952 lr_color, src_lr_rect, src_lr_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2953 }
2954 else if (buf_config.src_type == GL_RENDERBUFFER)
2955 {
2956 gl.genRenderbuffers(1, buf_config.src_cbuf);
2957 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
2958
2959 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, buf_config.src_cbuf, GL_RGBA8);
2960
2961 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *buf_config.src_cbuf,
2962 ul_color, src_ul_rect, src_ul_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2963 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *buf_config.src_cbuf,
2964 ur_color, src_ur_rect, src_ur_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2965 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *buf_config.src_cbuf,
2966 ll_color, src_ll_rect, src_ll_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2967 result &= clearColorBuffer(m_fbos[0], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *buf_config.src_cbuf,
2968 lr_color, src_lr_rect, src_lr_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2969 }
2970 else
2971 {
2972 result &= clearColorBuffer(m_defaultFBO, 0, 0, 0, ul_color, src_ul_rect, src_ul_center,
2973 DEFAULT_COLOR_CHANNEL_BITS, false); /* default buffer */
2974 result &= clearColorBuffer(m_defaultFBO, 0, 0, 0, ur_color, src_ur_rect, src_ur_center,
2975 DEFAULT_COLOR_CHANNEL_BITS, false); /* default buffer */
2976 result &= clearColorBuffer(m_defaultFBO, 0, 0, 0, ll_color, src_ll_rect, src_ll_center,
2977 DEFAULT_COLOR_CHANNEL_BITS, false); /* default buffer */
2978 result &= clearColorBuffer(m_defaultFBO, 0, 0, 0, lr_color, src_lr_rect, src_lr_center,
2979 DEFAULT_COLOR_CHANNEL_BITS, false); /* default buffer */
2980 }
2981
2982 /* initial destination color to the destination buffer */
2983 if (buf_config.dst_type == GL_TEXTURE_2D)
2984 {
2985 *buf_config.dst_cbuf = *buf_config.src_cbuf;
2986 if (!buf_config.same_read_and_draw_buffer)
2987 {
2988 gl.genTextures(1, buf_config.dst_cbuf);
2989 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2990
2991 result &= init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, buf_config.dst_cbuf, GL_RGBA8);
2992 }
2993 result &= clearColorBuffer(m_fbos[1], GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *buf_config.dst_cbuf,
2994 DST_COLOR, dst_rect, dst_center, DEFAULT_COLOR_CHANNEL_BITS, false);
2995 }
2996 else if (buf_config.dst_type == GL_RENDERBUFFER)
2997 {
2998 *buf_config.dst_cbuf = *buf_config.src_cbuf;
2999 if (!buf_config.same_read_and_draw_buffer)
3000 {
3001 gl.genRenderbuffers(1, buf_config.dst_cbuf);
3002 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
3003
3004 result &=
3005 init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, buf_config.dst_cbuf, GL_RGBA8);
3006 }
3007 result &= clearColorBuffer(m_fbos[1], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *buf_config.dst_cbuf,
3008 DST_COLOR, dst_rect, dst_center, DEFAULT_COLOR_CHANNEL_BITS, false);
3009 }
3010 else
3011 {
3012 result &= clearColorBuffer(m_defaultFBO, 0, 0, 0, DST_COLOR, dst_rect, dst_center,
3013 DEFAULT_COLOR_CHANNEL_BITS, false); /* default buffer */
3014 }
3015 }
3016
3017 /* prepare depth buffers */
3018 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3019 {
3020 /* multicolor pattern to the source buffer */
3021 if (buf_config.src_type == GL_TEXTURE_2D)
3022 {
3023 gl.genTextures(1, buf_config.src_dbuf);
3024 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3025
3026 if (buf_config.dst_type != 0)
3027 {
3028 if (effective_bits & GL_STENCIL_BUFFER_BIT)
3029 {
3030 /* ES3.0 requires that depth and stencil attachments, if present, are the same image.
3031 * Desktop GL doesn't require implementations to support different depth+stencil from
3032 * different images (4.3 core page 279). */
3033 m_stcil_internalFormat = m_depth_internalFormat = GL_DEPTH24_STENCIL8;
3034 m_stcil_type = m_depth_type = GL_UNSIGNED_INT_24_8;
3035 m_stcil_format = m_depth_format = GL_DEPTH_STENCIL;
3036 }
3037 else
3038 {
3039 m_depth_internalFormat = GL_DEPTH_COMPONENT16;
3040 m_depth_type = GL_UNSIGNED_SHORT;
3041 m_depth_format = GL_DEPTH_COMPONENT;
3042 }
3043 }
3044 result &=
3045 init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, buf_config.src_dbuf, m_depth_internalFormat);
3046
3047 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_dbuf,
3048 m_depth_internalFormat, ul_depth, src_ul_rect, src_ul_center);
3049 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_dbuf,
3050 m_depth_internalFormat, ur_depth, src_ur_rect, src_ur_center);
3051 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_dbuf,
3052 m_depth_internalFormat, ll_depth, src_ll_rect, src_ll_center);
3053 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_dbuf,
3054 m_depth_internalFormat, lr_depth, src_lr_rect, src_lr_center);
3055 }
3056 else if (buf_config.src_type == GL_RENDERBUFFER)
3057 {
3058 gl.genRenderbuffers(1, buf_config.src_dbuf);
3059 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
3060
3061 if (buf_config.dst_type != 0)
3062 {
3063 if (effective_bits & GL_STENCIL_BUFFER_BIT)
3064 {
3065 /* ES3.0 requires that depth and stencil attachments, if present, are the same image.
3066 * Desktop GL doesn't require implementations to support different depth+stencil from
3067 * different images (4.3 core page 279). */
3068 m_stcil_internalFormat = m_depth_internalFormat = GL_DEPTH24_STENCIL8;
3069 m_stcil_type = m_depth_type = GL_UNSIGNED_INT_24_8;
3070 m_stcil_format = m_depth_format = GL_DEPTH_STENCIL;
3071 }
3072 else
3073 {
3074 m_depth_internalFormat = GL_DEPTH_COMPONENT16;
3075 m_depth_type = GL_UNSIGNED_SHORT;
3076 m_depth_format = GL_DEPTH_COMPONENT;
3077 }
3078 }
3079 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, buf_config.src_dbuf,
3080 m_depth_internalFormat);
3081 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_dbuf,
3082 m_depth_internalFormat, ul_depth, src_ul_rect, src_ul_center);
3083 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_dbuf,
3084 m_depth_internalFormat, ur_depth, src_ur_rect, src_ur_center);
3085 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_dbuf,
3086 m_depth_internalFormat, ll_depth, src_ll_rect, src_ll_center);
3087 result &= clearDepthBuffer(m_fbos[0], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_dbuf,
3088 m_depth_internalFormat, lr_depth, src_lr_rect, src_lr_center);
3089 }
3090 else
3091 {
3092 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, m_depth_internalFormat, ul_depth, src_ul_rect,
3093 src_ul_center); /* default buffer */
3094 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, m_depth_internalFormat, ur_depth, src_ur_rect,
3095 src_ur_center); /* default buffer */
3096 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, m_depth_internalFormat, ll_depth, src_ll_rect,
3097 src_ll_center); /* default buffer */
3098 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, m_depth_internalFormat, lr_depth, src_lr_rect,
3099 src_lr_center); /* default buffer */
3100 }
3101
3102 /* initial destination depth to the destination buffer */
3103 if (buf_config.dst_type == GL_TEXTURE_2D)
3104 {
3105 /* The depth blit requires source and dest has the same depth format */
3106 *buf_config.dst_dbuf = *buf_config.src_dbuf;
3107 if (!buf_config.same_read_and_draw_buffer)
3108 {
3109 gl.genTextures(1, buf_config.dst_dbuf);
3110 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3111
3112 result &= init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, buf_config.dst_dbuf,
3113 m_depth_internalFormat);
3114 }
3115 result &= clearDepthBuffer(m_fbos[1], GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *buf_config.dst_dbuf,
3116 m_depth_internalFormat, DST_DEPTH, dst_rect, dst_center);
3117 }
3118 else if (buf_config.dst_type == GL_RENDERBUFFER)
3119 {
3120 /* The depth blit requires source and dest has the same depth format */
3121 *buf_config.dst_dbuf = *buf_config.src_dbuf;
3122 if (!buf_config.same_read_and_draw_buffer)
3123 {
3124 gl.genRenderbuffers(1, buf_config.dst_dbuf);
3125 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
3126
3127 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, buf_config.dst_dbuf,
3128 m_depth_internalFormat);
3129 }
3130 result &= clearDepthBuffer(m_fbos[1], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *buf_config.dst_dbuf,
3131 m_depth_internalFormat, DST_DEPTH, dst_rect, dst_center);
3132 }
3133 else
3134 {
3135 result &= clearDepthBuffer(m_defaultFBO, 0, 0, 0, m_depth_internalFormat, DST_DEPTH, dst_rect,
3136 dst_center); /* default buffer */
3137 }
3138 }
3139
3140 /* prepare stencil buffers */
3141 if (effective_bits & GL_STENCIL_BUFFER_BIT)
3142 {
3143 /* multicolor pattern to the source buffer */
3144 if (buf_config.src_type == GL_TEXTURE_2D)
3145 {
3146 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3147 {
3148 /* ES3.0 requires that depth and stencil attachments, if present, are the same image.
3149 * Desktop GL doesn't require implementations to support different depth+stencil from
3150 * different images (4.3 core page 279). */
3151 *buf_config.src_sbuf = *buf_config.src_dbuf;
3152 }
3153 else
3154 {
3155 gl.genTextures(1, buf_config.src_sbuf);
3156 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3157
3158 if (buf_config.dst_type != 0)
3159 {
3160 m_stcil_internalFormat = GL_DEPTH24_STENCIL8;
3161 m_stcil_type = GL_UNSIGNED_INT_24_8;
3162 m_stcil_format = GL_DEPTH_STENCIL;
3163 }
3164
3165 result &= init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, buf_config.src_sbuf,
3166 m_stcil_internalFormat);
3167 }
3168 result &= clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_sbuf,
3169 m_stcil_internalFormat, ul_stcil, src_ul_rect, src_ul_center);
3170 result &= clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_sbuf,
3171 m_stcil_internalFormat, ur_stcil, src_ur_rect, src_ur_center);
3172 result &= clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_sbuf,
3173 m_stcil_internalFormat, ll_stcil, src_ll_rect, src_ll_center);
3174 result &= clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *buf_config.src_sbuf,
3175 m_stcil_internalFormat, lr_stcil, src_lr_rect, src_lr_center);
3176 }
3177 else if (buf_config.src_type == GL_RENDERBUFFER)
3178 {
3179 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3180 {
3181 /* ES3.0 requires that depth and stencil attachments, if present, are the same image.
3182 * Desktop GL doesn't require implementations to support different depth+stencil from
3183 * different images (4.3 core page 279). */
3184 *buf_config.src_sbuf = *buf_config.src_dbuf;
3185 }
3186 else
3187 {
3188 gl.genRenderbuffers(1, buf_config.src_sbuf);
3189 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
3190
3191 if (buf_config.dst_type != 0)
3192 {
3193 if (buf_config.dst_type == GL_TEXTURE_2D)
3194 {
3195 m_stcil_internalFormat = GL_DEPTH24_STENCIL8;
3196 m_stcil_type = GL_UNSIGNED_INT_24_8;
3197 m_stcil_format = GL_DEPTH_STENCIL;
3198 }
3199 else
3200 {
3201 m_stcil_internalFormat = GL_STENCIL_INDEX8;
3202 m_stcil_type = 0;
3203 m_stcil_format = 0;
3204 }
3205 }
3206
3207 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, buf_config.src_sbuf,
3208 m_stcil_internalFormat);
3209 }
3210 result &=
3211 clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_sbuf,
3212 m_stcil_internalFormat, ul_stcil, src_ul_rect, src_ul_center);
3213 result &=
3214 clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_sbuf,
3215 m_stcil_internalFormat, ur_stcil, src_ur_rect, src_ur_center);
3216 result &=
3217 clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_sbuf,
3218 m_stcil_internalFormat, ll_stcil, src_ll_rect, src_ll_center);
3219 result &=
3220 clearStencilBuffer(m_fbos[0], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *buf_config.src_sbuf,
3221 m_stcil_internalFormat, lr_stcil, src_lr_rect, src_lr_center);
3222 }
3223 else /* default buffer */
3224 {
3225 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, m_stcil_internalFormat, ul_stcil, src_ul_rect,
3226 src_ul_center); /* default buffer */
3227 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, m_stcil_internalFormat, ur_stcil, src_ur_rect,
3228 src_ur_center); /* default buffer */
3229 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, m_stcil_internalFormat, ll_stcil, src_ll_rect,
3230 src_ll_center); /* default buffer */
3231 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, m_stcil_internalFormat, lr_stcil, src_lr_rect,
3232 src_lr_center); /* default buffer */
3233 }
3234
3235 /* initial destination stencil to the destination buffer */
3236 if (buf_config.dst_type == GL_TEXTURE_2D)
3237 {
3238 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3239 {
3240 /* ES3.0 requires that depth and stencil attachments, if present, are the same image.
3241 * Desktop GL doesn't require implementations to support different depth+stencil from
3242 * different images (4.3 core page 279). */
3243 *buf_config.dst_sbuf = *buf_config.dst_dbuf;
3244 }
3245 else
3246 {
3247 /* The stencil blit requires source and dest has the same stencil format */
3248 *buf_config.dst_sbuf = *buf_config.src_sbuf;
3249 if (!buf_config.same_read_and_draw_buffer)
3250 {
3251 gl.genTextures(1, buf_config.dst_sbuf);
3252 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3253
3254 result &= init_gl_objs<GL_TEXTURE_2D, 0>(gl.bindTexture, 1, buf_config.dst_sbuf,
3255 m_stcil_internalFormat);
3256 }
3257 }
3258 result &= clearStencilBuffer(m_fbos[1], GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *buf_config.dst_sbuf,
3259 m_stcil_internalFormat, DST_STCIL, dst_rect, dst_center);
3260 }
3261 else if (buf_config.dst_type == GL_RENDERBUFFER)
3262 {
3263 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3264 {
3265 /* ES3.0 requires that depth and stencil attachments, if present, are the same image.
3266 * Desktop GL doesn't require implementations to support different depth+stencil from
3267 * different images (4.3 core page 279). */
3268 *buf_config.dst_sbuf = *buf_config.dst_dbuf;
3269 }
3270 else
3271 {
3272 /* The stencil blit requires source and dest has the same stencil format */
3273 *buf_config.dst_sbuf = *buf_config.src_sbuf;
3274 if (!buf_config.same_read_and_draw_buffer)
3275 {
3276 gl.genRenderbuffers(1, buf_config.dst_sbuf);
3277 GLU_EXPECT_NO_ERROR(gl.getError(), "genRenderbuffers");
3278
3279 result &= init_gl_objs<GL_RENDERBUFFER, 0>(gl.bindRenderbuffer, 1, buf_config.dst_sbuf,
3280 m_stcil_internalFormat);
3281 }
3282 }
3283 result &=
3284 clearStencilBuffer(m_fbos[1], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *buf_config.dst_sbuf,
3285 m_stcil_internalFormat, DST_STCIL, dst_rect, dst_center);
3286 }
3287 else
3288 {
3289 result &= clearStencilBuffer(m_defaultFBO, 0, 0, 0, m_stcil_internalFormat, DST_STCIL, dst_rect,
3290 dst_center); /* default buffer */
3291 }
3292 }
3293
3294 printGlobalBufferInfo();
3295
3296 /* bind framebuffers */
3297 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, buf_config.src_type == 0 ? m_defaultFBO : *buf_config.src_fbo);
3298 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3299
3300 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo);
3301 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3302
3303 /* attach color, depth and stencil buffers */
3304 if (effective_bits & GL_COLOR_BUFFER_BIT)
3305 {
3306 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, attachment, buf_config.src_type,
3307 *buf_config.src_cbuf);
3308 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, attachment, buf_config.dst_type,
3309 *buf_config.dst_cbuf);
3310 }
3311 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3312 {
3313 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, buf_config.src_type,
3314 *buf_config.src_dbuf);
3315 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, buf_config.dst_type,
3316 *buf_config.dst_dbuf);
3317 }
3318 if (effective_bits & GL_STENCIL_BUFFER_BIT)
3319 {
3320 result &= attachBufferToFramebuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, buf_config.src_type,
3321 *buf_config.src_sbuf);
3322 result &= attachBufferToFramebuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, buf_config.dst_type,
3323 *buf_config.dst_sbuf);
3324 }
3325
3326 /* setup the read and draw color buffers */
3327 if (buf_config.src_type != 0)
3328 {
3329 gl.readBuffer(attachment);
3330 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
3331 }
3332
3333 if (buf_config.dst_type != 0)
3334 {
3335 if (m_isContextES)
3336 {
3337 std::vector<GLenum> draw_attachments(max_color_attachments, GL_NONE);
3338 draw_attachments[j] = attachment;
3339 gl.drawBuffers(j + 1, draw_attachments.data());
3340 }
3341 else
3342 {
3343 gl.drawBuffers(1, &attachment);
3344 }
3345 GLU_EXPECT_NO_ERROR(gl.getError(), "drawBuffers");
3346 }
3347
3348 /* special case for 4.14 test, enable scissoring */
3349 if (m_setup.scissor_rect.w != m_fullRect.w && m_setup.scissor_rect.h != m_fullRect.h)
3350 {
3351 GLint x = m_setup.scissor_rect.x;
3352 GLint y = m_setup.scissor_rect.y;
3353 GLint w = m_setup.scissor_rect.w;
3354 GLint h = m_setup.scissor_rect.h;
3355
3356 tcu_fail_msg("SCISSOR[%d,%d,%d,%d]", x, y, w, h);
3357 gl.scissor(x, y, w, h);
3358 GLU_EXPECT_NO_ERROR(gl.getError(), "scissor");
3359
3360 gl.enable(GL_SCISSOR_TEST);
3361 GLU_EXPECT_NO_ERROR(gl.getError(), "enable");
3362 }
3363
3364 status = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
3365 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
3366 CHECK(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
3367
3368 status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
3369 GLU_EXPECT_NO_ERROR(gl.getError(), "checkFramebufferStatus");
3370 CHECK(status, GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus);
3371
3372 /* blit */
3373 {
3374 GLint srcX0 = blt_src_rect.x;
3375 GLint srcY0 = blt_src_rect.y;
3376 GLint srcX1 = blt_src_rect.x + blt_src_rect.w;
3377 GLint srcY1 = blt_src_rect.y + blt_src_rect.h;
3378
3379 GLint dstX0 = blt_dst_rect.x;
3380 GLint dstY0 = blt_dst_rect.y;
3381 GLint dstX1 = blt_dst_rect.x + blt_dst_rect.w;
3382 GLint dstY1 = blt_dst_rect.y + blt_dst_rect.h;
3383
3384 GLint temp;
3385
3386 if (m_setup.negative_src_width)
3387 {
3388 temp = srcX0;
3389 srcX0 = srcX1;
3390 srcX1 = temp;
3391 temp = dst_ul_rect.w;
3392 dst_ul_rect.w = dst_ur_rect.w;
3393 dst_ur_rect.w = temp;
3394 dst_ur_rect.x = dst_ul_rect.x + dst_ul_rect.w;
3395 temp = dst_ll_rect.w;
3396 dst_ll_rect.w = dst_lr_rect.w;
3397 dst_lr_rect.w = temp;
3398 dst_lr_rect.x = dst_ll_rect.x + dst_ll_rect.w;
3399 }
3400 if (m_setup.negative_src_height)
3401 {
3402 temp = srcY0;
3403 srcY0 = srcY1;
3404 srcY1 = temp;
3405 temp = dst_ul_rect.h;
3406 dst_ul_rect.h = dst_ll_rect.h;
3407 dst_ll_rect.h = temp;
3408 dst_ul_rect.y = dst_ll_rect.y + dst_ll_rect.h;
3409 temp = dst_ur_rect.h;
3410 dst_ur_rect.h = dst_lr_rect.h;
3411 dst_lr_rect.h = temp;
3412 dst_ur_rect.y = dst_lr_rect.y + dst_lr_rect.h;
3413 }
3414 if (m_setup.negative_dst_width)
3415 {
3416 temp = dstX0;
3417 dstX0 = dstX1;
3418 dstX1 = temp;
3419 temp = dst_ul_rect.w;
3420 dst_ul_rect.w = dst_ur_rect.w;
3421 dst_ur_rect.w = temp;
3422 dst_ur_rect.x = dst_ul_rect.x + dst_ul_rect.w;
3423 temp = dst_ll_rect.w;
3424 dst_ll_rect.w = dst_lr_rect.w;
3425 dst_lr_rect.w = temp;
3426 dst_lr_rect.x = dst_ll_rect.x + dst_ll_rect.w;
3427 }
3428 if (m_setup.negative_dst_height)
3429 {
3430 temp = dstY0;
3431 dstY0 = dstY1;
3432 dstY1 = temp;
3433 temp = dst_ul_rect.h;
3434 dst_ul_rect.h = dst_ll_rect.h;
3435 dst_ll_rect.h = temp;
3436 dst_ul_rect.y = dst_ll_rect.y + dst_ll_rect.h;
3437 temp = dst_ur_rect.h;
3438 dst_ur_rect.h = dst_lr_rect.h;
3439 dst_lr_rect.h = temp;
3440 dst_ur_rect.y = dst_lr_rect.y + dst_lr_rect.h;
3441 }
3442
3443 tcu_fail_msg("BLIT blt_src_rect=[%d,%d,%d,%d] blt_dst_rect=[%d,%d,%d,%d]", srcX0, srcY0, srcX1, srcY1,
3444 dstX0, dstY0, dstX1, dstY1);
3445
3446 gl.blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, effective_bits, GL_NEAREST);
3447 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
3448 }
3449
3450 /* bind dst_fbo to GL_READ_FRAMEBUFFER */
3451 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo);
3452 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
3453
3454 /* setup the read color buffer again if the destination
3455 * buffer is an user fbo */
3456 if (buf_config.dst_type != 0)
3457 {
3458 gl.readBuffer(attachment);
3459 GLU_EXPECT_NO_ERROR(gl.getError(), "readBuffer");
3460 }
3461
3462 /* special case for 4.14 test, disable scissoring */
3463 if (m_setup.scissor_rect.w != m_fullRect.w && m_setup.scissor_rect.h != m_fullRect.h)
3464 {
3465 gl.disable(GL_SCISSOR_TEST);
3466 GLU_EXPECT_NO_ERROR(gl.getError(), "disable");
3467 }
3468
3469 /* read and verify color, depth and stencil values */
3470 if (effective_bits & GL_COLOR_BUFFER_BIT)
3471 {
3472 getColor(end_ul_coord, &tmp_color, false);
3473 result &= checkColor(tmp_color, m_setup.ul_color, DEFAULT_COLOR_CHANNEL_BITS);
3474 CHECK_COLOR(result, true, checkColor);
3475
3476 getColor(end_ur_coord, &tmp_color, false);
3477 result &= checkColor(tmp_color, m_setup.ur_color, DEFAULT_COLOR_CHANNEL_BITS);
3478 CHECK_COLOR(result, true, checkColor);
3479
3480 getColor(end_ll_coord, &tmp_color, false);
3481 result &= checkColor(tmp_color, m_setup.ll_color, DEFAULT_COLOR_CHANNEL_BITS);
3482 CHECK_COLOR(result, true, checkColor);
3483
3484 getColor(end_lr_coord, &tmp_color, false);
3485 result &= checkColor(tmp_color, m_setup.lr_color, DEFAULT_COLOR_CHANNEL_BITS);
3486 CHECK_COLOR(result, true, checkColor);
3487 }
3488 if (effective_bits & GL_DEPTH_BUFFER_BIT)
3489 {
3490 GLuint resultPreBits, depthPreBits;
3491 GLfloat epsilon;
3492
3493 depthPreBits = GetDepthPrecisionBits(m_depth_internalFormat);
3494
3495 getDepth(end_ul_coord, &tmp_depth, &resultPreBits,
3496 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, m_depth_internalFormat,
3497 dst_ul_rect);
3498 epsilon = GetEpsilon(resultPreBits, depthPreBits);
3499 result &= checkDepth(tmp_depth, m_setup.ul_depth, epsilon);
3500 CHECK_COLOR(result, true, checkDepth);
3501
3502 getDepth(end_ur_coord, &tmp_depth, &resultPreBits,
3503 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, m_depth_internalFormat,
3504 dst_ur_rect);
3505 epsilon = GetEpsilon(resultPreBits, depthPreBits);
3506 result &= checkDepth(tmp_depth, m_setup.ur_depth, epsilon);
3507 CHECK_COLOR(result, true, checkDepth);
3508
3509 getDepth(end_ll_coord, &tmp_depth, &resultPreBits,
3510 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, m_depth_internalFormat,
3511 dst_ll_rect);
3512 epsilon = GetEpsilon(resultPreBits, depthPreBits);
3513 result &= checkDepth(tmp_depth, m_setup.ll_depth, epsilon);
3514 CHECK_COLOR(result, true, checkDepth);
3515
3516 getDepth(end_lr_coord, &tmp_depth, &resultPreBits,
3517 buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo, m_depth_internalFormat,
3518 dst_lr_rect);
3519 epsilon = GetEpsilon(resultPreBits, depthPreBits);
3520 result &= checkDepth(tmp_depth, m_setup.lr_depth, epsilon);
3521 CHECK_COLOR(result, true, checkDepth);
3522 }
3523 if (effective_bits & GL_STENCIL_BUFFER_BIT)
3524 {
3525 Stencil tmp_stcil = 0;
3526 getStencil(end_ul_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
3527 m_stcil_internalFormat, dst_ul_rect);
3528 result &= checkStencil(tmp_stcil, m_setup.ul_stcil);
3529 CHECK_COLOR(result, true, checkStencil);
3530
3531 getStencil(end_ur_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
3532 m_stcil_internalFormat, dst_ur_rect);
3533 result &= checkStencil(tmp_stcil, m_setup.ur_stcil);
3534 CHECK_COLOR(result, true, checkStencil);
3535
3536 getStencil(end_ll_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
3537 m_stcil_internalFormat, dst_ll_rect);
3538 result &= checkStencil(tmp_stcil, m_setup.ll_stcil);
3539 CHECK_COLOR(result, true, checkStencil);
3540
3541 getStencil(end_lr_coord, &tmp_stcil, buf_config.dst_type == 0 ? m_defaultFBO : *buf_config.dst_fbo,
3542 m_stcil_internalFormat, dst_lr_rect);
3543 result &= checkStencil(tmp_stcil, m_setup.lr_stcil);
3544 CHECK_COLOR(result, true, checkStencil);
3545 }
3546
3547 /* cleanup */
3548 if (*buf_config.dst_cbuf == *buf_config.src_cbuf && buf_config.dst_type == buf_config.src_type)
3549 {
3550 *buf_config.dst_cbuf = 0;
3551 }
3552 if (*buf_config.dst_dbuf == *buf_config.src_dbuf && buf_config.dst_type == buf_config.src_type)
3553 {
3554 *buf_config.dst_dbuf = 0;
3555 }
3556 if (*buf_config.dst_sbuf == *buf_config.src_sbuf && buf_config.dst_type == buf_config.src_type)
3557 {
3558 *buf_config.dst_sbuf = 0;
3559 }
3560 if (*buf_config.src_sbuf == *buf_config.src_dbuf && buf_config.dst_type == buf_config.src_type)
3561 {
3562 *buf_config.src_sbuf = 0;
3563 }
3564
3565 gl.deleteTextures(2, m_color_tbos);
3566 gl.deleteTextures(2, m_depth_tbos);
3567 gl.deleteTextures(2, m_stcil_tbos);
3568 gl.deleteRenderbuffers(2, m_color_rbos);
3569 gl.deleteRenderbuffers(2, m_depth_rbos);
3570 gl.deleteRenderbuffers(2, m_stcil_rbos);
3571 gl.deleteFramebuffers(2, m_fbos);
3572
3573 m_color_tbos[0] = 0;
3574 m_color_tbos[1] = 0;
3575 m_depth_tbos[0] = 0;
3576 m_depth_tbos[1] = 0;
3577 m_stcil_tbos[0] = 0;
3578 m_stcil_tbos[1] = 0;
3579 m_color_rbos[0] = 0;
3580 m_color_rbos[1] = 0;
3581 m_depth_rbos[0] = 0;
3582 m_depth_rbos[1] = 0;
3583 m_stcil_rbos[0] = 0;
3584 m_stcil_rbos[1] = 0;
3585 m_fbos[0] = 0;
3586 m_fbos[1] = 0;
3587
3588 m_testCtx.getLog() << tcu::TestLog::Message
3589 << "END --------------------------------------------------------------------"
3590 << tcu::TestLog::EndMessage;
3591 }
3592 }
3593 return result;
3594 }
3595
3596 /** Executes test iteration.
3597 *
3598 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
3599 */
iterate()3600 tcu::TestNode::IterateResult FramebufferBlitScissorTestCase::iterate()
3601 {
3602 bool result = true;
3603 GLint max_color_attachments = 0;
3604 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3605
3606 gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
3607 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
3608
3609 CHECK_RET(max_color_attachments >= m_minColorAttachments, GL_TRUE, glGetIntegerv);
3610
3611 if (m_isContextES)
3612 {
3613 GLint max_draw_buffers = 0;
3614 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
3615 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
3616
3617 CHECK_RET(max_draw_buffers >= m_minDrawBuffers, GL_TRUE, glGetIntegerv);
3618 if (max_draw_buffers < max_color_attachments)
3619 {
3620 max_color_attachments = max_draw_buffers;
3621 }
3622 }
3623
3624 /* Test all color buffer formats, depth and stencil buffers attached here */
3625 CHECK_RET(runMultiColorPatternTest(max_color_attachments), true, "Multi color blit test failed");
3626
3627 if (result)
3628 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3629 else
3630 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3631 return STOP;
3632 }
3633
3634 /** Constructor.
3635 *
3636 * @param context Rendering context.
3637 */
FramebufferBlitTests(deqp::Context & context)3638 FramebufferBlitTests::FramebufferBlitTests(deqp::Context &context)
3639 : TestCaseGroup(context, "framebuffer_blit", "Verify conformance of framebuffer blit implementation")
3640 {
3641 }
3642
3643 /** Initializes the test group contents. */
init()3644 void FramebufferBlitTests::init()
3645 {
3646 addChild(new FramebufferBlitMultiToSingleSampledColorConfigTestCase(m_context));
3647 addChild(new FramebufferBlitMultiToSingleSampledDepthConfigTestCase(m_context));
3648 addChild(new FramebufferBlitScissorTestCase(m_context));
3649 }
3650
3651 } // namespace glcts
3652