1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.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 Framebuffer Object Tests. 22 * 23 * Notes: 24 * + Like in API tests, tcu::sgl2s::Context class is used. 25 * + ReferenceContext is used to generate reference images. 26 * + API calls can be logged \todo [pyry] Implement. 27 *//*--------------------------------------------------------------------*/ 28 29#include "es2fFboRenderTest.hpp" 30#include "sglrContextUtil.hpp" 31#include "sglrGLContext.hpp" 32#include "sglrReferenceContext.hpp" 33#include "tcuSurface.hpp" 34#include "tcuTextureUtil.hpp" 35#include "tcuImageCompare.hpp" 36#include "tcuRenderTarget.hpp" 37#include "gluPixelTransfer.hpp" 38#include "gluTextureUtil.hpp" 39#include "gluStrUtil.hpp" 40#include "deRandom.hpp" 41#include "deString.h" 42 43#include "glwFunctions.hpp" 44#include "glwEnums.hpp" 45 46using std::vector; 47using std::string; 48using tcu::Vec2; 49using tcu::Vec3; 50using tcu::Vec4; 51using tcu::RGBA; 52using tcu::Surface; 53using namespace glw; // GL types 54 55namespace deqp 56{ 57namespace gles2 58{ 59namespace Functional 60{ 61 62// Shaders. 63 64class FlatColorShader : public sglr::ShaderProgram 65{ 66public: 67 FlatColorShader (void) 68 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 69 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 70 << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT) 71 << sglr::pdec::Uniform("u_color", glu::TYPE_FLOAT_VEC4) 72 << sglr::pdec::VertexSource( 73 "attribute highp vec4 a_position;\n" 74 "void main (void)\n" 75 "{\n" 76 " gl_Position = a_position;\n" 77 "}\n") 78 << sglr::pdec::FragmentSource( 79 "uniform mediump vec4 u_color;\n" 80 "void main (void)\n" 81 "{\n" 82 " gl_FragColor = u_color;\n" 83 "}\n")) 84 { 85 } 86 87 void setColor (sglr::Context& gl, deUint32 program, const tcu::Vec4& color) 88 { 89 gl.useProgram(program); 90 gl.uniform4fv(gl.getUniformLocation(program, "u_color"), 1, color.getPtr()); 91 } 92 93 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 94 { 95 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 96 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx); 97 } 98 99 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 100 { 101 const tcu::Vec4 color(m_uniforms[0].value.f4); 102 103 DE_UNREF(packets); 104 105 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 106 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 107 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 108 } 109}; 110 111class SingleTex2DShader : public sglr::ShaderProgram 112{ 113public: 114 SingleTex2DShader (void) 115 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 116 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 117 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 118 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 119 << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT) 120 << sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D) 121 << sglr::pdec::VertexSource( 122 "attribute highp vec4 a_position;\n" 123 "attribute mediump vec2 a_coord;\n" 124 "varying mediump vec2 v_coord;\n" 125 "void main (void)\n" 126 "{\n" 127 " gl_Position = a_position;\n" 128 " v_coord = a_coord;\n" 129 "}\n") 130 << sglr::pdec::FragmentSource( 131 "uniform sampler2D u_sampler0;\n" 132 "varying mediump vec2 v_coord;\n" 133 "void main (void)\n" 134 "{\n" 135 " gl_FragColor = texture2D(u_sampler0, v_coord);\n" 136 "}\n")) 137 { 138 } 139 140 void setUnit (sglr::Context& gl, deUint32 program, int unitNdx) 141 { 142 gl.useProgram(program); 143 gl.uniform1i(gl.getUniformLocation(program, "u_sampler0"), unitNdx); 144 } 145 146 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 147 { 148 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 149 { 150 rr::VertexPacket& packet = *packets[packetNdx]; 151 152 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 153 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 154 } 155 } 156 157 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 158 { 159 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 160 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 161 { 162 const tcu::Vec4 v_coord = rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx); 163 const float lod = 0.0f; 164 165 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, this->m_uniforms[0].sampler.tex2D->sample(v_coord.x(), v_coord.y(), lod)); 166 } 167 } 168 169}; 170 171class MixTexturesShader : public sglr::ShaderProgram 172{ 173public: 174 MixTexturesShader (void) 175 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 176 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 177 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 178 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 179 << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT) 180 << sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D) 181 << sglr::pdec::Uniform("u_sampler1", glu::TYPE_SAMPLER_2D) 182 << sglr::pdec::VertexSource( 183 "attribute highp vec4 a_position;\n" 184 "attribute mediump vec2 a_coord;\n" 185 "varying mediump vec2 v_coord;\n" 186 "void main (void)\n" 187 "{\n" 188 " gl_Position = a_position;\n" 189 " v_coord = a_coord;\n" 190 "}\n") 191 << sglr::pdec::FragmentSource( 192 "uniform sampler2D u_sampler0;\n" 193 "uniform sampler2D u_sampler1;\n" 194 "varying mediump vec2 v_coord;\n" 195 "void main (void)\n" 196 "{\n" 197 " gl_FragColor = texture2D(u_sampler0, v_coord)*0.5 + texture2D(u_sampler1, v_coord)*0.5;\n" 198 "}\n")) 199 { 200 } 201 202 void setUnits (sglr::Context& gl, deUint32 program, int unit0, int unit1) 203 { 204 gl.useProgram(program); 205 gl.uniform1i(gl.getUniformLocation(program, "u_sampler0"), unit0); 206 gl.uniform1i(gl.getUniformLocation(program, "u_sampler1"), unit1); 207 } 208 209 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 210 { 211 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 212 { 213 rr::VertexPacket& packet = *packets[packetNdx]; 214 215 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 216 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 217 } 218 } 219 220 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 221 { 222 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 223 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 224 { 225 const tcu::Vec4 v_coord = rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx); 226 const float lod = 0.0f; 227 228 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, this->m_uniforms[0].sampler.tex2D->sample(v_coord.x(), v_coord.y(), lod) * 0.5f 229 + this->m_uniforms[1].sampler.tex2D->sample(v_coord.x(), v_coord.y(), lod) * 0.5f); 230 } 231 } 232}; 233 234// Framebuffer config. 235 236class FboConfig 237{ 238public: 239 FboConfig (void) 240 : colorbufferType (GL_NONE) 241 , colorbufferFormat (GL_NONE) 242 , depthbufferType (GL_NONE) 243 , depthbufferFormat (GL_NONE) 244 , stencilbufferType (GL_NONE) 245 , stencilbufferFormat (GL_NONE) 246 { 247 } 248 249 std::string getName (void) const; 250 251 GLenum colorbufferType; //!< GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER 252 GLenum colorbufferFormat; //!< Internal format for color buffer texture or renderbuffer 253 254 GLenum depthbufferType; //!< GL_RENDERBUFFER 255 GLenum depthbufferFormat; 256 257 GLenum stencilbufferType; //!< GL_RENDERBUFFER 258 GLenum stencilbufferFormat; 259 260private: 261 static const char* getFormatName (GLenum format); 262}; 263 264const char* FboConfig::getFormatName (GLenum format) 265{ 266 switch (format) 267 { 268 case GL_RGB: return "rgb"; 269 case GL_RGBA: return "rgba"; 270 case GL_ALPHA: return "alpha"; 271 case GL_LUMINANCE: return "luminance"; 272 case GL_LUMINANCE_ALPHA: return "luminance_alpha"; 273 case GL_RGB565: return "rgb565"; 274 case GL_RGB5_A1: return "rgb5_a1"; 275 case GL_RGBA4: return "rgba4"; 276 case GL_RGBA16F: return "rgba16f"; 277 case GL_RGB16F: return "rgb16f"; 278 case GL_DEPTH_COMPONENT16: return "depth_component16"; 279 case GL_STENCIL_INDEX8: return "stencil_index8"; 280 default: DE_ASSERT(false); return DE_NULL; 281 } 282} 283 284std::string FboConfig::getName (void) const 285{ 286 std::string name = ""; 287 288 if (colorbufferType != GL_NONE) 289 { 290 switch (colorbufferType) 291 { 292 case GL_TEXTURE_2D: name += "tex2d_"; break; 293 case GL_TEXTURE_CUBE_MAP: name += "texcube_"; break; 294 case GL_RENDERBUFFER: name += "rbo_"; break; 295 default: DE_ASSERT(false); break; 296 } 297 name += getFormatName(colorbufferFormat); 298 } 299 300 if (depthbufferType != GL_NONE) 301 { 302 DE_ASSERT(depthbufferType == GL_RENDERBUFFER); 303 if (name.length() > 0) 304 name += "_"; 305 name += getFormatName(depthbufferFormat); 306 } 307 308 if (stencilbufferType != GL_NONE) 309 { 310 DE_ASSERT(stencilbufferType == GL_RENDERBUFFER); 311 if (name.length() > 0) 312 name += "_"; 313 name += getFormatName(stencilbufferFormat); 314 } 315 316 return name; 317} 318 319class FboIncompleteException : public tcu::TestError 320{ 321public: 322 FboIncompleteException (const FboConfig& config, GLenum reason, const char* file, int line); 323 virtual ~FboIncompleteException (void) throw() {} 324 325 const FboConfig& getConfig (void) const { return m_config; } 326 GLenum getReason (void) const { return m_reason; } 327 328private: 329 FboConfig m_config; 330 GLenum m_reason; 331}; 332 333static const char* getFboIncompleteReasonName (GLenum reason) 334{ 335 switch (reason) 336 { 337 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; 338 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; 339 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; 340 case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED"; 341 case GL_FRAMEBUFFER_COMPLETE: return "GL_FRAMEBUFFER_COMPLETE"; 342 default: return "UNKNOWN"; 343 } 344} 345 346FboIncompleteException::FboIncompleteException (const FboConfig& config, GLenum reason, const char* file, int line) 347 : TestError("Framebuffer is not complete", getFboIncompleteReasonName(reason), file, line) 348 , m_config(config) 349 , m_reason(reason) 350{ 351} 352 353class Framebuffer 354{ 355public: 356 Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo = 0, deUint32 colorbuffer = 0, deUint32 depthbuffer = 0, deUint32 stencilbuffer = 0); 357 ~Framebuffer (void); 358 359 const FboConfig& getConfig (void) const { return m_config; } 360 deUint32 getFramebuffer (void) const { return m_framebuffer; } 361 deUint32 getColorbuffer (void) const { return m_colorbuffer; } 362 deUint32 getDepthbuffer (void) const { return m_depthbuffer; } 363 deUint32 getStencilbuffer (void) const { return m_stencilbuffer; } 364 365 void checkCompleteness (void); 366 367private: 368 void createRbo (deUint32& name, GLenum format, int width, int height); 369 void destroyBuffer (deUint32 name, GLenum type); 370 371 FboConfig m_config; 372 sglr::Context& m_context; 373 deUint32 m_framebuffer; 374 deUint32 m_colorbuffer; 375 deUint32 m_depthbuffer; 376 deUint32 m_stencilbuffer; 377}; 378 379static bool isExtensionSupported (sglr::Context& context, const char* name) 380{ 381 std::istringstream extensions(context.getString(GL_EXTENSIONS)); 382 std::string extension; 383 384 while (std::getline(extensions, extension, ' ')) 385 { 386 if (extension == name) 387 return true; 388 } 389 390 return false; 391} 392 393static void checkColorFormatSupport (sglr::Context& context, deUint32 sizedFormat) 394{ 395 switch (sizedFormat) 396 { 397 case GL_RGBA16F: 398 case GL_RGB16F: 399 case GL_RG16F: 400 case GL_R16F: 401 if (!isExtensionSupported(context, "GL_EXT_color_buffer_half_float")) 402 throw tcu::NotSupportedError("GL_EXT_color_buffer_half_float is not supported"); 403 404 default: 405 break; 406 } 407} 408 409Framebuffer::Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo, deUint32 colorbuffer, deUint32 depthbuffer, deUint32 stencilbuffer) 410 : m_config (config) 411 , m_context (context) 412 , m_framebuffer (fbo) 413 , m_colorbuffer (colorbuffer) 414 , m_depthbuffer (depthbuffer) 415 , m_stencilbuffer (stencilbuffer) 416{ 417 // Verify that color format is supported 418 checkColorFormatSupport(context, config.colorbufferFormat); 419 420 if (m_framebuffer == 0) 421 context.genFramebuffers(1, &m_framebuffer); 422 context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 423 424 switch (m_config.colorbufferType) 425 { 426 case GL_TEXTURE_2D: 427 if (m_colorbuffer == 0) 428 context.genTextures(1, &m_colorbuffer); 429 context.bindTexture(GL_TEXTURE_2D, m_colorbuffer); 430 context.texImage2D(GL_TEXTURE_2D, 0, m_config.colorbufferFormat, width, height); 431 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 432 433 if (!deIsPowerOfTwo32(width) || !deIsPowerOfTwo32(height)) 434 { 435 // Set wrap mode to clamp for NPOT FBOs 436 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 437 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 438 } 439 440 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorbuffer, 0); 441 break; 442 443 case GL_TEXTURE_CUBE_MAP: 444 DE_FATAL("TODO"); 445 break; 446 447 case GL_RENDERBUFFER: 448 createRbo(m_colorbuffer, m_config.colorbufferFormat, width, height); 449 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorbuffer); 450 break; 451 452 default: 453 DE_ASSERT(m_config.colorbufferType == GL_NONE); 454 break; 455 } 456 457 if (m_config.depthbufferType == GL_RENDERBUFFER) 458 { 459 createRbo(m_depthbuffer, m_config.depthbufferFormat, width, height); 460 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer); 461 } 462 else 463 DE_ASSERT(m_config.depthbufferType == GL_NONE); 464 465 if (m_config.stencilbufferType == GL_RENDERBUFFER) 466 { 467 createRbo(m_stencilbuffer, m_config.stencilbufferFormat, width, height); 468 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilbuffer); 469 } 470 else 471 DE_ASSERT(m_config.stencilbufferType == GL_NONE); 472 473 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 474} 475 476Framebuffer::~Framebuffer (void) 477{ 478 m_context.deleteFramebuffers(1, &m_framebuffer); 479 destroyBuffer(m_colorbuffer, m_config.colorbufferType); 480 destroyBuffer(m_depthbuffer, m_config.depthbufferType); 481 destroyBuffer(m_stencilbuffer, m_config.stencilbufferType); 482} 483 484void Framebuffer::checkCompleteness (void) 485{ 486 m_context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 487 GLenum status = m_context.checkFramebufferStatus(GL_FRAMEBUFFER); 488 m_context.bindFramebuffer(GL_FRAMEBUFFER, 0); 489 if (status != GL_FRAMEBUFFER_COMPLETE) 490 throw FboIncompleteException(m_config, status, __FILE__, __LINE__); 491} 492 493void Framebuffer::createRbo (deUint32& name, GLenum format, int width, int height) 494{ 495 if (name == 0) 496 m_context.genRenderbuffers(1, &name); 497 m_context.bindRenderbuffer(GL_RENDERBUFFER, name); 498 m_context.renderbufferStorage(GL_RENDERBUFFER, format, width, height); 499} 500 501void Framebuffer::destroyBuffer (deUint32 name, GLenum type) 502{ 503 if (type == GL_TEXTURE_2D || type == GL_TEXTURE_CUBE_MAP) 504 m_context.deleteTextures(1, &name); 505 else if (type == GL_RENDERBUFFER) 506 m_context.deleteRenderbuffers(1, &name); 507 else 508 DE_ASSERT(type == GL_NONE); 509} 510 511static void createMetaballsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height) 512{ 513 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType); 514 tcu::TextureLevel level (texFormat, width, height); 515 516 tcu::fillWithMetaballs(level.getAccess(), 5, name ^ width ^ height); 517 518 context.bindTexture(GL_TEXTURE_2D, name); 519 context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr()); 520 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 521} 522 523static void createQuadsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height) 524{ 525 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType); 526 tcu::TextureLevel level (texFormat, width, height); 527 528 tcu::fillWithRGBAQuads(level.getAccess()); 529 530 context.bindTexture(GL_TEXTURE_2D, name); 531 context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr()); 532 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 533} 534 535class FboRenderCase : public TestCase 536{ 537public: 538 FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config); 539 virtual ~FboRenderCase (void) {} 540 541 virtual IterateResult iterate (void); 542 virtual void render (sglr::Context& fboContext, Surface& dst) = DE_NULL; 543 544 const FboConfig& getConfig (void) const { return m_config; } 545 546 static bool isConfigSupported (const FboConfig& config) { DE_UNREF(config); return true; } 547 548private: 549 FboConfig m_config; 550}; 551 552FboRenderCase::FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config) 553 : TestCase(context, name, description) 554 , m_config(config) 555{ 556} 557 558TestCase::IterateResult FboRenderCase::iterate (void) 559{ 560 Vec4 clearColor (0.125f, 0.25f, 0.5f, 1.0f); 561 glu::RenderContext& renderCtx = m_context.getRenderContext(); 562 const tcu::RenderTarget& renderTarget = m_context.getRenderTarget(); 563 tcu::TestLog& log = m_testCtx.getLog(); 564 const char* failReason = DE_NULL; 565 566 // Position & size for context 567 deRandom rnd; 568 deRandom_init(&rnd, deStringHash(getName())); 569 570 int width = deMin32(renderTarget.getWidth(), 128); 571 int height = deMin32(renderTarget.getHeight(), 128); 572 int xMax = renderTarget.getWidth()-width+1; 573 int yMax = renderTarget.getHeight()-height+1; 574 int x = deRandom_getUint32(&rnd) % xMax; 575 int y = deRandom_getUint32(&rnd) % yMax; 576 577 tcu::Surface gles2Frame (width, height); 578 tcu::Surface refFrame (width, height); 579 GLenum gles2Error; 580 GLenum refError; 581 582 // Render using GLES2 583 try 584 { 585 sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height)); 586 587 context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w()); 588 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 589 590 render(context, gles2Frame); // Call actual render func 591 gles2Error = context.getError(); 592 } 593 catch (const FboIncompleteException& e) 594 { 595 if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED) 596 { 597 // Mark test case as unsupported 598 log << e; 599 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); 600 return STOP; 601 } 602 else 603 throw; // Propagate error 604 } 605 606 // Render reference image 607 { 608 sglr::ReferenceContextBuffers buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height); 609 sglr::ReferenceContext context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer()); 610 611 context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w()); 612 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 613 614 render(context, refFrame); 615 refError = context.getError(); 616 } 617 618 // Compare error codes 619 bool errorCodesOk = (gles2Error == refError); 620 621 if (!errorCodesOk) 622 { 623 log << tcu::TestLog::Message << "Error code mismatch: got " << glu::getErrorStr(gles2Error) << ", expected " << glu::getErrorStr(refError) << tcu::TestLog::EndMessage; 624 failReason = "Got unexpected error"; 625 } 626 627 // Compare images 628 const float threshold = 0.03f; 629 bool imagesOk = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, gles2Frame, threshold, tcu::COMPARE_LOG_RESULT); 630 631 if (!imagesOk && !failReason) 632 failReason = "Image comparison failed"; 633 634 // Store test result 635 bool isOk = errorCodesOk && imagesOk; 636 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 637 isOk ? "Pass" : failReason); 638 639 return STOP; 640} 641 642namespace FboCases 643{ 644 645class ColorClearsTest : public FboRenderCase 646{ 647public: 648 ColorClearsTest (Context& context, const FboConfig& config); 649 ~ColorClearsTest (void) {} 650 651 void render (sglr::Context& context, Surface& dst); 652}; 653 654ColorClearsTest::ColorClearsTest (Context& context, const FboConfig& config) 655 : FboRenderCase(context, config.getName().c_str(), "Color buffer clears", config) 656{ 657} 658 659void ColorClearsTest::render (sglr::Context& context, Surface& dst) 660{ 661 int width = 128; 662 int height = 128; 663 deRandom rnd; 664 665 deRandom_init(&rnd, 0); 666 667 // Create framebuffer 668 Framebuffer fbo(context, getConfig(), width, height); 669 fbo.checkCompleteness(); 670 671 // Clear fbo 672 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 673 context.viewport(0, 0, width, height); 674 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 675 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 676 677 // Enable scissor test. 678 context.enable(GL_SCISSOR_TEST); 679 680 // Do 10 random color clears 681 for (int i = 0; i < 15; i++) 682 { 683 int cX = (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % width; 684 int cY = (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % height; 685 int cWidth = (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % (width-cX); 686 int cHeight = (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % (height-cY); 687 Vec4 color = RGBA(deRandom_getUint32(&rnd)).toVec(); 688 689 context.scissor(cX, cY, cWidth, cHeight); 690 context.clearColor(color.x(), color.y(), color.z(), color.w()); 691 context.clear(GL_COLOR_BUFFER_BIT); 692 } 693 694 // Disable scissor. 695 context.disable(GL_SCISSOR_TEST); 696 697 if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D) 698 { 699 // Unbind fbo 700 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 701 702 // Draw to screen 703 SingleTex2DShader shader; 704 deUint32 shaderID = context.createProgram(&shader); 705 706 shader.setUnit(context, shaderID, 0); 707 708 context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 709 context.viewport(0, 0, context.getWidth(), context.getHeight()); 710 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 711 712 // Read from screen 713 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 714 } 715 else 716 { 717 // Read from fbo 718 context.readPixels(dst, 0, 0, width, height); 719 } 720} 721 722class IntersectingQuadsTest : public FboRenderCase 723{ 724public: 725 IntersectingQuadsTest (Context& context, const FboConfig& config, bool npot = false); 726 virtual ~IntersectingQuadsTest (void) {} 727 728 virtual void render (sglr::Context& context, Surface& dst); 729 730 static bool isConfigSupported (const FboConfig& config); 731 732private: 733 int m_fboWidth; 734 int m_fboHeight; 735}; 736 737class IntersectingQuadsNpotTest : public IntersectingQuadsTest 738{ 739public: 740 IntersectingQuadsNpotTest (Context& context, const FboConfig& config) 741 : IntersectingQuadsTest(context, config, true) 742 { 743 } 744}; 745 746IntersectingQuadsTest::IntersectingQuadsTest (Context& context, const FboConfig& config, bool npot) 747 : FboRenderCase (context, (string(npot ? "npot_" : "") + config.getName()).c_str(), "Intersecting textured quads", config) 748 , m_fboWidth (npot ? 127 : 128) 749 , m_fboHeight (npot ? 95 : 128) 750{ 751} 752 753bool IntersectingQuadsTest::isConfigSupported (const FboConfig& config) 754{ 755 // \note Disabled for stencil configurations since doesn't exercise stencil buffer 756 return config.depthbufferType != GL_NONE && 757 config.stencilbufferType == GL_NONE; 758} 759 760void IntersectingQuadsTest::render (sglr::Context& ctx, Surface& dst) 761{ 762 SingleTex2DShader texShader; 763 deUint32 texShaderID = ctx.createProgram(&texShader); 764 765 deUint32 metaballsTex = 1; 766 deUint32 quadsTex = 2; 767 768 createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 769 createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 770 771 int width = m_fboWidth; 772 int height = m_fboHeight; 773 Framebuffer fbo(ctx, getConfig(), width, height); 774 fbo.checkCompleteness(); 775 776 // Setup shaders 777 texShader.setUnit(ctx, texShaderID, 0); 778 779 // Draw scene 780 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 781 ctx.viewport(0, 0, width, height); 782 ctx.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 783 ctx.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 784 785 ctx.enable(GL_DEPTH_TEST); 786 787 ctx.bindTexture(GL_TEXTURE_2D, metaballsTex); 788 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 789 790 ctx.bindTexture(GL_TEXTURE_2D, quadsTex); 791 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 1.0f), Vec3(1.0f, 1.0f, -1.0f)); 792 793 ctx.disable(GL_DEPTH_TEST); 794 795 if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D) 796 { 797 // Unbind fbo 798 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); 799 800 // Draw to screen 801 ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 802 ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight()); 803 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 804 805 // Read from screen 806 ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight()); 807 } 808 else 809 { 810 // Read from fbo 811 ctx.readPixels(dst, 0, 0, width, height); 812 } 813} 814 815class MixTest : public FboRenderCase 816{ 817public: 818 MixTest (Context& context, const FboConfig& config, bool npot = false); 819 virtual ~MixTest (void) {} 820 821 void render (sglr::Context& context, Surface& dst); 822 823 static bool isConfigSupported (const FboConfig& config); 824 825private: 826 int m_fboAWidth; 827 int m_fboAHeight; 828 int m_fboBWidth; 829 int m_fboBHeight; 830}; 831 832class MixNpotTest : public MixTest 833{ 834public: 835 MixNpotTest (Context& context, const FboConfig& config) 836 : MixTest(context, config, true) 837 { 838 } 839}; 840 841MixTest::MixTest (Context& context, const FboConfig& config, bool npot) 842 : FboRenderCase (context, (string(npot ? "mix_npot_" : "mix_") + config.getName()).c_str(), "Use two fbos as sources in draw operation", config) 843 , m_fboAWidth (npot ? 127 : 128) 844 , m_fboAHeight (npot ? 95 : 128) 845 , m_fboBWidth (npot ? 55 : 64) 846 , m_fboBHeight (npot ? 63 : 64) 847{ 848} 849 850bool MixTest::isConfigSupported (const FboConfig& config) 851{ 852 // \note Disabled for stencil configurations since doesn't exercise stencil buffer 853 return config.colorbufferType == GL_TEXTURE_2D && 854 config.stencilbufferType == GL_NONE; 855} 856 857void MixTest::render (sglr::Context& context, Surface& dst) 858{ 859 SingleTex2DShader singleTexShader; 860 MixTexturesShader mixShader; 861 862 deUint32 singleTexShaderID = context.createProgram(&singleTexShader); 863 deUint32 mixShaderID = context.createProgram(&mixShader); 864 865 // Texture with metaballs 866 deUint32 metaballsTex = 1; 867 context.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 868 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 869 870 // Setup shaders 871 singleTexShader.setUnit(context, singleTexShaderID, 0); 872 mixShader.setUnits(context, mixShaderID, 0, 1); 873 874 // Fbo, quad with metaballs texture 875 Framebuffer fboA(context, getConfig(), m_fboAWidth, m_fboAHeight); 876 fboA.checkCompleteness(); 877 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer()); 878 context.viewport(0, 0, m_fboAWidth, m_fboAHeight); 879 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 880 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 881 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 882 sglr::drawQuad(context, singleTexShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 883 884 // Fbo, color clears 885 Framebuffer fboB(context, getConfig(), m_fboBWidth, m_fboBHeight); 886 fboB.checkCompleteness(); 887 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 888 context.viewport(0, 0, m_fboBWidth, m_fboBHeight); 889 context.enable(GL_SCISSOR_TEST); 890 context.scissor(0, 0, 32, 64); 891 context.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 892 context.clear(GL_COLOR_BUFFER_BIT); 893 context.scissor(32, 0, 32, 64); 894 context.clearColor(0.0f, 1.0f, 0.0f, 1.0f); 895 context.clear(GL_COLOR_BUFFER_BIT); 896 context.disable(GL_SCISSOR_TEST); 897 898 // Final mix op 899 context.activeTexture(GL_TEXTURE0); 900 context.bindTexture(GL_TEXTURE_2D, fboA.getColorbuffer()); 901 context.activeTexture(GL_TEXTURE1); 902 context.bindTexture(GL_TEXTURE_2D, fboB.getColorbuffer()); 903 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 904 context.viewport(0, 0, context.getWidth(), context.getHeight()); 905 sglr::drawQuad(context, mixShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 906 907 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 908} 909 910class BlendTest : public FboRenderCase 911{ 912public: 913 BlendTest (Context& context, const FboConfig& config, bool npot = false); 914 virtual ~BlendTest (void) {} 915 916 void render (sglr::Context& context, Surface& dst); 917 918 static bool isConfigSupported (const FboConfig& config); 919 920private: 921 int m_fboWidth; 922 int m_fboHeight; 923}; 924 925class BlendNpotTest : public BlendTest 926{ 927public: 928 BlendNpotTest (Context& context, const FboConfig& config) 929 : BlendTest(context, config, true) 930 { 931 } 932}; 933 934BlendTest::BlendTest (Context& context, const FboConfig& config, bool npot) 935 : FboRenderCase (context, (string(npot ? "blend_npot_" : "blend_") + config.getName()).c_str(), "Blend to fbo", config) 936 , m_fboWidth (npot ? 111 : 128) 937 , m_fboHeight (npot ? 122 : 128) 938{ 939} 940 941bool BlendTest::isConfigSupported (const FboConfig& config) 942{ 943 // \note Disabled for stencil configurations since doesn't exercise stencil buffer 944 return config.stencilbufferType == GL_NONE; 945} 946 947void BlendTest::render (sglr::Context& context, Surface& dst) 948{ 949 SingleTex2DShader shader; 950 deUint32 shaderID = context.createProgram(&shader); 951 int width = m_fboWidth; 952 int height = m_fboHeight; 953 deUint32 metaballsTex = 1; 954 955 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64); 956 957 Framebuffer fbo(context, getConfig(), width, height); 958 fbo.checkCompleteness(); 959 960 shader.setUnit(context, shaderID, 0); 961 962 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 963 context.viewport(0, 0, width, height); 964 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 965 context.clearColor(0.6f, 0.0f, 0.6f, 1.0f); 966 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 967 968 context.enable(GL_BLEND); 969 context.blendEquation(GL_FUNC_ADD); 970 context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); 971 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 972 context.disable(GL_BLEND); 973 974 if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D) 975 { 976 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 977 context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 978 context.viewport(0, 0, context.getWidth(), context.getHeight()); 979 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 980 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 981 } 982 else 983 context.readPixels(dst, 0, 0, width, height); 984} 985 986class StencilClearsTest : public FboRenderCase 987{ 988public: 989 StencilClearsTest (Context& context, const FboConfig& config); 990 virtual ~StencilClearsTest (void) {}; 991 992 void render (sglr::Context& context, Surface& dst); 993 994 static bool isConfigSupported (const FboConfig& config); 995}; 996 997StencilClearsTest::StencilClearsTest (Context& context, const FboConfig& config) 998 : FboRenderCase(context, config.getName().c_str(), "Stencil clears", config) 999{ 1000} 1001 1002void StencilClearsTest::render (sglr::Context& context, Surface& dst) 1003{ 1004 SingleTex2DShader shader; 1005 deUint32 shaderID = context.createProgram(&shader); 1006 int width = 128; 1007 int height = 128; 1008 deUint32 quadsTex = 1; 1009 deUint32 metaballsTex = 2; 1010 1011 createQuadsTex2D(context, quadsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height); 1012 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height); 1013 1014 Framebuffer fbo(context, getConfig(), width, height); 1015 fbo.checkCompleteness(); 1016 1017 // Bind framebuffer and clear 1018 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1019 context.viewport(0, 0, width, height); 1020 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1021 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1022 1023 // Do stencil clears 1024 context.enable(GL_SCISSOR_TEST); 1025 context.scissor(10, 16, 32, 120); 1026 context.clearStencil(1); 1027 context.clear(GL_STENCIL_BUFFER_BIT); 1028 context.scissor(16, 32, 100, 64); 1029 context.clearStencil(2); 1030 context.clear(GL_STENCIL_BUFFER_BIT); 1031 context.disable(GL_SCISSOR_TEST); 1032 1033 // Draw 2 textures with stecil tests 1034 context.activeTexture(GL_TEXTURE0); 1035 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1036 context.activeTexture(GL_TEXTURE1); 1037 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1038 1039 context.enable(GL_STENCIL_TEST); 1040 context.stencilFunc(GL_EQUAL, 1, 0xffffffffu); 1041 shader.setUnit(context, shaderID, 0); 1042 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1043 1044 context.stencilFunc(GL_EQUAL, 2, 0xffffffffu); 1045 shader.setUnit(context, shaderID, 1); 1046 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1047 1048 context.disable(GL_STENCIL_TEST); 1049 1050 if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D) 1051 { 1052 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1053 context.activeTexture(GL_TEXTURE0); 1054 context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 1055 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1056 shader.setUnit(context, shaderID, 0); 1057 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1058 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1059 } 1060 else 1061 context.readPixels(dst, 0, 0, width, height); 1062} 1063 1064bool StencilClearsTest::isConfigSupported (const FboConfig& config) 1065{ 1066 return config.stencilbufferType != GL_NONE; 1067} 1068 1069class StencilTest : public FboRenderCase 1070{ 1071public: 1072 StencilTest (Context& context, const FboConfig& config, bool npot = false); 1073 virtual ~StencilTest (void) {}; 1074 1075 void render (sglr::Context& context, Surface& dst); 1076 1077 static bool isConfigSupported (const FboConfig& config); 1078 1079private: 1080 int m_fboWidth; 1081 int m_fboHeight; 1082}; 1083 1084class StencilNpotTest : public StencilTest 1085{ 1086public: 1087 StencilNpotTest (Context& context, const FboConfig& config) 1088 : StencilTest(context, config, true) 1089 { 1090 } 1091}; 1092 1093StencilTest::StencilTest (Context& context, const FboConfig& config, bool npot) 1094 : FboRenderCase (context, (string(npot ? "npot_" : "") + config.getName()).c_str(), "Stencil ops", config) 1095 , m_fboWidth (npot ? 99 : 128) 1096 , m_fboHeight (npot ? 110 : 128) 1097{ 1098} 1099 1100bool StencilTest::isConfigSupported (const FboConfig& config) 1101{ 1102 return config.stencilbufferType != GL_NONE; 1103} 1104 1105void StencilTest::render (sglr::Context& ctx, Surface& dst) 1106{ 1107 FlatColorShader colorShader; 1108 SingleTex2DShader texShader; 1109 deUint32 colorShaderID = ctx.createProgram(&colorShader); 1110 deUint32 texShaderID = ctx.createProgram(&texShader); 1111 int width = m_fboWidth; 1112 int height = m_fboHeight; 1113 int texWidth = 64; 1114 int texHeight = 64; 1115 deUint32 quadsTex = 1; 1116 deUint32 metaballsTex = 2; 1117 bool depth = getConfig().depthbufferType != GL_NONE; 1118 1119 createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight); 1120 createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight); 1121 1122 Framebuffer fbo(ctx, getConfig(), width, height); 1123 fbo.checkCompleteness(); 1124 1125 // Bind framebuffer and clear 1126 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1127 ctx.viewport(0, 0, width, height); 1128 ctx.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1129 ctx.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1130 1131 // Render intersecting quads - increment stencil on depth pass 1132 ctx.enable(GL_DEPTH_TEST); 1133 ctx.enable(GL_STENCIL_TEST); 1134 ctx.stencilFunc(GL_ALWAYS, 0, 0xffu); 1135 ctx.stencilOp(GL_KEEP, GL_KEEP, GL_INCR); 1136 1137 colorShader.setColor(ctx, colorShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 1138 sglr::drawQuad(ctx, colorShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 1139 1140 ctx.bindTexture(GL_TEXTURE_2D, quadsTex); 1141 texShader.setUnit(ctx, texShaderID, 0); 1142 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(+1.0f, +1.0f, +1.0f)); 1143 1144 // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure 1145 ctx.disable(GL_DEPTH_TEST); 1146 ctx.stencilFunc(GL_EQUAL, depth ? 2 : 1, 0xffu); 1147 ctx.stencilOp(GL_DECR, GL_KEEP, GL_KEEP); 1148 colorShader.setColor(ctx, colorShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 1149 sglr::drawQuad(ctx, colorShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(+0.5f, +0.5f, 0.0f)); 1150 1151 // Draw metaballs with stencil test where stencil > 1 or 2 depending on depth buffer 1152 ctx.bindTexture(GL_TEXTURE_2D, metaballsTex); 1153 ctx.stencilFunc(GL_GREATER, depth ? 1 : 2, 0xffu); 1154 ctx.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 1155 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 1156 1157 ctx.disable(GL_STENCIL_TEST); 1158 1159 if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D) 1160 { 1161 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); 1162 ctx.activeTexture(GL_TEXTURE0); 1163 ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 1164 ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight()); 1165 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1166 ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight()); 1167 } 1168 else 1169 ctx.readPixels(dst, 0, 0, width, height); 1170} 1171 1172class SharedColorbufferTest : public FboRenderCase 1173{ 1174public: 1175 SharedColorbufferTest (Context& context, const FboConfig& config); 1176 virtual ~SharedColorbufferTest (void) {}; 1177 1178 void render (sglr::Context& context, Surface& dst); 1179}; 1180 1181SharedColorbufferTest::SharedColorbufferTest (Context& context, const FboConfig& config) 1182 : FboRenderCase(context, config.getName().c_str(), "Shared colorbuffer", config) 1183{ 1184} 1185 1186void SharedColorbufferTest::render (sglr::Context& context, Surface& dst) 1187{ 1188 SingleTex2DShader shader; 1189 deUint32 shaderID = context.createProgram(&shader); 1190 int width = 128; 1191 int height = 128; 1192// bool depth = getConfig().depthbufferFormat != GL_NONE; 1193 bool stencil = getConfig().stencilbufferFormat != GL_NONE; 1194 1195 // Textures 1196 deUint32 quadsTex = 1; 1197 deUint32 metaballsTex = 2; 1198 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1199 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64); 1200 1201 context.viewport(0, 0, width, height); 1202 1203 shader.setUnit(context, shaderID, 0); 1204 1205 // Fbo A 1206 Framebuffer fboA(context, getConfig(), width, height); 1207 fboA.checkCompleteness(); 1208 1209 // Fbo B - don't create colorbuffer 1210 FboConfig cfg = getConfig(); 1211 cfg.colorbufferType = GL_NONE; 1212 cfg.colorbufferFormat = GL_NONE; 1213 Framebuffer fboB(context, cfg, width, height); 1214 1215 // Attach color buffer from fbo A 1216 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 1217 switch (getConfig().colorbufferType) 1218 { 1219 case GL_TEXTURE_2D: 1220 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboA.getColorbuffer(), 0); 1221 break; 1222 1223 case GL_RENDERBUFFER: 1224 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboA.getColorbuffer()); 1225 break; 1226 1227 default: 1228 DE_ASSERT(false); 1229 } 1230 1231 // Clear depth and stencil in fbo B 1232 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1233 1234 // Render quads to fbo 1, with depth 0.0 1235 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer()); 1236 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1237 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1238 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1239 1240 if (stencil) 1241 { 1242 // Stencil to 1 in fbo A 1243 context.clearStencil(1); 1244 context.clear(GL_STENCIL_BUFFER_BIT); 1245 } 1246 1247 context.enable(GL_DEPTH_TEST); 1248 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1249 context.disable(GL_DEPTH_TEST); 1250 1251 // Blend metaballs to fbo 2 1252 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 1253 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1254 context.enable(GL_BLEND); 1255 context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); 1256 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1257 1258 // Render small quad that is only visible if depth buffer is not shared with fbo A - or there is no depth bits 1259 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1260 context.enable(GL_DEPTH_TEST); 1261 sglr::drawQuad(context, shaderID, Vec3(0.5f, 0.5f, 0.5f), Vec3(1.0f, 1.0f, 0.5f)); 1262 context.disable(GL_DEPTH_TEST); 1263 1264 if (stencil) 1265 { 1266 FlatColorShader flatShader; 1267 deUint32 flatShaderID = context.createProgram(&flatShader); 1268 1269 flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 1270 1271 // Clear subset of stencil buffer to 1 1272 context.enable(GL_SCISSOR_TEST); 1273 context.scissor(10, 10, 12, 25); 1274 context.clearStencil(1); 1275 context.clear(GL_STENCIL_BUFFER_BIT); 1276 context.disable(GL_SCISSOR_TEST); 1277 1278 // Render quad with stencil mask == 1 1279 context.enable(GL_STENCIL_TEST); 1280 context.stencilFunc(GL_EQUAL, 1, 0xffu); 1281 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1282 context.disable(GL_STENCIL_TEST); 1283 } 1284 1285 // Get results 1286 if (fboA.getConfig().colorbufferType == GL_TEXTURE_2D) 1287 { 1288 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1289 context.bindTexture(GL_TEXTURE_2D, fboA.getColorbuffer()); 1290 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1291 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1292 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1293 } 1294 else 1295 context.readPixels(dst, 0, 0, width, height); 1296} 1297 1298class SharedColorbufferClearsTest : public FboRenderCase 1299{ 1300public: 1301 SharedColorbufferClearsTest (Context& context, const FboConfig& config); 1302 virtual ~SharedColorbufferClearsTest (void) {} 1303 1304 static bool isConfigSupported (const FboConfig& config); 1305 void render (sglr::Context& context, Surface& dst); 1306}; 1307 1308SharedColorbufferClearsTest::SharedColorbufferClearsTest (Context& context, const FboConfig& config) 1309 : FboRenderCase(context, config.getName().c_str(), "Shared colorbuffer clears", config) 1310{ 1311} 1312 1313bool SharedColorbufferClearsTest::isConfigSupported (const FboConfig& config) 1314{ 1315 return config.colorbufferType != GL_NONE && 1316 config.depthbufferType == GL_NONE && 1317 config.stencilbufferType == GL_NONE; 1318} 1319 1320void SharedColorbufferClearsTest::render (sglr::Context& context, Surface& dst) 1321{ 1322 int width = 128; 1323 int height = 128; 1324 deUint32 colorbuffer = 1; 1325 1326 checkColorFormatSupport(context, getConfig().colorbufferFormat); 1327 1328 // Single colorbuffer 1329 if (getConfig().colorbufferType == GL_TEXTURE_2D) 1330 { 1331 context.bindTexture(GL_TEXTURE_2D, colorbuffer); 1332 context.texImage2D(GL_TEXTURE_2D, 0, getConfig().colorbufferFormat, width, height); 1333 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1334 } 1335 else 1336 { 1337 DE_ASSERT(getConfig().colorbufferType == GL_RENDERBUFFER); 1338 context.bindRenderbuffer(GL_RENDERBUFFER, colorbuffer); 1339 context.renderbufferStorage(GL_RENDERBUFFER, getConfig().colorbufferFormat, width, height); 1340 } 1341 1342 // Multiple framebuffers sharing the colorbuffer 1343 for (int fbo = 1; fbo <= 3; fbo++) 1344 { 1345 context.bindFramebuffer(GL_FRAMEBUFFER, fbo); 1346 1347 if (getConfig().colorbufferType == GL_TEXTURE_2D) 1348 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); 1349 else 1350 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); 1351 } 1352 1353 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 1354 1355 // Check completeness 1356 { 1357 GLenum status = context.checkFramebufferStatus(GL_FRAMEBUFFER); 1358 if (status != GL_FRAMEBUFFER_COMPLETE) 1359 throw FboIncompleteException(getConfig(), status, __FILE__, __LINE__); 1360 } 1361 1362 // Render to them 1363 context.viewport(0, 0, width, height); 1364 context.clearColor(0.0f, 0.0f, 1.0f, 1.0f); 1365 context.clear(GL_COLOR_BUFFER_BIT); 1366 1367 context.enable(GL_SCISSOR_TEST); 1368 1369 context.bindFramebuffer(GL_FRAMEBUFFER, 2); 1370 context.clearColor(0.6f, 0.0f, 0.0f, 1.0f); 1371 context.scissor(10, 10, 64, 64); 1372 context.clear(GL_COLOR_BUFFER_BIT); 1373 context.clearColor(0.0f, 0.6f, 0.0f, 1.0f); 1374 context.scissor(60, 60, 40, 20); 1375 context.clear(GL_COLOR_BUFFER_BIT); 1376 1377 context.bindFramebuffer(GL_FRAMEBUFFER, 3); 1378 context.clearColor(0.0f, 0.0f, 0.6f, 1.0f); 1379 context.scissor(20, 20, 100, 10); 1380 context.clear(GL_COLOR_BUFFER_BIT); 1381 1382 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 1383 context.clearColor(0.6f, 0.0f, 0.6f, 1.0f); 1384 context.scissor(20, 20, 5, 100); 1385 context.clear(GL_COLOR_BUFFER_BIT); 1386 1387 context.disable(GL_SCISSOR_TEST); 1388 1389 if (getConfig().colorbufferType == GL_TEXTURE_2D) 1390 { 1391 SingleTex2DShader shader; 1392 deUint32 shaderID = context.createProgram(&shader); 1393 1394 shader.setUnit(context, shaderID, 0); 1395 1396 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1397 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1398 sglr::drawQuad(context, shaderID, Vec3(-0.9f, -0.9f, 0.0f), Vec3(0.9f, 0.9f, 0.0f)); 1399 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1400 } 1401 else 1402 context.readPixels(dst, 0, 0, width, height); 1403} 1404 1405class SharedDepthbufferTest : public FboRenderCase 1406{ 1407public: 1408 SharedDepthbufferTest (Context& context, const FboConfig& config); 1409 virtual ~SharedDepthbufferTest (void) {}; 1410 1411 static bool isConfigSupported (const FboConfig& config); 1412 void render (sglr::Context& context, Surface& dst); 1413}; 1414 1415SharedDepthbufferTest::SharedDepthbufferTest (Context& context, const FboConfig& config) 1416 : FboRenderCase(context, config.getName().c_str(), "Shared depthbuffer", config) 1417{ 1418} 1419 1420bool SharedDepthbufferTest::isConfigSupported (const FboConfig& config) 1421{ 1422 return config.depthbufferType == GL_RENDERBUFFER; 1423} 1424 1425void SharedDepthbufferTest::render (sglr::Context& context, Surface& dst) 1426{ 1427 SingleTex2DShader texShader; 1428 FlatColorShader colorShader; 1429 deUint32 texShaderID = context.createProgram(&texShader); 1430 deUint32 colorShaderID = context.createProgram(&colorShader); 1431 int width = 128; 1432 int height = 128; 1433 bool stencil = getConfig().stencilbufferType != GL_NONE; 1434 1435 // Setup shaders 1436 texShader.setUnit(context, texShaderID, 0); 1437 colorShader.setColor(context, colorShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 1438 1439 // Textures 1440 deUint32 metaballsTex = 5; 1441 deUint32 quadsTex = 6; 1442 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1443 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1444 1445 context.viewport(0, 0, width, height); 1446 1447 // Fbo A 1448 Framebuffer fboA(context, getConfig(), width, height); 1449 fboA.checkCompleteness(); 1450 1451 // Fbo B 1452 FboConfig cfg = getConfig(); 1453 cfg.depthbufferType = GL_NONE; 1454 cfg.depthbufferFormat = GL_NONE; 1455 Framebuffer fboB(context, cfg, width, height); 1456 1457 // Bind depth buffer from fbo A to fbo B 1458 DE_ASSERT(fboA.getConfig().depthbufferType == GL_RENDERBUFFER); 1459 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 1460 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboA.getDepthbuffer()); 1461 1462 // Clear fbo B color to red and stencil to 1 1463 context.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 1464 context.clearStencil(1); 1465 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1466 1467 // Enable depth test. 1468 context.enable(GL_DEPTH_TEST); 1469 1470 // Render quad to fbo A 1471 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer()); 1472 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1473 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1474 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1475 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1476 1477 // Render metaballs to fbo B 1478 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 1479 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1480 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 1481 1482 context.disable(GL_DEPTH_TEST); 1483 1484 if (stencil) 1485 { 1486 // Clear subset of stencil buffer to 0 1487 context.enable(GL_SCISSOR_TEST); 1488 context.scissor(10, 10, 12, 25); 1489 context.clearStencil(0); 1490 context.clear(GL_STENCIL_BUFFER_BIT); 1491 context.disable(GL_SCISSOR_TEST); 1492 1493 // Render quad with stencil mask == 0 1494 context.enable(GL_STENCIL_TEST); 1495 context.stencilFunc(GL_EQUAL, 0, 0xffu); 1496 sglr::drawQuad(context, colorShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1497 context.disable(GL_STENCIL_TEST); 1498 } 1499 1500 if (getConfig().colorbufferType == GL_TEXTURE_2D) 1501 { 1502 // Render both to screen 1503 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1504 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1505 context.bindTexture(GL_TEXTURE_2D, fboA.getColorbuffer()); 1506 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f)); 1507 context.bindTexture(GL_TEXTURE_2D, fboB.getColorbuffer()); 1508 sglr::drawQuad(context, texShaderID, Vec3(0.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1509 1510 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1511 } 1512 else 1513 { 1514 // Read results from fbo B 1515 context.readPixels(dst, 0, 0, width, height); 1516 } 1517} 1518 1519class TexSubImageAfterRenderTest : public FboRenderCase 1520{ 1521public: 1522 TexSubImageAfterRenderTest (Context& context, const FboConfig& config); 1523 virtual ~TexSubImageAfterRenderTest (void) {} 1524 1525 static bool isConfigSupported (const FboConfig& config); 1526 void render (sglr::Context& context, Surface& dst); 1527}; 1528 1529TexSubImageAfterRenderTest::TexSubImageAfterRenderTest (Context& context, const FboConfig& config) 1530 : FboRenderCase(context, (string("after_render_") + config.getName()).c_str(), "TexSubImage after rendering to texture", config) 1531{ 1532} 1533 1534bool TexSubImageAfterRenderTest::isConfigSupported (const FboConfig& config) 1535{ 1536 return config.colorbufferType == GL_TEXTURE_2D && 1537 (config.colorbufferFormat == GL_RGB || config.colorbufferFormat == GL_RGBA) && 1538 config.depthbufferType == GL_NONE && 1539 config.stencilbufferType == GL_NONE; 1540} 1541 1542void TexSubImageAfterRenderTest::render (sglr::Context& context, Surface& dst) 1543{ 1544 SingleTex2DShader shader; 1545 deUint32 shaderID = context.createProgram(&shader); 1546 bool isRGBA = getConfig().colorbufferFormat == GL_RGBA; 1547 1548 tcu::TextureLevel fourQuads(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64); 1549 tcu::fillWithRGBAQuads(fourQuads.getAccess()); 1550 1551 tcu::TextureLevel metaballs(tcu::TextureFormat(isRGBA ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64); 1552 tcu::fillWithMetaballs(metaballs.getAccess(), 5, 3); 1553 1554 shader.setUnit(context, shaderID, 0); 1555 1556 deUint32 fourQuadsTex = 1; 1557 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1558 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1559 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, fourQuads.getAccess().getDataPtr()); 1560 1561 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 1562 1563 deUint32 fboTex = 2; 1564 context.bindTexture(GL_TEXTURE_2D, fboTex); 1565 context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128); 1566 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1567 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0); 1568 1569 // Render to fbo 1570 context.viewport(0, 0, 128, 128); 1571 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1572 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1573 1574 // Update texture using TexSubImage2D 1575 context.bindTexture(GL_TEXTURE_2D, fboTex); 1576 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, 64, 64, isRGBA ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, metaballs.getAccess().getDataPtr()); 1577 1578 // Draw to screen 1579 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1580 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1581 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1582 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1583} 1584 1585class TexSubImageBetweenRenderTest : public FboRenderCase 1586{ 1587public: 1588 TexSubImageBetweenRenderTest (Context& context, const FboConfig& config); 1589 virtual ~TexSubImageBetweenRenderTest (void) {} 1590 1591 static bool isConfigSupported (const FboConfig& config); 1592 void render (sglr::Context& context, Surface& dst); 1593}; 1594 1595TexSubImageBetweenRenderTest::TexSubImageBetweenRenderTest (Context& context, const FboConfig& config) 1596 : FboRenderCase(context, (string("between_render_") + config.getName()).c_str(), "TexSubImage between rendering calls", config) 1597{ 1598} 1599 1600bool TexSubImageBetweenRenderTest::isConfigSupported (const FboConfig& config) 1601{ 1602 return config.colorbufferType == GL_TEXTURE_2D && 1603 (config.colorbufferFormat == GL_RGB || config.colorbufferFormat == GL_RGBA) && 1604 config.depthbufferType == GL_NONE && 1605 config.stencilbufferType == GL_NONE; 1606} 1607 1608void TexSubImageBetweenRenderTest::render (sglr::Context& context, Surface& dst) 1609{ 1610 SingleTex2DShader shader; 1611 deUint32 shaderID = context.createProgram(&shader); 1612 bool isRGBA = getConfig().colorbufferFormat == GL_RGBA; 1613 1614 tcu::TextureLevel fourQuads(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64); 1615 tcu::fillWithRGBAQuads(fourQuads.getAccess()); 1616 1617 tcu::TextureLevel metaballs(tcu::TextureFormat(isRGBA ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64); 1618 tcu::fillWithMetaballs(metaballs.getAccess(), 5, 3); 1619 1620 tcu::TextureLevel metaballs2(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 64, 64); 1621 tcu::fillWithMetaballs(metaballs2.getAccess(), 5, 4); 1622 1623 deUint32 metaballsTex = 3; 1624 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1625 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1626 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, metaballs2.getAccess().getDataPtr()); 1627 1628 deUint32 fourQuadsTex = 1; 1629 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1630 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1631 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, fourQuads.getAccess().getDataPtr()); 1632 1633 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 1634 1635 deUint32 fboTex = 2; 1636 context.bindTexture(GL_TEXTURE_2D, fboTex); 1637 context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128); 1638 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1639 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0); 1640 1641 shader.setUnit(context, shaderID, 0); 1642 1643 // Render to fbo 1644 context.viewport(0, 0, 128, 128); 1645 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1646 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1647 1648 // Update texture using TexSubImage2D 1649 context.bindTexture(GL_TEXTURE_2D, fboTex); 1650 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, 64, 64, isRGBA ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, metaballs.getAccess().getDataPtr()); 1651 1652 // Render again to fbo 1653 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1654 context.enable(GL_BLEND); 1655 context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); 1656 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1657 context.disable(GL_BLEND); 1658 1659 // Draw to screen 1660 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1661 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1662 context.bindTexture(GL_TEXTURE_2D, fboTex); 1663 sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1664 1665 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1666} 1667 1668class ResizeTest : public FboRenderCase 1669{ 1670public: 1671 ResizeTest (Context& context, const FboConfig& config); 1672 virtual ~ResizeTest (void) {} 1673 1674 void render (sglr::Context& context, Surface& dst); 1675}; 1676 1677ResizeTest::ResizeTest (Context& context, const FboConfig& config) 1678 : FboRenderCase(context, config.getName().c_str(), "Resize framebuffer", config) 1679{ 1680} 1681 1682void ResizeTest::render (sglr::Context& context, Surface& dst) 1683{ 1684 SingleTex2DShader texShader; 1685 FlatColorShader colorShader; 1686 deUint32 texShaderID = context.createProgram(&texShader); 1687 deUint32 colorShaderID = context.createProgram(&colorShader); 1688 deUint32 quadsTex = 1; 1689 deUint32 metaballsTex = 2; 1690 bool depth = getConfig().depthbufferType != GL_NONE; 1691 bool stencil = getConfig().stencilbufferType != GL_NONE; 1692 1693 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1694 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 32, 32); 1695 1696 Framebuffer fbo(context, getConfig(), 128, 128); 1697 fbo.checkCompleteness(); 1698 1699 // Setup shaders 1700 texShader.setUnit(context, texShaderID, 0); 1701 colorShader.setColor(context, colorShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 1702 1703 // Render quads 1704 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1705 context.viewport(0, 0, 128, 128); 1706 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1707 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1708 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1709 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1710 1711 if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D) 1712 { 1713 // Render fbo to screen 1714 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1715 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1716 context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 1717 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1718 1719 // Restore binding 1720 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1721 } 1722 1723 int newWidth = 64; 1724 int newHeight = 32; 1725 1726 // Resize buffers 1727 switch (fbo.getConfig().colorbufferType) 1728 { 1729 case GL_TEXTURE_2D: 1730 context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 1731 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorbufferFormat, newWidth, newHeight); 1732 break; 1733 1734 case GL_RENDERBUFFER: 1735 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getColorbuffer()); 1736 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorbufferFormat, newWidth, newHeight); 1737 break; 1738 1739 default: 1740 DE_ASSERT(false); 1741 } 1742 1743 if (depth) 1744 { 1745 DE_ASSERT(fbo.getConfig().depthbufferType == GL_RENDERBUFFER); 1746 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getDepthbuffer()); 1747 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthbufferFormat, newWidth, newHeight); 1748 } 1749 1750 if (stencil) 1751 { 1752 DE_ASSERT(fbo.getConfig().stencilbufferType == GL_RENDERBUFFER); 1753 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getStencilbuffer()); 1754 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().stencilbufferFormat, newWidth, newHeight); 1755 } 1756 1757 // Render to resized fbo 1758 context.viewport(0, 0, newWidth, newHeight); 1759 context.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 1760 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1761 1762 context.enable(GL_DEPTH_TEST); 1763 1764 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1765 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 1766 1767 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1768 sglr::drawQuad(context, texShaderID, Vec3(0.0f, 0.0f, -1.0f), Vec3(+1.0f, +1.0f, 1.0f)); 1769 1770 context.disable(GL_DEPTH_TEST); 1771 1772 if (stencil) 1773 { 1774 context.enable(GL_SCISSOR_TEST); 1775 context.scissor(10, 10, 5, 15); 1776 context.clearStencil(1); 1777 context.clear(GL_STENCIL_BUFFER_BIT); 1778 context.disable(GL_SCISSOR_TEST); 1779 1780 context.enable(GL_STENCIL_TEST); 1781 context.stencilFunc(GL_EQUAL, 1, 0xffu); 1782 sglr::drawQuad(context, colorShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 1783 context.disable(GL_STENCIL_TEST); 1784 } 1785 1786 if (getConfig().colorbufferType == GL_TEXTURE_2D) 1787 { 1788 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1789 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1790 context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer()); 1791 sglr::drawQuad(context, texShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(0.5f, 0.5f, 0.0f)); 1792 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1793 } 1794 else 1795 context.readPixels(dst, 0, 0, newWidth, newHeight); 1796} 1797 1798template <GLenum Buffers> 1799class RecreateBuffersTest : public FboRenderCase 1800{ 1801public: 1802 RecreateBuffersTest (Context& context, const FboConfig& config, bool rebind); 1803 virtual ~RecreateBuffersTest (void) {} 1804 1805 static bool isConfigSupported (const FboConfig& config); 1806 void render (sglr::Context& context, Surface& dst); 1807 1808private: 1809 bool m_rebind; 1810}; 1811 1812template <GLenum Buffers> 1813class RecreateBuffersNoRebindTest : public RecreateBuffersTest<Buffers> 1814{ 1815public: 1816 RecreateBuffersNoRebindTest (Context& context, const FboConfig& config) 1817 : RecreateBuffersTest<Buffers>(context, config, false) 1818 { 1819 } 1820}; 1821 1822template <GLenum Buffers> 1823class RecreateBuffersRebindTest : public RecreateBuffersTest<Buffers> 1824{ 1825public: 1826 RecreateBuffersRebindTest (Context& context, const FboConfig& config) 1827 : RecreateBuffersTest<Buffers>(context, config, true) 1828 { 1829 } 1830}; 1831 1832template <GLenum Buffers> 1833RecreateBuffersTest<Buffers>::RecreateBuffersTest (Context& context, const FboConfig& config, bool rebind) 1834 : FboRenderCase (context, (string(rebind ? "rebind_" : "no_rebind_") + config.getName()).c_str(), "Recreate buffers", config) 1835 , m_rebind (rebind) 1836{ 1837} 1838 1839template <GLenum Buffers> 1840bool RecreateBuffersTest<Buffers>::isConfigSupported (const FboConfig& config) 1841{ 1842 if ((Buffers & GL_COLOR_BUFFER_BIT) && config.colorbufferType == GL_NONE) 1843 return false; 1844 if ((Buffers & GL_DEPTH_BUFFER_BIT) && config.depthbufferType == GL_NONE) 1845 return false; 1846 if ((Buffers & GL_STENCIL_BUFFER_BIT) && config.stencilbufferType == GL_NONE) 1847 return false; 1848 return true; 1849} 1850 1851template <GLenum Buffers> 1852void RecreateBuffersTest<Buffers>::render (sglr::Context& ctx, Surface& dst) 1853{ 1854 SingleTex2DShader texShader; 1855 deUint32 texShaderID = ctx.createProgram(&texShader); 1856 int width = 128; 1857 int height = 128; 1858 deUint32 metaballsTex = 1; 1859 deUint32 quadsTex = 2; 1860 bool stencil = getConfig().stencilbufferType != GL_NONE; 1861 1862 createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1863 createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1864 1865 Framebuffer fbo(ctx, getConfig(), width, height); 1866 fbo.checkCompleteness(); 1867 1868 // Setup shader 1869 texShader.setUnit(ctx, texShaderID, 0); 1870 1871 // Draw scene 1872 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1873 ctx.viewport(0, 0, width, height); 1874 ctx.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 1875 ctx.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1876 1877 ctx.enable(GL_DEPTH_TEST); 1878 1879 ctx.bindTexture(GL_TEXTURE_2D, quadsTex); 1880 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1881 1882 if (stencil) 1883 { 1884 ctx.enable(GL_SCISSOR_TEST); 1885 ctx.scissor(width/4, height/4, width/2, height/2); 1886 ctx.clearStencil(1); 1887 ctx.clear(GL_STENCIL_BUFFER_BIT); 1888 ctx.disable(GL_SCISSOR_TEST); 1889 } 1890 1891 // Recreate buffers 1892 if (!m_rebind) 1893 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); 1894 1895 if (Buffers & GL_COLOR_BUFFER_BIT) 1896 { 1897 deUint32 colorbuf = fbo.getColorbuffer(); 1898 switch (fbo.getConfig().colorbufferType) 1899 { 1900 case GL_TEXTURE_2D: 1901 ctx.deleteTextures(1, &colorbuf); 1902 ctx.bindTexture(GL_TEXTURE_2D, colorbuf); 1903 ctx.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorbufferFormat, width, height); 1904 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1905 1906 if (m_rebind) 1907 ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf, 0); 1908 break; 1909 1910 case GL_RENDERBUFFER: 1911 ctx.deleteRenderbuffers(1, &colorbuf); 1912 ctx.bindRenderbuffer(GL_RENDERBUFFER, colorbuf); 1913 ctx.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorbufferFormat, width, height); 1914 1915 if (m_rebind) 1916 ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf); 1917 break; 1918 1919 default: 1920 DE_ASSERT(false); 1921 } 1922 } 1923 1924 if (Buffers & GL_DEPTH_BUFFER_BIT) 1925 { 1926 deUint32 depthbuf = fbo.getDepthbuffer(); 1927 DE_ASSERT(fbo.getConfig().depthbufferType == GL_RENDERBUFFER); 1928 1929 ctx.deleteRenderbuffers(1, &depthbuf); 1930 ctx.bindRenderbuffer(GL_RENDERBUFFER, depthbuf); 1931 ctx.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthbufferFormat, width, height); 1932 1933 if (m_rebind) 1934 ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuf); 1935 } 1936 1937 if (Buffers & GL_STENCIL_BUFFER_BIT) 1938 { 1939 deUint32 stencilbuf = fbo.getStencilbuffer(); 1940 DE_ASSERT(fbo.getConfig().stencilbufferType == GL_RENDERBUFFER); 1941 1942 ctx.deleteRenderbuffers(1, &stencilbuf); 1943 ctx.bindRenderbuffer(GL_RENDERBUFFER, stencilbuf); 1944 ctx.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().stencilbufferFormat, width, height); 1945 1946 if (m_rebind) 1947 ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilbuf); 1948 } 1949 1950 if (!m_rebind) 1951 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1952 1953 ctx.clearColor(0.0f, 0.0f, 1.0f, 0.0f); 1954 ctx.clearStencil(0); 1955 ctx.clear(Buffers); // \note Clear only buffers that were re-created 1956 1957 if (stencil) 1958 { 1959 // \note Stencil test enabled only if we have stencil buffer 1960 ctx.enable(GL_STENCIL_TEST); 1961 ctx.stencilFunc(GL_EQUAL, 0, 0xffu); 1962 } 1963 ctx.bindTexture(GL_TEXTURE_2D, metaballsTex); 1964 sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 1.0f), Vec3(1.0f, 1.0f, -1.0f)); 1965 if (stencil) 1966 ctx.disable(GL_STENCIL_TEST); 1967 1968 ctx.disable(GL_DEPTH_TEST); 1969 1970 // Read from fbo 1971 ctx.readPixels(dst, 0, 0, width, height); 1972} 1973 1974class RepeatedClearCase : public FboRenderCase 1975{ 1976private: 1977 static FboConfig makeConfig (deUint32 format) 1978 { 1979 FboConfig cfg; 1980 cfg.colorbufferType = GL_TEXTURE_2D; 1981 cfg.colorbufferFormat = format; 1982 cfg.depthbufferType = GL_NONE; 1983 cfg.stencilbufferType = GL_NONE; 1984 return cfg; 1985 } 1986 1987public: 1988 RepeatedClearCase (Context& context, deUint32 format) 1989 : FboRenderCase(context, makeConfig(format).getName().c_str(), "Repeated clears", makeConfig(format)) 1990 { 1991 } 1992 1993protected: 1994 void render (sglr::Context& ctx, Surface& dst) 1995 { 1996 const int numRowsCols = 4; 1997 const int cellSize = 16; 1998 const int fboSizes[] = { cellSize, cellSize*numRowsCols }; 1999 2000 SingleTex2DShader fboBlitShader; 2001 const deUint32 fboBlitShaderID = ctx.createProgram(&fboBlitShader); 2002 2003 de::Random rnd (18169662); 2004 deUint32 fbos[] = { 0, 0 }; 2005 deUint32 textures[] = { 0, 0 }; 2006 2007 ctx.genFramebuffers(2, &fbos[0]); 2008 ctx.genTextures(2, &textures[0]); 2009 2010 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++) 2011 { 2012 ctx.bindTexture(GL_TEXTURE_2D, textures[fboNdx]); 2013 ctx.texImage2D(GL_TEXTURE_2D, 0, getConfig().colorbufferFormat, fboSizes[fboNdx], fboSizes[fboNdx], 0, 2014 getConfig().colorbufferFormat, GL_UNSIGNED_BYTE, DE_NULL); 2015 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2016 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 2017 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2018 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2019 2020 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]); 2021 ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0); 2022 2023 { 2024 const GLenum status = ctx.checkFramebufferStatus(GL_FRAMEBUFFER); 2025 if (status != GL_FRAMEBUFFER_COMPLETE) 2026 throw FboIncompleteException(getConfig(), status, __FILE__, __LINE__); 2027 } 2028 } 2029 2030 // larger fbo bound -- clear to transparent black 2031 ctx.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 2032 ctx.clear(GL_COLOR_BUFFER_BIT); 2033 2034 fboBlitShader.setUnit(ctx, fboBlitShaderID, 0); 2035 ctx.bindTexture(GL_TEXTURE_2D, textures[0]); 2036 2037 for (int cellY = 0; cellY < numRowsCols; cellY++) 2038 for (int cellX = 0; cellX < numRowsCols; cellX++) 2039 { 2040 const float r = rnd.getFloat(); 2041 const float g = rnd.getFloat(); 2042 const float b = rnd.getFloat(); 2043 const float a = rnd.getFloat(); 2044 2045 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbos[0]); 2046 ctx.clearColor(r, g, b, a); 2047 ctx.clear(GL_COLOR_BUFFER_BIT); 2048 2049 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbos[1]); 2050 ctx.viewport(cellX*cellSize, cellY*cellSize, cellSize, cellSize); 2051 sglr::drawQuad(ctx, fboBlitShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 2052 } 2053 2054 ctx.readPixels(dst, 0, 0, fboSizes[1], fboSizes[1]); 2055 } 2056}; 2057 2058} // FboCases 2059 2060FboRenderTestGroup::FboRenderTestGroup (Context& context) 2061 : TestCaseGroup(context, "render", "Rendering Tests") 2062{ 2063} 2064 2065FboRenderTestGroup::~FboRenderTestGroup (void) 2066{ 2067} 2068 2069namespace 2070{ 2071 2072struct TypeFormatPair 2073{ 2074 GLenum type; 2075 GLenum format; 2076}; 2077 2078template <typename CaseType> 2079void addChildVariants (deqp::gles2::TestCaseGroup* group) 2080{ 2081 TypeFormatPair colorbufferConfigs[] = 2082 { 2083// { GL_TEXTURE_2D, GL_ALPHA }, 2084// { GL_TEXTURE_2D, GL_LUMINANCE }, 2085// { GL_TEXTURE_2D, GL_LUMINANCE_ALPHA }, 2086 { GL_TEXTURE_2D, GL_RGB }, 2087 { GL_TEXTURE_2D, GL_RGBA }, 2088 { GL_RENDERBUFFER, GL_RGB565 }, 2089 { GL_RENDERBUFFER, GL_RGB5_A1 }, 2090 { GL_RENDERBUFFER, GL_RGBA4 }, 2091// { GL_RENDERBUFFER, GL_RGBA16F }, 2092// { GL_RENDERBUFFER, GL_RGB16F } 2093 }; 2094 TypeFormatPair depthbufferConfigs[] = 2095 { 2096 { GL_NONE, GL_NONE }, 2097 { GL_RENDERBUFFER, GL_DEPTH_COMPONENT16 } 2098 }; 2099 TypeFormatPair stencilbufferConfigs[] = 2100 { 2101 { GL_NONE, GL_NONE }, 2102 { GL_RENDERBUFFER, GL_STENCIL_INDEX8 } 2103 }; 2104 2105 for (int colorbufferNdx = 0; colorbufferNdx < DE_LENGTH_OF_ARRAY(colorbufferConfigs); colorbufferNdx++) 2106 for (int depthbufferNdx = 0; depthbufferNdx < DE_LENGTH_OF_ARRAY(depthbufferConfigs); depthbufferNdx++) 2107 for (int stencilbufferNdx = 0; stencilbufferNdx < DE_LENGTH_OF_ARRAY(stencilbufferConfigs); stencilbufferNdx++) 2108 { 2109 FboConfig config; 2110 config.colorbufferType = colorbufferConfigs[colorbufferNdx].type; 2111 config.colorbufferFormat = colorbufferConfigs[colorbufferNdx].format; 2112 config.depthbufferType = depthbufferConfigs[depthbufferNdx].type; 2113 config.depthbufferFormat = depthbufferConfigs[depthbufferNdx].format; 2114 config.stencilbufferType = stencilbufferConfigs[stencilbufferNdx].type; 2115 config.stencilbufferFormat = stencilbufferConfigs[stencilbufferNdx].format; 2116 2117 if (CaseType::isConfigSupported(config)) 2118 group->addChild(new CaseType(group->getContext(), config)); 2119 } 2120} 2121 2122template <typename CaseType> 2123void createChildGroup (deqp::gles2::TestCaseGroup* parent, const char* name, const char* description) 2124{ 2125 deqp::gles2::TestCaseGroup* tmpGroup = new deqp::gles2::TestCaseGroup(parent->getContext(), name, description); 2126 parent->addChild(tmpGroup); 2127 addChildVariants<CaseType>(tmpGroup); 2128} 2129 2130template <GLbitfield Buffers> 2131void createRecreateBuffersGroup (deqp::gles2::TestCaseGroup* parent, const char* name, const char* description) 2132{ 2133 deqp::gles2::TestCaseGroup* tmpGroup = new deqp::gles2::TestCaseGroup(parent->getContext(), name, description); 2134 parent->addChild(tmpGroup); 2135 addChildVariants<FboCases::RecreateBuffersRebindTest<Buffers> > (tmpGroup); 2136 addChildVariants<FboCases::RecreateBuffersNoRebindTest<Buffers> > (tmpGroup); 2137} 2138 2139} // anonymous 2140 2141void FboRenderTestGroup::init (void) 2142{ 2143 createChildGroup<FboCases::ColorClearsTest> (this, "color_clear", "Color buffer clears"); 2144 createChildGroup<FboCases::StencilClearsTest> (this, "stencil_clear", "Stencil buffer clears"); 2145 2146 deqp::gles2::TestCaseGroup* colorGroup = new deqp::gles2::TestCaseGroup(m_context, "color", "Color buffer tests"); 2147 addChild(colorGroup); 2148 addChildVariants<FboCases::MixTest> (colorGroup); 2149 addChildVariants<FboCases::MixNpotTest> (colorGroup); 2150 addChildVariants<FboCases::BlendTest> (colorGroup); 2151 addChildVariants<FboCases::BlendNpotTest> (colorGroup); 2152 2153 deqp::gles2::TestCaseGroup* depthGroup = new deqp::gles2::TestCaseGroup(m_context, "depth", "Depth bufer tests"); 2154 addChild(depthGroup); 2155 addChildVariants<FboCases::IntersectingQuadsTest> (depthGroup); 2156 addChildVariants<FboCases::IntersectingQuadsNpotTest> (depthGroup); 2157 2158 deqp::gles2::TestCaseGroup* stencilGroup = new deqp::gles2::TestCaseGroup(m_context, "stencil", "Stencil buffer tests"); 2159 addChild(stencilGroup); 2160 addChildVariants<FboCases::StencilTest> (stencilGroup); 2161 addChildVariants<FboCases::StencilNpotTest> (stencilGroup); 2162 2163 createChildGroup<FboCases::SharedColorbufferClearsTest> (this, "shared_colorbuffer_clear", "Shared colorbuffer clears"); 2164 createChildGroup<FboCases::SharedColorbufferTest> (this, "shared_colorbuffer", "Shared colorbuffer tests"); 2165 createChildGroup<FboCases::SharedDepthbufferTest> (this, "shared_depthbuffer", "Shared depthbuffer tests"); 2166 createChildGroup<FboCases::ResizeTest> (this, "resize", "FBO resize tests"); 2167 2168 createRecreateBuffersGroup<GL_COLOR_BUFFER_BIT> (this, "recreate_colorbuffer", "Recreate colorbuffer tests"); 2169 createRecreateBuffersGroup<GL_DEPTH_BUFFER_BIT> (this, "recreate_depthbuffer", "Recreate depthbuffer tests"); 2170 createRecreateBuffersGroup<GL_STENCIL_BUFFER_BIT> (this, "recreate_stencilbuffer", "Recreate stencilbuffer tests"); 2171 2172 deqp::gles2::TestCaseGroup* texSubImageGroup = new deqp::gles2::TestCaseGroup(m_context, "texsubimage", "TexSubImage interop with FBO colorbuffer texture"); 2173 addChild(texSubImageGroup); 2174 addChildVariants<FboCases::TexSubImageAfterRenderTest> (texSubImageGroup); 2175 addChildVariants<FboCases::TexSubImageBetweenRenderTest> (texSubImageGroup); 2176 2177 { 2178 tcu::TestCaseGroup* const repeatedClearGroup = new tcu::TestCaseGroup(m_testCtx, "repeated_clear", "Repeated FBO clears"); 2179 addChild(repeatedClearGroup); 2180 2181 repeatedClearGroup->addChild(new FboCases::RepeatedClearCase(m_context, GL_RGB)); 2182 repeatedClearGroup->addChild(new FboCases::RepeatedClearCase(m_context, GL_RGBA)); 2183 } 2184} 2185 2186} // Functional 2187} // gles2 2188} // deqp 2189