Port WebGL multisampled renderbuffer resize test
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
diff --git a/android/cts/master/gles3-master.txt b/android/cts/master/gles3-master.txt
index c321527..46062f6 100644
--- a/android/cts/master/gles3-master.txt
+++ b/android/cts/master/gles3-master.txt
@@ -30428,6 +30428,10 @@
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
diff --git a/modules/gles3/functional/es3fFboMultisampleTests.cpp b/modules/gles3/functional/es3fFboMultisampleTests.cpp
index c29cdb8..c013a54 100644
--- a/modules/gles3/functional/es3fFboMultisampleTests.cpp
+++ b/modules/gles3/functional/es3fFboMultisampleTests.cpp
@@ -21,6 +21,7 @@
* \brief FBO multisample tests.
*//*--------------------------------------------------------------------*/
+#include "es3fApiCase.hpp"
#include "es3fFboMultisampleTests.hpp"
#include "es3fFboTestCase.hpp"
#include "es3fFboTestUtil.hpp"
@@ -246,6 +247,98 @@
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 @@
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