diff --git a/framework/opengl/gluFboRenderContext.cpp b/framework/opengl/gluFboRenderContext.cpp index 588cf7d2a..0721ffee7 100644 --- a/framework/opengl/gluFboRenderContext.cpp +++ b/framework/opengl/gluFboRenderContext.cpp @@ -132,6 +132,7 @@ FboRenderContext::FboRenderContext(RenderContext *context, const RenderConfig &c : m_context(context) , m_framebuffer(0) , m_colorBuffer(0) + , m_colorIsTexture(false) , m_depthStencilBuffer(0) , m_renderTarget() { @@ -151,6 +152,7 @@ FboRenderContext::FboRenderContext(const ContextFactory &factory, const RenderCo : m_context(nullptr) , m_framebuffer(0) , m_colorBuffer(0) + , m_colorIsTexture(false) , m_depthStencilBuffer(0) , m_renderTarget() { @@ -215,19 +217,41 @@ void FboRenderContext::createFramebuffer(const RenderConfig &config) height = (height == glu::RenderConfig::DONT_CARE) ? maxSize : height; } + // MOBILEGL: allow the colour attachment to be a texture instead of a + // renderbuffer. MobileGL's DirectVulkan backend returns zeros when reading + // back a renderbuffer-attached FBO, which makes every image comparison fail + // for one reason and hides everything else. Setting + // MOBILEGL_CTS_FBO_COLOR_TEXTURE=1 isolates that single defect so the rest + // of the suite can be measured. Off by default: stock behaviour. { - pixelFormat = getPixelFormat(colorFormat); + const char *useTexEnv = getenv("MOBILEGL_CTS_FBO_COLOR_TEXTURE"); + m_colorIsTexture = (useTexEnv && useTexEnv[0] == '1' && config.numSamples <= 0); - gl.genRenderbuffers(1, &m_colorBuffer); - gl.bindRenderbuffer(GL_RENDERBUFFER, m_colorBuffer); + pixelFormat = getPixelFormat(colorFormat); - if (config.numSamples > 0) - gl.renderbufferStorageMultisample(GL_RENDERBUFFER, config.numSamples, colorFormat, width, height); + if (m_colorIsTexture) + { + gl.genTextures(1, &m_colorBuffer); + gl.bindTexture(GL_TEXTURE_2D, m_colorBuffer); + gl.texStorage2D(GL_TEXTURE_2D, 1, colorFormat, width, height); + gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.bindTexture(GL_TEXTURE_2D, 0); + GLU_EXPECT_NO_ERROR(gl.getError(), "Creating color texture"); + } else - gl.renderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height); - - gl.bindRenderbuffer(GL_RENDERBUFFER, 0); - GLU_EXPECT_NO_ERROR(gl.getError(), "Creating color renderbuffer"); + { + gl.genRenderbuffers(1, &m_colorBuffer); + gl.bindRenderbuffer(GL_RENDERBUFFER, m_colorBuffer); + + if (config.numSamples > 0) + gl.renderbufferStorageMultisample(GL_RENDERBUFFER, config.numSamples, colorFormat, width, height); + else + gl.renderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height); + + gl.bindRenderbuffer(GL_RENDERBUFFER, 0); + GLU_EXPECT_NO_ERROR(gl.getError(), "Creating color renderbuffer"); + } } if (depthStencilFormat != GL_NONE) @@ -250,7 +274,12 @@ void FboRenderContext::createFramebuffer(const RenderConfig &config) gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); if (m_colorBuffer) - gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorBuffer); + { + if (m_colorIsTexture) + gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0); + else + gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorBuffer); + } if (m_depthStencilBuffer) { @@ -290,7 +319,10 @@ void FboRenderContext::destroyFramebuffer(void) if (m_colorBuffer) { - gl.deleteRenderbuffers(1, &m_colorBuffer); + if (m_colorIsTexture) + gl.deleteTextures(1, &m_colorBuffer); + else + gl.deleteRenderbuffers(1, &m_colorBuffer); m_colorBuffer = 0; } } diff --git a/framework/opengl/gluFboRenderContext.hpp b/framework/opengl/gluFboRenderContext.hpp index 75a0ff6b7..09ff1e7a9 100644 --- a/framework/opengl/gluFboRenderContext.hpp +++ b/framework/opengl/gluFboRenderContext.hpp @@ -80,6 +80,7 @@ private: RenderContext *m_context; uint32_t m_framebuffer; uint32_t m_colorBuffer; + bool m_colorIsTexture; uint32_t m_depthStencilBuffer; tcu::RenderTarget m_renderTarget; };