1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2017 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 EXT Shader Framebuffer Fetch Tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fShaderFramebufferFetchTests.hpp" 25 #include "es31fFboTestUtil.hpp" 26 27 #include "tcuTestLog.hpp" 28 #include "tcuSurface.hpp" 29 #include "tcuTextureUtil.hpp" 30 #include "tcuImageCompare.hpp" 31 #include "tcuVectorUtil.hpp" 32 33 #include "gluShaderProgram.hpp" 34 #include "gluPixelTransfer.hpp" 35 #include "gluTextureUtil.hpp" 36 #include "gluContextInfo.hpp" 37 #include "gluObjectWrapper.hpp" 38 39 #include "glwFunctions.hpp" 40 #include "glwEnums.hpp" 41 42 #include "deStringUtil.hpp" 43 44 #include <vector> 45 46 namespace deqp 47 { 48 namespace gles31 49 { 50 namespace Functional 51 { 52 namespace 53 { 54 55 using std::vector; 56 using std::string; 57 using tcu::TestLog; 58 59 using namespace glw; 60 using namespace FboTestUtil; 61 62 static void checkExtensionSupport (Context& context, const char* extName) 63 { 64 if (!context.getContextInfo().isExtensionSupported(extName)) 65 throw tcu::NotSupportedError(string(extName) + " not supported"); 66 } 67 68 static void checkFramebufferFetchSupport (Context& context) 69 { 70 checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch"); 71 } 72 73 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext) 74 { 75 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)); 76 switch (format) 77 { 78 // Color-renderable formats 79 case GL_RGBA32I: 80 case GL_RGBA32UI: 81 case GL_RGBA16I: 82 case GL_RGBA16UI: 83 case GL_RGBA8: 84 case GL_RGBA8I: 85 case GL_RGBA8UI: 86 case GL_SRGB8_ALPHA8: 87 case GL_RGB10_A2: 88 case GL_RGB10_A2UI: 89 case GL_RGBA4: 90 case GL_RGB5_A1: 91 case GL_RGB8: 92 case GL_RGB565: 93 case GL_RG32I: 94 case GL_RG32UI: 95 case GL_RG16I: 96 case GL_RG16UI: 97 case GL_RG8: 98 case GL_RG8I: 99 case GL_RG8UI: 100 case GL_R32I: 101 case GL_R32UI: 102 case GL_R16I: 103 case GL_R16UI: 104 case GL_R8: 105 case GL_R8I: 106 case GL_R8UI: 107 return true; 108 109 // Float format 110 case GL_RGBA32F: 111 case GL_RGB32F: 112 case GL_R11F_G11F_B10F: 113 case GL_RG32F: 114 case GL_R32F: 115 return isES32; 116 117 default: 118 return false; 119 } 120 } 121 122 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format) 123 { 124 switch (tcu::getTextureChannelClass(format.type)) 125 { 126 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 127 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32); 128 129 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 130 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32); 131 132 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 133 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 134 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 135 136 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 137 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT); 138 139 default: 140 DE_ASSERT(false); 141 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 142 } 143 } 144 145 tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat) 146 { 147 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT); 148 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT); 149 150 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER); 151 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER); 152 153 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER); 154 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER); 155 156 const tcu::IVec4 srcBits = tcu::getTextureFormatBitDepth(sourceFormat); 157 const tcu::IVec4 readBits = tcu::getTextureFormatBitDepth(readPixelsFormat); 158 159 return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>(); 160 } 161 162 tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat) 163 { 164 const tcu::IVec4 srcMantissaBits = tcu::getTextureFormatMantissaBitDepth(sourceFormat); 165 const tcu::IVec4 readMantissaBits = tcu::getTextureFormatMantissaBitDepth(readPixelsFormat); 166 tcu::IVec4 ULPDiff(0); 167 168 for (int i = 0; i < 4; i++) 169 if (readMantissaBits[i] >= srcMantissaBits[i]) 170 ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i]; 171 172 return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>())); 173 } 174 175 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts) 176 { 177 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++) 178 { 179 const std::string& extension = *iter; 180 181 if (context.getContextInfo().isExtensionSupported(extension.c_str())) 182 return true; 183 } 184 185 return false; 186 } 187 188 static std::string getColorOutputType(tcu::TextureFormat format) 189 { 190 switch (tcu::getTextureChannelClass(format.type)) 191 { 192 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: return "uvec4"; 193 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: return "ivec4"; 194 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 195 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 196 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: return "vec4"; 197 default: 198 DE_FATAL("Unsupported TEXTURECHANNELCLASS"); 199 return ""; 200 } 201 } 202 203 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext) 204 { 205 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)); 206 std::vector<std::string> out; 207 208 DE_ASSERT(!isRequiredFormat(format, renderContext)); 209 210 switch (format) 211 { 212 case GL_RGB16F: 213 out.push_back("GL_EXT_color_buffer_half_float"); 214 break; 215 216 case GL_RGBA16F: 217 case GL_RG16F: 218 case GL_R16F: 219 out.push_back("GL_EXT_color_buffer_half_float"); 220 221 case GL_RGBA32F: 222 case GL_RGB32F: 223 case GL_R11F_G11F_B10F: 224 case GL_RG32F: 225 case GL_R32F: 226 if (!isES32) 227 out.push_back("GL_EXT_color_buffer_float"); 228 break; 229 230 default: 231 break; 232 } 233 234 return out; 235 } 236 237 void checkFormatSupport (Context& context, deUint32 sizedFormat) 238 { 239 const bool isCoreFormat = isRequiredFormat(sizedFormat, context.getRenderContext()); 240 const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>(); 241 242 // Check that we don't try to use invalid formats. 243 DE_ASSERT(isCoreFormat || !requiredExts.empty()); 244 245 if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts)) 246 throw tcu::NotSupportedError("Format not supported"); 247 } 248 249 tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color) 250 { 251 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(format); 252 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin; 253 const tcu::Vec4 cBias = fmtInfo.valueMin; 254 255 return tcu::RGBA(color).toVec() * cScale + cBias; 256 } 257 258 // Base class for framebuffer fetch test cases 259 260 class FramebufferFetchTestCase : public TestCase 261 { 262 public: 263 FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format); 264 ~FramebufferFetchTestCase (void); 265 266 void init (void); 267 void deinit (void); 268 269 protected: 270 string genPassThroughVertSource (void); 271 virtual glu::ProgramSources genShaderSources (void); 272 273 void genFramebufferWithTexture (const tcu::Vec4& color); 274 void genAttachementTexture (const tcu::Vec4& color); 275 void genUniformColor (const tcu::Vec4& color); 276 277 void render (void); 278 void verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result); 279 280 const glw::Functions& m_gl; 281 const deUint32 m_format; 282 283 glu::ShaderProgram* m_program; 284 GLuint m_framebuffer; 285 GLuint m_texColorBuffer; 286 287 tcu::TextureFormat m_texFmt; 288 glu::TransferFormat m_transferFmt; 289 bool m_isFilterable; 290 291 enum 292 { 293 VIEWPORT_WIDTH = 64, 294 VIEWPORT_HEIGHT = 64, 295 }; 296 }; 297 298 FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format) 299 : TestCase (context, name, desc) 300 , m_gl (m_context.getRenderContext().getFunctions()) 301 , m_format (format) 302 , m_program (DE_NULL) 303 , m_framebuffer (0) 304 , m_texColorBuffer (0) 305 , m_texFmt (glu::mapGLInternalFormat(m_format)) 306 , m_transferFmt (glu::getTransferFormat(m_texFmt)) 307 , m_isFilterable (glu::isGLInternalColorFormatFilterable(m_format)) 308 { 309 } 310 311 FramebufferFetchTestCase::~FramebufferFetchTestCase (void) 312 { 313 FramebufferFetchTestCase::deinit(); 314 } 315 316 void FramebufferFetchTestCase::init (void) 317 { 318 checkFramebufferFetchSupport (m_context); 319 checkFormatSupport(m_context, m_format); 320 321 DE_ASSERT(!m_program); 322 m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources()); 323 324 m_testCtx.getLog() << *m_program; 325 326 if (!m_program->isOk()) 327 { 328 delete m_program; 329 m_program = DE_NULL; 330 TCU_FAIL("Failed to compile shader program"); 331 } 332 333 m_gl.useProgram(m_program->getProgram()); 334 } 335 336 void FramebufferFetchTestCase::deinit (void) 337 { 338 delete m_program; 339 m_program = DE_NULL; 340 341 if (m_framebuffer) 342 { 343 m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 344 m_gl.deleteFramebuffers(1, &m_framebuffer); 345 m_framebuffer = 0; 346 } 347 348 if (m_texColorBuffer) 349 { 350 m_gl.deleteTextures(1, &m_texColorBuffer); 351 m_texColorBuffer = 0; 352 } 353 } 354 355 string FramebufferFetchTestCase::genPassThroughVertSource (void) 356 { 357 std::ostringstream vertShaderSource; 358 359 vertShaderSource << "#version 310 es\n" 360 << "in highp vec4 a_position;\n" 361 << "\n" 362 << "void main (void)\n" 363 << "{\n" 364 << " gl_Position = a_position;\n" 365 << "}\n"; 366 367 return vertShaderSource.str(); 368 } 369 370 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void) 371 { 372 const string vecType = getColorOutputType(m_texFmt); 373 std::ostringstream fragShaderSource; 374 375 fragShaderSource << "#version 310 es\n" 376 << "#extension GL_EXT_shader_framebuffer_fetch : require\n" 377 << "layout(location = 0) inout highp " << vecType << " o_color;\n" 378 << "uniform highp " << vecType << " u_color;\n" 379 << "\n" 380 << "void main (void)\n" 381 << "{\n" 382 << " o_color += u_color;\n" 383 << "}\n"; 384 385 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str()); 386 } 387 388 void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color) 389 { 390 m_gl.genFramebuffers(1, &m_framebuffer); 391 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 392 393 genAttachementTexture(color); 394 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()"); 395 396 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0); 397 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 398 } 399 400 void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color) 401 { 402 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 403 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type); 404 405 m_gl.genTextures(1, &m_texColorBuffer); 406 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer); 407 408 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 409 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 410 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 411 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST); 412 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST); 413 414 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 415 tcu::clear(data.getAccess(), color.asUint()); 416 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 417 tcu::clear(data.getAccess(), color.asInt()); 418 else 419 tcu::clear(data.getAccess(), color); 420 421 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr()); 422 m_gl.bindTexture(GL_TEXTURE_2D, 0); 423 } 424 425 void FramebufferFetchTestCase::verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result) 426 { 427 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 428 429 switch (tcu::getTextureChannelClass(format.type)) 430 { 431 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 432 { 433 const string name = "Renderbuffer"; 434 const string desc = "Compare renderbuffer (floating_point)"; 435 const tcu::UVec4 threshold = getFloatULPThreshold(format, result.getFormat()); 436 437 if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT)) 438 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 439 440 break; 441 } 442 443 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 444 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 445 { 446 const string name = "Renderbuffer"; 447 const string desc = "Compare renderbuffer (integer)"; 448 const tcu::UVec4 threshold (1, 1, 1, 1); 449 450 if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT)) 451 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 452 453 break; 454 } 455 456 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 457 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 458 { 459 const string name = "Renderbuffer"; 460 const string desc = "Compare renderbuffer (fixed point)"; 461 const tcu::Vec4 threshold = getFixedPointFormatThreshold(format, result.getFormat()); 462 463 if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT)) 464 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 465 466 break; 467 } 468 469 default: 470 { 471 DE_ASSERT(DE_FALSE); 472 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 473 } 474 } 475 } 476 477 void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color) 478 { 479 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_color"); 480 481 switch (tcu::getTextureChannelClass(m_texFmt.type)) 482 { 483 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 484 { 485 m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr()); 486 break; 487 } 488 489 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 490 { 491 m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr()); 492 break; 493 } 494 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 495 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 496 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 497 { 498 m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr()); 499 break; 500 } 501 default: 502 DE_ASSERT(DE_FALSE); 503 } 504 505 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()"); 506 } 507 508 void FramebufferFetchTestCase::render (void) 509 { 510 const GLfloat coords[] = 511 { 512 -1.0f, -1.0f, 513 +1.0f, -1.0f, 514 +1.0f, +1.0f, 515 -1.0f, +1.0f, 516 }; 517 518 const GLushort indices[] = 519 { 520 0, 1, 2, 2, 3, 0, 521 }; 522 523 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position"); 524 525 m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 526 527 glu::Buffer coordinatesBuffer(m_context.getRenderContext()); 528 glu::Buffer elementsBuffer(m_context.getRenderContext()); 529 530 m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer); 531 m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW); 532 m_gl.enableVertexAttribArray(coordLocation); 533 m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL); 534 535 m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer); 536 m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW); 537 538 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL); 539 GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()"); 540 } 541 542 // Test description: 543 // - Attach texture containing solid color to framebuffer. 544 // - Draw full quad covering the entire viewport. 545 // - Sum framebuffer read color with passed in uniform color. 546 // - Compare resulting surface with reference. 547 548 class TextureFormatTestCase : public FramebufferFetchTestCase 549 { 550 public: 551 TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format); 552 ~TextureFormatTestCase (void) {}; 553 554 IterateResult iterate (void); 555 556 private: 557 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor); 558 }; 559 560 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format) 561 : FramebufferFetchTestCase(context, name, desc, format) 562 { 563 } 564 565 tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor) 566 { 567 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 568 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type); 569 570 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 571 { 572 tcu::clear(reference.getAccess(), fbColor.asUint() + uniformColor.asUint()); 573 } 574 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 575 { 576 tcu::clear(reference.getAccess(), fbColor.asInt() + uniformColor.asInt()); 577 } 578 else 579 { 580 if (tcu::isSRGB(m_texFmt)) 581 { 582 const tcu::Vec4 fragmentColor = tcu::sRGBToLinear(fbColor) + uniformColor; 583 tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor)); 584 } 585 else 586 { 587 tcu::clear(reference.getAccess(), fbColor + uniformColor); 588 } 589 } 590 591 return reference; 592 } 593 594 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void) 595 { 596 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f)); 597 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f)); 598 599 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor); 600 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 601 602 genFramebufferWithTexture(fbColor); 603 genUniformColor(uniformColor); 604 render(); 605 606 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 607 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 608 609 return STOP; 610 } 611 612 // Test description: 613 // - Attach multiple textures containing solid colors to framebuffer. 614 // - Draw full quad covering the entire viewport. 615 // - For each render target sum framebuffer read color with passed in uniform color. 616 // - Compare resulting surfaces with references. 617 618 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase 619 { 620 public: 621 MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format); 622 ~MultipleRenderTargetsTestCase (void); 623 624 IterateResult iterate (void); 625 void deinit (void); 626 627 private: 628 void genFramebufferWithTextures (const vector<tcu::Vec4>& colors); 629 void genAttachmentTextures (const vector<tcu::Vec4>& colors); 630 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor); 631 glu::ProgramSources genShaderSources (void); 632 633 enum 634 { 635 MAX_COLOR_BUFFERS = 4 636 }; 637 638 GLuint m_texColorBuffers [MAX_COLOR_BUFFERS]; 639 GLenum m_colorBuffers [MAX_COLOR_BUFFERS]; 640 }; 641 642 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format) 643 : FramebufferFetchTestCase(context, name, desc, format) 644 , m_texColorBuffers () 645 { 646 m_colorBuffers[0] = GL_COLOR_ATTACHMENT0; 647 m_colorBuffers[1] = GL_COLOR_ATTACHMENT1; 648 m_colorBuffers[2] = GL_COLOR_ATTACHMENT2; 649 m_colorBuffers[3] = GL_COLOR_ATTACHMENT3; 650 } 651 652 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void) 653 { 654 MultipleRenderTargetsTestCase::deinit(); 655 } 656 657 void MultipleRenderTargetsTestCase::deinit (void) 658 { 659 // Clean up texture data 660 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i) 661 { 662 if (m_texColorBuffers[i]) 663 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]); 664 } 665 666 FramebufferFetchTestCase::deinit(); 667 } 668 669 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors) 670 { 671 m_gl.genFramebuffers(1, &m_framebuffer); 672 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 673 674 genAttachmentTextures(colors); 675 676 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i) 677 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0); 678 679 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 680 681 m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]); 682 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()"); 683 } 684 685 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors) 686 { 687 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 688 689 m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers); 690 691 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i) 692 { 693 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]); 694 695 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 696 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 697 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 698 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST); 699 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST); 700 701 clear(data.getAccess(), colors[i]); 702 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr()); 703 } 704 705 m_gl.bindTexture(GL_TEXTURE_2D, 0); 706 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()"); 707 } 708 709 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor) 710 { 711 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 712 tcu::clear(reference.getAccess(), fbColor + uniformColor); 713 714 return reference; 715 } 716 717 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void) 718 { 719 const string vecType = getColorOutputType(m_texFmt); 720 std::ostringstream fragShaderSource; 721 722 fragShaderSource << "#version 310 es\n" 723 << "#extension GL_EXT_shader_framebuffer_fetch : require\n" 724 << "layout(location = 0) inout highp " << vecType << " o_color0;\n" 725 << "layout(location = 1) inout highp " << vecType << " o_color1;\n" 726 << "layout(location = 2) inout highp " << vecType << " o_color2;\n" 727 << "layout(location = 3) inout highp " << vecType << " o_color3;\n" 728 << "uniform highp " << vecType << " u_color;\n" 729 << "\n" 730 << "void main (void)\n" 731 << "{\n" 732 << " o_color0 += u_color;\n" 733 << " o_color1 += u_color;\n" 734 << " o_color2 += u_color;\n" 735 << " o_color3 += u_color;\n" 736 << "}\n"; 737 738 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str()); 739 } 740 741 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void) 742 { 743 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f)); 744 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 745 746 vector<tcu::Vec4> colors; 747 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f))); 748 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f))); 749 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f))); 750 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f))); 751 752 genFramebufferWithTextures(colors); 753 genUniformColor(uniformColor); 754 render(); 755 756 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i) 757 { 758 tcu::TextureLevel reference = genReferenceTexture(colors[i], uniformColor); 759 760 m_gl.readBuffer(m_colorBuffers[i]); 761 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 762 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 763 } 764 765 return STOP; 766 } 767 768 // Test description: 769 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0 770 771 class LastFragDataTestCase : public FramebufferFetchTestCase 772 { 773 public: 774 LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format); 775 ~LastFragDataTestCase (void) {}; 776 777 IterateResult iterate (void); 778 779 private: 780 glu::ProgramSources genShaderSources (void); 781 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor); 782 }; 783 784 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format) 785 : FramebufferFetchTestCase(context, name, desc, format) 786 { 787 } 788 789 glu::ProgramSources LastFragDataTestCase::genShaderSources (void) 790 { 791 const string vecType = getColorOutputType(m_texFmt); 792 std::ostringstream vertShaderSource; 793 std::ostringstream fragShaderSource; 794 795 vertShaderSource << "#version 100\n" 796 << "attribute vec4 a_position;\n" 797 << "\n" 798 << "void main (void)\n" 799 << "{\n" 800 << " gl_Position = a_position;\n" 801 << "}\n"; 802 803 fragShaderSource << "#version 100\n" 804 << "#extension GL_EXT_shader_framebuffer_fetch : require\n" 805 << "uniform highp " << vecType << " u_color;\n" 806 << "\n" 807 << "void main (void)\n" 808 << "{\n" 809 << " gl_FragColor = u_color + gl_LastFragData[0];\n" 810 << "}\n"; 811 812 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str()); 813 } 814 815 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor) 816 { 817 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 818 tcu::clear(reference.getAccess(), fbColor + uniformColor); 819 820 return reference; 821 } 822 823 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void) 824 { 825 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f)); 826 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f)); 827 828 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor); 829 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 830 831 genFramebufferWithTexture(fbColor); 832 genUniformColor(uniformColor); 833 render(); 834 835 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 836 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 837 838 return STOP; 839 } 840 841 // Test description: 842 // - Attach texture containing solid color to framebuffer. 843 // - Create one 2D texture for sampler with a grid pattern 844 // - Draw full screen quad covering the entire viewport. 845 // - Sum color values taken from framebuffer texture and sampled texture 846 // - Compare resulting surface with reference. 847 848 class TexelFetchTestCase : public FramebufferFetchTestCase 849 { 850 public: 851 TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format); 852 ~TexelFetchTestCase (void) {} 853 854 IterateResult iterate (void); 855 856 private: 857 glu::ProgramSources genShaderSources (void); 858 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor); 859 void genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd); 860 861 GLuint m_samplerTexture; 862 }; 863 864 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format) 865 : FramebufferFetchTestCase(context, name, desc, format) 866 , m_samplerTexture(0) 867 { 868 } 869 870 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd) 871 { 872 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 873 874 m_gl.activeTexture(GL_TEXTURE1); 875 876 m_gl.genTextures(1, &m_samplerTexture); 877 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer); 878 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 879 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 880 881 tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd); 882 883 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr()); 884 m_gl.bindTexture(GL_TEXTURE_2D, 0); 885 886 const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler"); 887 m_gl.uniform1i(samplerLocation, 1); 888 889 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()"); 890 } 891 892 glu::ProgramSources TexelFetchTestCase::genShaderSources (void) 893 { 894 const string vecType = getColorOutputType(m_texFmt); 895 std::ostringstream fragShaderSource; 896 897 fragShaderSource << "#version 310 es\n" 898 << "#extension GL_EXT_shader_framebuffer_fetch : require\n" 899 << "layout(location = 0) inout highp " << vecType << " o_color;\n" 900 << "\n" 901 << "uniform sampler2D u_sampler;\n" 902 << "void main (void)\n" 903 << "{\n" 904 << " o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n" 905 << "}\n"; 906 907 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str()); 908 } 909 910 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor) 911 { 912 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 913 tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor); 914 915 return reference; 916 } 917 918 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void) 919 { 920 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f)); 921 const tcu::Vec4 colorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)); 922 const tcu::Vec4 colorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f)); 923 924 genSamplerTexture(colorEven, colorOdd); 925 tcu::TextureLevel reference = genReferenceTexture(colorEven, colorOdd, fbColor); 926 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 927 928 genFramebufferWithTexture(fbColor); 929 render(); 930 931 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 932 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 933 934 // cleanup 935 m_gl.deleteTextures(1, &m_samplerTexture); 936 937 return STOP; 938 } 939 940 // Test description: 941 // - Attach texture containing solid color to framebuffer. 942 // - Draw full screen quad covering the entire viewport. 943 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen. 944 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen. 945 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color. 946 // - Compare resulting surface with reference. 947 948 class MultipleAssignmentTestCase : public FramebufferFetchTestCase 949 { 950 public: 951 MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format); 952 ~MultipleAssignmentTestCase (void) {} 953 954 IterateResult iterate (void); 955 956 private: 957 glu::ProgramSources genShaderSources (void); 958 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor); 959 }; 960 961 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format) 962 : FramebufferFetchTestCase(context, name, desc, format) 963 { 964 } 965 966 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void) 967 { 968 const string vecType = getColorOutputType(m_texFmt); 969 std::ostringstream vertShaderSource; 970 std::ostringstream fragShaderSource; 971 972 vertShaderSource << "#version 310 es\n" 973 << "in highp vec4 a_position;\n" 974 << "out highp vec4 v_position;\n" 975 << "\n" 976 << "void main (void)\n" 977 << "{\n" 978 << " gl_Position = a_position;\n" 979 << " v_position = gl_Position;\n" 980 << "}\n"; 981 982 fragShaderSource << "#version 310 es\n" 983 << "#extension GL_EXT_shader_framebuffer_fetch : require\n" 984 << "in highp vec4 v_position;\n" 985 << "layout(location = 0) inout highp " << vecType << " o_color;\n" 986 << "uniform highp " << vecType << " u_color;\n" 987 << "\n" 988 << "void main (void)\n" 989 << "{\n" 990 << " if (v_position.x > 0.0f)\n" 991 << " o_color += u_color;\n" 992 << "\n" 993 << " o_color += u_color;\n" 994 << "}\n"; 995 996 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str()); 997 } 998 999 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor) 1000 { 1001 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 1002 1003 int width = reference.getAccess().getWidth(); 1004 int height = reference.getAccess().getHeight(); 1005 int left = width /2; 1006 int top = height/2; 1007 1008 tcu::Vec4 compositeColor(uniformColor * 2.0f); 1009 1010 tcu::clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), fbColor + compositeColor); 1011 tcu::clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), fbColor + uniformColor); 1012 tcu::clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), fbColor + compositeColor); 1013 tcu::clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), fbColor + uniformColor); 1014 1015 return reference; 1016 } 1017 1018 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void) 1019 { 1020 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f)); 1021 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f)); 1022 1023 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor); 1024 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 1025 1026 genFramebufferWithTexture(fbColor); 1027 genUniformColor(uniformColor); 1028 render(); 1029 1030 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 1031 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 1032 1033 return STOP; 1034 } 1035 1036 // Test description: 1037 // - Attach texture containing grid pattern to framebuffer. 1038 // - Using framebuffer reads discard odd squares in the grid. 1039 // - The even squares framebuffer color is added to the passed in uniform color. 1040 1041 class FragmentDiscardTestCase : public FramebufferFetchTestCase 1042 { 1043 public: 1044 FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format); 1045 ~FragmentDiscardTestCase (void) {} 1046 1047 IterateResult iterate (void); 1048 1049 private: 1050 glu::ProgramSources genShaderSources (void); 1051 void genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd); 1052 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd); 1053 }; 1054 1055 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format) 1056 : FramebufferFetchTestCase(context, name, desc, format) 1057 { 1058 } 1059 1060 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void) 1061 { 1062 const string vecType = getColorOutputType(m_texFmt); 1063 std::ostringstream fragShaderSource; 1064 1065 fragShaderSource << "#version 310 es\n" 1066 << "#extension GL_EXT_shader_framebuffer_fetch : require\n" 1067 << "layout(location = 0) inout highp " << vecType << " o_color;\n" 1068 << "uniform highp " << vecType << " u_color;\n" 1069 << "\n" 1070 << "void main (void)\n" 1071 << "{\n" 1072 << " const highp float threshold = 0.0005f;\n" 1073 << " bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n" 1074 << " if (valuesEqual)\n" 1075 << " o_color += u_color;\n" 1076 << " else\n" 1077 << " discard;\n" 1078 << "}\n"; 1079 1080 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str()); 1081 } 1082 1083 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd) 1084 { 1085 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 1086 1087 m_gl.genFramebuffers(1, &m_framebuffer); 1088 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 1089 1090 m_gl.genTextures(1, &m_texColorBuffer); 1091 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer); 1092 1093 tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd); 1094 1095 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr()); 1096 m_gl.bindTexture(GL_TEXTURE_2D, 0); 1097 1098 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0); 1099 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 1100 } 1101 1102 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd) 1103 { 1104 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 1105 tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd); 1106 1107 return reference; 1108 } 1109 1110 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void) 1111 { 1112 const tcu::Vec4 fbColorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f)); 1113 const tcu::Vec4 fbColorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f)); 1114 1115 tcu::TextureLevel reference = genReferenceTexture(fbColorEven, fbColorOdd); 1116 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 1117 genFramebufferWithGrid(fbColorEven, fbColorOdd); 1118 1119 genUniformColor(fbColorEven); 1120 render(); 1121 1122 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 1123 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 1124 1125 return STOP; 1126 } 1127 1128 // Test description: 1129 // - Create 2D texture array containing three mipmaps. 1130 // - Each mipmap level is assigned a different color. 1131 // - Attach single mipmap level to framebuffer and draw full screen quad. 1132 // - Sum framebuffer read color with passed in uniform color. 1133 // - Compare resulting surface with reference. 1134 // - Repeat for subsequent mipmap levels. 1135 1136 class TextureLevelTestCase : public FramebufferFetchTestCase 1137 { 1138 public: 1139 TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format); 1140 ~TextureLevelTestCase (void) {} 1141 1142 IterateResult iterate (void); 1143 1144 private: 1145 void create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors); 1146 tcu::TextureLevel genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor); 1147 void genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference); 1148 }; 1149 1150 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format) 1151 : FramebufferFetchTestCase(context, name, desc, format) 1152 { 1153 } 1154 1155 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors) 1156 { 1157 int numLevels = (int)colors.size(); 1158 tcu::TextureLevel levelData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType)); 1159 1160 m_gl.genTextures(1, &m_texColorBuffer); 1161 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer); 1162 1163 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL); 1164 m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY); 1165 1166 for (int level = 0; level < numLevels; level++) 1167 { 1168 int levelW = de::max(1, VIEWPORT_WIDTH >> level); 1169 int levelH = de::max(1, VIEWPORT_HEIGHT >> level); 1170 1171 levelData.setSize(levelW, levelH, 1); 1172 1173 clear(levelData.getAccess(), colors[level]); 1174 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr()); 1175 } 1176 1177 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0); 1178 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()"); 1179 } 1180 1181 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor) 1182 { 1183 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1); 1184 1185 genReferenceMipmap(colors[level] + uniformColor, reference); 1186 1187 return reference; 1188 } 1189 1190 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference) 1191 { 1192 const int width = reference.getAccess().getWidth(); 1193 const int height = reference.getAccess().getHeight(); 1194 const int left = width / 2; 1195 const int top = height / 2; 1196 1197 clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), color); 1198 clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), color); 1199 clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), color); 1200 clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), color); 1201 } 1202 1203 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void) 1204 { 1205 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f)); 1206 vector<tcu::Vec4> levelColors; 1207 1208 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f))); 1209 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f))); 1210 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); 1211 1212 m_gl.genFramebuffers(1, &m_framebuffer); 1213 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 1214 1215 create2DTextureArrayMipMaps(levelColors); 1216 1217 // attach successive mipmap layers to framebuffer and render 1218 for (int level = 0; level < (int)levelColors.size(); ++level) 1219 { 1220 std::ostringstream name, desc; 1221 name << "Level " << level; 1222 desc << "Mipmap level " << level; 1223 1224 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str()); 1225 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level); 1226 tcu::TextureLevel reference = genReferenceTexture(level, levelColors, uniformColor); 1227 1228 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0); 1229 1230 genUniformColor(uniformColor); 1231 render(); 1232 1233 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 1234 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 1235 1236 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS) 1237 return STOP; 1238 } 1239 1240 return STOP; 1241 } 1242 1243 class TextureLayerTestCase : public FramebufferFetchTestCase 1244 { 1245 public: 1246 TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format); 1247 ~TextureLayerTestCase (void) {} 1248 1249 IterateResult iterate (void); 1250 1251 private: 1252 void create2DTextureArrayLayers (const vector<tcu::Vec4>& colors); 1253 tcu::TextureLevel genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor); 1254 }; 1255 1256 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format) 1257 : FramebufferFetchTestCase(context, name, desc, format) 1258 { 1259 } 1260 1261 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors) 1262 { 1263 int numLayers = (int)colors.size(); 1264 tcu::TextureLevel layerData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType)); 1265 1266 m_gl.genTextures(1, &m_texColorBuffer); 1267 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer); 1268 m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers); 1269 m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format); 1270 1271 layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers); 1272 1273 for (int layer = 0; layer < numLayers; layer++) 1274 { 1275 clear(layerData.getAccess(), colors[layer]); 1276 m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr()); 1277 } 1278 1279 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0); 1280 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()"); 1281 } 1282 1283 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor) 1284 { 1285 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1); 1286 clear(reference.getAccess(), colors[layer] + uniformColor); 1287 1288 return reference; 1289 } 1290 1291 // Test description 1292 // - Create 2D texture array containing three layers. 1293 // - Each layer is assigned a different color. 1294 // - Attach single layer to framebuffer and draw full screen quad. 1295 // - Sum framebuffer read color with passed in uniform color. 1296 // - Compare resulting surface with reference. 1297 // - Repeat for subsequent texture layers. 1298 1299 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void) 1300 { 1301 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f)); 1302 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 1303 vector<tcu::Vec4> layerColors; 1304 1305 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f))); 1306 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f))); 1307 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); 1308 1309 m_gl.genFramebuffers(1, &m_framebuffer); 1310 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 1311 1312 create2DTextureArrayLayers(layerColors); 1313 1314 for (int layer = 0; layer < (int)layerColors.size(); ++layer) 1315 { 1316 std::ostringstream name, desc; 1317 name << "Layer " << layer; 1318 desc << "Layer " << layer; 1319 1320 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str()); 1321 tcu::TextureLevel reference = genReferenceTexture(layer, layerColors, uniformColor); 1322 1323 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer); 1324 1325 genUniformColor(uniformColor); 1326 render(); 1327 1328 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 1329 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result); 1330 1331 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS) 1332 return STOP; 1333 } 1334 1335 return STOP; 1336 } 1337 1338 } // Anonymous 1339 1340 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context) 1341 : TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests") 1342 { 1343 } 1344 1345 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void) 1346 { 1347 } 1348 1349 void ShaderFramebufferFetchTests::init (void) 1350 { 1351 tcu::TestCaseGroup* const basicTestGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic framebuffer shader fetch tests"); 1352 tcu::TestCaseGroup* const framebufferFormatTestGroup = new tcu::TestCaseGroup(m_testCtx, "framebuffer_format", "Texture render target formats tests"); 1353 1354 // basic 1355 { 1356 basicTestGroup->addChild(new TexelFetchTestCase (m_context, "texel_fetch", "Framebuffer fetches in conjunction with shader texel fetches", GL_RGBA8)); 1357 basicTestGroup->addChild(new LastFragDataTestCase (m_context, "last_frag_data", "Framebuffer fetches with built-in fragment output of ES 2.0", GL_RGBA8)); 1358 basicTestGroup->addChild(new FragmentDiscardTestCase (m_context, "fragment_discard", "Framebuffer fetches in combination with fragment discards", GL_RGBA8)); 1359 basicTestGroup->addChild(new MultipleAssignmentTestCase (m_context, "multiple_assignment", "Multiple assignments to fragment color inout", GL_RGBA8)); 1360 basicTestGroup->addChild(new MultipleRenderTargetsTestCase (m_context, "multiple_render_targets", "Framebuffer fetches used in combination with multiple render targets", GL_RGBA8)); 1361 basicTestGroup->addChild(new TextureLevelTestCase (m_context, "framebuffer_texture_level", "Framebuffer fetches with individual texture render target mipmaps", GL_RGBA8)); 1362 basicTestGroup->addChild(new TextureLayerTestCase (m_context, "framebuffer_texture_layer", "Framebuffer fetches with individual texture render target layers", GL_RGBA8)); 1363 } 1364 1365 // framebuffer formats 1366 { 1367 static const deUint32 colorFormats[] = 1368 { 1369 // RGBA formats 1370 GL_RGBA32I, 1371 GL_RGBA32UI, 1372 GL_RGBA16I, 1373 GL_RGBA16UI, 1374 GL_RGBA8, 1375 GL_RGBA8I, 1376 GL_RGBA8UI, 1377 GL_SRGB8_ALPHA8, 1378 GL_RGB10_A2, 1379 GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1, 1380 1381 // RGB formats 1382 GL_RGB8, 1383 GL_RGB565, 1384 1385 // RG formats 1386 GL_RG32I, 1387 GL_RG32UI, 1388 GL_RG16I, 1389 GL_RG16UI, 1390 GL_RG8, 1391 GL_RG8I, 1392 GL_RG8UI, 1393 1394 // R formats 1395 GL_R32I, 1396 GL_R32UI, 1397 GL_R16I, 1398 GL_R16UI, 1399 GL_R8, 1400 GL_R8I, 1401 GL_R8UI, 1402 1403 // GL_EXT_color_buffer_float 1404 GL_RGBA32F, 1405 GL_RGBA16F, 1406 GL_R11F_G11F_B10F, 1407 GL_RG32F, 1408 GL_RG16F, 1409 GL_R32F, 1410 GL_R16F, 1411 1412 // GL_EXT_color_buffer_half_float 1413 GL_RGB16F 1414 }; 1415 1416 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++) 1417 framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx])); 1418 } 1419 1420 addChild(basicTestGroup); 1421 addChild(framebufferFormatTestGroup); 1422 } 1423 1424 } // Functional 1425 } // gles31 1426 } // deqp 1427