1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2021 Google Inc. 6 * Copyright (c) 2021 The Khronos Group Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 */ /*! 21 * \file glcTexSubImageTests.cpp 22 * \brief Texture compatibility tests 23 */ /*-------------------------------------------------------------------*/ 24 25#include "glcTextureCompatibilityTests.hpp" 26 27#include "glwEnums.hpp" 28#include "glwFunctions.hpp" 29 30#include "tcuImageCompare.hpp" 31#include "tcuStringTemplate.hpp" 32#include "tcuSurface.hpp" 33#include "tcuTestLog.hpp" 34#include "tcuTextureUtil.hpp" 35 36#include "gluDefs.hpp" 37#include "gluDrawUtil.hpp" 38#include "gluPixelTransfer.hpp" 39#include "gluShaderProgram.hpp" 40#include "gluStrUtil.hpp" 41#include "gluTextureUtil.hpp" 42 43#include <map> 44#include <memory> 45#include <vector> 46 47namespace glcts 48{ 49namespace 50{ 51const float vertexPositions[] = 52{ 53 -1.0f, -1.0f, 54 1.0f, -1.0f, 55 -1.0f, 1.0f, 56 1.0f, 1.0f, 57}; 58 59const float vertexTexCoords[] = 60{ 61 0.0f, 0.0f, 62 1.0f, 0.0f, 63 0.0f, 1.0f, 64 1.0f, 1.0f, 65}; 66 67const char* vertShader = 68 "${VERSION}\n" 69 "in highp vec4 in_position;\n" 70 "in highp vec2 in_texCoord;\n" 71 "out highp vec2 v_texCoord;\n" 72 "void main (void)\n" 73 "{\n" 74 " gl_Position = in_position;\n" 75 " v_texCoord = in_texCoord;\n" 76 "}\n"; 77 78const char* fragShader = 79 "${VERSION}\n" 80 "precision mediump float;\n" 81 "uniform sampler2D texture0;\n" 82 "in vec2 v_texCoord;\n" 83 "out vec4 color;\n" 84 "void main(void)\n" 85 "{\n" 86 " color = texture(texture0, v_texCoord);\n" 87 "}"; 88 89struct TestParameters 90{ 91 std::string testName; 92 glw::GLenum internalFormat; 93 glw::GLenum format; 94 glw::GLenum testType; 95}; 96 97static const TestParameters testParameters[] = 98{ 99 { "rgba4_unsigned_byte", GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE }, 100 { "rgb5_a1_unsigned_byte", GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE }, 101 { "rgb5_a1_unsigned_int_10_a2", GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV }, 102 { "r16f_float", GL_R16F, GL_RED, GL_FLOAT }, 103 { "rg16f_float", GL_RG16F, GL_RG, GL_FLOAT }, 104 { "rgb16f_float", GL_RGB16F, GL_RGB, GL_FLOAT }, 105 { "rgba16f_float", GL_RGBA16F, GL_RGBA, GL_FLOAT }, 106 { "r11f_g11f_b10f_half_float", GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT }, 107 { "r11f_g11f_b10f_float", GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT }, 108 { "rgb9_e5_half_float", GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT }, 109 { "rgb9_e5_float", GL_RGB9_E5, GL_RGB, GL_FLOAT }, 110 { "rgb565_unsigned_byte", GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE }, 111 { "depth_component16_uint", GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT } 112}; 113 114class SubImageFormatTest : public deqp::TestCase 115{ 116public: 117 SubImageFormatTest(deqp::Context& context, const TestParameters testParam, glw::GLsizei textureSize); 118 119 virtual ~SubImageFormatTest(); 120 121 virtual void init (void); 122 virtual void deinit (void); 123 124 virtual IterateResult iterate (void); 125 126private: 127 void setTextureParameters (glw::GLenum target); 128 void drawTexture (void); 129 130 void initializeProgram(); 131 void setVertexBufferObjects(); 132 void setVertexArrayObjects(); 133 134 std::shared_ptr<glu::ShaderProgram> m_program; 135 136 TestParameters m_testParams; 137 glw::GLsizei m_textureSize; 138 glw::GLuint m_texId; 139 glw::GLuint m_vaoId; 140 glw::GLenum m_vboIds[2]; 141}; 142 143SubImageFormatTest::SubImageFormatTest (deqp::Context& context, const TestParameters testParams, glw::GLsizei textureSize) 144 : deqp::TestCase (context, ("texsubimage_format_" + testParams.testName).c_str(), "Pass glTexSubImage with different client format to glTexImage") 145 , m_testParams (testParams) 146 , m_textureSize (textureSize) 147 , m_texId (0) 148 , m_vaoId (0) 149 , m_vboIds { 0, 0 } 150{ 151} 152 153SubImageFormatTest::~SubImageFormatTest() 154{ 155} 156 157void SubImageFormatTest::init(void) 158{ 159 initializeProgram(); 160 setVertexBufferObjects(); 161 setVertexArrayObjects(); 162} 163 164void SubImageFormatTest::deinit(void) 165{ 166 const auto& gl = m_context.getRenderContext().getFunctions(); 167 168 gl.deleteTextures(1, &m_texId); 169 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed"); 170 171 gl.deleteBuffers(1, &m_vaoId); 172 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed"); 173 174 gl.deleteBuffers(DE_LENGTH_OF_ARRAY(m_vboIds), m_vboIds); 175 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed"); 176} 177 178SubImageFormatTest::IterateResult SubImageFormatTest::iterate(void) 179{ 180 const auto& gl = m_context.getRenderContext().getFunctions(); 181 182 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 183 184 // Render buffer 185 glw::GLuint rboId; 186 gl.genRenderbuffers(1, &rboId); 187 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers() failed"); 188 gl.bindRenderbuffer(GL_RENDERBUFFER, rboId); 189 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed"); 190 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, m_textureSize, m_textureSize); 191 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage() failed"); 192 gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 193 194 // Frame buffer 195 glw::GLuint fboId; 196 gl.genFramebuffers(1, &fboId); 197 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed"); 198 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId); 199 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed"); 200 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId); 201 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer() failed"); 202 203 gl.viewport(0, 0, m_textureSize, m_textureSize); 204 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed"); 205 206 gl.disable(GL_BLEND); 207 208 gl.bindTexture(GL_TEXTURE_2D, m_texId); 209 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed"); 210 211 gl.bindVertexArray(m_vaoId); 212 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed"); 213 214 // Create main texture. 215 tcu::TextureFormat refTexFormat (glu::mapGLInternalFormat(m_testParams.internalFormat)); 216 glu::TransferFormat refTransferFormat = glu::getTransferFormat(refTexFormat); 217 tcu::Texture2D refTexture (refTexFormat, m_textureSize, m_textureSize, 1); 218 219 refTexture.allocLevel(0); 220 tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 221 222 // Create variables for reference sub texture. 223 tcu::TextureFormat refTexFormatSub = glu::mapGLInternalFormat(m_testParams.internalFormat); 224 tcu::Texture2D refSubTexture (refTexFormatSub, m_textureSize / 2, m_textureSize / 2, 1); 225 tcu::Surface refSurface (m_textureSize, m_textureSize); 226 227 refSubTexture.allocLevel(0); 228 tcu::fillWithComponentGradients(refSubTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 229 230 // Upload the main texture data. 231 gl.texImage2D(GL_TEXTURE_2D, 0, m_testParams.internalFormat, m_textureSize, m_textureSize, 0, refTransferFormat.format, refTransferFormat.dataType, refTexture.getLevel(0).getDataPtr()); 232 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str()); 233 234 // Update the content of a previously allocated texture with reference sub texture. 235 // Reference sub texture is using the same format and data type than main texture. 236 gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_textureSize / 2, m_textureSize / 2, refTransferFormat.format, refTransferFormat.dataType, refSubTexture.getLevel(0).getDataPtr()); 237 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexSubImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str()); 238 239 setTextureParameters(GL_TEXTURE_2D); 240 241 drawTexture(); 242 243 m_context.getTestContext().getLog() << tcu::TestLog::Message << m_testParams.testName.c_str() << " (" 244 << m_textureSize << " x " << m_textureSize << ")" << tcu::TestLog::EndMessage; 245 246 // Read rendered pixels to reference surface. 247 glu::readPixels(m_context.getRenderContext(), 0, 0, refSurface.getAccess()); 248 249 // Create variables for test sub texture. 250 tcu::TextureFormat testTexFormatSub = glu::mapGLTransferFormat(m_testParams.format, m_testParams.testType); 251 tcu::Texture2D testSubTexture (testTexFormatSub, m_textureSize / 2, m_textureSize / 2, 1); 252 tcu::Surface testSurface (m_textureSize, m_textureSize); 253 254 testSubTexture.allocLevel(0); 255 tcu::fillWithComponentGradients(testSubTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 256 257 // Upload the main texture data again. 258 gl.texImage2D(GL_TEXTURE_2D, 0, m_testParams.internalFormat, m_textureSize, m_textureSize, 0, refTransferFormat.format, refTransferFormat.dataType, refTexture.getLevel(0).getDataPtr()); 259 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str()); 260 261 // Update the content of a previously allocated texture with sub texture but different data type. 262 gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_textureSize / 2, m_textureSize / 2, m_testParams.format, m_testParams.testType, testSubTexture.getLevel(0).getDataPtr()); 263 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexSubImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str()); 264 265 setTextureParameters(GL_TEXTURE_2D); 266 267 drawTexture(); 268 269 // Read rendered pixels to test surface. 270 readPixels(m_context.getRenderContext(), 0, 0, testSurface.getAccess()); 271 272 // Execute the comparison. 273 if (tcu::fuzzyCompare(m_testCtx.getLog(), "texsubimage_format_", "Pass glTexSubImage with different client format to glTexImage", 274 refSurface, testSurface, 0.001f, tcu::COMPARE_LOG_RESULT)) 275 { 276 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 277 } 278 279 // Cleanup 280 gl.bindTexture(GL_TEXTURE_2D, 0); 281 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId); 282 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 283 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 284 gl.deleteFramebuffers(1, &fboId); 285 286 return IterateResult::STOP; 287} 288 289void SubImageFormatTest::setTextureParameters(glw::GLenum target) 290{ 291 const auto& gl = m_context.getRenderContext().getFunctions(); 292 293 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 294 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 295 296 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 297 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 298 299 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); 300 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 301 302 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0); 303 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 304 305 gl.texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 306 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 307 308 gl.texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 309 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 310 311 gl.texParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 312 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed"); 313} 314 315void SubImageFormatTest::drawTexture(void) 316{ 317 const auto& gl = m_context.getRenderContext().getFunctions(); 318 319 gl.useProgram(m_program->getProgram()); 320 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed"); 321 322 gl.clearColor(1.0f, 0.0f, 1.0f, 1.0f); 323 gl.clear(GL_COLOR_BUFFER_BIT); 324 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() failed"); 325 326 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 327 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed"); 328 329 gl.finish(); 330} 331 332void SubImageFormatTest::setVertexBufferObjects() 333{ 334 const auto& gl = m_context.getRenderContext().getFunctions(); 335 336 gl.genBuffers(DE_LENGTH_OF_ARRAY(m_vboIds), m_vboIds); 337 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed"); 338 339 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]); 340 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed"); 341 342 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); 343 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed"); 344 345 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]); 346 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed"); 347 348 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexTexCoords), vertexTexCoords, GL_STATIC_DRAW); 349 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed"); 350 351 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 352 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed"); 353} 354 355void SubImageFormatTest::setVertexArrayObjects() 356{ 357 const auto& gl = m_context.getRenderContext().getFunctions(); 358 const auto program = m_program->getProgram(); 359 const auto positionLoc = gl.getAttribLocation(program, "in_position"); 360 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed"); 361 362 const auto texCoordLoc = gl.getAttribLocation(program, "in_texCoord"); 363 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed"); 364 365 gl.genVertexArrays(1, &m_vaoId); 366 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed"); 367 368 gl.bindVertexArray(m_vaoId); 369 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed"); 370 371 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]); 372 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed"); 373 374 gl.enableVertexAttribArray(positionLoc); 375 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() failed"); 376 377 gl.vertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); 378 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() failed"); 379 380 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]); 381 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed"); 382 383 gl.enableVertexAttribArray(texCoordLoc); 384 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() failed"); 385 386 gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); 387 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() failed"); 388 389 gl.bindVertexArray(0); 390 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed"); 391} 392 393void SubImageFormatTest::initializeProgram() 394{ 395 const auto& gl = m_context.getRenderContext().getFunctions(); 396 397 gl.genTextures(1, &m_texId); 398 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed"); 399 400 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)); 401 const auto glslVersion = glu::getGLSLVersionDeclaration(supportsES32 ? glu::GLSLVersion::GLSL_VERSION_320_ES : glu::GLSLVersion::GLSL_VERSION_310_ES); 402 const auto args = std::map<std::string, std::string>{ { "VERSION", glslVersion } }; 403 const auto vs = tcu::StringTemplate(vertShader).specialize(args); 404 const auto fs = tcu::StringTemplate(fragShader).specialize(args); 405 406 m_program = std::make_shared<glu::ShaderProgram>(m_context.getRenderContext(), 407 glu::ProgramSources() << glu::VertexSource(vs) << glu::FragmentSource(fs)); 408 409 if (!m_program->isOk()) 410 throw std::runtime_error("Compiling shader program failed."); 411} 412 413} // <anonymous> 414 415TextureCompatibilityTests::TextureCompatibilityTests(deqp::Context& context) 416 : deqp::TestCaseGroup(context, "texture_compatibility", "Tests for texture format compatibility") 417{ 418} 419 420TextureCompatibilityTests::~TextureCompatibilityTests(void) 421{ 422} 423 424void TextureCompatibilityTests::init(void) 425{ 426 for (const auto& test : testParameters) 427 addChild(new SubImageFormatTest(m_context, test, 32)); 428} 429 430} // glcts 431