xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fRboStateQueryTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
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 Rbo state query tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fRboStateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es3fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "deRandom.hpp"
31 #include "deMath.h"
32 
33 using namespace glw; // GLint and other GL types
34 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
35 
36 namespace deqp
37 {
38 namespace gles3
39 {
40 namespace Functional
41 {
42 namespace
43 {
44 
checkRenderbufferComponentSize(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,int r,int g,int b,int a,int d,int s)45 void checkRenderbufferComponentSize(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, int r, int g, int b, int a,
46                                     int d, int s)
47 {
48     using tcu::TestLog;
49 
50     const int referenceSizes[] = {r, g, b, a, d, s};
51     const GLenum paramNames[]  = {GL_RENDERBUFFER_RED_SIZE,   GL_RENDERBUFFER_GREEN_SIZE, GL_RENDERBUFFER_BLUE_SIZE,
52                                   GL_RENDERBUFFER_ALPHA_SIZE, GL_RENDERBUFFER_DEPTH_SIZE, GL_RENDERBUFFER_STENCIL_SIZE};
53 
54     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(referenceSizes) == DE_LENGTH_OF_ARRAY(paramNames));
55 
56     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(referenceSizes); ++ndx)
57     {
58         if (referenceSizes[ndx] == -1)
59             continue;
60 
61         StateQueryMemoryWriteGuard<GLint> state;
62         gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, paramNames[ndx], &state);
63 
64         if (!state.verifyValidity(testCtx))
65             return;
66 
67         if (state < referenceSizes[ndx])
68         {
69             testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to " << referenceSizes[ndx]
70                              << "; got " << state << TestLog::EndMessage;
71             if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
72                 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
73         }
74     }
75 }
76 
checkIntEquals(tcu::TestContext & testCtx,GLint got,GLint expected)77 void checkIntEquals(tcu::TestContext &testCtx, GLint got, GLint expected)
78 {
79     using tcu::TestLog;
80 
81     if (got != expected)
82     {
83         testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got
84                          << TestLog::EndMessage;
85         if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
86             testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
87     }
88 }
89 
checkIntGreaterOrEqual(tcu::TestContext & testCtx,GLint got,GLint expected)90 void checkIntGreaterOrEqual(tcu::TestContext &testCtx, GLint got, GLint expected)
91 {
92     using tcu::TestLog;
93 
94     if (got < expected)
95     {
96         testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to " << expected << "; got " << got
97                          << TestLog::EndMessage;
98         if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
99             testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
100     }
101 }
102 
checkRenderbufferParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLenum pname,GLenum reference)103 void checkRenderbufferParam(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLenum pname, GLenum reference)
104 {
105     StateQueryMemoryWriteGuard<GLint> state;
106     gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, pname, &state);
107 
108     if (state.verifyValidity(testCtx))
109         checkIntEquals(testCtx, state, reference);
110 }
111 
checkRenderbufferParamGreaterOrEqual(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLenum pname,GLenum reference)112 void checkRenderbufferParamGreaterOrEqual(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLenum pname,
113                                           GLenum reference)
114 {
115     StateQueryMemoryWriteGuard<GLint> state;
116     gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, pname, &state);
117 
118     if (state.verifyValidity(testCtx))
119         checkIntGreaterOrEqual(testCtx, state, reference);
120 }
121 
122 class RboSizeCase : public ApiCase
123 {
124 public:
RboSizeCase(Context & context,const char * name,const char * description)125     RboSizeCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
126     {
127     }
128 
test(void)129     void test(void)
130     {
131         de::Random rnd(0xabcdef);
132 
133         GLuint renderbufferID = 0;
134         glGenRenderbuffers(1, &renderbufferID);
135         glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
136         expectError(GL_NO_ERROR);
137 
138         checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_WIDTH, 0);
139         checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_HEIGHT, 0);
140         expectError(GL_NO_ERROR);
141 
142         const int numIterations = 60;
143         for (int i = 0; i < numIterations; ++i)
144         {
145             const GLint w = rnd.getInt(0, 128);
146             const GLint h = rnd.getInt(0, 128);
147 
148             glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, w, h);
149 
150             checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_WIDTH, w);
151             checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_HEIGHT, h);
152         }
153 
154         glDeleteRenderbuffers(1, &renderbufferID);
155     }
156 };
157 
158 class RboInternalFormatCase : public ApiCase
159 {
160 public:
RboInternalFormatCase(Context & context,const char * name,const char * description)161     RboInternalFormatCase(Context &context, const char *name, const char *description)
162         : ApiCase(context, name, description)
163     {
164     }
165 
test(void)166     void test(void)
167     {
168         GLuint renderbufferID = 0;
169         glGenRenderbuffers(1, &renderbufferID);
170         glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
171         expectError(GL_NO_ERROR);
172 
173         const glu::ContextType &contextType = m_context.getRenderContext().getType();
174         const bool isCoreGL45               = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
175 
176         GLenum initialValue = isCoreGL45 ? GL_RGBA : GL_RGBA4;
177         checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, initialValue);
178         expectError(GL_NO_ERROR);
179 
180         const GLenum requiredColorformats[] = {
181             GL_R8,       GL_RG8,        GL_RGB8,         GL_RGB565,  GL_RGBA4,    GL_RGB5_A1, GL_RGBA8,
182             GL_RGB10_A2, GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I,     GL_R8UI,     GL_R16I,    GL_R16UI,
183             GL_R32I,     GL_R32UI,      GL_RG8I,         GL_RG8UI,   GL_RG16I,    GL_RG16UI,  GL_RG32I,
184             GL_RG32UI,   GL_RGBA8I,     GL_RGBA8UI,      GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI};
185 
186         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorformats); ++ndx)
187         {
188             glRenderbufferStorage(GL_RENDERBUFFER, requiredColorformats[ndx], 128, 128);
189             expectError(GL_NO_ERROR);
190 
191             checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, requiredColorformats[ndx]);
192         }
193 
194         glDeleteRenderbuffers(1, &renderbufferID);
195     }
196 };
197 
198 class RboComponentSizeColorCase : public ApiCase
199 {
200 public:
RboComponentSizeColorCase(Context & context,const char * name,const char * description)201     RboComponentSizeColorCase(Context &context, const char *name, const char *description)
202         : ApiCase(context, name, description)
203     {
204     }
205 
test(void)206     void test(void)
207     {
208         GLuint renderbufferID = 0;
209         glGenRenderbuffers(1, &renderbufferID);
210         glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
211         expectError(GL_NO_ERROR);
212 
213         checkRenderbufferComponentSize(m_testCtx, *this, 0, 0, 0, 0, 0, 0);
214         expectError(GL_NO_ERROR);
215 
216         const struct ColorFormat
217         {
218             GLenum internalFormat;
219             int bitsR, bitsG, bitsB, bitsA;
220         } requiredColorFormats[] = {
221             {GL_R8, 8, 0, 0, 0},           {GL_RG8, 8, 8, 0, 0},          {GL_RGB8, 8, 8, 8, 0},
222             {GL_RGB565, 5, 6, 5, 0},       {GL_RGBA4, 4, 4, 4, 4},        {GL_RGB5_A1, 5, 5, 5, 1},
223             {GL_RGBA8, 8, 8, 8, 8},        {GL_RGB10_A2, 10, 10, 10, 2},  {GL_RGB10_A2UI, 10, 10, 10, 2},
224             {GL_SRGB8_ALPHA8, 8, 8, 8, 8}, {GL_R8I, 8, 0, 0, 0},          {GL_R8UI, 8, 0, 0, 0},
225             {GL_R16I, 16, 0, 0, 0},        {GL_R16UI, 16, 0, 0, 0},       {GL_R32I, 32, 0, 0, 0},
226             {GL_R32UI, 32, 0, 0, 0},       {GL_RG8I, 8, 8, 0, 0},         {GL_RG8UI, 8, 8, 0, 0},
227             {GL_RG16I, 16, 16, 0, 0},      {GL_RG16UI, 16, 16, 0, 0},     {GL_RG32I, 32, 32, 0, 0},
228             {GL_RG32UI, 32, 32, 0, 0},     {GL_RGBA8I, 8, 8, 8, 8},       {GL_RGBA8UI, 8, 8, 8, 8},
229             {GL_RGBA16I, 16, 16, 16, 16},  {GL_RGBA16UI, 16, 16, 16, 16}, {GL_RGBA32I, 32, 32, 32, 32},
230             {GL_RGBA32UI, 32, 32, 32, 32}};
231 
232         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorFormats); ++ndx)
233         {
234             glRenderbufferStorage(GL_RENDERBUFFER, requiredColorFormats[ndx].internalFormat, 128, 128);
235             expectError(GL_NO_ERROR);
236 
237             checkRenderbufferComponentSize(m_testCtx, *this, requiredColorFormats[ndx].bitsR,
238                                            requiredColorFormats[ndx].bitsG, requiredColorFormats[ndx].bitsB,
239                                            requiredColorFormats[ndx].bitsA, -1, -1);
240         }
241 
242         glDeleteRenderbuffers(1, &renderbufferID);
243     }
244 };
245 
246 class RboComponentSizeDepthCase : public ApiCase
247 {
248 public:
RboComponentSizeDepthCase(Context & context,const char * name,const char * description)249     RboComponentSizeDepthCase(Context &context, const char *name, const char *description)
250         : ApiCase(context, name, description)
251     {
252     }
253 
test(void)254     void test(void)
255     {
256         using tcu::TestLog;
257 
258         GLuint renderbufferID = 0;
259         glGenRenderbuffers(1, &renderbufferID);
260         glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
261         expectError(GL_NO_ERROR);
262 
263         const struct DepthFormat
264         {
265             GLenum internalFormat;
266             int dbits;
267             int sbits;
268         } requiredDepthFormats[] = {
269             {GL_DEPTH_COMPONENT16, 16, 0}, {GL_DEPTH_COMPONENT24, 24, 0}, {GL_DEPTH_COMPONENT32F, 32, 0},
270             {GL_DEPTH24_STENCIL8, 24, 8},  {GL_DEPTH32F_STENCIL8, 32, 8},
271         };
272 
273         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredDepthFormats); ++ndx)
274         {
275             glRenderbufferStorage(GL_RENDERBUFFER, requiredDepthFormats[ndx].internalFormat, 128, 128);
276             expectError(GL_NO_ERROR);
277 
278             checkRenderbufferComponentSize(m_testCtx, *this, -1, -1, -1, -1, requiredDepthFormats[ndx].dbits,
279                                            requiredDepthFormats[ndx].sbits);
280         }
281 
282         // STENCIL_INDEX8 is required, in that case sBits >= 8
283         {
284             glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 128, 128);
285             expectError(GL_NO_ERROR);
286 
287             StateQueryMemoryWriteGuard<GLint> state;
288             glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, &state);
289 
290             if (state.verifyValidity(m_testCtx) && state < 8)
291             {
292                 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to 8; got " << state
293                                    << TestLog::EndMessage;
294                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
295                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
296             }
297         }
298 
299         glDeleteRenderbuffers(1, &renderbufferID);
300     }
301 };
302 
303 class RboSamplesCase : public ApiCase
304 {
305 public:
RboSamplesCase(Context & context,const char * name,const char * description)306     RboSamplesCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
307     {
308     }
309 
test(void)310     void test(void)
311     {
312         GLuint renderbufferID = 0;
313         glGenRenderbuffers(1, &renderbufferID);
314         glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
315         expectError(GL_NO_ERROR);
316 
317         checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, 0);
318         expectError(GL_NO_ERROR);
319 
320         StateQueryMemoryWriteGuard<GLint> max_samples;
321         glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
322         if (!max_samples.verifyValidity(m_testCtx))
323             return;
324 
325         // 0 samples is a special case
326         {
327             glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 128, 128);
328             expectError(GL_NO_ERROR);
329 
330             checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, 0);
331         }
332 
333         // test [1, n] samples
334         for (int samples = 1; samples <= max_samples; ++samples)
335         {
336             glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, 128, 128);
337             expectError(GL_NO_ERROR);
338 
339             checkRenderbufferParamGreaterOrEqual(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, samples);
340         }
341 
342         glDeleteRenderbuffers(1, &renderbufferID);
343     }
344 };
345 
346 } // namespace
347 
RboStateQueryTests(Context & context)348 RboStateQueryTests::RboStateQueryTests(Context &context) : TestCaseGroup(context, "rbo", "Rbo State Query tests")
349 {
350 }
351 
init(void)352 void RboStateQueryTests::init(void)
353 {
354     addChild(new RboSizeCase(m_context, "renderbuffer_size", "RENDERBUFFER_WIDTH and RENDERBUFFER_HEIGHT"));
355     addChild(new RboInternalFormatCase(m_context, "renderbuffer_internal_format", "RENDERBUFFER_INTERNAL_FORMAT"));
356     addChild(new RboComponentSizeColorCase(m_context, "renderbuffer_component_size_color", "RENDERBUFFER_x_SIZE"));
357     addChild(new RboComponentSizeDepthCase(m_context, "renderbuffer_component_size_depth", "RENDERBUFFER_x_SIZE"));
358     addChild(new RboSamplesCase(m_context, "renderbuffer_samples", "RENDERBUFFER_SAMPLES"));
359 }
360 
361 } // namespace Functional
362 } // namespace gles3
363 } // namespace deqp
364