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 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); 159 glDeleteRenderbuffers(1, &renderbufferID); 160 } 161}; 162 163class RboInternalFormatCase : public ApiCase 164{ 165public: 166 RboInternalFormatCase (Context& context, const char* name, const char* description) 167 : ApiCase(context, name, description) 168 { 169 } 170 171 void test (void) 172 { 173 GLuint renderbufferID = 0; 174 glGenRenderbuffers(1, &renderbufferID); 175 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID); 176 expectError(GL_NO_ERROR); 177 178 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RGBA4); 179 expectError(GL_NO_ERROR); 180 181 const GLenum requiredColorformats[] = 182 { 183 GL_R8, GL_RG8, GL_RGB8, GL_RGB565, GL_RGBA4, GL_RGB5_A1, GL_RGBA8, GL_RGB10_A2, 184 GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I, GL_R8UI, GL_R16I, GL_R16UI, GL_R32I, GL_R32UI, 185 GL_RG8I, GL_RG8UI, GL_RG16I, GL_RG16UI, GL_RG32I, GL_RG32UI, GL_RGBA8I, GL_RGBA8UI, 186 GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI 187 }; 188 189 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorformats); ++ndx) 190 { 191 glRenderbufferStorage(GL_RENDERBUFFER, requiredColorformats[ndx], 128, 128); 192 expectError(GL_NO_ERROR); 193 194 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, requiredColorformats[ndx]); 195 } 196 197 glDeleteRenderbuffers(1, &renderbufferID); 198 } 199}; 200 201class RboComponentSizeColorCase : public ApiCase 202{ 203public: 204 RboComponentSizeColorCase (Context& context, const char* name, const char* description) 205 : ApiCase(context, name, description) 206 { 207 } 208 209 void test (void) 210 { 211 GLuint renderbufferID = 0; 212 glGenRenderbuffers(1, &renderbufferID); 213 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID); 214 expectError(GL_NO_ERROR); 215 216 checkRenderbufferComponentSize(m_testCtx, *this, 0, 0, 0, 0, 0, 0); 217 expectError(GL_NO_ERROR); 218 219 const struct ColorFormat 220 { 221 GLenum internalFormat; 222 int bitsR, bitsG, bitsB, bitsA; 223 } requiredColorFormats[] = 224 { 225 { GL_R8, 8, 0, 0, 0 }, 226 { GL_RG8, 8, 8, 0, 0 }, 227 { GL_RGB8, 8, 8, 8, 0 }, 228 { GL_RGB565, 5, 6, 5, 0 }, 229 { GL_RGBA4, 4, 4, 4, 4 }, 230 { GL_RGB5_A1, 5, 5, 5, 1 }, 231 { GL_RGBA8, 8, 8, 8, 8 }, 232 { GL_RGB10_A2, 10, 10, 10, 2 }, 233 { GL_RGB10_A2UI, 10, 10, 10, 2 }, 234 { GL_SRGB8_ALPHA8, 8, 8, 8, 8 }, 235 { GL_R8I, 8, 0, 0, 0 }, 236 { GL_R8UI, 8, 0, 0, 0 }, 237 { GL_R16I, 16, 0, 0, 0 }, 238 { GL_R16UI, 16, 0, 0, 0 }, 239 { GL_R32I, 32, 0, 0, 0 }, 240 { GL_R32UI, 32, 0, 0, 0 }, 241 { GL_RG8I, 8, 8, 0, 0 }, 242 { GL_RG8UI, 8, 8, 0, 0 }, 243 { GL_RG16I, 16, 16, 0, 0 }, 244 { GL_RG16UI, 16, 16, 0, 0 }, 245 { GL_RG32I, 32, 32, 0, 0 }, 246 { GL_RG32UI, 32, 32, 0, 0 }, 247 { GL_RGBA8I, 8, 8, 8, 8 }, 248 { GL_RGBA8UI, 8, 8, 8, 8 }, 249 { GL_RGBA16I, 16, 16, 16, 16 }, 250 { GL_RGBA16UI, 16, 16, 16, 16 }, 251 { GL_RGBA32I, 32, 32, 32, 32 }, 252 { GL_RGBA32UI, 32, 32, 32, 32 } 253 }; 254 255 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorFormats); ++ndx) 256 { 257 glRenderbufferStorage(GL_RENDERBUFFER, requiredColorFormats[ndx].internalFormat, 128, 128); 258 expectError(GL_NO_ERROR); 259 260 checkRenderbufferComponentSize(m_testCtx, *this, requiredColorFormats[ndx].bitsR, requiredColorFormats[ndx].bitsG, requiredColorFormats[ndx].bitsB, requiredColorFormats[ndx].bitsA, -1, -1); 261 } 262 263 glDeleteRenderbuffers(1, &renderbufferID); 264 } 265}; 266 267class RboComponentSizeDepthCase : public ApiCase 268{ 269public: 270 RboComponentSizeDepthCase (Context& context, const char* name, const char* description) 271 : ApiCase(context, name, description) 272 { 273 } 274 275 void test (void) 276 { 277 using tcu::TestLog; 278 279 GLuint renderbufferID = 0; 280 glGenRenderbuffers(1, &renderbufferID); 281 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID); 282 expectError(GL_NO_ERROR); 283 284 const struct DepthFormat 285 { 286 GLenum internalFormat; 287 int dbits; 288 int sbits; 289 } requiredDepthFormats[] = 290 { 291 { GL_DEPTH_COMPONENT16, 16, 0 }, 292 { GL_DEPTH_COMPONENT24, 24, 0 }, 293 { GL_DEPTH_COMPONENT32F, 32, 0 }, 294 { GL_DEPTH24_STENCIL8, 24, 8 }, 295 { GL_DEPTH32F_STENCIL8, 32, 8 }, 296 }; 297 298 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredDepthFormats); ++ndx) 299 { 300 glRenderbufferStorage(GL_RENDERBUFFER, requiredDepthFormats[ndx].internalFormat, 128, 128); 301 expectError(GL_NO_ERROR); 302 303 checkRenderbufferComponentSize(m_testCtx, *this, -1, -1, -1, -1, requiredDepthFormats[ndx].dbits, requiredDepthFormats[ndx].sbits); 304 } 305 306 // STENCIL_INDEX8 is required, in that case sBits >= 8 307 { 308 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 128, 128); 309 expectError(GL_NO_ERROR); 310 311 StateQueryMemoryWriteGuard<GLint> state; 312 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, &state); 313 314 if (state.verifyValidity(m_testCtx) && state < 8) 315 { 316 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to 8; got " << state << TestLog::EndMessage; 317 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 318 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 319 } 320 } 321 322 glDeleteRenderbuffers(1, &renderbufferID); 323 } 324}; 325 326class RboSamplesCase : public ApiCase 327{ 328public: 329 RboSamplesCase (Context& context, const char* name, const char* description) 330 : ApiCase(context, name, description) 331 { 332 } 333 334 void test (void) 335 { 336 de::Random rnd(0xabcdef); 337 338 GLuint renderbufferID = 0; 339 glGenRenderbuffers(1, &renderbufferID); 340 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID); 341 expectError(GL_NO_ERROR); 342 343 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, 0); 344 expectError(GL_NO_ERROR); 345 346 StateQueryMemoryWriteGuard<GLint> max_samples; 347 glGetIntegerv(GL_MAX_SAMPLES, &max_samples); 348 if (!max_samples.verifyValidity(m_testCtx)) 349 return; 350 351 // 0 samples is a special case 352 { 353 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 128, 128); 354 expectError(GL_NO_ERROR); 355 356 checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, 0); 357 } 358 359 // test [1, n] samples 360 for (int samples = 1; samples <= max_samples; ++samples) 361 { 362 glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, 128, 128); 363 expectError(GL_NO_ERROR); 364 365 checkRenderbufferParamGreaterOrEqual(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, samples); 366 } 367 368 glDeleteRenderbuffers(1, &renderbufferID); 369 } 370}; 371 372} // anonymous 373 374 375RboStateQueryTests::RboStateQueryTests (Context& context) 376 : TestCaseGroup(context, "rbo", "Rbo State Query tests") 377{ 378} 379 380void RboStateQueryTests::init (void) 381{ 382 addChild(new RboSizeCase (m_context, "renderbuffer_size", "RENDERBUFFER_WIDTH and RENDERBUFFER_HEIGHT")); 383 addChild(new RboInternalFormatCase (m_context, "renderbuffer_internal_format", "RENDERBUFFER_INTERNAL_FORMAT")); 384 addChild(new RboComponentSizeColorCase (m_context, "renderbuffer_component_size_color", "RENDERBUFFER_x_SIZE")); 385 addChild(new RboComponentSizeDepthCase (m_context, "renderbuffer_component_size_depth", "RENDERBUFFER_x_SIZE")); 386 addChild(new RboSamplesCase (m_context, "renderbuffer_samples", "RENDERBUFFER_SAMPLES")); 387} 388 389} // Functional 390} // gles3 391} // deqp 392