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