1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2014-2016 The Khronos Group Inc. 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 22 */ /*-------------------------------------------------------------------*/ 23 24 /*! 25 * \file esextcTextureBufferParameters.cpp 26 * \brief Texture Buffer GetTexLevelParameter and GetIntegerv test (Test 6) 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "esextcTextureBufferParameters.hpp" 30 #include "gluContextInfo.hpp" 31 #include "gluDefs.hpp" 32 #include "glwEnums.hpp" 33 #include "glwFunctions.hpp" 34 #include "tcuTestLog.hpp" 35 #include <stddef.h> 36 37 namespace glcts 38 { 39 40 const glw::GLuint TextureBufferParameters::m_n_texels_phase_one = 128; 41 const glw::GLuint TextureBufferParameters::m_n_texels_phase_two = 256; 42 43 /** Constructor 44 * 45 * @param context Test context 46 * @param name Test case's name 47 * @param description Test case's description 48 **/ 49 TextureBufferParameters::TextureBufferParameters(Context& context, const ExtParameters& extParams, const char* name, 50 const char* description) 51 : TestCaseBase(context, extParams, name, description), m_tbo_id(0), m_to_id(0) 52 { 53 } 54 55 /** Initializes all GLES objects and reference values for the test. */ 56 void TextureBufferParameters::initTest(void) 57 { 58 /* Skip if required extensions are not supported. */ 59 if (!m_is_texture_buffer_supported) 60 { 61 throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 62 } 63 64 m_internal_formats[GL_R8] = sizeof(glw::GLubyte) * 1 /* components */; 65 m_internal_formats[GL_R16F] = sizeof(glw::GLhalf) * 1 /* components */; 66 m_internal_formats[GL_R32F] = sizeof(glw::GLfloat) * 1 /* components */; 67 m_internal_formats[GL_R8I] = sizeof(glw::GLbyte) * 1 /* components */; 68 m_internal_formats[GL_R16I] = sizeof(glw::GLshort) * 1 /* components */; 69 m_internal_formats[GL_R32I] = sizeof(glw::GLint) * 1 /* components */; 70 m_internal_formats[GL_R8UI] = sizeof(glw::GLubyte) * 1 /* components */; 71 m_internal_formats[GL_R16UI] = sizeof(glw::GLushort) * 1 /* components */; 72 m_internal_formats[GL_R32UI] = sizeof(glw::GLuint) * 1 /* components */; 73 m_internal_formats[GL_RG8] = sizeof(glw::GLubyte) * 2 /* components */; 74 m_internal_formats[GL_RG16F] = sizeof(glw::GLhalf) * 2 /* components */; 75 m_internal_formats[GL_RG32F] = sizeof(glw::GLfloat) * 2 /* components */; 76 m_internal_formats[GL_RG8I] = sizeof(glw::GLbyte) * 2 /* components */; 77 m_internal_formats[GL_RG16I] = sizeof(glw::GLshort) * 2 /* components */; 78 m_internal_formats[GL_RG32I] = sizeof(glw::GLint) * 2 /* components */; 79 m_internal_formats[GL_RG8UI] = sizeof(glw::GLubyte) * 2 /* components */; 80 m_internal_formats[GL_RG16UI] = sizeof(glw::GLushort) * 2 /* components */; 81 m_internal_formats[GL_RG32UI] = sizeof(glw::GLuint) * 2 /* components */; 82 m_internal_formats[GL_RGB32F] = sizeof(glw::GLfloat) * 3 /* components */; 83 m_internal_formats[GL_RGB32I] = sizeof(glw::GLint) * 3 /* components */; 84 m_internal_formats[GL_RGB32UI] = sizeof(glw::GLuint) * 3 /* components */; 85 m_internal_formats[GL_RGBA8] = sizeof(glw::GLubyte) * 4 /* components */; 86 m_internal_formats[GL_RGBA16F] = sizeof(glw::GLhalf) * 4 /* components */; 87 m_internal_formats[GL_RGBA32F] = sizeof(glw::GLfloat) * 4 /* components */; 88 m_internal_formats[GL_RGBA8I] = sizeof(glw::GLbyte) * 4 /* components */; 89 m_internal_formats[GL_RGBA16I] = sizeof(glw::GLshort) * 4 /* components */; 90 m_internal_formats[GL_RGBA32I] = sizeof(glw::GLint) * 4 /* components */; 91 m_internal_formats[GL_RGBA8UI] = sizeof(glw::GLubyte) * 4 /* components */; 92 m_internal_formats[GL_RGBA16UI] = sizeof(glw::GLushort) * 4 /* components */; 93 m_internal_formats[GL_RGBA32UI] = sizeof(glw::GLuint) * 4 /* components */; 94 95 /* Retrieve GLES entry points. */ 96 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 97 98 gl.genTextures(1, &m_to_id); 99 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate texture object!"); 100 101 gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_to_id); 102 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture object!"); 103 104 gl.genBuffers(1, &m_tbo_id); 105 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate buffer object!"); 106 107 gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tbo_id); 108 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!"); 109 } 110 111 /** Deinitializes GLES objects created during the test */ 112 void TextureBufferParameters::deinit(void) 113 { 114 /* Retrieve GLES entry points. */ 115 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 116 117 /* Reset GLES state */ 118 gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0); 119 gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0); 120 121 /* Delete GLEs objects */ 122 if (m_to_id != 0) 123 { 124 gl.deleteTextures(1, &m_to_id); 125 m_to_id = 0; 126 } 127 128 if (m_tbo_id != 0) 129 { 130 gl.deleteBuffers(1, &m_tbo_id); 131 m_tbo_id = 0; 132 } 133 134 /* Deinitialize base class */ 135 TestCaseBase::deinit(); 136 } 137 138 /** Executes the test. 139 * 140 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 141 * 142 * Note the function throws exception should an error occur! 143 * 144 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 145 **/ 146 tcu::TestNode::IterateResult TextureBufferParameters::iterate(void) 147 { 148 /* Initialization */ 149 initTest(); 150 151 /* Retrieve GLEs entry points. */ 152 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 153 154 glw::GLboolean test_passed = true; 155 156 /* Check GL_TEXTURE_BINDING_BUFFER_EXT */ 157 test_passed = test_passed && queryTextureBufferBinding(m_to_id); 158 159 /* Check GL_TEXTURE_BUFFER_BINDING_EXT */ 160 test_passed = test_passed && queryTextureBindingBuffer(m_tbo_id); 161 162 /* For each GL_TEXTURE_INTERNAL_FORMAT */ 163 for (InternalFormatsMap::iterator iter = m_internal_formats.begin(); iter != m_internal_formats.end(); ++iter) 164 { 165 std::vector<glw::GLubyte> data_phase_one(m_n_texels_phase_one * iter->second, 0); 166 gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_n_texels_phase_one * iter->second, &data_phase_one[0], 167 GL_STATIC_READ); 168 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not allocate buffer object's data store!"); 169 170 gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, iter->first, m_tbo_id); 171 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set buffer object as data source for texture buffer!"); 172 173 /* Check GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT */ 174 test_passed = test_passed && queryTextureBufferDataStoreBinding(m_tbo_id); 175 176 /* Check GL_TEXTURE_INTERNAL_FORMAT */ 177 test_passed = test_passed && queryTextureInternalFormat(iter->first); 178 179 /* Check GL_TEXTURE_BUFFER_OFFSET_EXT */ 180 test_passed = test_passed && queryTextureBufferOffset(0); 181 182 /* Ckeck GL_TEXTURE_BUFFER_SIZE_EXT */ 183 test_passed = test_passed && queryTextureBufferSize(m_n_texels_phase_one * iter->second); 184 185 /* Ckeck wrong lod level */ 186 test_passed = test_passed && queryTextureInvalidLevel(); 187 188 /* Get texture buffer offset alignment */ 189 glw::GLint offset_alignment = 0; 190 gl.getIntegerv(m_glExtTokens.TEXTURE_BUFFER_OFFSET_ALIGNMENT, &offset_alignment); 191 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get texture buffer offset alignment!"); 192 193 /* Resize buffer object */ 194 std::vector<glw::GLubyte> data_phase_two(m_n_texels_phase_two * iter->second + offset_alignment, 0); 195 gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_n_texels_phase_two * iter->second + offset_alignment, 196 &data_phase_two[0], GL_STATIC_READ); 197 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not allocate buffer object's data store!"); 198 199 /* Check GL_TEXTURE_BUFFER_OFFSET_EXT */ 200 test_passed = test_passed && queryTextureBufferOffset(0); 201 202 /* Check GL_TEXTURE_BUFFER_SIZE_EXT */ 203 test_passed = test_passed && queryTextureBufferSize(m_n_texels_phase_two * iter->second + offset_alignment); 204 205 gl.texBufferRange(m_glExtTokens.TEXTURE_BUFFER, iter->first, m_tbo_id, offset_alignment, 206 m_n_texels_phase_two * iter->second); 207 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set buffer object as data source for texture buffer!"); 208 209 /* Check GL_TEXTURE_BUFFER_OFFSET_EXT */ 210 test_passed = test_passed && queryTextureBufferOffset(offset_alignment); 211 212 /* Check GL_TEXTURE_BUFFER_SIZE_EXT */ 213 test_passed = test_passed && queryTextureBufferSize(m_n_texels_phase_two * iter->second); 214 215 gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, iter->first, 0); 216 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not reset buffer object binding!"); 217 } 218 219 if (test_passed) 220 { 221 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 222 } 223 else 224 { 225 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 226 } 227 228 return STOP; 229 } 230 231 /** Query GL_TEXTURE_BUFFER_BINDING_EXT and compare with the expected value. 232 * 233 * Note - the function throws exception should an error occur! 234 * 235 * @param expected Expected value used for comparison. 236 * 237 * @return true if the comparison has passed, 238 * false if the comparison has failed. 239 **/ 240 glw::GLboolean TextureBufferParameters::queryTextureBindingBuffer(glw::GLint expected) 241 { 242 /* Retrieve GLES entry points. */ 243 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 244 245 glw::GLint result = -1; 246 glw::GLboolean test_passed = true; 247 248 gl.getIntegerv(m_glExtTokens.TEXTURE_BUFFER_BINDING, &result); 249 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_BINDING_EXT"); 250 251 if (result != expected) 252 { 253 test_passed = false; 254 255 m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv(GL_TEXTURE_BINDING_BUFFER_EXT) returned " 256 << result << " which is not equal to expected buffer object id == " << expected << ".\n" 257 << tcu::TestLog::EndMessage; 258 } 259 260 return test_passed; 261 } 262 263 /** Query GL_TEXTURE_BINDING_BUFFER_EXT and compare with the expected value. 264 * 265 * Note - the function throws exception should an error occur! 266 * 267 * @param expected Expected value used for comparison. 268 * 269 * @return true if the comparison has passed, 270 * false if the comparison has failed. 271 **/ 272 glw::GLboolean TextureBufferParameters::queryTextureBufferBinding(glw::GLint expected) 273 { 274 /* Retrieve GLES entry points. */ 275 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 276 277 glw::GLint result = -1; 278 glw::GLboolean test_passed = true; 279 280 gl.getIntegerv(m_glExtTokens.TEXTURE_BINDING_BUFFER, &result); 281 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BINDING_BUFFER_EXT"); 282 283 if (result != expected) 284 { 285 test_passed = false; 286 287 m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv(GL_TEXTURE_BUFFER_BINDING_EXT) returned " 288 << result << " which is not equal to expected texture object id == " << expected << ".\n" 289 << tcu::TestLog::EndMessage; 290 } 291 292 return test_passed; 293 } 294 295 /** Query GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT and compare with the expected value. 296 * 297 * Note - the function throws exception should an error occur! 298 * 299 * @param expected Expected value used for comparison. 300 * 301 * @return true if the comparison has passed, 302 * false if the comparison has failed. 303 **/ 304 glw::GLboolean TextureBufferParameters::queryTextureBufferDataStoreBinding(glw::GLint expected) 305 { 306 /* Retrieve GLES entry points. */ 307 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 308 309 glw::GLint result = -1; 310 glw::GLboolean test_passed = true; 311 312 gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_DATA_STORE_BINDING, 313 &result); 314 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT"); 315 316 if (result != expected) 317 { 318 test_passed = false; 319 320 m_testCtx.getLog() << tcu::TestLog::Message 321 << "glGetTexLevelParameteriv(GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT) returned " << result 322 << " which is not equal to expected buffer object id == " << expected << ".\n" 323 << tcu::TestLog::EndMessage; 324 } 325 326 return test_passed; 327 } 328 329 /** Query GL_TEXTURE_BUFFER_OFFSET_EXT and compare with the expected value. 330 * 331 * Note - the function throws exception should an error occur! 332 * 333 * @param expected Expected value used for comparison. 334 * 335 * @return true if the comparison has passed, 336 * false if the comparison has failed. 337 **/ 338 glw::GLboolean TextureBufferParameters::queryTextureBufferOffset(glw::GLint expected) 339 { 340 /* Retrieve GLES entry points. */ 341 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 342 343 glw::GLint result = -1; 344 glw::GLboolean test_passed = true; 345 346 gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_OFFSET, &result); 347 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_OFFSET_EXT"); 348 349 if (result != expected) 350 { 351 test_passed = false; 352 353 m_testCtx.getLog() << tcu::TestLog::Message 354 << "glGetTexLevelParameteriv(GL_TEXTURE_BUFFER_OFFSET_EXT) returned " << result 355 << " which is not equal to expected offset " << expected << ".\n" 356 << tcu::TestLog::EndMessage; 357 } 358 359 return test_passed; 360 } 361 362 /** Query GL_TEXTURE_BUFFER_SIZE_EXT and compare with the expected value. 363 * 364 * Note - the function throws exception should an error occur! 365 * 366 * @param expected Expected value used for comparison. 367 * 368 * @return true if the comparison has passed, 369 * false if the comparison has failed. 370 **/ 371 glw::GLboolean TextureBufferParameters::queryTextureBufferSize(glw::GLint expected) 372 { 373 /* Retrieve GLES entry points. */ 374 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 375 376 glw::GLint result = -1; 377 glw::GLboolean test_passed = true; 378 379 gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_SIZE, &result); 380 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_SIZE_EXT"); 381 382 if (result != expected) 383 { 384 test_passed = false; 385 386 m_testCtx.getLog() << tcu::TestLog::Message << "glGetTexLevelParameteriv(GL_TEXTURE_BUFFER_SIZE_EXT) returned " 387 << result << " which is not equal to expected size " << expected << ".\n" 388 << tcu::TestLog::EndMessage; 389 } 390 391 return test_passed; 392 } 393 394 /** Query GL_TEXTURE_INTERNAL_FORMAT and compare with the expected value. 395 * 396 * Note - the function throws exception should an error occur! 397 * 398 * @param expected Expected value used for comparison. 399 * 400 * @return true if the comparison has passed, 401 * false if the comparison has failed. 402 **/ 403 glw::GLboolean TextureBufferParameters::queryTextureInternalFormat(glw::GLint expected) 404 { 405 /* Retrieve GLES entry points. */ 406 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 407 408 glw::GLint result = -1; 409 glw::GLboolean test_passed = true; 410 411 gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, GL_TEXTURE_INTERNAL_FORMAT, &result); 412 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_INTERNAL_FORMAT"); 413 414 if (result != expected) 415 { 416 test_passed = false; 417 418 m_testCtx.getLog() << tcu::TestLog::Message << "glGetTexLevelParameteriv(GL_TEXTURE_INTERNAL_FORMAT) returned " 419 << result << " which is not equal to expected internal format " << expected 420 << tcu::TestLog::EndMessage; 421 } 422 423 return test_passed; 424 } 425 426 /** Query GL_TEXTURE_BUFFER_SIZE_EXT with invalid texture level 427 * and checks for GL_INVALID_VALUE error. 428 * 429 * Note - the function throws exception should an error occur! 430 * 431 * @return true if the GL_INVALID_VALUE error was generated, 432 * false if the GL_INVALID_VALUE error was not generated. 433 **/ 434 glw::GLboolean TextureBufferParameters::queryTextureInvalidLevel() 435 { 436 /* Retrieve GLES entry points. */ 437 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 438 439 glw::GLint result = -1; 440 glw::GLboolean test_passed = true; 441 442 gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 1, m_glExtTokens.TEXTURE_BUFFER_SIZE, &result); 443 glw::GLenum error_code = gl.getError(); 444 445 if (error_code != GL_INVALID_VALUE) 446 { 447 test_passed = false; 448 449 m_testCtx.getLog() << tcu::TestLog::Message 450 << "glGetTexLevelParameteriv() called for GL_TEXTURE_BUFFER_EXT texture target " 451 << "with lod level different than 0 did not generate an GL_INVALID_VALUE error.\n" 452 << tcu::TestLog::EndMessage; 453 } 454 455 return test_passed; 456 } 457 458 } /* namespace glcts */ 459