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