Commit 113b7e63 by Shahbaz Youssefi Committed by Commit Bot

Add a sample shading test to verify FS invocation per sample

A test is added that uses the RedGreenGradient shader, which doesn't include gl_SampleID, gl_SamplePosition or the sample qualifier, but uses GL_SAMPLE_SHADING to perform per-sample shading. The samples from the resulting image are copied to a buffer in compute and verified. Bug: angleproject:5395 Change-Id: I3567329e4d567d149e4548eb12222b8dd5255bba Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2559266 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarMohan Maiya <m.maiya@samsung.com>
parent 939fcd1a
...@@ -1068,7 +1068,120 @@ TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch) ...@@ -1068,7 +1068,120 @@ TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch)
} }
} }
class TextureSampleShadingTest : public ANGLETest
{
protected:
TextureSampleShadingTest() {}
};
// Test that sample shading actually produces different interpolations per sample. Note that
// variables such as gl_SampleID and gl_SamplePosition are avoided, as well as the |sample|
// qualifier as they automatically enable sample shading.
TEST_P(TextureSampleShadingTest, Basic)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_sample_shading"));
// http://anglebug.com/5410
ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
constexpr GLsizei kSize = 1;
constexpr GLsizei kSampleCount = 4;
// Create a multisampled texture and framebuffer.
GLFramebuffer msaaFBO;
glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
GLTexture msaaTexture;
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTexture);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, kSampleCount, GL_RGBA8, kSize, kSize,
false);
ASSERT_GL_NO_ERROR();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
msaaTexture, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
// Enable sample shading and draw a gradient.
glEnable(GL_SAMPLE_SHADING_OES);
glMinSampleShadingOES(1.0f);
ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
essl31_shaders::fs::RedGreenGradient());
glViewport(0, 0, kSize, kSize);
drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
ASSERT_GL_NO_ERROR();
// Create a buffer for verification.
constexpr GLsizei kPixelChannels = 4;
constexpr GLsizei kBufferSize =
kSize * kSize * kSampleCount * kPixelChannels * sizeof(uint32_t);
GLBuffer buffer;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
// Issue a dispatch call that copies the multisampled texture into a buffer.
constexpr char kCS[] = R"(#version 310 es
layout(local_size_x=4, local_size_y=1, local_size_z=1) in;
uniform highp sampler2DMS imageIn;
layout(std430, binding = 0) buffer dataOut {
uint data[];
};
void main()
{
int sampleIndex = int(gl_GlobalInvocationID.x) % 4;
vec4 color = texelFetch(imageIn, ivec2(0), sampleIndex);
uvec4 unnormalized = uvec4(color * 255.0);
int outIndex = sampleIndex * 4;
data[outIndex ] = unnormalized.r;
data[outIndex + 1] = unnormalized.g;
data[outIndex + 2] = unnormalized.b;
data[outIndex + 3] = unnormalized.a;
})";
ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
glUseProgram(program);
// Bind the multisampled texture as sampler.
GLint imageLocation = glGetUniformLocation(program, "imageIn");
ASSERT_GE(imageLocation, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTexture);
glUniform1i(imageLocation, 0);
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
// Verify that the buffer has correct data.
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
const uint32_t *ptr = reinterpret_cast<uint32_t *>(
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
constexpr GLColor kExpectedColors[4] = {
GLColor(96, 32, 0, 255),
GLColor(223, 96, 0, 255),
GLColor(32, 159, 0, 255),
GLColor(159, 223, 0, 255),
};
for (GLsizei pixel = 0; pixel < kSampleCount; ++pixel)
{
for (GLsizei channel = 0; channel < kPixelChannels; ++channel)
{
EXPECT_NEAR(ptr[pixel * kPixelChannels + channel], kExpectedColors[pixel][channel], 1)
<< pixel << " " << channel;
}
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
}
ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(TextureMultisampleTest); ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(TextureMultisampleTest);
ANGLE_INSTANTIATE_TEST_ES3(NegativeTextureMultisampleTest); ANGLE_INSTANTIATE_TEST_ES3(NegativeTextureMultisampleTest);
ANGLE_INSTANTIATE_TEST_ES31(TextureMultisampleArrayWebGLTest); ANGLE_INSTANTIATE_TEST_ES31(TextureMultisampleArrayWebGLTest);
ANGLE_INSTANTIATE_TEST_ES31(TextureSampleShadingTest);
} // anonymous namespace } // anonymous namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment