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;
 };
