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 ...@@ -200,7 +200,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
std::vector<RenderTarget11*> maskedClearRenderTargets; std::vector<MaskedRenderTarget> maskedClearRenderTargets;
RenderTarget11* maskedClearDepthStencil = NULL; RenderTarget11* maskedClearDepthStencil = NULL;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
...@@ -249,7 +249,14 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ...@@ -249,7 +249,14 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
(internalAlphaBits > 0 && !clearParams.colorMaskAlpha)) (internalAlphaBits > 0 && !clearParams.colorMaskAlpha))
{ {
// A scissored or masked clear is required // 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 else
{ {
...@@ -353,18 +360,19 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ...@@ -353,18 +360,19 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame
std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size()); std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size());
for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
{ {
ID3D11RenderTargetView *renderTarget = maskedClearRenderTargets[i]->getRenderTargetView(); RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget;
if (!renderTarget) ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
if (!rtv)
{ {
ERR("Render target pointer unexpectedly null."); ERR("Render target view unexpectedly null.");
return; return;
} }
rtvs[i] = renderTarget; rtvs[i] = rtv;
} }
ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL; 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 FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
const UINT sampleMask = 0xFFFFFFFF; const UINT sampleMask = 0xFFFFFFFF;
...@@ -447,19 +455,20 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ...@@ -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 }; ClearBlendInfo blendKey = { 0 };
for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{ {
if (i < rts.size()) 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][0] = (rts[i].colorMask[0] && gl::GetRedBits(internalFormat) > 0);
blendKey.maskChannels[i][1] = clearParams.clearColor ? (clearParams.colorMaskGreen && gl::GetGreenBits(internalFormat) > 0) : false; blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && gl::GetGreenBits(internalFormat) > 0);
blendKey.maskChannels[i][2] = clearParams.clearColor ? (clearParams.colorMaskBlue && gl::GetBlueBits(internalFormat) > 0) : false; blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && gl::GetBlueBits(internalFormat) > 0);
blendKey.maskChannels[i][3] = clearParams.clearColor ? (clearParams.colorMaskAlpha && gl::GetAlphaBits(internalFormat) > 0) : false; blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && gl::GetAlphaBits(internalFormat) > 0);
} }
else else
{ {
......
...@@ -41,7 +41,13 @@ class Clear11 ...@@ -41,7 +41,13 @@ class Clear11
typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap; typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
ClearBlendStateMap mClearBlendStates; 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 struct ClearShader
{ {
......
...@@ -12,6 +12,7 @@ protected: ...@@ -12,6 +12,7 @@ protected:
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
setConfigDepthBits(24); setConfigDepthBits(24);
setClientVersion(3);
} }
virtual void SetUp() virtual void SetUp()
...@@ -44,22 +45,26 @@ protected: ...@@ -44,22 +45,26 @@ protected:
{ {
FAIL() << "shader compilation failed."; FAIL() << "shader compilation failed.";
} }
glGenFramebuffers(1, &mFBO);
ASSERT_GL_NO_ERROR();
} }
virtual void TearDown() virtual void TearDown()
{ {
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
glDeleteFramebuffers(1, &mFBO);
ANGLETest::TearDown(); ANGLETest::TearDown();
} }
GLuint mProgram; GLuint mProgram;
GLuint mFBO;
}; };
TEST_F(ClearTest, ClearIssue) TEST_F(ClearTest, ClearIssue)
{ {
EXPECT_GL_NO_ERROR();
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
...@@ -69,9 +74,7 @@ TEST_F(ClearTest, ClearIssue) ...@@ -69,9 +74,7 @@ TEST_F(ClearTest, ClearIssue)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
GLuint fbo; glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint rbo; GLuint rbo;
glGenRenderbuffers(1, &rbo); glGenRenderbuffers(1, &rbo);
...@@ -97,3 +100,41 @@ TEST_F(ClearTest, ClearIssue) ...@@ -97,3 +100,41 @@ TEST_F(ClearTest, ClearIssue)
EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); 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