Port WebGL multisampled renderbuffer resize test
authorKai Ninomiya <kainino@chromium.org>
Tue, 9 Jan 2018 18:59:09 +0000 (10:59 -0800)
committerKai Ninomiya <kainino@chromium.org>
Fri, 19 Jan 2018 00:26:02 +0000 (16:26 -0800)
Port a WebGL test for a driver bug affecting resizing/reallocation
of multisampled renderbuffers on Qualcomm drivers:
* conformance2/renderbuffers/multisampled-renderbuffer-initialization.html

New tests: dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.*
Components: AOSP
Change-Id: Ib4377eaf35c1d4b5f431cd433e06301003966d54

android/cts/master/gles3-master.txt
modules/gles3/functional/es3fFboMultisampleTests.cpp

index c321527..46062f6 100644 (file)
@@ -30428,6 +30428,10 @@ dEQP-GLES3.functional.fbo.msaa.8_samples.depth_component16
 dEQP-GLES3.functional.fbo.msaa.8_samples.depth32f_stencil8
 dEQP-GLES3.functional.fbo.msaa.8_samples.depth24_stencil8
 dEQP-GLES3.functional.fbo.msaa.8_samples.stencil_index8
+dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.nonms_to_nonms
+dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.nonms_to_ms
+dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.ms_to_nonms
+dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.ms_to_ms
 dEQP-GLES3.functional.fbo.multiview.samples_1
 dEQP-GLES3.functional.fbo.multiview.samples_2
 dEQP-GLES3.functional.fbo.multiview.samples_4
index c29cdb8..c013a54 100644 (file)
@@ -21,6 +21,7 @@
  * \brief FBO multisample tests.
  *//*--------------------------------------------------------------------*/
 
+#include "es3fApiCase.hpp"
 #include "es3fFboMultisampleTests.hpp"
 #include "es3fFboTestCase.hpp"
 #include "es3fFboTestUtil.hpp"
@@ -246,6 +247,98 @@ private:
        int                     m_numSamples;
 };
 
+// Ported from WebGL [1], originally written to test a Qualcomm driver bug [2].
+// [1] https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html
+// [2] http://crbug.com/696126
+class RenderbufferResizeCase : public ApiCase
+{
+public:
+       RenderbufferResizeCase (Context& context, const char* name, const char* desc, bool multisampled1, bool multisampled2)
+               : ApiCase       (context, name, desc)
+               , m_multisampled1(multisampled1)
+               , m_multisampled2(multisampled2)
+       {
+       }
+
+protected:
+       void test ()
+       {
+               glDisable(GL_DEPTH_TEST);
+
+               int maxSamples = 0;
+               glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &maxSamples);
+               deUint32 samp1 = m_multisampled1 ? maxSamples : 0;
+               deUint32 samp2 = m_multisampled2 ? maxSamples : 0;
+
+               static const deUint32 W1 = 10, H1 = 10;
+               static const deUint32 W2 = 40, H2 = 40;
+
+               // Set up non-multisampled buffer to blit to and read back from.
+               deUint32 fboResolve = 0;
+               deUint32 rboResolve = 0;
+               {
+                       glGenFramebuffers(1, &fboResolve);
+                       glBindFramebuffer(GL_FRAMEBUFFER, fboResolve);
+                       glGenRenderbuffers(1, &rboResolve);
+                       glBindRenderbuffer(GL_RENDERBUFFER, rboResolve);
+                       glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W2, H2);
+                       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboResolve);
+                       TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+                       glClearBufferfv(GL_COLOR, 0, Vec4(1.0f, 0.0f, 0.0f, 1.0f).getPtr());
+               }
+               expectError(GL_NO_ERROR);
+
+               // Set up multisampled buffer to test.
+               deUint32 fboMultisampled = 0;
+               deUint32 rboMultisampled = 0;
+               {
+                       glGenFramebuffers(1, &fboMultisampled);
+                       glBindFramebuffer(GL_FRAMEBUFFER, fboMultisampled);
+                       glGenRenderbuffers(1, &rboMultisampled);
+                       glBindRenderbuffer(GL_RENDERBUFFER, rboMultisampled);
+                       // Allocate,
+                       glRenderbufferStorageMultisample(GL_RENDERBUFFER, samp1, GL_RGBA8, W1, H1);
+                       // attach,
+                       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboMultisampled);
+                       TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+                       glClearBufferfv(GL_COLOR, 0, Vec4(0.0f, 0.0f, 1.0f, 1.0f).getPtr());
+                       // and allocate again with different parameters.
+                       glRenderbufferStorageMultisample(GL_RENDERBUFFER, samp2, GL_RGBA8, W2, H2);
+                       TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+                       glClearBufferfv(GL_COLOR, 0, Vec4(0.0f, 1.0f, 0.0f, 1.0f).getPtr());
+               }
+               expectError(GL_NO_ERROR);
+
+               // This is a blit from the multisampled buffer to the non-multisampled buffer.
+               glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMultisampled);
+               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboResolve);
+               // Blit color from fboMultisampled (should be green) to fboResolve (should currently be red).
+               glBlitFramebuffer(0, 0, W2, H2, 0, 0, W2, H2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+               expectError(GL_NO_ERROR);
+
+               // fboResolve should now be green.
+               glBindFramebuffer(GL_READ_FRAMEBUFFER, fboResolve);
+               deUint32 pixels[W2 * H2] = {};
+               glReadPixels(0, 0, W2, H2, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+               expectError(GL_NO_ERROR);
+
+               const tcu::RGBA threshold (tcu::max(getFormatThreshold(GL_RGBA8), tcu::RGBA(12, 12, 12, 12)));
+               for (deUint32 y = 0; y < H2; ++y)
+               {
+                       for (deUint32 x = 0; x < W2; ++x)
+                       {
+                               tcu::RGBA color(pixels[y * W2 + x]);
+                               TCU_CHECK(compareThreshold(color, tcu::RGBA::green(), threshold));
+                       }
+               }
+       }
+
+private:
+       bool m_multisampled1;
+       bool m_multisampled2;
+};
+
 FboMultisampleTests::FboMultisampleTests (Context& context)
        : TestCaseGroup(context, "msaa", "Multisample FBO tests")
 {
@@ -312,6 +405,19 @@ void FboMultisampleTests::init (void)
                for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
                        sampleCountGroup->addChild(new BasicFboMultisampleCase(m_context, getFormatName(depthStencilFormats[fmtNdx]), "", GL_RGBA8, depthStencilFormats[fmtNdx], IVec2(119, 131), samples));
        }
+
+       // .renderbuffer_resize
+       {
+               tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, "renderbuffer_resize", "Multisample renderbuffer resize");
+               addChild(group);
+
+               {
+                       group->addChild(new RenderbufferResizeCase(m_context, "nonms_to_nonms", "", false, false));
+                       group->addChild(new RenderbufferResizeCase(m_context, "nonms_to_ms", "", false, true));
+                       group->addChild(new RenderbufferResizeCase(m_context, "ms_to_nonms", "", true, false));
+                       group->addChild(new RenderbufferResizeCase(m_context, "ms_to_ms", "", true, true));
+               }
+       }
 }
 
 } // Functional