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 FBO colorbuffer tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es3fFboColorbufferTests.hpp" 25 #include "es3fFboTestCase.hpp" 26 #include "es3fFboTestUtil.hpp" 27 #include "gluTextureUtil.hpp" 28 #include "gluContextInfo.hpp" 29 #include "tcuImageCompare.hpp" 30 #include "tcuRGBA.hpp" 31 #include "tcuTestLog.hpp" 32 #include "tcuTextureUtil.hpp" 33 #include "sglrContextUtil.hpp" 34 #include "deRandom.hpp" 35 #include "deString.h" 36 #include "glwEnums.hpp" 37 38 namespace deqp 39 { 40 namespace gles3 41 { 42 namespace Functional 43 { 44 45 using std::string; 46 using tcu::Vec2; 47 using tcu::Vec3; 48 using tcu::Vec4; 49 using tcu::IVec2; 50 using tcu::IVec3; 51 using tcu::IVec4; 52 using tcu::UVec4; 53 using tcu::TestLog; 54 using namespace FboTestUtil; 55 56 const tcu::RGBA MIN_THRESHOLD(12, 12, 12, 12); 57 58 template <int Size> 59 static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f)) 60 { 61 tcu::Vector<float, Size> res; 62 for (int ndx = 0; ndx < Size; ndx++) 63 res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]); 64 return res; 65 } 66 67 static tcu::Vec4 generateRandomColor (de::Random& random) 68 { 69 tcu::Vec4 retVal; 70 71 for (int i = 0; i < 3; ++i) 72 retVal[i] = random.getFloat(); 73 retVal[3] = 1.0f; 74 75 return retVal; 76 } 77 78 class FboColorbufferCase : public FboTestCase 79 { 80 public: 81 FboColorbufferCase (Context& context, const char* name, const char* desc, const deUint32 format) 82 : FboTestCase (context, name, desc) 83 , m_format (format) 84 { 85 } 86 87 bool compare (const tcu::Surface& reference, const tcu::Surface& result) 88 { 89 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_format), MIN_THRESHOLD)); 90 91 m_testCtx.getLog() << TestLog::Message << "Comparing images, threshold: " << threshold << TestLog::EndMessage; 92 93 return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT); 94 } 95 96 protected: 97 const deUint32 m_format; 98 }; 99 100 class FboColorClearCase : public FboColorbufferCase 101 { 102 public: 103 FboColorClearCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height) 104 : FboColorbufferCase (context, name, desc, format) 105 , m_width (width) 106 , m_height (height) 107 { 108 } 109 110 protected: 111 void preCheck (void) 112 { 113 checkFormatSupport(m_format); 114 } 115 116 void render (tcu::Surface& dst) 117 { 118 tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format); 119 tcu::TextureChannelClass fmtClass = tcu::getTextureChannelClass(fboFormat.type); 120 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat); 121 de::Random rnd (17); 122 const int numClears = 16; 123 deUint32 fbo = 0; 124 deUint32 rbo = 0; 125 126 glGenFramebuffers(1, &fbo); 127 glGenRenderbuffers(1, &rbo); 128 129 glBindRenderbuffer(GL_RENDERBUFFER, rbo); 130 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height); 131 checkError(); 132 133 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 134 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); 135 checkError(); 136 checkFramebufferStatus(GL_FRAMEBUFFER); 137 138 glViewport(0, 0, m_width, m_height); 139 140 // Initialize to transparent black. 141 switch (fmtClass) 142 { 143 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 144 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 145 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 146 glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr()); 147 break; 148 149 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 150 glClearBufferuiv(GL_COLOR, 0, UVec4(0).getPtr()); 151 break; 152 153 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 154 glClearBufferiv(GL_COLOR, 0, IVec4(0).getPtr()); 155 break; 156 157 default: 158 DE_ASSERT(DE_FALSE); 159 } 160 161 // Do random scissored clears. 162 glEnable(GL_SCISSOR_TEST); 163 for (int ndx = 0; ndx < numClears; ndx++) 164 { 165 int x = rnd.getInt(0, m_width - 1); 166 int y = rnd.getInt(0, m_height - 1); 167 int w = rnd.getInt(1, m_width - x); 168 int h = rnd.getInt(1, m_height - y); 169 Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax); 170 171 glScissor(x, y, w, h); 172 173 switch (fmtClass) 174 { 175 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 176 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 177 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 178 glClearBufferfv(GL_COLOR, 0, color.getPtr()); 179 break; 180 181 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 182 glClearBufferuiv(GL_COLOR, 0, color.cast<deUint32>().getPtr()); 183 break; 184 185 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 186 glClearBufferiv(GL_COLOR, 0, color.cast<int>().getPtr()); 187 break; 188 189 default: 190 DE_ASSERT(DE_FALSE); 191 } 192 } 193 194 // Read results from renderbuffer. 195 readPixels(dst, 0, 0, m_width, m_height, fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias); 196 checkError(); 197 } 198 199 private: 200 const int m_width; 201 const int m_height; 202 }; 203 204 class FboColorMultiTex2DCase : public FboColorbufferCase 205 { 206 public: 207 FboColorMultiTex2DCase (Context& context, const char* name, const char* description, deUint32 tex0Fmt, const IVec2& tex0Size, deUint32 tex1Fmt, const IVec2& tex1Size) 208 : FboColorbufferCase (context, name, description, tex0Fmt) 209 , m_tex0Fmt (tex0Fmt) 210 , m_tex1Fmt (tex1Fmt) 211 , m_tex0Size (tex0Size) 212 , m_tex1Size (tex1Size) 213 { 214 } 215 216 protected: 217 void preCheck (void) 218 { 219 checkFormatSupport(m_tex0Fmt); 220 checkFormatSupport(m_tex1Fmt); 221 } 222 223 void render (tcu::Surface& dst) 224 { 225 tcu::TextureFormat texFmt0 = glu::mapGLInternalFormat(m_tex0Fmt); 226 tcu::TextureFormat texFmt1 = glu::mapGLInternalFormat(m_tex1Fmt); 227 tcu::TextureFormatInfo fmtInfo0 = tcu::getTextureFormatInfo(texFmt0); 228 tcu::TextureFormatInfo fmtInfo1 = tcu::getTextureFormatInfo(texFmt1); 229 230 Texture2DShader texToFbo0Shader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt0), fmtInfo0.valueMax-fmtInfo0.valueMin, fmtInfo0.valueMin); 231 Texture2DShader texToFbo1Shader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt1), fmtInfo1.valueMax-fmtInfo1.valueMin, fmtInfo1.valueMin); 232 Texture2DShader multiTexShader (DataTypes() << glu::getSampler2DType(texFmt0) << glu::getSampler2DType(texFmt1), glu::TYPE_FLOAT_VEC4); 233 234 deUint32 texToFbo0ShaderID = getCurrentContext()->createProgram(&texToFbo0Shader); 235 deUint32 texToFbo1ShaderID = getCurrentContext()->createProgram(&texToFbo1Shader); 236 deUint32 multiTexShaderID = getCurrentContext()->createProgram(&multiTexShader); 237 238 // Setup shaders 239 multiTexShader.setTexScaleBias(0, fmtInfo0.lookupScale * 0.5f, fmtInfo0.lookupBias * 0.5f); 240 multiTexShader.setTexScaleBias(1, fmtInfo1.lookupScale * 0.5f, fmtInfo1.lookupBias * 0.5f); 241 texToFbo0Shader.setUniforms(*getCurrentContext(), texToFbo0ShaderID); 242 texToFbo1Shader.setUniforms(*getCurrentContext(), texToFbo1ShaderID); 243 multiTexShader.setUniforms (*getCurrentContext(), multiTexShaderID); 244 245 // Framebuffers. 246 deUint32 fbo0, fbo1; 247 deUint32 tex0, tex1; 248 249 for (int ndx = 0; ndx < 2; ndx++) 250 { 251 glu::TransferFormat transferFmt = glu::getTransferFormat(ndx ? texFmt1 : texFmt0); 252 deUint32 format = ndx ? m_tex1Fmt : m_tex0Fmt; 253 bool isFilterable = glu::isGLInternalColorFormatFilterable(format); 254 const IVec2& size = ndx ? m_tex1Size : m_tex0Size; 255 deUint32& fbo = ndx ? fbo1 : fbo0; 256 deUint32& tex = ndx ? tex1 : tex0; 257 258 glGenFramebuffers(1, &fbo); 259 glGenTextures(1, &tex); 260 261 glBindTexture(GL_TEXTURE_2D, tex); 262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST); 265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST); 266 glTexImage2D(GL_TEXTURE_2D, 0, format, size.x(), size.y(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 267 268 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 269 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 270 checkError(); 271 checkFramebufferStatus(GL_FRAMEBUFFER); 272 } 273 274 // Render textures to both framebuffers. 275 for (int ndx = 0; ndx < 2; ndx++) 276 { 277 const deUint32 format = GL_RGBA; 278 const deUint32 dataType = GL_UNSIGNED_BYTE; 279 const int texW = 128; 280 const int texH = 128; 281 deUint32 tmpTex = 0; 282 deUint32 fbo = ndx ? fbo1 : fbo0; 283 const IVec2& viewport = ndx ? m_tex1Size : m_tex0Size; 284 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1); 285 286 if (ndx == 0) 287 tcu::fillWithComponentGradients(data.getAccess(), Vec4(0.0f), Vec4(1.0f)); 288 else 289 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f)); 290 291 glGenTextures(1, &tmpTex); 292 glBindTexture(GL_TEXTURE_2D, tmpTex); 293 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 294 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 297 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr()); 298 299 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 300 glViewport(0, 0, viewport.x(), viewport.y()); 301 sglr::drawQuad(*getCurrentContext(), ndx ? texToFbo1ShaderID : texToFbo0ShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 302 } 303 304 // Render to framebuffer. 305 glBindFramebuffer(GL_FRAMEBUFFER, 0); 306 glViewport(0, 0, getWidth(), getHeight()); 307 glActiveTexture(GL_TEXTURE0); 308 glBindTexture(GL_TEXTURE_2D, tex0); 309 glActiveTexture(GL_TEXTURE1); 310 glBindTexture(GL_TEXTURE_2D, tex1); 311 sglr::drawQuad(*getCurrentContext(), multiTexShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 312 313 readPixels(dst, 0, 0, getWidth(), getHeight()); 314 } 315 316 private: 317 deUint32 m_tex0Fmt; 318 deUint32 m_tex1Fmt; 319 IVec2 m_tex0Size; 320 IVec2 m_tex1Size; 321 }; 322 323 class FboColorTexCubeCase : public FboColorbufferCase 324 { 325 public: 326 FboColorTexCubeCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec2& texSize) 327 : FboColorbufferCase (context, name, description, texFmt) 328 , m_texSize (texSize) 329 { 330 } 331 332 protected: 333 void preCheck (void) 334 { 335 checkFormatSupport(m_format); 336 } 337 338 void render (tcu::Surface& dst) 339 { 340 static const deUint32 cubeGLFaces[] = 341 { 342 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 343 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 344 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 345 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 346 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 347 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 348 }; 349 350 static const tcu::CubeFace cubeTexFaces[] = 351 { 352 tcu::CUBEFACE_POSITIVE_X, 353 tcu::CUBEFACE_POSITIVE_Y, 354 tcu::CUBEFACE_POSITIVE_Z, 355 tcu::CUBEFACE_NEGATIVE_X, 356 tcu::CUBEFACE_NEGATIVE_Y, 357 tcu::CUBEFACE_NEGATIVE_Z 358 }; 359 360 de::Random rnd (deStringHash(getName()) ^ 0x9eef603d); 361 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_format); 362 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt); 363 364 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin); 365 TextureCubeShader cubeTexShader (glu::getSamplerCubeType(texFmt), glu::TYPE_FLOAT_VEC4); 366 367 deUint32 texToFboShaderID = getCurrentContext()->createProgram(&texToFboShader); 368 deUint32 cubeTexShaderID = getCurrentContext()->createProgram(&cubeTexShader); 369 370 // Setup shaders 371 texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID); 372 cubeTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias); 373 374 // Framebuffers. 375 std::vector<deUint32> fbos; 376 deUint32 tex; 377 378 { 379 glu::TransferFormat transferFmt = glu::getTransferFormat(texFmt); 380 bool isFilterable = glu::isGLInternalColorFormatFilterable(m_format); 381 const IVec2& size = m_texSize; 382 383 384 glGenTextures(1, &tex); 385 386 glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 387 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 388 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 389 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST); 390 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST); 391 392 // Generate an image and FBO for each cube face 393 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeGLFaces); ndx++) 394 glTexImage2D(cubeGLFaces[ndx], 0, m_format, size.x(), size.y(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 395 checkError(); 396 397 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeGLFaces); ndx++) 398 { 399 deUint32 layerFbo; 400 401 glGenFramebuffers(1, &layerFbo); 402 glBindFramebuffer(GL_FRAMEBUFFER, layerFbo); 403 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeGLFaces[ndx], tex, 0); 404 checkError(); 405 checkFramebufferStatus(GL_FRAMEBUFFER); 406 407 fbos.push_back(layerFbo); 408 } 409 } 410 411 // Render test images to random cube faces 412 std::vector<int> order; 413 414 for (size_t n = 0; n < fbos.size(); n++) 415 order.push_back((int)n); 416 rnd.shuffle(order.begin(), order.end()); 417 418 DE_ASSERT(order.size() >= 4); 419 for (int ndx = 0; ndx < 4; ndx++) 420 { 421 const int face = order[ndx]; 422 const deUint32 format = GL_RGBA; 423 const deUint32 dataType = GL_UNSIGNED_BYTE; 424 const int texW = 128; 425 const int texH = 128; 426 deUint32 tmpTex = 0; 427 const deUint32 fbo = fbos[face]; 428 const IVec2& viewport = m_texSize; 429 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1); 430 431 tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f)); 432 433 glGenTextures(1, &tmpTex); 434 glBindTexture(GL_TEXTURE_2D, tmpTex); 435 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 436 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 437 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 439 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr()); 440 441 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 442 glViewport(0, 0, viewport.x(), viewport.y()); 443 sglr::drawQuad(*getCurrentContext(), texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 444 checkError(); 445 446 // Render to framebuffer 447 { 448 const Vec3 p0 = Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f); 449 const Vec3 p1 = p0 + Vec3(1.0f, 1.0f, 0.0f); 450 451 glBindFramebuffer(GL_FRAMEBUFFER, 0); 452 glViewport(0, 0, getWidth(), getHeight()); 453 454 glActiveTexture(GL_TEXTURE0); 455 glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 456 457 cubeTexShader.setFace(cubeTexFaces[face]); 458 cubeTexShader.setUniforms(*getCurrentContext(), cubeTexShaderID); 459 460 sglr::drawQuad(*getCurrentContext(), cubeTexShaderID, p0, p1); 461 checkError(); 462 } 463 } 464 465 readPixels(dst, 0, 0, getWidth(), getHeight()); 466 } 467 468 private: 469 IVec2 m_texSize; 470 }; 471 472 class FboColorTex2DArrayCase : public FboColorbufferCase 473 { 474 public: 475 FboColorTex2DArrayCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec3& texSize) 476 : FboColorbufferCase (context, name, description, texFmt) 477 , m_texSize (texSize) 478 { 479 } 480 481 protected: 482 void preCheck (void) 483 { 484 checkFormatSupport(m_format); 485 } 486 487 void render (tcu::Surface& dst) 488 { 489 de::Random rnd (deStringHash(getName()) ^ 0xed607a89); 490 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_format); 491 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt); 492 493 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin); 494 Texture2DArrayShader arrayTexShader (glu::getSampler2DArrayType(texFmt), glu::TYPE_FLOAT_VEC4); 495 496 deUint32 texToFboShaderID = getCurrentContext()->createProgram(&texToFboShader); 497 deUint32 arrayTexShaderID = getCurrentContext()->createProgram(&arrayTexShader); 498 499 // Setup textures 500 texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID); 501 arrayTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias); 502 503 // Framebuffers. 504 std::vector<deUint32> fbos; 505 deUint32 tex; 506 507 { 508 glu::TransferFormat transferFmt = glu::getTransferFormat(texFmt); 509 bool isFilterable = glu::isGLInternalColorFormatFilterable(m_format); 510 const IVec3& size = m_texSize; 511 512 513 glGenTextures(1, &tex); 514 515 glBindTexture(GL_TEXTURE_2D_ARRAY, tex); 516 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 517 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 518 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 519 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST); 520 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST); 521 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, size.x(), size.y(), size.z(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 522 523 // Generate an FBO for each layer 524 for (int ndx = 0; ndx < m_texSize.z(); ndx++) 525 { 526 deUint32 layerFbo; 527 528 glGenFramebuffers(1, &layerFbo); 529 glBindFramebuffer(GL_FRAMEBUFFER, layerFbo); 530 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, ndx); 531 checkError(); 532 checkFramebufferStatus(GL_FRAMEBUFFER); 533 534 fbos.push_back(layerFbo); 535 } 536 } 537 538 // Render test images to random texture layers 539 std::vector<int> order; 540 541 for (size_t n = 0; n < fbos.size(); n++) 542 order.push_back((int)n); 543 rnd.shuffle(order.begin(), order.end()); 544 545 for (size_t ndx = 0; ndx < order.size(); ndx++) 546 { 547 const int layer = order[ndx]; 548 const deUint32 format = GL_RGBA; 549 const deUint32 dataType = GL_UNSIGNED_BYTE; 550 const int texW = 128; 551 const int texH = 128; 552 deUint32 tmpTex = 0; 553 const deUint32 fbo = fbos[layer]; 554 const IVec3& viewport = m_texSize; 555 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1); 556 557 tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f)); 558 559 glGenTextures(1, &tmpTex); 560 glBindTexture(GL_TEXTURE_2D, tmpTex); 561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 562 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 565 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr()); 566 567 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 568 glViewport(0, 0, viewport.x(), viewport.y()); 569 sglr::drawQuad(*getCurrentContext(), texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 570 checkError(); 571 572 // Render to framebuffer 573 { 574 const Vec3 p0 = Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f); 575 const Vec3 p1 = p0 + Vec3(1.0f, 1.0f, 0.0f); 576 577 glBindFramebuffer(GL_FRAMEBUFFER, 0); 578 glViewport(0, 0, getWidth(), getHeight()); 579 580 glActiveTexture(GL_TEXTURE0); 581 glBindTexture(GL_TEXTURE_2D_ARRAY, tex); 582 583 arrayTexShader.setLayer(layer); 584 arrayTexShader.setUniforms(*getCurrentContext(), arrayTexShaderID); 585 586 sglr::drawQuad(*getCurrentContext(), arrayTexShaderID, p0, p1); 587 checkError(); 588 } 589 } 590 591 readPixels(dst, 0, 0, getWidth(), getHeight()); 592 } 593 594 private: 595 IVec3 m_texSize; 596 }; 597 598 class FboColorTex3DCase : public FboColorbufferCase 599 { 600 public: 601 FboColorTex3DCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec3& texSize) 602 : FboColorbufferCase (context, name, description, texFmt) 603 , m_texSize (texSize) 604 { 605 } 606 607 protected: 608 void preCheck (void) 609 { 610 checkFormatSupport(m_format); 611 } 612 613 void render (tcu::Surface& dst) 614 { 615 de::Random rnd (deStringHash(getName()) ^ 0x74d947b2); 616 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_format); 617 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt); 618 619 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin); 620 Texture3DShader tdTexShader (glu::getSampler3DType(texFmt), glu::TYPE_FLOAT_VEC4); 621 622 deUint32 texToFboShaderID= getCurrentContext()->createProgram(&texToFboShader); 623 deUint32 tdTexShaderID = getCurrentContext()->createProgram(&tdTexShader); 624 625 // Setup shaders 626 texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID); 627 tdTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias); 628 629 // Framebuffers. 630 std::vector<deUint32> fbos; 631 deUint32 tex; 632 633 { 634 glu::TransferFormat transferFmt = glu::getTransferFormat(texFmt); 635 const IVec3& size = m_texSize; 636 637 glGenTextures(1, &tex); 638 639 glBindTexture(GL_TEXTURE_3D, tex); 640 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 641 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 642 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 643 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 644 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 645 glTexImage3D(GL_TEXTURE_3D, 0, m_format, size.x(), size.y(), size.z(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 646 647 // Generate an FBO for each layer 648 for (int ndx = 0; ndx < m_texSize.z(); ndx++) 649 { 650 deUint32 layerFbo; 651 652 glGenFramebuffers(1, &layerFbo); 653 glBindFramebuffer(GL_FRAMEBUFFER, layerFbo); 654 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, ndx); 655 checkError(); 656 checkFramebufferStatus(GL_FRAMEBUFFER); 657 658 fbos.push_back(layerFbo); 659 } 660 } 661 662 // Render test images to random texture layers 663 std::vector<int> order; 664 665 for (size_t n = 0; n < fbos.size(); n++) 666 order.push_back((int)n); 667 rnd.shuffle(order.begin(), order.end()); 668 669 for (size_t ndx = 0; ndx < order.size(); ndx++) 670 { 671 const int layer = order[ndx]; 672 const deUint32 format = GL_RGBA; 673 const deUint32 dataType = GL_UNSIGNED_BYTE; 674 const int texW = 128; 675 const int texH = 128; 676 deUint32 tmpTex = 0; 677 const deUint32 fbo = fbos[layer]; 678 const IVec3& viewport = m_texSize; 679 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1); 680 681 tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f)); 682 683 glGenTextures(1, &tmpTex); 684 glBindTexture(GL_TEXTURE_2D, tmpTex); 685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 686 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 687 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 688 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 689 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr()); 690 691 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 692 glViewport(0, 0, viewport.x(), viewport.y()); 693 sglr::drawQuad(*getCurrentContext() , texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 694 checkError(); 695 696 // Render to framebuffer 697 { 698 const Vec3 p0 = Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f); 699 const Vec3 p1 = p0 + Vec3(1.0f, 1.0f, 0.0f); 700 701 glBindFramebuffer(GL_FRAMEBUFFER, 0); 702 glViewport(0, 0, getWidth(), getHeight()); 703 704 glActiveTexture(GL_TEXTURE0); 705 glBindTexture(GL_TEXTURE_3D, tex); 706 707 tdTexShader.setDepth(float(layer) / float(m_texSize.z()-1)); 708 tdTexShader.setUniforms(*getCurrentContext(), tdTexShaderID); 709 710 sglr::drawQuad(*getCurrentContext(), tdTexShaderID, p0, p1); 711 checkError(); 712 } 713 } 714 715 readPixels(dst, 0, 0, getWidth(), getHeight()); 716 } 717 718 private: 719 IVec3 m_texSize; 720 }; 721 722 class FboBlendCase : public FboColorbufferCase 723 { 724 public: 725 FboBlendCase (Context& context, const char* name, const char* desc, deUint32 format, IVec2 size, deUint32 funcRGB, deUint32 funcAlpha, deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha) 726 : FboColorbufferCase (context, name, desc, format) 727 , m_size (size) 728 , m_funcRGB (funcRGB) 729 , m_funcAlpha (funcAlpha) 730 , m_srcRGB (srcRGB) 731 , m_dstRGB (dstRGB) 732 , m_srcAlpha (srcAlpha) 733 , m_dstAlpha (dstAlpha) 734 { 735 } 736 737 protected: 738 void preCheck (void) 739 { 740 checkFormatSupport(m_format); 741 } 742 743 void render (tcu::Surface& dst) 744 { 745 // \note Assumes floating-point or fixed-point format. 746 tcu::TextureFormat fboFmt = glu::mapGLInternalFormat(m_format); 747 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); 748 GradientShader gradShader (glu::TYPE_FLOAT_VEC4); 749 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 750 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); 751 deUint32 fbo = 0; 752 deUint32 rbo = 0; 753 754 // Setup shaders 755 texShader.setUniforms (*getCurrentContext(), texShaderID); 756 gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f)); 757 758 glGenFramebuffers(1, &fbo); 759 glGenRenderbuffers(1, &rbo); 760 761 glBindRenderbuffer(GL_RENDERBUFFER, rbo); 762 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_size.x(), m_size.y()); 763 checkError(); 764 765 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 766 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); 767 checkError(); 768 checkFramebufferStatus(GL_FRAMEBUFFER); 769 770 glViewport(0, 0, m_size.x(), m_size.y()); 771 772 // Fill framebuffer with grid pattern. 773 { 774 const deUint32 format = GL_RGBA; 775 const deUint32 dataType = GL_UNSIGNED_BYTE; 776 const int texW = 128; 777 const int texH = 128; 778 deUint32 gridTex = 0; 779 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1); 780 781 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f)); 782 783 glGenTextures(1, &gridTex); 784 glBindTexture(GL_TEXTURE_2D, gridTex); 785 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 786 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 787 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 788 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 789 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr()); 790 791 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 792 } 793 794 // Setup blend. 795 glEnable(GL_BLEND); 796 glBlendEquationSeparate(m_funcRGB, m_funcAlpha); 797 glBlendFuncSeparate(m_srcRGB, m_dstRGB, m_srcAlpha, m_dstAlpha); 798 799 // Render gradient with blend. 800 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 801 802 readPixels(dst, 0, 0, m_size.x(), m_size.y(), fboFmt, Vec4(1.0f), Vec4(0.0f)); 803 } 804 805 private: 806 IVec2 m_size; 807 deUint32 m_funcRGB; 808 deUint32 m_funcAlpha; 809 deUint32 m_srcRGB; 810 deUint32 m_dstRGB; 811 deUint32 m_srcAlpha; 812 deUint32 m_dstAlpha; 813 }; 814 815 class FboRepeatedClearSampleTex2DCase : public FboColorbufferCase 816 { 817 public: 818 FboRepeatedClearSampleTex2DCase (Context& context, const char* name, const char* desc, deUint32 format) 819 : FboColorbufferCase(context, name, desc, format) 820 { 821 } 822 823 protected: 824 void preCheck (void) 825 { 826 checkFormatSupport(m_format); 827 } 828 829 void render (tcu::Surface& dst) 830 { 831 const tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format); 832 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat); 833 const int numRowsCols = 4; 834 const int cellSize = 16; 835 const int fboSizes[] = { cellSize, cellSize*numRowsCols }; 836 837 Texture2DShader fboBlitShader (DataTypes() << glu::getSampler2DType(fboFormat), getFragmentOutputType(fboFormat), Vec4(1.0f), Vec4(0.0f)); 838 const deUint32 fboBlitShaderID = getCurrentContext()->createProgram(&fboBlitShader); 839 840 de::Random rnd (18169662); 841 deUint32 fbos[] = { 0, 0 }; 842 deUint32 textures[] = { 0, 0 }; 843 844 glGenFramebuffers(2, &fbos[0]); 845 glGenTextures(2, &textures[0]); 846 847 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++) 848 { 849 glBindTexture(GL_TEXTURE_2D, textures[fboNdx]); 850 glTexStorage2D(GL_TEXTURE_2D, 1, m_format, fboSizes[fboNdx], fboSizes[fboNdx]); 851 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 852 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 854 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 855 checkError(); 856 857 glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]); 858 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0); 859 checkError(); 860 checkFramebufferStatus(GL_FRAMEBUFFER); 861 } 862 863 // larger fbo bound -- clear to transparent black 864 clearColorBuffer(fboFormat, Vec4(0.0f)); 865 866 fboBlitShader.setUniforms(*getCurrentContext(), fboBlitShaderID); 867 glBindTexture(GL_TEXTURE_2D, textures[0]); 868 869 for (int cellY = 0; cellY < numRowsCols; cellY++) 870 for (int cellX = 0; cellX < numRowsCols; cellX++) 871 { 872 const Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax); 873 874 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); 875 clearColorBuffer(fboFormat, color); 876 877 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); 878 glViewport(cellX*cellSize, cellY*cellSize, cellSize, cellSize); 879 sglr::drawQuad(*getCurrentContext(), fboBlitShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 880 } 881 882 readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias); 883 checkError(); 884 } 885 }; 886 887 class FboRepeatedClearBlitTex2DCase : public FboColorbufferCase 888 { 889 public: 890 FboRepeatedClearBlitTex2DCase (Context& context, const char* name, const char* desc, deUint32 format) 891 : FboColorbufferCase(context, name, desc, format) 892 { 893 } 894 895 protected: 896 void preCheck (void) 897 { 898 checkFormatSupport(m_format); 899 } 900 901 void render (tcu::Surface& dst) 902 { 903 const tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format); 904 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat); 905 const int numRowsCols = 4; 906 const int cellSize = 16; 907 const int fboSizes[] = { cellSize, cellSize*numRowsCols }; 908 909 de::Random rnd (18169662); 910 deUint32 fbos[] = { 0, 0 }; 911 deUint32 textures[] = { 0, 0 }; 912 913 glGenFramebuffers(2, &fbos[0]); 914 glGenTextures(2, &textures[0]); 915 916 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++) 917 { 918 glBindTexture(GL_TEXTURE_2D, textures[fboNdx]); 919 glTexStorage2D(GL_TEXTURE_2D, 1, m_format, fboSizes[fboNdx], fboSizes[fboNdx]); 920 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 921 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 922 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 923 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 924 checkError(); 925 926 glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]); 927 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0); 928 checkError(); 929 checkFramebufferStatus(GL_FRAMEBUFFER); 930 } 931 932 // larger fbo bound -- clear to transparent black 933 clearColorBuffer(fboFormat, Vec4(0.0f)); 934 935 for (int cellY = 0; cellY < numRowsCols; cellY++) 936 for (int cellX = 0; cellX < numRowsCols; cellX++) 937 { 938 const Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax); 939 940 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); 941 clearColorBuffer(fboFormat, color); 942 943 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); 944 glBlitFramebuffer(0, 0, cellSize, cellSize, cellX*cellSize, cellY*cellSize, (cellX+1)*cellSize, (cellY+1)*cellSize, GL_COLOR_BUFFER_BIT, GL_NEAREST); 945 } 946 947 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); 948 readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias); 949 checkError(); 950 } 951 }; 952 953 class FboRepeatedClearBlitRboCase : public FboColorbufferCase 954 { 955 public: 956 FboRepeatedClearBlitRboCase (Context& context, const char* name, const char* desc, deUint32 format) 957 : FboColorbufferCase(context, name, desc, format) 958 { 959 } 960 961 protected: 962 void preCheck (void) 963 { 964 checkFormatSupport(m_format); 965 } 966 967 void render (tcu::Surface& dst) 968 { 969 const tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format); 970 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat); 971 const int numRowsCols = 4; 972 const int cellSize = 16; 973 const int fboSizes[] = { cellSize, cellSize*numRowsCols }; 974 975 de::Random rnd (18169662); 976 deUint32 fbos[] = { 0, 0 }; 977 deUint32 rbos[] = { 0, 0 }; 978 979 glGenFramebuffers(2, &fbos[0]); 980 glGenRenderbuffers(2, &rbos[0]); 981 982 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++) 983 { 984 glBindRenderbuffer(GL_RENDERBUFFER, rbos[fboNdx]); 985 glRenderbufferStorage(GL_RENDERBUFFER, m_format, fboSizes[fboNdx], fboSizes[fboNdx]); 986 checkError(); 987 988 glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]); 989 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbos[fboNdx]); 990 checkError(); 991 checkFramebufferStatus(GL_FRAMEBUFFER); 992 } 993 994 // larger fbo bound -- clear to transparent black 995 clearColorBuffer(fboFormat, Vec4(0.0f)); 996 997 for (int cellY = 0; cellY < numRowsCols; cellY++) 998 for (int cellX = 0; cellX < numRowsCols; cellX++) 999 { 1000 const Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax); 1001 1002 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); 1003 clearColorBuffer(fboFormat, color); 1004 1005 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); 1006 glBlitFramebuffer(0, 0, cellSize, cellSize, cellX*cellSize, cellY*cellSize, (cellX+1)*cellSize, (cellY+1)*cellSize, GL_COLOR_BUFFER_BIT, GL_NEAREST); 1007 } 1008 1009 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); 1010 readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias); 1011 checkError(); 1012 } 1013 }; 1014 1015 FboColorTests::FboColorTests (Context& context) 1016 : TestCaseGroup(context, "color", "Colorbuffer tests") 1017 { 1018 } 1019 1020 FboColorTests::~FboColorTests (void) 1021 { 1022 } 1023 1024 void FboColorTests::init (void) 1025 { 1026 static const deUint32 colorFormats[] = 1027 { 1028 // RGBA formats 1029 GL_RGBA32I, 1030 GL_RGBA32UI, 1031 GL_RGBA16I, 1032 GL_RGBA16UI, 1033 GL_RGBA8, 1034 GL_RGBA8I, 1035 GL_RGBA8UI, 1036 GL_SRGB8_ALPHA8, 1037 GL_RGB10_A2, 1038 GL_RGB10_A2UI, 1039 GL_RGBA4, 1040 GL_RGB5_A1, 1041 1042 // RGB formats 1043 GL_RGB8, 1044 GL_RGB565, 1045 1046 // RG formats 1047 GL_RG32I, 1048 GL_RG32UI, 1049 GL_RG16I, 1050 GL_RG16UI, 1051 GL_RG8, 1052 GL_RG8I, 1053 GL_RG8UI, 1054 1055 // R formats 1056 GL_R32I, 1057 GL_R32UI, 1058 GL_R16I, 1059 GL_R16UI, 1060 GL_R8, 1061 GL_R8I, 1062 GL_R8UI, 1063 1064 // GL_EXT_color_buffer_float 1065 GL_RGBA32F, 1066 GL_RGBA16F, 1067 GL_R11F_G11F_B10F, 1068 GL_RG32F, 1069 GL_RG16F, 1070 GL_R32F, 1071 GL_R16F, 1072 1073 // GL_EXT_color_buffer_half_float 1074 GL_RGB16F 1075 }; 1076 1077 // .clear 1078 { 1079 tcu::TestCaseGroup* clearGroup = new tcu::TestCaseGroup(m_testCtx, "clear", "Color clears"); 1080 addChild(clearGroup); 1081 1082 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++) 1083 clearGroup->addChild(new FboColorClearCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], 129, 117)); 1084 } 1085 1086 // .tex2d 1087 { 1088 tcu::TestCaseGroup* tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "Texture 2D tests"); 1089 addChild(tex2DGroup); 1090 1091 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1092 tex2DGroup->addChild(new FboColorMultiTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]), "", 1093 colorFormats[fmtNdx], IVec2(129, 117), 1094 colorFormats[fmtNdx], IVec2(99, 128))); 1095 } 1096 1097 // .texcube 1098 { 1099 tcu::TestCaseGroup* texCubeGroup = new tcu::TestCaseGroup(m_testCtx, "texcube", "Texture cube map tests"); 1100 addChild(texCubeGroup); 1101 1102 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1103 texCubeGroup->addChild(new FboColorTexCubeCase(m_context, getFormatName(colorFormats[fmtNdx]), "", 1104 colorFormats[fmtNdx], IVec2(128, 128))); 1105 } 1106 1107 // .tex2darray 1108 { 1109 tcu::TestCaseGroup* tex2DArrayGroup = new tcu::TestCaseGroup(m_testCtx, "tex2darray", "Texture 2D array tests"); 1110 addChild(tex2DArrayGroup); 1111 1112 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1113 tex2DArrayGroup->addChild(new FboColorTex2DArrayCase(m_context, getFormatName(colorFormats[fmtNdx]), "", 1114 colorFormats[fmtNdx], IVec3(128, 128, 5))); 1115 } 1116 1117 // .tex3d 1118 { 1119 tcu::TestCaseGroup* tex3DGroup = new tcu::TestCaseGroup(m_testCtx, "tex3d", "Texture 3D tests"); 1120 addChild(tex3DGroup); 1121 1122 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1123 tex3DGroup->addChild(new FboColorTex3DCase(m_context, getFormatName(colorFormats[fmtNdx]), "", 1124 colorFormats[fmtNdx], IVec3(128, 128, 5))); 1125 } 1126 1127 // .blend 1128 { 1129 tcu::TestCaseGroup* blendGroup = new tcu::TestCaseGroup(m_testCtx, "blend", "Blending tests"); 1130 addChild(blendGroup); 1131 1132 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1133 { 1134 deUint32 format = colorFormats[fmtNdx]; 1135 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(format); 1136 tcu::TextureChannelClass fmtClass = tcu::getTextureChannelClass(texFmt.type); 1137 string fmtName = getFormatName(format); 1138 1139 if (texFmt.type == tcu::TextureFormat::FLOAT || 1140 fmtClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || 1141 fmtClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 1142 continue; // Blending is not supported. 1143 1144 blendGroup->addChild(new FboBlendCase(m_context, (fmtName + "_src_over").c_str(), "", format, IVec2(127, 111), GL_FUNC_ADD, GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE)); 1145 } 1146 } 1147 1148 // .repeated_clear 1149 { 1150 tcu::TestCaseGroup* const repeatedClearGroup = new tcu::TestCaseGroup(m_testCtx, "repeated_clear", "Repeated clears and blits"); 1151 addChild(repeatedClearGroup); 1152 1153 // .sample.tex2d 1154 { 1155 tcu::TestCaseGroup* const sampleGroup = new tcu::TestCaseGroup(m_testCtx, "sample", "Read by sampling"); 1156 repeatedClearGroup->addChild(sampleGroup); 1157 1158 tcu::TestCaseGroup* const tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "2D Texture"); 1159 sampleGroup->addChild(tex2DGroup); 1160 1161 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1162 tex2DGroup->addChild(new FboRepeatedClearSampleTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]), 1163 "", colorFormats[fmtNdx])); 1164 } 1165 1166 // .blit 1167 { 1168 tcu::TestCaseGroup* const blitGroup = new tcu::TestCaseGroup(m_testCtx, "blit", "Blitted"); 1169 repeatedClearGroup->addChild(blitGroup); 1170 1171 // .tex2d 1172 { 1173 tcu::TestCaseGroup* const tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "2D Texture"); 1174 blitGroup->addChild(tex2DGroup); 1175 1176 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1177 tex2DGroup->addChild(new FboRepeatedClearBlitTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]), 1178 "", colorFormats[fmtNdx])); 1179 } 1180 1181 // .rbo 1182 { 1183 tcu::TestCaseGroup* const rboGroup = new tcu::TestCaseGroup(m_testCtx, "rbo", "Renderbuffer"); 1184 blitGroup->addChild(rboGroup); 1185 1186 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++) 1187 rboGroup->addChild(new FboRepeatedClearBlitRboCase(m_context, getFormatName(colorFormats[fmtNdx]), 1188 "", colorFormats[fmtNdx])); 1189 } 1190 } 1191 } 1192 } 1193 1194 } // Functional 1195 } // gles3 1196 } // deqp 1197