1 #ifndef _GLCFRAMEBUFFERBLITTESTS_HPP 2 #define _GLCFRAMEBUFFERBLITTESTS_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2024 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26 /** 27 */ /*! 28 * \file glcFramebufferBlitTests.hpp 29 * \brief Conformance tests for framebuffer blit feature functionality. 30 */ /*-------------------------------------------------------------------*/ 31 32 #include "glcTestCase.hpp" 33 #include "glwDefs.hpp" 34 #include "tcuVector.hpp" 35 #include "tcuVectorType.hpp" 36 #include "gluShaderProgram.hpp" 37 38 #include <map> 39 40 namespace glcts 41 { 42 namespace blt 43 { 44 // test utils 45 struct Rectangle 46 { Rectangleglcts::blt::Rectangle47 Rectangle(glw::GLint x_, glw::GLint y_, glw::GLint width_, glw::GLint height_) : x(x_), y(y_), w(width_), h(height_) 48 { 49 } 50 Rectangleglcts::blt::Rectangle51 Rectangle() : x(0), y(0), w(0), h(0) 52 { 53 } 54 55 glw::GLint x; 56 glw::GLint y; 57 glw::GLint w; 58 glw::GLint h; 59 }; 60 61 using Stencil = glw::GLuint; 62 using Depth = glw::GLfloat; 63 using Color = tcu::Vec4; 64 using Coord = tcu::IVec2; 65 66 /* struct used in 4.8 - 4.14 tests to confirm that the negative 67 * height, negative width, negative dimensions, magnifying and 68 * minifying works properly */ 69 struct MultiColorTestSetup 70 { 71 Rectangle ul_rect; /* upper left region to multicolor pattern */ 72 Rectangle ur_rect; /* upper right region to multicolor pattern */ 73 Rectangle ll_rect; /* lower left region to multicolor pattern */ 74 Rectangle lr_rect; /* lower right region to multicolor pattern */ 75 Rectangle blt_src_rect; /* src rectangle to glBlitFramebuffer */ 76 Rectangle blt_dst_rect; /* dst rectangle to glBlitFramebuffer */ 77 Rectangle scissor_rect; /* scissor rectangle used in 4.14 test */ 78 Coord ul_coord = {0, 0}; /* coord from which the upper left pixel is read */ 79 Coord ur_coord = {0, 0}; /* coord from which the upper right pixel is read */ 80 Coord ll_coord = {0, 0}; /* coord from which the lower left pixel is read */ 81 Coord lr_coord = {0, 0}; /* coord from which the lower right pixel is read */ 82 Color ul_color = {0, 0, 0, 0}; /* expected upper left color */ 83 Color ur_color = {0, 0, 0, 0}; /* expected upper right color */ 84 Color ll_color = {0, 0, 0, 0}; /* expected lower left color */ 85 Color lr_color = {0, 0, 0, 0}; /* expected lower right color */ 86 Depth ul_depth = 0.f; /* expected upper left depth */ 87 Depth ur_depth = 0.f; /* expected upper right depth */ 88 Depth ll_depth = 0.f; /* expected lower left depth */ 89 Depth lr_depth = 0.f; /* expected lower right depth */ 90 Stencil ul_stcil = 0; /* expected upper left stcil */ 91 Stencil ur_stcil = 0; /* expected upper right stcil */ 92 Stencil ll_stcil = 0; /* expected lower left stcil */ 93 Stencil lr_stcil = 0; /* expected lower right stcil */ 94 glw::GLboolean negative_src_width = 0; /* negative src rectangle width */ 95 glw::GLboolean negative_src_height = 0; /* negative src rectangle height */ 96 glw::GLboolean negative_dst_width = 0; /* negative dst rectangle width */ 97 glw::GLboolean negative_dst_height = 0; /* negative dst rectangle height */ 98 }; 99 100 /* typedefs, structs */ 101 struct BufferConfig 102 { 103 glw::GLuint *src_fbo = nullptr; 104 glw::GLuint *dst_fbo = nullptr; 105 glw::GLuint src_type = 0; 106 glw::GLuint dst_type; 107 glw::GLuint *src_cbuf = nullptr; 108 glw::GLuint *src_dbuf = nullptr; 109 glw::GLuint *src_sbuf = nullptr; 110 glw::GLuint *dst_cbuf = nullptr; 111 glw::GLuint *dst_dbuf = nullptr; 112 glw::GLuint *dst_sbuf = nullptr; 113 glw::GLuint same_read_and_draw_buffer = 0; 114 }; 115 116 struct MultisampleColorConfig 117 { 118 glw::GLint internal_format = 0; 119 glw::GLenum format = 0; 120 glw::GLenum type = 0; 121 glw::GLuint color_channel_bits = 0; 122 glw::GLboolean bIsFloat = 0; 123 }; 124 125 struct DepthConfig 126 { 127 glw::GLenum internal_format = 0; 128 glw::GLenum format = 0; 129 glw::GLenum type = 0; 130 glw::GLenum attachment = 0; 131 glw::GLuint precisionBits = 0; 132 }; 133 } // namespace blt 134 135 /** Base class for below test cases which encapsulates shared functionality and resources */ 136 class FramebufferBlitBaseTestCase : public deqp::TestCase 137 { 138 public: 139 /* Public methods */ 140 FramebufferBlitBaseTestCase(deqp::Context &context, const char *, const char *); 141 142 virtual void deinit() override; 143 virtual void init() override; 144 145 bool GetDefaultFramebufferBlitFormat(bool *noDepth, bool *noStencil); 146 147 bool GetDrawbuffer32DepthComponentType(glw::GLint *value); 148 149 template <typename... Args> 150 void tcu_fail_msg(const std::string &format, Args... args); 151 152 template <glw::GLenum E, glw::GLuint S, typename F> 153 bool init_gl_objs(F f, const glw::GLuint count, const glw::GLuint *buf, const glw::GLint format); 154 155 bool check_param(const glw::GLboolean, const char *); 156 157 bool clearColorBuffer(const glw::GLuint, const glw::GLenum, const glw::GLenum, const glw::GLuint, 158 const blt::Color &, const blt::Rectangle &, const blt::Coord &, const glw::GLuint, 159 const bool); 160 161 bool attachBufferToFramebuffer(const glw::GLenum, const glw::GLenum, const glw::GLenum, const glw::GLuint); 162 163 bool getColor(const blt::Coord &, blt::Color *, const bool); 164 165 bool checkColor(const blt::Color &, const blt::Color &, const glw::GLuint); 166 167 glw::GLubyte floatToByte(const glw::GLfloat f); 168 169 bool clearDepthBuffer(const glw::GLuint, const glw::GLenum, const glw::GLenum, const glw::GLuint, const glw::GLuint, 170 const blt::Depth, const blt::Rectangle &, const blt::Coord &); 171 172 bool getDepth(const blt::Coord &, blt::Depth *, glw::GLuint *, const glw::GLuint, const glw::GLuint, 173 const blt::Rectangle &); 174 175 glw::GLuint GetDepthPrecisionBits(const glw::GLenum depthInternalFormat); 176 177 bool checkDepth(const blt::Depth actual, const blt::Depth expected, const glw::GLfloat epsilon); 178 179 bool setupDefaultShader(glw::GLuint &vao, glw::GLuint &vbo); 180 181 bool getStencil(const blt::Coord &, blt::Stencil *, const glw::GLuint, const glw::GLuint, const blt::Rectangle &); 182 183 bool clearStencilBuffer(const glw::GLuint, const glw::GLenum, const glw::GLenum, const glw::GLuint, 184 const glw::GLuint, const blt::Stencil, const blt::Rectangle &, const blt::Coord &); 185 186 bool checkStencil(const blt::Stencil actual, const blt::Stencil expected); 187 188 bool setupRenderShader(glw::GLuint &vao, glw::GLuint &vbo, glw::GLint *uColor); 189 190 void printGlobalBufferInfo(); 191 192 protected: 193 /* Private members */ 194 glw::GLuint m_fbos[2]; 195 196 glw::GLuint m_color_tbos[2]; 197 glw::GLuint m_depth_tbos[2]; 198 glw::GLuint m_stcil_tbos[2]; 199 glw::GLuint m_color_rbos[2]; 200 glw::GLuint m_depth_rbos[2]; 201 glw::GLuint m_stcil_rbos[2]; 202 203 glw::GLuint m_dflt; 204 205 blt::Rectangle m_fullRect; 206 tcu::IVec2 m_defaultCoord; 207 208 static const glw::GLchar *m_default_vert_shader; 209 static const glw::GLchar *m_default_frag_shader; 210 211 static const glw::GLchar *m_render_vert_shader; 212 static const glw::GLchar *m_render_frag_shader; 213 214 std::map<std::string, std::string> specializationMap; 215 216 glu::ShaderProgram *m_defaultProg; 217 glu::ShaderProgram *m_renderProg; 218 219 blt::MultiColorTestSetup m_setup; 220 221 bool m_isContextES; 222 223 glw::GLuint m_defaultFBO; 224 225 bool m_cbfTestSupported; 226 bool m_msTbosSupported; 227 228 glw::GLint m_minDrawBuffers; 229 glw::GLint m_minColorAttachments; 230 231 std::vector<blt::BufferConfig> m_bufferCfg; 232 std::vector<blt::DepthConfig> m_depthCfg; 233 234 glw::GLuint m_depth_internalFormat; 235 glw::GLuint m_depth_type; 236 glw::GLuint m_depth_format; 237 238 glw::GLuint m_stcil_internalFormat; 239 glw::GLuint m_stcil_type; 240 glw::GLuint m_stcil_format; 241 }; 242 243 /* 4.15 Confirm that blits from multisampled to single sampled 244 * framebuffers of various types are properly resolved. 245 * 246 * Initialize the full source framebuffer to a multicolor pattern 247 * using each of color formats R8, RG8, RGB8, RGBA8, SRGB8_ALPHA8, 248 * RGB10_A2, RGBA4, RGB5_A1, RGB565, R11F_G11F_B10F, RG16F, and R16F 249 * and depth formats DEPTH_COMPONENT24, DEPTH_COMPONENT16, 250 * DEPTH24_STENCIL8, DEPTH_COMPONENT32F, and DEPTH32F_STENCIL8 at 251 * least once. Initialize the destination framebuffer to color black, 252 * depth value zero, and stencil value zero. Blit the pixels from the 253 * source to the destination using a color, depth, and stencil mask, 254 * nearest filter, and source dimensions covering the complete 255 * framebuffer size and equal source and destination dimensions. Read 256 * four pixels from each of the corners of the lower left quadrant of 257 * the destination. Confirm that the read color, depth, and stencil 258 * values are as follows: 259 * 260 * upper left: red , 0.25, 1 261 * upper right: green, 0.50, 2 262 * lower left: blue , 0.75, 3 263 * lower right: white, 1.00, 4 264 * 265 * Procedure: 266 * 267 * Run a modified multicolor pattern test (see 268 * runMultiColorPatternTest function) for the color and depth buffer 269 * formats. Test runs through all the appropriate buffer 270 * configurations (see BltBufferConfigs struct) of the default 271 * framebuffer and user framebuffers (with the texture and 272 * renderbuffer attachments) as read and draw framebuffers. 273 * 274 * Test is divided in two sections. First, blitting in color buffers 275 * of various formats are verified without any depth buffers 276 * attached. Then, blitting in depth buffers of various formats are 277 * verified without any color buffers attached. 278 * 279 * Test prepares the color and depth (and depth_stencil) buffers to 280 * the multicolor pattern, binds framebuffer objects for reading and 281 * drawing, attaches the user-generated buffers to the framebuffers, 282 * checks framebuffer status, blits from the read framebuffer to the 283 * draw framebuffer, and finally checks the appropriate color, depth, 284 * and stencil values. 285 * 286 * Notes: 287 * 288 * 1) Is it OK to test all formats separately so that missing buffers 289 * are ignored? For example, by setting up only one 290 * color/depth/stencil buffer without assigning any other buffers, and 291 * letting glFramebufferBlit with color/depth/stencil bits to ignore 292 * other buffers. Or should we test the color, depth and stencil 293 * buffers in same glFramebufferBlit call? 294 * 295 * 2) Should we read pixels from the corners of the whole buffer 296 * instead of the corners of the lower left quadrant? 297 */ 298 299 /** Test case which encapsulates blit multisampled to single sampled targets of 300 * all available formats */ 301 class FramebufferBlitMultiToSingleSampledTestCase : public FramebufferBlitBaseTestCase 302 { 303 public: 304 /* Public methods */ 305 FramebufferBlitMultiToSingleSampledTestCase(deqp::Context &context); 306 FramebufferBlitMultiToSingleSampledTestCase(deqp::Context &context, const char *, const char *); 307 308 void deinit() override; 309 void init() override; 310 tcu::TestNode::IterateResult iterate() override; 311 312 protected: 313 /* Private members */ 314 std::vector<blt::MultisampleColorConfig> m_multisampleColorCfg; 315 }; 316 317 class FramebufferBlitMultiToSingleSampledColorConfigTestCase : public FramebufferBlitMultiToSingleSampledTestCase 318 { 319 public: 320 /* Public methods */ 321 FramebufferBlitMultiToSingleSampledColorConfigTestCase(deqp::Context &context); 322 323 template <glw::GLuint> 324 bool testColorBlitConfig(const tcu::IVec2 &, const tcu::IVec2 &, const tcu::IVec2 &, const tcu::IVec2 &, 325 const glw::GLint); 326 }; 327 328 class FramebufferBlitMultiToSingleSampledDepthConfigTestCase : public FramebufferBlitMultiToSingleSampledTestCase 329 { 330 public: 331 /* Public methods */ 332 FramebufferBlitMultiToSingleSampledDepthConfigTestCase(deqp::Context &context); 333 334 template <glw::GLuint> 335 bool testDepthBlitConfig(const tcu::IVec2 &, const tcu::IVec2 &, const tcu::IVec2 &, const tcu::IVec2 &); 336 }; 337 338 /* 4.14 Confirm that the scissor test is properly respected. 339 * 340 * Initialize the source framebuffer to color green, depth value one, 341 * and stencil value one. Initialize the destination framebuffer to 342 * color black, depth value zero, and stencil value zero. Define a 343 * scissor box that encompasses the lower left quadrant of the 344 * destination. Blit from the source to the destination using a color, 345 * depth, and stencil mask, nearest filter, and equal source and 346 * destination dimensions. Read four pixels from each of the corners 347 * of the lower left quadrant of the destination. Confirm that the 348 * lower left pixel is green with stencil and depth values of one, and 349 * that the other pixels are all red with stencil and depth values of 350 * zero. 351 * 352 * Procedure: 353 * 354 * Setup the MultiColorTestSetup struct with appropriate quadrant 355 * rectangles, source and destination rectangles for blitting, scissor 356 * rectangle, guadrant coordinates from which to verify the quadrant 357 * pixel values, and expected quadrant color/depth/stencil 358 * values. Then, run the multicolor pattern test with this setup. 359 * 360 * Notes: 361 * 362 * Should we read the pixels from the buffer corners instead of the 363 * lower left quadrant corners? In addition, inconsistency between the 364 * green source color and the expected red color. 365 */ 366 367 class FramebufferBlitScissorTestCase : public FramebufferBlitBaseTestCase 368 { 369 public: 370 /* Public methods */ 371 FramebufferBlitScissorTestCase(deqp::Context &context); 372 373 void deinit(); 374 void init(); 375 tcu::TestNode::IterateResult iterate(); 376 377 bool runMultiColorPatternTest(const glw::GLint); 378 379 private: 380 /* Private members */ 381 }; 382 383 /** Test group which encapsulates all conformance tests */ 384 class FramebufferBlitTests : public deqp::TestCaseGroup 385 { 386 public: 387 /* Public methods */ 388 FramebufferBlitTests(deqp::Context &context); 389 390 void init(); 391 392 private: 393 FramebufferBlitTests(const FramebufferBlitTests &other); 394 FramebufferBlitTests &operator=(const FramebufferBlitTests &other); 395 }; 396 397 } // namespace glcts 398 399 #endif // _GLCFRAMEBUFFERBLITTESTS_HPP 400