Commit a09403c0 by Jamie Madill

Fix masked ClearBuffer.

We were not properly setting the masked channels for these APIs. Since we use a std::vector for tracking the render targets for a particular ClearBuffer call, we lose the indexing into the clear parameters. Fix this by storing the information in the std::vector along with the Render Target. BUG=angle:702 Change-Id: Ie3b1e870aa04054411c4f155682b86a340ec00cf Reviewed-on: https://chromium-review.googlesource.com/209103Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent bfdea66b
......@@ -200,7 +200,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
std::vector<RenderTarget11*> maskedClearRenderTargets;
std::vector<MaskedRenderTarget> maskedClearRenderTargets;
RenderTarget11* maskedClearDepthStencil = NULL;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
......@@ -249,7 +249,14 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
(internalAlphaBits > 0 && !clearParams.colorMaskAlpha))
{
// A scissored or masked clear is required
maskedClearRenderTargets.push_back(renderTarget);
MaskedRenderTarget maskAndRt;
bool clearColor = clearParams.clearColor[colorAttachment];
maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen);
maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue);
maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha);
maskAndRt.renderTarget = renderTarget;
maskedClearRenderTargets.push_back(maskAndRt);
}
else
{
......@@ -353,18 +360,19 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size());
for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
{
ID3D11RenderTargetView *renderTarget = maskedClearRenderTargets[i]->getRenderTargetView();
if (!renderTarget)
RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget;
ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
if (!rtv)
{
ERR("Render target pointer unexpectedly null.");
ERR("Render target view unexpectedly null.");
return;
}
rtvs[i] = renderTarget;
rtvs[i] = rtv;
}
ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL;
ID3D11BlendState *blendState = getBlendState(clearParams, maskedClearRenderTargets);
ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets);
const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
const UINT sampleMask = 0xFFFFFFFF;
......@@ -447,19 +455,20 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
}
}
ID3D11BlendState *Clear11::getBlendState(const gl::ClearParameters &clearParams, const std::vector<RenderTarget11*>& rts)
ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts)
{
ClearBlendInfo blendKey = { 0 };
for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
if (i < rts.size())
{
GLint internalFormat = rts[i]->getInternalFormat();
RenderTarget11 *rt = rts[i].renderTarget;
GLint internalFormat = rt->getInternalFormat();
blendKey.maskChannels[i][0] = clearParams.clearColor ? (clearParams.colorMaskRed && gl::GetRedBits(internalFormat) > 0) : false;
blendKey.maskChannels[i][1] = clearParams.clearColor ? (clearParams.colorMaskGreen && gl::GetGreenBits(internalFormat) > 0) : false;
blendKey.maskChannels[i][2] = clearParams.clearColor ? (clearParams.colorMaskBlue && gl::GetBlueBits(internalFormat) > 0) : false;
blendKey.maskChannels[i][3] = clearParams.clearColor ? (clearParams.colorMaskAlpha && gl::GetAlphaBits(internalFormat) > 0) : false;
blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && gl::GetRedBits(internalFormat) > 0);
blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && gl::GetGreenBits(internalFormat) > 0);
blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && gl::GetBlueBits(internalFormat) > 0);
blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && gl::GetAlphaBits(internalFormat) > 0);
}
else
{
......
......@@ -41,7 +41,13 @@ class Clear11
typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
ClearBlendStateMap mClearBlendStates;
ID3D11BlendState *getBlendState(const gl::ClearParameters &clearParams, const std::vector<RenderTarget11*>& rts);
struct MaskedRenderTarget
{
bool colorMask[4];
RenderTarget11 *renderTarget;
};
ID3D11BlendState *getBlendState(const std::vector<MaskedRenderTarget> &rts);
struct ClearShader
{
......
......@@ -12,6 +12,7 @@ protected:
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
setClientVersion(3);
}
virtual void SetUp()
......@@ -44,22 +45,26 @@ protected:
{
FAIL() << "shader compilation failed.";
}
glGenFramebuffers(1, &mFBO);
ASSERT_GL_NO_ERROR();
}
virtual void TearDown()
{
glDeleteProgram(mProgram);
glDeleteFramebuffers(1, &mFBO);
ANGLETest::TearDown();
}
GLuint mProgram;
GLuint mFBO;
};
TEST_F(ClearTest, ClearIssue)
{
EXPECT_GL_NO_ERROR();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
......@@ -69,9 +74,7 @@ TEST_F(ClearTest, ClearIssue)
EXPECT_GL_NO_ERROR();
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
GLuint rbo;
glGenRenderbuffers(1, &rbo);
......@@ -97,3 +100,41 @@ TEST_F(ClearTest, ClearIssue)
EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
}
// Requires ES3
// This tests a bug where in a masked clear when calling "ClearBuffer", we would
// mistakenly clear every channel (including the masked-out ones)
TEST_F(ClearTest, MaskedClearBufferBug)
{
unsigned char pixelData[] = { 255, 255, 255, 255 };
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
GLuint textures[2];
glGenTextures(2, &textures[0]);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
float clearValue[] = { 0, 0.5f, 0.5f, 1.0f };
GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, drawBuffers);
glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
glClearBufferfv(GL_COLOR, 1, clearValue);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
// TODO: glReadBuffer support
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
EXPECT_PIXEL_EQ(0, 0, 0, 127, 255, 255);
}
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