• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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