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