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 invalidate tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es3fFboInvalidateTests.hpp" 25#include "es3fFboTestCase.hpp" 26#include "es3fFboTestUtil.hpp" 27#include "gluTextureUtil.hpp" 28#include "tcuImageCompare.hpp" 29#include "tcuTextureUtil.hpp" 30#include "sglrContextUtil.hpp" 31 32#include "glwEnums.hpp" 33 34#include <algorithm> 35 36namespace deqp 37{ 38namespace gles3 39{ 40namespace Functional 41{ 42 43using std::string; 44using std::vector; 45using tcu::Vec2; 46using tcu::Vec3; 47using tcu::Vec4; 48using tcu::IVec2; 49using tcu::IVec3; 50using tcu::IVec4; 51using tcu::UVec4; 52using namespace FboTestUtil; 53 54static std::vector<deUint32> getDefaultFBDiscardAttachments (deUint32 discardBufferBits) 55{ 56 vector<deUint32> attachments; 57 58 if (discardBufferBits & GL_COLOR_BUFFER_BIT) 59 attachments.push_back(GL_COLOR); 60 61 if (discardBufferBits & GL_DEPTH_BUFFER_BIT) 62 attachments.push_back(GL_DEPTH); 63 64 if (discardBufferBits & GL_STENCIL_BUFFER_BIT) 65 attachments.push_back(GL_STENCIL); 66 67 return attachments; 68} 69 70static std::vector<deUint32> getFBODiscardAttachments (deUint32 discardBufferBits) 71{ 72 vector<deUint32> attachments; 73 74 if (discardBufferBits & GL_COLOR_BUFFER_BIT) 75 attachments.push_back(GL_COLOR_ATTACHMENT0); 76 77 // \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB 78 if ((discardBufferBits & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) 79 attachments.push_back(GL_DEPTH_STENCIL_ATTACHMENT); 80 else if (discardBufferBits & GL_DEPTH_BUFFER_BIT) 81 attachments.push_back(GL_DEPTH_ATTACHMENT); 82 else if (discardBufferBits & GL_STENCIL_BUFFER_BIT) 83 attachments.push_back(GL_STENCIL_ATTACHMENT); 84 85 return attachments; 86} 87 88static inline bool hasAttachment (const std::vector<deUint32>& attachmentList, deUint32 attachment) 89{ 90 return std::find(attachmentList.begin(), attachmentList.end(), attachment) != attachmentList.end(); 91} 92 93static deUint32 getCompatibleColorFormat (const tcu::RenderTarget& renderTargetInfo) 94{ 95 const tcu::PixelFormat& pxFmt = renderTargetInfo.getPixelFormat(); 96 DE_ASSERT(de::inBounds(pxFmt.redBits, 0, 0xff) && 97 de::inBounds(pxFmt.greenBits, 0, 0xff) && 98 de::inBounds(pxFmt.blueBits, 0, 0xff) && 99 de::inBounds(pxFmt.alphaBits, 0, 0xff)); 100 101#define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A)) 102 103 // \note [pyry] This may not hold true on some implementations - best effort guess only. 104 switch (PACK_FMT(pxFmt.redBits, pxFmt.greenBits, pxFmt.blueBits, pxFmt.alphaBits)) 105 { 106 case PACK_FMT(8,8,8,8): return GL_RGBA8; 107 case PACK_FMT(8,8,8,0): return GL_RGB8; 108 case PACK_FMT(4,4,4,4): return GL_RGBA4; 109 case PACK_FMT(5,5,5,1): return GL_RGB5_A1; 110 case PACK_FMT(5,6,5,0): return GL_RGB565; 111 default: return GL_NONE; 112 } 113 114#undef PACK_FMT 115} 116 117static deUint32 getCompatibleDepthStencilFormat (const tcu::RenderTarget& renderTargetInfo) 118{ 119 const int depthBits = renderTargetInfo.getDepthBits(); 120 const int stencilBits = renderTargetInfo.getStencilBits(); 121 const bool hasDepth = depthBits > 0; 122 const bool hasStencil = stencilBits > 0; 123 124 if (!hasDepth || !hasStencil || (stencilBits != 8)) 125 return GL_NONE; 126 127 if (depthBits == 32) 128 return GL_DEPTH32F_STENCIL8; 129 else if (depthBits == 24) 130 return GL_DEPTH24_STENCIL8; 131 else 132 return GL_NONE; 133} 134 135class InvalidateDefaultFramebufferRenderCase : public FboTestCase 136{ 137public: 138 InvalidateDefaultFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers, deUint32 fboTarget = GL_FRAMEBUFFER) 139 : FboTestCase (context, name, description) 140 , m_buffers (buffers) 141 , m_fboTarget (fboTarget) 142 { 143 } 144 145 void render (tcu::Surface& dst) 146 { 147 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 148 vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); 149 deUint32 flatShaderID= getCurrentContext()->createProgram(&flatShader); 150 151 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 152 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 153 154 glEnable (GL_DEPTH_TEST); 155 glEnable (GL_STENCIL_TEST); 156 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 157 glStencilFunc (GL_ALWAYS, 1, 0xff); 158 159 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 160 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 161 162 glInvalidateFramebuffer(m_fboTarget, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]); 163 164 if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0) 165 { 166 // Color was not preserved - fill with green. 167 glDisable(GL_DEPTH_TEST); 168 glDisable(GL_STENCIL_TEST); 169 170 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 171 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 172 173 glEnable(GL_DEPTH_TEST); 174 glEnable(GL_STENCIL_TEST); 175 } 176 177 if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0) 178 { 179 // Depth was not preserved. 180 glDepthFunc(GL_ALWAYS); 181 } 182 183 if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0) 184 { 185 // Stencil was preserved. 186 glStencilFunc(GL_EQUAL, 1, 0xff); 187 } 188 189 glEnable (GL_BLEND); 190 glBlendFunc (GL_ONE, GL_ONE); 191 glBlendEquation (GL_FUNC_ADD); 192 193 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 194 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 195 196 readPixels(dst, 0, 0, getWidth(), getHeight()); 197 } 198 199private: 200 deUint32 m_buffers; 201 deUint32 m_fboTarget; 202}; 203 204class InvalidateDefaultFramebufferBindCase : public FboTestCase 205{ 206public: 207 InvalidateDefaultFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers) 208 : FboTestCase (context, name, description) 209 , m_buffers (buffers) 210 { 211 } 212 213 void render (tcu::Surface& dst) 214 { 215 deUint32 fbo = 0; 216 deUint32 tex = 0; 217 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 218 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); 219 GradientShader gradShader (glu::TYPE_FLOAT_VEC4); 220 vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); 221 deUint32 flatShaderID= getCurrentContext()->createProgram(&flatShader); 222 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 223 deUint32 gradShaderID= getCurrentContext()->createProgram(&gradShader); 224 225 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 226 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 227 228 // Create fbo. 229 glGenFramebuffers (1, &fbo); 230 glGenTextures (1, &tex); 231 glBindTexture (GL_TEXTURE_2D, tex); 232 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); 233 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 234 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 235 glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 236 glBindTexture (GL_TEXTURE_2D, 0); 237 checkFramebufferStatus (GL_FRAMEBUFFER); 238 239 glBindFramebuffer (GL_FRAMEBUFFER, 0); 240 241 glEnable (GL_DEPTH_TEST); 242 glEnable (GL_STENCIL_TEST); 243 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 244 glStencilFunc (GL_ALWAYS, 1, 0xff); 245 246 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 247 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 248 249 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]); 250 251 // Switch to fbo and render gradient into it. 252 glDisable (GL_DEPTH_TEST); 253 glDisable (GL_STENCIL_TEST); 254 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 255 256 gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f)); 257 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 258 259 // Restore default fbo. 260 glBindFramebuffer (GL_FRAMEBUFFER, 0); 261 262 if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0) 263 { 264 // Color was not preserved - fill with green. 265 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 266 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 267 } 268 269 if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0) 270 { 271 // Depth was not preserved. 272 glDepthFunc(GL_ALWAYS); 273 } 274 275 if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0) 276 { 277 // Stencil was preserved. 278 glStencilFunc(GL_EQUAL, 1, 0xff); 279 } 280 281 glEnable (GL_DEPTH_TEST); 282 glEnable (GL_STENCIL_TEST); 283 glEnable (GL_BLEND); 284 glBlendFunc (GL_ONE, GL_ONE); 285 glBlendEquation (GL_FUNC_ADD); 286 glBindTexture (GL_TEXTURE_2D, tex); 287 288 texShader.setUniforms(*getCurrentContext(), texShaderID); 289 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 290 291 readPixels(dst, 0, 0, getWidth(), getHeight()); 292 } 293 294private: 295 deUint32 m_buffers; 296}; 297 298class InvalidateDefaultSubFramebufferRenderCase : public FboTestCase 299{ 300public: 301 InvalidateDefaultSubFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers) 302 : FboTestCase (context, name, description) 303 , m_buffers (buffers) 304 { 305 } 306 307 void render (tcu::Surface& dst) 308 { 309 int invalidateX = getWidth() / 4; 310 int invalidateY = getHeight() / 4; 311 int invalidateW = getWidth() / 2; 312 int invalidateH = getHeight() / 2; 313 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 314 vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); 315 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 316 317 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 318 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 319 320 glEnable (GL_DEPTH_TEST); 321 glEnable (GL_STENCIL_TEST); 322 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 323 glStencilFunc (GL_ALWAYS, 1, 0xff); 324 325 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 326 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 327 328 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); 329 330 // Clear invalidated buffers. 331 glClearColor (0.0f, 1.0f, 0.0f, 1.0f); 332 glClearStencil (1); 333 glScissor (invalidateX, invalidateY, invalidateW, invalidateH); 334 glEnable (GL_SCISSOR_TEST); 335 glClear (m_buffers); 336 glDisable (GL_SCISSOR_TEST); 337 338 glEnable (GL_BLEND); 339 glBlendFunc (GL_ONE, GL_ONE); 340 glBlendEquation (GL_FUNC_ADD); 341 342 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 343 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 344 345 readPixels(dst, 0, 0, getWidth(), getHeight()); 346 } 347 348private: 349 deUint32 m_buffers; 350}; 351 352class InvalidateDefaultSubFramebufferBindCase : public FboTestCase 353{ 354public: 355 InvalidateDefaultSubFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers) 356 : FboTestCase (context, name, description) 357 , m_buffers (buffers) 358 { 359 } 360 361 void render (tcu::Surface& dst) 362 { 363 deUint32 fbo = 0; 364 deUint32 tex = 0; 365 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 366 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); 367 GradientShader gradShader (glu::TYPE_FLOAT_VEC4); 368 vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); 369 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 370 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 371 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); 372 373 int invalidateX = getWidth() / 4; 374 int invalidateY = getHeight() / 4; 375 int invalidateW = getWidth() / 2; 376 int invalidateH = getHeight() / 2; 377 378 379 flatShader.setColor (*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 380 texShader.setUniforms (*getCurrentContext(), texShaderID); 381 gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f)); 382 383 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 384 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 385 386 // Create fbo. 387 glGenFramebuffers (1, &fbo); 388 glGenTextures (1, &tex); 389 glBindTexture (GL_TEXTURE_2D, tex); 390 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); 391 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 392 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 393 glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 394 glBindTexture (GL_TEXTURE_2D, 0); 395 checkFramebufferStatus (GL_FRAMEBUFFER); 396 397 glBindFramebuffer (GL_FRAMEBUFFER, 0); 398 399 glEnable (GL_DEPTH_TEST); 400 glEnable (GL_STENCIL_TEST); 401 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 402 glStencilFunc (GL_ALWAYS, 1, 0xff); 403 404 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 405 406 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); 407 408 // Switch to fbo and render gradient into it. 409 glDisable (GL_DEPTH_TEST); 410 glDisable (GL_STENCIL_TEST); 411 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 412 413 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 414 415 // Restore default fbo. 416 glBindFramebuffer (GL_FRAMEBUFFER, 0); 417 418 // Clear invalidated buffers. 419 glClearColor (0.0f, 1.0f, 0.0f, 1.0f); 420 glClearStencil (1); 421 glScissor (invalidateX, invalidateY, invalidateW, invalidateH); 422 glEnable (GL_SCISSOR_TEST); 423 glClear (m_buffers); 424 glDisable (GL_SCISSOR_TEST); 425 426 glEnable (GL_DEPTH_TEST); 427 glEnable (GL_STENCIL_TEST); 428 glEnable (GL_BLEND); 429 glBlendFunc (GL_ONE, GL_ONE); 430 glBlendEquation (GL_FUNC_ADD); 431 glBindTexture (GL_TEXTURE_2D, tex); 432 433 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 434 435 readPixels(dst, 0, 0, getWidth(), getHeight()); 436 } 437 438private: 439 deUint32 m_buffers; 440}; 441 442class InvalidateFboRenderCase : public FboTestCase 443{ 444public: 445 InvalidateFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) 446 : FboTestCase (context, name, description) 447 , m_colorFmt (colorFmt) 448 , m_depthStencilFmt (depthStencilFmt) 449 , m_invalidateBuffers (invalidateBuffers) 450 { 451 } 452 453protected: 454 void preCheck (void) 455 { 456 if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); 457 if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); 458 } 459 460 void render (tcu::Surface& dst) 461 { 462 tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); 463 tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); 464 tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); 465 bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; 466 bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; 467 const tcu::Vec4& cBias = colorFmtInfo.valueMin; 468 tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin; 469 deUint32 fbo = 0; 470 deUint32 colorRbo = 0; 471 deUint32 depthStencilRbo = 0; 472 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 473 vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); 474 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 475 476 // Create fbo. 477 glGenRenderbuffers (1, &colorRbo); 478 glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); 479 glRenderbufferStorage (GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight()); 480 481 if (m_depthStencilFmt != GL_NONE) 482 { 483 glGenRenderbuffers (1, &depthStencilRbo); 484 glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); 485 glRenderbufferStorage (GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight()); 486 } 487 488 glGenFramebuffers (1, &fbo); 489 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 490 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 491 492 if (depth) 493 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 494 495 if (stencil) 496 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 497 498 checkFramebufferStatus (GL_FRAMEBUFFER); 499 500 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 501 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 502 503 glEnable (GL_DEPTH_TEST); 504 glEnable (GL_STENCIL_TEST); 505 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 506 glStencilFunc (GL_ALWAYS, 1, 0xff); 507 508 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias); 509 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 510 511 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]); 512 513 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) 514 { 515 // Color was not preserved - fill with green. 516 glDisable(GL_DEPTH_TEST); 517 glDisable(GL_STENCIL_TEST); 518 519 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias); 520 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 521 522 glEnable(GL_DEPTH_TEST); 523 glEnable(GL_STENCIL_TEST); 524 } 525 526 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) 527 { 528 // Depth was not preserved. 529 glDepthFunc(GL_ALWAYS); 530 } 531 532 if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0) 533 { 534 // Stencil was preserved. 535 glStencilFunc(GL_EQUAL, 1, 0xff); 536 } 537 538 glEnable (GL_BLEND); 539 glBlendFunc (GL_ONE, GL_ONE); 540 glBlendEquation (GL_FUNC_ADD); 541 542 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias); 543 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 544 545 readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); 546 } 547 548private: 549 deUint32 m_colorFmt; 550 deUint32 m_depthStencilFmt; 551 deUint32 m_invalidateBuffers; 552}; 553 554class InvalidateFboUnbindReadCase : public FboTestCase 555{ 556public: 557 InvalidateFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) 558 : FboTestCase (context, name, description) 559 , m_colorFmt (colorFmt) 560 , m_depthStencilFmt (depthStencilFmt) 561 , m_invalidateBuffers (invalidateBuffers) 562 { 563 DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)); 564 } 565 566protected: 567 void preCheck (void) 568 { 569 if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); 570 if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); 571 } 572 573 void render (tcu::Surface& dst) 574 { 575 tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); 576 tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); 577 tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); 578 bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; 579 bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; 580 deUint32 fbo = 0; 581 deUint32 colorTex = 0; 582 deUint32 depthStencilTex = 0; 583 GradientShader gradShader (getFragmentOutputType(colorFmt)); 584 vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); 585 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); 586 587 // Create fbo. 588 { 589 glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt); 590 591 glGenTextures (1, &colorTex); 592 glBindTexture (GL_TEXTURE_2D, colorTex); 593 glTexImage2D (GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 594 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 595 } 596 597 if (m_depthStencilFmt != GL_NONE) 598 { 599 glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt); 600 601 glGenTextures (1, &depthStencilTex); 602 glBindTexture (GL_TEXTURE_2D, depthStencilTex); 603 glTexImage2D (GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 604 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 605 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 606 } 607 608 glGenFramebuffers (1, &fbo); 609 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 610 glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0); 611 612 if (depth) 613 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); 614 615 if (stencil) 616 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); 617 618 checkFramebufferStatus (GL_FRAMEBUFFER); 619 620 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 621 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 622 623 glEnable (GL_DEPTH_TEST); 624 glEnable (GL_STENCIL_TEST); 625 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 626 glStencilFunc (GL_ALWAYS, 1, 0xff); 627 628 gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax); 629 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 630 631 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]); 632 633 glBindFramebuffer (GL_FRAMEBUFFER, 0); 634 glDisable (GL_DEPTH_TEST); 635 glDisable (GL_STENCIL_TEST); 636 637 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) 638 { 639 // Render color. 640 Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4); 641 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 642 643 texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); 644 texShader.setUniforms(*getCurrentContext(), texShaderID); 645 646 glBindTexture(GL_TEXTURE_2D, colorTex); 647 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 648 } 649 else 650 { 651 // Render depth. 652 Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4); 653 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 654 655 texShader.setUniforms(*getCurrentContext(), texShaderID); 656 657 glBindTexture(GL_TEXTURE_2D, depthStencilTex); 658 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 659 } 660 661 readPixels(dst, 0, 0, getWidth(), getHeight()); 662 } 663 664private: 665 deUint32 m_colorFmt; 666 deUint32 m_depthStencilFmt; 667 deUint32 m_invalidateBuffers; 668}; 669 670class InvalidateFboUnbindBlitCase : public FboTestCase 671{ 672public: 673 InvalidateFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers) 674 : FboTestCase (context, name, description, numSamples > 0) // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its 675 // behing-the-scenes viewport position randomization, because with glBlitFramebuffer, 676 // source and destination rectangles must match when multisampling. 677 , m_colorFmt (0) 678 , m_depthStencilFmt (0) 679 , m_numSamples (numSamples) 680 , m_invalidateBuffers (invalidateBuffers) 681 { 682 // Figure out formats that are compatible with default framebuffer. 683 m_colorFmt = getCompatibleColorFormat(m_context.getRenderTarget()); 684 m_depthStencilFmt = getCompatibleDepthStencilFormat(m_context.getRenderTarget()); 685 } 686 687protected: 688 void preCheck (void) 689 { 690 if (m_context.getRenderTarget().getNumSamples() > 0) 691 throw tcu::NotSupportedError("Not supported in MSAA config"); 692 693 if (m_colorFmt == GL_NONE) 694 throw tcu::NotSupportedError("Unsupported color format"); 695 696 if (m_depthStencilFmt == GL_NONE) 697 throw tcu::NotSupportedError("Unsupported depth/stencil format"); 698 699 checkFormatSupport(m_colorFmt); 700 checkFormatSupport(m_depthStencilFmt); 701 } 702 703 void render (tcu::Surface& dst) 704 { 705 // \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most. 706 IVec2 quadSizePixels (m_numSamples == 0 ? getWidth() : de::min(128, getWidth()), 707 m_numSamples == 0 ? getHeight() : de::min(128, getHeight())); 708 Vec2 quadNDCLeftBottomXY (-1.0f, -1.0f); 709 Vec2 quadNDCSize (2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight()); 710 Vec2 quadNDCRightTopXY = quadNDCLeftBottomXY + quadNDCSize; 711 tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); 712 bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; 713 bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; 714 deUint32 fbo = 0; 715 deUint32 colorRbo = 0; 716 deUint32 depthStencilRbo = 0; 717 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 718 vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); 719 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 720 721 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 722 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 723 724 // Create fbo. 725 glGenRenderbuffers (1, &colorRbo); 726 glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); 727 glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y()); 728 729 if (m_depthStencilFmt != GL_NONE) 730 { 731 glGenRenderbuffers (1, &depthStencilRbo); 732 glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); 733 glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y()); 734 } 735 736 glGenFramebuffers (1, &fbo); 737 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 738 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 739 740 if (depth) 741 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 742 743 if (stencil) 744 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 745 746 checkFramebufferStatus (GL_FRAMEBUFFER); 747 748 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 749 750 glEnable (GL_DEPTH_TEST); 751 glEnable (GL_STENCIL_TEST); 752 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 753 glStencilFunc (GL_ALWAYS, 1, 0xff); 754 755 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 756 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f)); 757 758 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]); 759 760 // Set default framebuffer as draw framebuffer and blit preserved buffers. 761 glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); 762 glBlitFramebuffer (0, 0, quadSizePixels.x(), quadSizePixels.y(), 763 0, 0, quadSizePixels.x(), quadSizePixels.y(), 764 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST); 765 glBindFramebuffer (GL_READ_FRAMEBUFFER, 0); 766 767 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) 768 { 769 // Color was not preserved - fill with green. 770 glDisable(GL_DEPTH_TEST); 771 glDisable(GL_STENCIL_TEST); 772 773 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 774 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); 775 776 glEnable(GL_DEPTH_TEST); 777 glEnable(GL_STENCIL_TEST); 778 } 779 780 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) 781 { 782 // Depth was not preserved. 783 glDepthFunc(GL_ALWAYS); 784 } 785 786 if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0) 787 { 788 // Stencil was preserved. 789 glStencilFunc(GL_EQUAL, 1, 0xff); 790 } 791 792 glEnable (GL_BLEND); 793 glBlendFunc (GL_ONE, GL_ONE); 794 glBlendEquation (GL_FUNC_ADD); 795 796 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 797 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); 798 799 readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y()); 800 } 801 802private: 803 deUint32 m_colorFmt; 804 deUint32 m_depthStencilFmt; 805 int m_numSamples; 806 deUint32 m_invalidateBuffers; 807}; 808 809class InvalidateSubFboRenderCase : public FboTestCase 810{ 811public: 812 InvalidateSubFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) 813 : FboTestCase (context, name, description) 814 , m_colorFmt (colorFmt) 815 , m_depthStencilFmt (depthStencilFmt) 816 , m_invalidateBuffers (invalidateBuffers) 817 { 818 } 819 820protected: 821 void preCheck (void) 822 { 823 if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); 824 if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); 825 } 826 827 void render (tcu::Surface& dst) 828 { 829 tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); 830 tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); 831 tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); 832 bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; 833 bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; 834 const tcu::Vec4& cBias = colorFmtInfo.valueMin; 835 tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin; 836 deUint32 fbo = 0; 837 deUint32 colorRbo = 0; 838 deUint32 depthStencilRbo = 0; 839 int invalidateX = getWidth() / 4; 840 int invalidateY = getHeight() / 4; 841 int invalidateW = getWidth() / 2; 842 int invalidateH = getHeight() / 2; 843 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 844 vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); 845 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 846 847 // Create fbo. 848 glGenRenderbuffers (1, &colorRbo); 849 glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); 850 glRenderbufferStorage (GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight()); 851 852 if (m_depthStencilFmt != GL_NONE) 853 { 854 glGenRenderbuffers (1, &depthStencilRbo); 855 glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); 856 glRenderbufferStorage (GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight()); 857 } 858 859 glGenFramebuffers (1, &fbo); 860 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 861 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 862 863 if (depth) 864 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 865 866 if (stencil) 867 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 868 869 checkFramebufferStatus (GL_FRAMEBUFFER); 870 871 glClearBufferfv (GL_COLOR, 0, (Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias).getPtr()); 872 glClearBufferfi (GL_DEPTH_STENCIL, 0, 1.0f, 0); 873 874 glEnable (GL_DEPTH_TEST); 875 glEnable (GL_STENCIL_TEST); 876 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 877 glStencilFunc (GL_ALWAYS, 1, 0xff); 878 879 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias); 880 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 881 882 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); 883 884 // Clear invalidated buffers. 885 glScissor (invalidateX, invalidateY, invalidateW, invalidateH); 886 glEnable (GL_SCISSOR_TEST); 887 888 if (m_invalidateBuffers & GL_COLOR_BUFFER_BIT) 889 glClearBufferfv(GL_COLOR, 0, (Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias).getPtr()); 890 891 glClear (m_invalidateBuffers & ~GL_COLOR_BUFFER_BIT); 892 glDisable (GL_SCISSOR_TEST); 893 894 glEnable (GL_BLEND); 895 glBlendFunc (GL_ONE, GL_ONE); 896 glBlendEquation (GL_FUNC_ADD); 897 898 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias); 899 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 900 901 readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); 902 } 903 904private: 905 deUint32 m_colorFmt; 906 deUint32 m_depthStencilFmt; 907 deUint32 m_invalidateBuffers; 908}; 909 910class InvalidateSubFboUnbindReadCase : public FboTestCase 911{ 912public: 913 InvalidateSubFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) 914 : FboTestCase (context, name, description) 915 , m_colorFmt (colorFmt) 916 , m_depthStencilFmt (depthStencilFmt) 917 , m_invalidateBuffers (invalidateBuffers) 918 { 919 DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)); 920 } 921 922protected: 923 void preCheck (void) 924 { 925 if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); 926 if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); 927 } 928 929 void render (tcu::Surface& dst) 930 { 931 tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); 932 tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); 933 tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); 934 bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; 935 bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; 936 deUint32 fbo = 0; 937 deUint32 colorTex = 0; 938 deUint32 depthStencilTex = 0; 939 int invalidateX = 0; 940 int invalidateY = 0; 941 int invalidateW = getWidth()/2; 942 int invalidateH = getHeight(); 943 int readX = invalidateW; 944 int readY = 0; 945 int readW = getWidth()/2; 946 int readH = getHeight(); 947 GradientShader gradShader (getFragmentOutputType(colorFmt)); 948 vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); 949 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); 950 951 // Create fbo. 952 { 953 glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt); 954 955 glGenTextures (1, &colorTex); 956 glBindTexture (GL_TEXTURE_2D, colorTex); 957 glTexImage2D (GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 958 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 959 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 960 } 961 962 if (m_depthStencilFmt != GL_NONE) 963 { 964 glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt); 965 966 glGenTextures (1, &depthStencilTex); 967 glBindTexture (GL_TEXTURE_2D, depthStencilTex); 968 glTexImage2D (GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); 969 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 970 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 971 } 972 973 glGenFramebuffers (1, &fbo); 974 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 975 glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0); 976 977 if (depth) 978 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); 979 980 if (stencil) 981 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); 982 983 checkFramebufferStatus (GL_FRAMEBUFFER); 984 985 clearColorBuffer(colorFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 986 glClear (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 987 988 glEnable (GL_DEPTH_TEST); 989 glEnable (GL_STENCIL_TEST); 990 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 991 glStencilFunc (GL_ALWAYS, 1, 0xff); 992 993 gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax); 994 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 995 996 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); 997 998 glBindFramebuffer (GL_FRAMEBUFFER, 0); 999 glDisable (GL_DEPTH_TEST); 1000 glDisable (GL_STENCIL_TEST); 1001 1002 glClearColor (0.25f, 0.5f, 0.75f, 1.0f); 1003 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1004 1005 // Limit read area using scissor. 1006 glScissor (readX, readY, readW, readH); 1007 glEnable (GL_SCISSOR_TEST); 1008 1009 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) 1010 { 1011 // Render color. 1012 Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4); 1013 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 1014 1015 texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); 1016 texShader.setUniforms(*getCurrentContext(), texShaderID); 1017 1018 glBindTexture(GL_TEXTURE_2D, colorTex); 1019 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1020 } 1021 else 1022 { 1023 // Render depth. 1024 Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4); 1025 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 1026 1027 texShader.setUniforms(*getCurrentContext(), texShaderID); 1028 1029 glBindTexture(GL_TEXTURE_2D, depthStencilTex); 1030 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1031 } 1032 1033 readPixels(dst, 0, 0, getWidth(), getHeight()); 1034 } 1035 1036 bool compare (const tcu::Surface& reference, const tcu::Surface& result) 1037 { 1038 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_colorFmt), tcu::RGBA(12, 12, 12, 12))); 1039 1040 return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT); 1041 } 1042 1043private: 1044 deUint32 m_colorFmt; 1045 deUint32 m_depthStencilFmt; 1046 deUint32 m_invalidateBuffers; 1047}; 1048 1049class InvalidateSubFboUnbindBlitCase : public FboTestCase 1050{ 1051public: 1052 InvalidateSubFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers) 1053 : FboTestCase (context, name, description, numSamples > 0) // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its 1054 // behing-the-scenes viewport position randomization, because with glBlitFramebuffer, 1055 // source and destination rectangles must match when multisampling. 1056 , m_colorFmt (0) 1057 , m_depthStencilFmt (0) 1058 , m_numSamples (numSamples) 1059 , m_invalidateBuffers (invalidateBuffers) 1060 { 1061 // Figure out formats that are compatible with default framebuffer. 1062 m_colorFmt = getCompatibleColorFormat(m_context.getRenderTarget()); 1063 m_depthStencilFmt = getCompatibleDepthStencilFormat(m_context.getRenderTarget()); 1064 } 1065 1066protected: 1067 void preCheck (void) 1068 { 1069 if (m_context.getRenderTarget().getNumSamples() > 0) 1070 throw tcu::NotSupportedError("Not supported in MSAA config"); 1071 1072 if (m_colorFmt == GL_NONE) 1073 throw tcu::NotSupportedError("Unsupported color format"); 1074 1075 if (m_depthStencilFmt == GL_NONE) 1076 throw tcu::NotSupportedError("Unsupported depth/stencil format"); 1077 1078 checkFormatSupport(m_colorFmt); 1079 checkFormatSupport(m_depthStencilFmt); 1080 } 1081 1082 void render (tcu::Surface& dst) 1083 { 1084 // \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most. 1085 IVec2 quadSizePixels (m_numSamples == 0 ? getWidth() : de::min(128, getWidth()), 1086 m_numSamples == 0 ? getHeight() : de::min(128, getHeight())); 1087 Vec2 quadNDCLeftBottomXY (-1.0f, -1.0f); 1088 Vec2 quadNDCSize (2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight()); 1089 Vec2 quadNDCRightTopXY = quadNDCLeftBottomXY + quadNDCSize; 1090 tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); 1091 bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; 1092 bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; 1093 deUint32 fbo = 0; 1094 deUint32 colorRbo = 0; 1095 deUint32 depthStencilRbo = 0; 1096 int invalidateX = 0; 1097 int invalidateY = 0; 1098 int invalidateW = quadSizePixels.x()/2; 1099 int invalidateH = quadSizePixels.y(); 1100 int blitX0 = invalidateW; 1101 int blitY0 = 0; 1102 int blitX1 = blitX0 + quadSizePixels.x()/2; 1103 int blitY1 = blitY0 + quadSizePixels.y(); 1104 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 1105 vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); 1106 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 1107 1108 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 1109 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1110 1111 // Create fbo. 1112 glGenRenderbuffers (1, &colorRbo); 1113 glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); 1114 glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y()); 1115 1116 if (m_depthStencilFmt != GL_NONE) 1117 { 1118 glGenRenderbuffers (1, &depthStencilRbo); 1119 glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); 1120 glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y()); 1121 } 1122 1123 glGenFramebuffers (1, &fbo); 1124 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 1125 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 1126 1127 if (depth) 1128 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 1129 1130 if (stencil) 1131 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 1132 1133 checkFramebufferStatus (GL_FRAMEBUFFER); 1134 1135 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1136 1137 glEnable (GL_DEPTH_TEST); 1138 glEnable (GL_STENCIL_TEST); 1139 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 1140 glStencilFunc (GL_ALWAYS, 1, 0xff); 1141 1142 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1143 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f)); 1144 1145 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); 1146 1147 // Set default framebuffer as draw framebuffer and blit preserved buffers. 1148 glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); 1149 glBlitFramebuffer (blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1, (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST); 1150 glBindFramebuffer (GL_READ_FRAMEBUFFER, 0); 1151 1152 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) 1153 { 1154 // Color was not preserved - fill with green. 1155 glDisable(GL_DEPTH_TEST); 1156 glDisable(GL_STENCIL_TEST); 1157 1158 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 1159 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); 1160 1161 glEnable(GL_DEPTH_TEST); 1162 glEnable(GL_STENCIL_TEST); 1163 } 1164 1165 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) 1166 { 1167 // Depth was not preserved. 1168 glDepthFunc(GL_ALWAYS); 1169 } 1170 1171 if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0) 1172 { 1173 // Stencil was preserved. 1174 glStencilFunc(GL_EQUAL, 1, 0xff); 1175 } 1176 1177 glEnable (GL_BLEND); 1178 glBlendFunc (GL_ONE, GL_ONE); 1179 glBlendEquation (GL_FUNC_ADD); 1180 1181 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 1182 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); 1183 1184 readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y()); 1185 } 1186 1187private: 1188 deUint32 m_colorFmt; 1189 deUint32 m_depthStencilFmt; 1190 int m_numSamples; 1191 deUint32 m_invalidateBuffers; 1192}; 1193 1194class InvalidateFboTargetCase : public FboTestCase 1195{ 1196public: 1197 InvalidateFboTargetCase (Context& context, const char* name, const char* description, deUint32 boundTarget, deUint32 invalidateTarget, const deUint32* invalidateAttachments, int numAttachments) 1198 : FboTestCase (context, name, description) 1199 , m_boundTarget (boundTarget) 1200 , m_invalidateTarget (invalidateTarget) 1201 , m_invalidateAttachments (invalidateAttachments, invalidateAttachments+numAttachments) 1202 { 1203 } 1204 1205protected: 1206 void render (tcu::Surface& dst) 1207 { 1208 const deUint32 colorFormat = GL_RGBA8; 1209 const deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8; 1210 const tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(colorFormat); 1211 const tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); 1212 const tcu::Vec4& cBias = colorFmtInfo.valueMin; 1213 const tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin; 1214 const bool isDiscarded = (m_boundTarget == GL_FRAMEBUFFER) || 1215 (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) || 1216 (m_invalidateTarget == m_boundTarget); 1217 const bool isColorDiscarded = isDiscarded && hasAttachment(m_invalidateAttachments, GL_COLOR_ATTACHMENT0); 1218 const bool isDepthDiscarded = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_DEPTH_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT)); 1219 const bool isStencilDiscarded = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_STENCIL_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT)); 1220 1221 deUint32 fbo = 0; 1222 deUint32 colorRbo = 0; 1223 deUint32 depthStencilRbo = 0; 1224 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 1225 deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); 1226 1227 // Create fbo. 1228 glGenRenderbuffers (1, &colorRbo); 1229 glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); 1230 glRenderbufferStorage (GL_RENDERBUFFER, colorFormat, getWidth(), getHeight()); 1231 1232 glGenRenderbuffers (1, &depthStencilRbo); 1233 glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); 1234 glRenderbufferStorage (GL_RENDERBUFFER, depthStencilFormat, getWidth(), getHeight()); 1235 1236 glGenFramebuffers (1, &fbo); 1237 glBindFramebuffer (GL_FRAMEBUFFER, fbo); 1238 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 1239 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 1240 glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); 1241 1242 checkFramebufferStatus (GL_FRAMEBUFFER); 1243 1244 glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 1245 glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1246 1247 glEnable (GL_DEPTH_TEST); 1248 glEnable (GL_STENCIL_TEST); 1249 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); 1250 glStencilFunc (GL_ALWAYS, 1, 0xff); 1251 1252 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias); 1253 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 1254 1255 // Bound FBO to test target and default to other 1256 if (m_boundTarget != GL_FRAMEBUFFER) 1257 { 1258 // Dummy fbo is used as complemeting target (read when discarding draw for example). 1259 // \note Framework takes care of deleting objects at the end of test case. 1260 const deUint32 dummyTarget = m_boundTarget == GL_DRAW_FRAMEBUFFER ? GL_READ_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER; 1261 deUint32 dummyFbo = 0; 1262 deUint32 dummyColorRbo = 0; 1263 1264 glGenRenderbuffers (1, &dummyColorRbo); 1265 glBindRenderbuffer (GL_RENDERBUFFER, dummyColorRbo); 1266 glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, 64, 64); 1267 glGenFramebuffers (1, &dummyFbo); 1268 glBindFramebuffer (dummyTarget, dummyFbo); 1269 glFramebufferRenderbuffer (dummyTarget, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dummyColorRbo); 1270 1271 glBindFramebuffer (m_boundTarget, fbo); 1272 } 1273 1274 glInvalidateFramebuffer(m_invalidateTarget, (int)m_invalidateAttachments.size(), m_invalidateAttachments.empty() ? DE_NULL : &m_invalidateAttachments[0]); 1275 1276 if (m_boundTarget != GL_FRAMEBUFFER) 1277 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1278 1279 if (isColorDiscarded) 1280 { 1281 // Color was not preserved - fill with green. 1282 glDisable(GL_DEPTH_TEST); 1283 glDisable(GL_STENCIL_TEST); 1284 1285 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias); 1286 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1287 1288 glEnable(GL_DEPTH_TEST); 1289 glEnable(GL_STENCIL_TEST); 1290 } 1291 1292 if (isDepthDiscarded) 1293 { 1294 // Depth was not preserved. 1295 glDepthFunc(GL_ALWAYS); 1296 } 1297 1298 if (!isStencilDiscarded) 1299 { 1300 // Stencil was preserved. 1301 glStencilFunc(GL_EQUAL, 1, 0xff); 1302 } 1303 1304 glEnable (GL_BLEND); 1305 glBlendFunc (GL_ONE, GL_ONE); 1306 glBlendEquation (GL_FUNC_ADD); 1307 1308 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias); 1309 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1310 1311 readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); 1312 } 1313 1314private: 1315 deUint32 m_boundTarget; 1316 deUint32 m_invalidateTarget; 1317 std::vector<deUint32> m_invalidateAttachments; 1318}; 1319 1320FboInvalidateTests::FboInvalidateTests (Context& context) 1321 : TestCaseGroup(context, "invalidate", "Framebuffer invalidate tests") 1322{ 1323} 1324 1325FboInvalidateTests::~FboInvalidateTests (void) 1326{ 1327} 1328 1329void FboInvalidateTests::init (void) 1330{ 1331 // invalidate.default. 1332 { 1333 tcu::TestCaseGroup* defaultFbGroup = new tcu::TestCaseGroup(m_testCtx, "default", "Default framebuffer invalidate tests"); 1334 addChild(defaultFbGroup); 1335 1336 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_none", "Invalidating no framebuffers (ref)", 0)); 1337 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_color", "Rendering after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); 1338 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_depth", "Rendering after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); 1339 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_stencil", "Rendering after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); 1340 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_depth_stencil", "Rendering after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1341 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_all", "Rendering after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1342 1343 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_color", "Binding fbo after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); 1344 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_depth", "Binding fbo after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); 1345 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_stencil", "Binding fbo after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); 1346 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_depth_stencil", "Binding fbo after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1347 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_all", "Binding fbo after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1348 1349 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_color", "Rendering after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); 1350 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_depth", "Rendering after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); 1351 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_stencil", "Rendering after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); 1352 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_depth_stencil", "Rendering after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1353 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_all", "Rendering after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1354 1355 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_color", "Binding fbo after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); 1356 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_depth", "Binding fbo after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); 1357 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_stencil", "Binding fbo after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); 1358 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_depth_stencil", "Binding fbo after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1359 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_all", "Binding fbo after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1360 1361 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "draw_framebuffer_color", "Invalidating GL_COLOR in GL_DRAW_FRAMEBUFFER", GL_COLOR_BUFFER_BIT, GL_DRAW_FRAMEBUFFER)); 1362 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "draw_framebuffer_all", "Invalidating all in GL_DRAW_FRAMEBUFFER", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, GL_DRAW_FRAMEBUFFER)); 1363 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "read_framebuffer_color", "Invalidating GL_COLOR in GL_READ_FRAMEBUFFER", GL_COLOR_BUFFER_BIT, GL_READ_FRAMEBUFFER)); 1364 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "read_framebuffer_all", "Invalidating all in GL_READ_FRAMEBUFFER", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, GL_READ_FRAMEBUFFER)); 1365 } 1366 1367 // invalidate.whole. 1368 { 1369 tcu::TestCaseGroup* wholeFboGroup = new tcu::TestCaseGroup(m_testCtx, "whole", "Invalidating whole framebuffer object"); 1370 addChild(wholeFboGroup); 1371 1372 wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_none", "", GL_RGBA8, GL_DEPTH24_STENCIL8, 0)); 1373 wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); 1374 wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); 1375 wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); 1376 wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1377 wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_all", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1378 1379 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); 1380 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); 1381 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); 1382 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1383 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_color_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1384 1385 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_color", "", 0, GL_COLOR_BUFFER_BIT)); 1386 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_depth", "", 0, GL_DEPTH_BUFFER_BIT)); 1387 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_stencil", "", 0, GL_STENCIL_BUFFER_BIT)); 1388 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_depth_stencil", "", 0, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1389 1390 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_color", "", 4, GL_COLOR_BUFFER_BIT)); 1391 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_depth", "", 4, GL_DEPTH_BUFFER_BIT)); 1392 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_stencil", "", 4, GL_STENCIL_BUFFER_BIT)); 1393 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_depth_stencil", "", 4, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1394 } 1395 1396 // invalidate.sub. 1397 { 1398 tcu::TestCaseGroup* subFboGroup = new tcu::TestCaseGroup(m_testCtx, "sub", "Invalidating subsection of framebuffer object"); 1399 addChild(subFboGroup); 1400 1401 subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_none", "", GL_RGBA8, GL_DEPTH24_STENCIL8, 0)); 1402 subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); 1403 subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); 1404 subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); 1405 subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1406 subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_all", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1407 1408 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); 1409 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); 1410 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); 1411 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1412 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1413 1414 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_color", "", 0, GL_COLOR_BUFFER_BIT)); 1415 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth", "", 0, GL_DEPTH_BUFFER_BIT)); 1416 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_stencil", "", 0, GL_STENCIL_BUFFER_BIT)); 1417 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth_stencil", "", 0, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1418 1419 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_color", "", 4, GL_COLOR_BUFFER_BIT)); 1420 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth", "", 4, GL_DEPTH_BUFFER_BIT)); 1421 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_stencil", "", 4, GL_STENCIL_BUFFER_BIT)); 1422 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth_stencil", "", 4, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1423 } 1424 1425 // invalidate.format. 1426 { 1427 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Invalidating framebuffers with selected formats"); 1428 addChild(formatGroup); 1429 1430 // Color buffer formats. 1431 static const deUint32 colorFormats[] = 1432 { 1433 // RGBA formats 1434 GL_RGBA32I, 1435 GL_RGBA32UI, 1436 GL_RGBA16I, 1437 GL_RGBA16UI, 1438 GL_RGBA8, 1439 GL_RGBA8I, 1440 GL_RGBA8UI, 1441 GL_SRGB8_ALPHA8, 1442 GL_RGB10_A2, 1443 GL_RGB10_A2UI, 1444 GL_RGBA4, 1445 GL_RGB5_A1, 1446 1447 // RGB formats 1448 GL_RGB8, 1449 GL_RGB565, 1450 1451 // RG formats 1452 GL_RG32I, 1453 GL_RG32UI, 1454 GL_RG16I, 1455 GL_RG16UI, 1456 GL_RG8, 1457 GL_RG8I, 1458 GL_RG8UI, 1459 1460 // R formats 1461 GL_R32I, 1462 GL_R32UI, 1463 GL_R16I, 1464 GL_R16UI, 1465 GL_R8, 1466 GL_R8I, 1467 GL_R8UI, 1468 1469 // GL_EXT_color_buffer_float 1470 GL_RGBA32F, 1471 GL_RGBA16F, 1472 GL_R11F_G11F_B10F, 1473 GL_RG32F, 1474 GL_RG16F, 1475 GL_R32F, 1476 GL_R16F 1477 }; 1478 1479 // Depth/stencilbuffer formats. 1480 static const deUint32 depthStencilFormats[] = 1481 { 1482 GL_DEPTH_COMPONENT32F, 1483 GL_DEPTH_COMPONENT24, 1484 GL_DEPTH_COMPONENT16, 1485 GL_DEPTH32F_STENCIL8, 1486 GL_DEPTH24_STENCIL8, 1487 GL_STENCIL_INDEX8 1488 }; 1489 1490 // Colorbuffer tests use invalidate, unbind, read test. 1491 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++) 1492 formatGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], GL_NONE, GL_COLOR_BUFFER_BIT)); 1493 1494 // Depth/stencilbuffer tests use invalidate, render test. 1495 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) 1496 formatGroup->addChild(new InvalidateSubFboRenderCase(m_context, getFormatName(depthStencilFormats[ndx]), "", GL_RGBA8, depthStencilFormats[ndx], GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); 1497 } 1498 1499 // invalidate.target 1500 { 1501 tcu::TestCaseGroup* targetGroup = new tcu::TestCaseGroup(m_testCtx, "target", "Invalidate target"); 1502 addChild(targetGroup); 1503 1504 static const struct 1505 { 1506 const char* name; 1507 deUint32 invalidateTarget; 1508 deUint32 boundTarget; 1509 } s_targetCases[] = 1510 { 1511 { "framebuffer_framebuffer", GL_FRAMEBUFFER, GL_FRAMEBUFFER }, 1512 { "framebuffer_read_framebuffer", GL_FRAMEBUFFER, GL_READ_FRAMEBUFFER }, 1513 { "framebuffer_draw_framebuffer", GL_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER }, 1514 { "read_framebuffer_framebuffer", GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER }, 1515 { "read_framebuffer_read_framebuffer", GL_READ_FRAMEBUFFER, GL_READ_FRAMEBUFFER }, 1516 { "read_framebuffer_draw_framebuffer", GL_READ_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER }, 1517 { "draw_framebuffer_framebuffer", GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER }, 1518 { "draw_framebuffer_read_framebuffer", GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER }, 1519 { "draw_framebuffer_draw_framebuffer", GL_DRAW_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER }, 1520 }; 1521 1522 static const deUint32 colorAttachment[] = { GL_COLOR_ATTACHMENT0 }; 1523 static const deUint32 depthStencilAttachment[] = { GL_DEPTH_STENCIL_ATTACHMENT }; 1524 static const deUint32 allAttachments[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; 1525 1526 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_targetCases); caseNdx++) 1527 { 1528 const std::string baseName = s_targetCases[caseNdx].name; 1529 const deUint32 invalidateT = s_targetCases[caseNdx].invalidateTarget; 1530 const deUint32 boundT = s_targetCases[caseNdx].boundTarget; 1531 1532 targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_color").c_str(), "", boundT, invalidateT, &colorAttachment[0], DE_LENGTH_OF_ARRAY(colorAttachment))); 1533 targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_depth_stencil").c_str(), "", boundT, invalidateT, &depthStencilAttachment[0], DE_LENGTH_OF_ARRAY(depthStencilAttachment))); 1534 targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_all").c_str(), "", boundT, invalidateT, &allAttachments[0], DE_LENGTH_OF_ARRAY(allAttachments))); 1535 } 1536 } 1537} 1538 1539} // Functional 1540} // gles3 1541} // deqp 1542