1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 "es2fRboStateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es2fApiCase.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 gles2
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
checkRenderbufferParam(tcu::TestContext & testCtx,glu::CallLogWrapper & gl,GLenum pname,GLenum reference)90 void checkRenderbufferParam(tcu::TestContext &testCtx, glu::CallLogWrapper &gl, GLenum pname, GLenum reference)
91 {
92 StateQueryMemoryWriteGuard<GLint> state;
93 gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, pname, &state);
94
95 if (state.verifyValidity(testCtx))
96 checkIntEquals(testCtx, state, reference);
97 }
98
99 class RboSizeCase : public ApiCase
100 {
101 public:
RboSizeCase(Context & context,const char * name,const char * description)102 RboSizeCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description)
103 {
104 }
105
test(void)106 void test(void)
107 {
108 de::Random rnd(0xabcdef);
109
110 GLuint renderbufferID = 0;
111 glGenRenderbuffers(1, &renderbufferID);
112 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
113 expectError(GL_NO_ERROR);
114
115 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_WIDTH, 0);
116 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_HEIGHT, 0);
117 expectError(GL_NO_ERROR);
118
119 const int numIterations = 30;
120 for (int i = 0; i < numIterations; ++i)
121 {
122 const GLint w = rnd.getInt(0, 128);
123 const GLint h = rnd.getInt(0, 128);
124
125 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, w, h);
126 expectError(GL_NO_ERROR);
127
128 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_WIDTH, w);
129 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_HEIGHT, h);
130 }
131
132 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
133 glDeleteRenderbuffers(1, &renderbufferID);
134 }
135 };
136
137 class RboInternalFormatCase : public ApiCase
138 {
139 public:
RboInternalFormatCase(Context & context,const char * name,const char * description)140 RboInternalFormatCase(Context &context, const char *name, const char *description)
141 : ApiCase(context, name, description)
142 {
143 }
144
test(void)145 void test(void)
146 {
147 GLuint renderbufferID = 0;
148 glGenRenderbuffers(1, &renderbufferID);
149 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
150 expectError(GL_NO_ERROR);
151
152 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RGBA4);
153 expectError(GL_NO_ERROR);
154
155 const GLenum requiredColorformats[] = {GL_RGBA4, GL_RGB5_A1, GL_RGB565};
156
157 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorformats); ++ndx)
158 {
159 glRenderbufferStorage(GL_RENDERBUFFER, requiredColorformats[ndx], 1, 1);
160 expectError(GL_NO_ERROR);
161
162 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, requiredColorformats[ndx]);
163 }
164
165 glDeleteRenderbuffers(1, &renderbufferID);
166 }
167 };
168
169 class RboComponentSizeColorCase : public ApiCase
170 {
171 public:
RboComponentSizeColorCase(Context & context,const char * name,const char * description)172 RboComponentSizeColorCase(Context &context, const char *name, const char *description)
173 : ApiCase(context, name, description)
174 {
175 }
176
test(void)177 void test(void)
178 {
179 GLuint renderbufferID = 0;
180 glGenRenderbuffers(1, &renderbufferID);
181 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
182 expectError(GL_NO_ERROR);
183
184 checkRenderbufferComponentSize(m_testCtx, *this, 0, 0, 0, 0, 0, 0);
185 expectError(GL_NO_ERROR);
186
187 const struct ColorFormat
188 {
189 GLenum internalFormat;
190 int bitsR, bitsG, bitsB, bitsA;
191 } requiredColorFormats[] = {
192 {GL_RGBA4, 4, 4, 4, 4},
193 {GL_RGB5_A1, 5, 5, 5, 1},
194 {GL_RGB565, 5, 6, 5, 0},
195 };
196
197 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorFormats); ++ndx)
198 {
199 glRenderbufferStorage(GL_RENDERBUFFER, requiredColorFormats[ndx].internalFormat, 1, 1);
200 expectError(GL_NO_ERROR);
201
202 checkRenderbufferComponentSize(m_testCtx, *this, requiredColorFormats[ndx].bitsR,
203 requiredColorFormats[ndx].bitsG, requiredColorFormats[ndx].bitsB,
204 requiredColorFormats[ndx].bitsA, -1, -1);
205 }
206
207 glDeleteRenderbuffers(1, &renderbufferID);
208 }
209 };
210
211 class RboComponentSizeDepthCase : public ApiCase
212 {
213 public:
RboComponentSizeDepthCase(Context & context,const char * name,const char * description)214 RboComponentSizeDepthCase(Context &context, const char *name, const char *description)
215 : ApiCase(context, name, description)
216 {
217 }
218
test(void)219 void test(void)
220 {
221 using tcu::TestLog;
222
223 GLuint renderbufferID = 0;
224 glGenRenderbuffers(1, &renderbufferID);
225 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
226 expectError(GL_NO_ERROR);
227
228 const struct DepthFormat
229 {
230 GLenum internalFormat;
231 int dbits;
232 int sbits;
233 } requiredDepthFormats[] = {
234 {GL_DEPTH_COMPONENT16, 16, 0},
235 };
236
237 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredDepthFormats); ++ndx)
238 {
239 glRenderbufferStorage(GL_RENDERBUFFER, requiredDepthFormats[ndx].internalFormat, 1, 1);
240 expectError(GL_NO_ERROR);
241
242 checkRenderbufferComponentSize(m_testCtx, *this, -1, -1, -1, -1, requiredDepthFormats[ndx].dbits,
243 requiredDepthFormats[ndx].sbits);
244 }
245
246 // STENCIL_INDEX8 is required, in that case sBits >= 8
247 {
248 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 1, 1);
249 expectError(GL_NO_ERROR);
250
251 StateQueryMemoryWriteGuard<GLint> state;
252 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, &state);
253
254 if (state.verifyValidity(m_testCtx) && state < 8)
255 {
256 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to 8; got " << state
257 << TestLog::EndMessage;
258 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
259 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
260 }
261 }
262
263 glDeleteRenderbuffers(1, &renderbufferID);
264 }
265 };
266
267 } // namespace
268
RboStateQueryTests(Context & context)269 RboStateQueryTests::RboStateQueryTests(Context &context) : TestCaseGroup(context, "rbo", "Rbo State Query tests")
270 {
271 }
272
init(void)273 void RboStateQueryTests::init(void)
274 {
275 addChild(new RboSizeCase(m_context, "renderbuffer_size", "RENDERBUFFER_WIDTH and RENDERBUFFER_HEIGHT"));
276 addChild(new RboInternalFormatCase(m_context, "renderbuffer_internal_format", "RENDERBUFFER_INTERNAL_FORMAT"));
277 addChild(new RboComponentSizeColorCase(m_context, "renderbuffer_component_size_color", "RENDERBUFFER_x_SIZE"));
278 addChild(new RboComponentSizeDepthCase(m_context, "renderbuffer_component_size_depth", "RENDERBUFFER_x_SIZE"));
279 }
280
281 } // namespace Functional
282 } // namespace gles2
283 } // namespace deqp
284