Commit 4b97d504 by Qin Jiajia Committed by Commit Bot

Fixed incorrect multisample rendering when enable SAMPLE_COVERAGE on Win

In RendererD3D::createRenderTarget, we use getNearestSamples(samples)'s result to assign D3D11_TEXTURE2D_DESC.SampleDesc.Count. However, in renderer11::updateState, we used the original samples to calculate mask by GetBlendSampleMask not the supported nearest samples. It would result that multisample rendering result was incorrect when enable AMPLE_COVERAGE and the samples is not in the suported list but less than max samples. At least, on Intel Win platform, we can reproduce it. The fixing is to use same samples in these two places. BUG=angleproject:1610 TEST=MultisampleCompatibilityTest.DrawCoverageAndResolve Change-Id: I255b12d1032317145adfcee94e65e88ae5307113 Reviewed-on: https://chromium-review.googlesource.com/408516Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 89dd8f37
......@@ -1615,7 +1615,17 @@ gl::Error Renderer11::updateState(const gl::ContextState &data, GLenum drawMode)
mStateManager.setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
// Applying rasterizer state to D3D11 device
int samples = framebuffer->getSamples(data);
// Since framebuffer->getSamples will return the original samples which may be different with
// the sample counts that we set in render target view, here we use renderTarget->getSamples to
// get the actual samples.
GLsizei samples = 0;
if (firstColorAttachment)
{
ASSERT(firstColorAttachment->isAttached());
RenderTarget11 *renderTarget = nullptr;
ANGLE_TRY(firstColorAttachment->getRenderTarget(&renderTarget));
samples = renderTarget->getSamples();
}
gl::RasterizerState rasterizer = glState.getRasterizerState();
rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0);
......
......@@ -1007,7 +1007,18 @@ gl::Error Renderer9::updateState(Context9 *context, GLenum drawMode)
setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
// Setting blend, depth stencil, and rasterizer states
int samples = framebuffer->getSamples(data);
// Since framebuffer->getSamples will return the original samples which may be different with
// the sample counts that we set in render target view, here we use renderTarget->getSamples to
// get the actual samples.
GLsizei samples = 0;
auto firstColorAttachment = framebuffer->getFirstColorbuffer();
if (firstColorAttachment)
{
ASSERT(firstColorAttachment->isAttached());
RenderTarget9 *renderTarget = nullptr;
ANGLE_TRY(firstColorAttachment->getRenderTarget(&renderTarget));
samples = renderTarget->getSamples();
}
gl::RasterizerState rasterizer = glState.getRasterizerState();
rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0);
......@@ -1030,7 +1041,18 @@ gl::Error Renderer9::setBlendDepthRasterStates(const gl::ContextState &glData, G
const auto &glState = glData.getState();
auto drawFramebuffer = glState.getDrawFramebuffer();
ASSERT(!drawFramebuffer->hasAnyDirtyBit());
int samples = drawFramebuffer->getSamples(glData);
// Since framebuffer->getSamples will return the original samples which may be different with
// the sample counts that we set in render target view, here we use renderTarget->getSamples to
// get the actual samples.
GLsizei samples = 0;
auto firstColorAttachment = drawFramebuffer->getFirstColorbuffer();
if (firstColorAttachment)
{
ASSERT(firstColorAttachment->isAttached());
RenderTarget9 *renderTarget = nullptr;
ANGLE_TRY(firstColorAttachment->getRenderTarget(&renderTarget));
samples = renderTarget->getSamples();
}
gl::RasterizerState rasterizer = glState.getRasterizerState();
rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0);
......
......@@ -9,6 +9,7 @@
//
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "shader_utils.h"
using namespace angle;
......@@ -296,5 +297,142 @@ TEST_P(EXTMultisampleCompatibilityTest, DrawAlphaOneAndResolve)
EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize));
}
ANGLE_INSTANTIATE_TEST(EXTMultisampleCompatibilityTest, ES2_OPENGL(), ES2_OPENGLES(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(EXTMultisampleCompatibilityTest, ES2_OPENGL(), ES2_OPENGLES(), ES3_OPENGL());
\ No newline at end of file
class MultisampleCompatibilityTest : public ANGLETest
{
protected:
MultisampleCompatibilityTest()
{
setWindowWidth(64);
setWindowHeight(64);
setConfigRedBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void prepareForDraw(GLsizei numSamples)
{
// Create a sample buffer.
glGenRenderbuffers(1, &mSampleRB);
glBindRenderbuffer(GL_RENDERBUFFER, mSampleRB);
glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, numSamples, GL_RGBA8, kWidth,
kHeight);
GLint param = 0;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &param);
EXPECT_GE(param, numSamples);
glGenFramebuffers(1, &mSampleFBO);
glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleRB);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Create another FBO to resolve the multisample buffer into.
glGenTextures(1, &mResolveTex);
glBindTexture(GL_TEXTURE_2D, mResolveTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glGenFramebuffers(1, &mResolveFBO);
glBindFramebuffer(GL_FRAMEBUFFER, mResolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mResolveTex, 0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
glViewport(0, 0, kWidth, kHeight);
glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
}
void prepareForVerify()
{
// Resolve.
glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFBO);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBlitFramebufferANGLE(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mResolveFBO);
ASSERT_GL_NO_ERROR();
}
void cleanup()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &mResolveFBO);
glDeleteFramebuffers(1, &mSampleFBO);
glDeleteTextures(1, &mResolveTex);
glDeleteRenderbuffers(1, &mSampleRB);
ASSERT_GL_NO_ERROR();
}
bool isApplicable() const
{
return extensionEnabled("GL_ANGLE_framebuffer_multisample") &&
extensionEnabled("GL_OES_rgb8_rgba8");
}
GLuint mSampleFBO;
GLuint mResolveFBO;
GLuint mSampleRB;
GLuint mResolveTex;
};
// Test that enabling GL_SAMPLE_COVERAGE affects rendering.
TEST_P(MultisampleCompatibilityTest, DrawCoverageAndResolve)
{
if (!isApplicable())
return;
// TODO: Figure out why this fails on Android.
if (IsAndroid())
{
std::cout << "Test skipped on Android." << std::endl;
return;
}
const std::string &vertex =
"attribute vec4 position;\n"
"void main()\n"
"{ gl_Position = position; }";
const std::string &fragment =
"void main()\n"
"{ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }";
ANGLE_GL_PROGRAM(drawRed, vertex, fragment);
GLsizei maxSamples = 0;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
int iterationCount = maxSamples + 1;
for (int samples = 1; samples < iterationCount; samples++)
{
prepareForDraw(samples);
glEnable(GL_SAMPLE_COVERAGE);
glSampleCoverage(1.0, false);
drawQuad(drawRed.get(), "position", 0.5f);
prepareForVerify();
GLsizei pixelCount = kWidth * kHeight;
std::vector<GLColor> actual(pixelCount, GLColor::black);
glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, actual.data());
glDisable(GL_SAMPLE_COVERAGE);
cleanup();
std::vector<GLColor> expected(pixelCount, GLColor::red);
EXPECT_EQ(expected, actual);
}
}
ANGLE_INSTANTIATE_TEST(MultisampleCompatibilityTest,
ES2_D3D9(),
ES2_OPENGL(),
ES2_OPENGLES(),
ES3_D3D11(),
ES3_OPENGL(),
ES3_OPENGLES());
\ No newline at end of file
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