Commit 3dbe480b by shrekshao Committed by Commit Bot

Validating draw buffers now also considers color mask settings

It will always return true if all 4 channels of color mask are set to false. This should only apply to WebGL. Will fix this in a later patch. Bug: chromium:958374 Change-Id: I46befaf3ae1b63027dfbb309ac32724c616025d3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1594629 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 29f4ba7d
...@@ -4512,6 +4512,7 @@ void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolea ...@@ -4512,6 +4512,7 @@ void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolea
{ {
mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue), mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
ConvertToBool(alpha)); ConvertToBool(alpha));
mStateCache.onColorMaskChange(this);
} }
void Context::cullFace(CullFaceMode mode) void Context::cullFace(CullFaceMode mode)
...@@ -8525,6 +8526,11 @@ void StateCache::onUniformBufferStateChange(Context *context) ...@@ -8525,6 +8526,11 @@ void StateCache::onUniformBufferStateChange(Context *context)
updateBasicDrawStatesError(); updateBasicDrawStatesError();
} }
void StateCache::onColorMaskChange(Context *context)
{
updateBasicDrawStatesError();
}
void StateCache::setValidDrawModes(bool pointsOK, void StateCache::setValidDrawModes(bool pointsOK,
bool linesOK, bool linesOK,
bool trisOK, bool trisOK,
......
...@@ -141,7 +141,8 @@ class StateCache final : angle::NonCopyable ...@@ -141,7 +141,8 @@ class StateCache final : angle::NonCopyable
// 11. onQueryChange. // 11. onQueryChange.
// 12. onActiveTransformFeedbackChange. // 12. onActiveTransformFeedbackChange.
// 13. onUniformBufferStateChange. // 13. onUniformBufferStateChange.
// 14. onBufferBindingChange. // 14. onColorMaskChange.
// 15. onBufferBindingChange.
bool hasBasicDrawStatesError(Context *context) const bool hasBasicDrawStatesError(Context *context) const
{ {
if (mCachedBasicDrawStatesError == 0) if (mCachedBasicDrawStatesError == 0)
...@@ -233,6 +234,7 @@ class StateCache final : angle::NonCopyable ...@@ -233,6 +234,7 @@ class StateCache final : angle::NonCopyable
void onQueryChange(Context *context); void onQueryChange(Context *context);
void onActiveTransformFeedbackChange(Context *context); void onActiveTransformFeedbackChange(Context *context);
void onUniformBufferStateChange(Context *context); void onUniformBufferStateChange(Context *context);
void onColorMaskChange(Context *context);
void onBufferBindingChange(Context *context); void onBufferBindingChange(Context *context);
private: private:
......
...@@ -580,11 +580,6 @@ const RasterizerState &State::getRasterizerState() const ...@@ -580,11 +580,6 @@ const RasterizerState &State::getRasterizerState() const
return mRasterizer; return mRasterizer;
} }
const BlendState &State::getBlendState() const
{
return mBlend;
}
const DepthStencilState &State::getDepthStencilState() const const DepthStencilState &State::getDepthStencilState() const
{ {
return mDepthStencil; return mDepthStencil;
......
...@@ -89,7 +89,7 @@ class State : angle::NonCopyable ...@@ -89,7 +89,7 @@ class State : angle::NonCopyable
// State chunk getters // State chunk getters
const RasterizerState &getRasterizerState() const; const RasterizerState &getRasterizerState() const;
const BlendState &getBlendState() const; const BlendState &getBlendState() const { return mBlend; }
const DepthStencilState &getDepthStencilState() const; const DepthStencilState &getDepthStencilState() const;
// Clear behavior setters & state parameter block generation function // Clear behavior setters & state parameter block generation function
......
...@@ -2778,16 +2778,19 @@ const char *ValidateDrawStates(Context *context) ...@@ -2778,16 +2778,19 @@ const char *ValidateDrawStates(Context *context)
return kVertexShaderTypeMismatch; return kVertexShaderTypeMismatch;
} }
// Detect that if there's active color buffer without fragment shader output if (!context->getState().getBlendState().allChannelsMasked())
if (!ValidateFragmentShaderColorBufferMaskMatch(context))
{ {
return kDrawBufferMaskMismatch; // Detect that if there's active color buffer without fragment shader output
} if (!ValidateFragmentShaderColorBufferMaskMatch(context))
{
return kDrawBufferMaskMismatch;
}
// Detect that the color buffer types match the fragment shader output types // Detect that the color buffer types match the fragment shader output types
if (!ValidateFragmentShaderColorBufferTypeMatch(context)) if (!ValidateFragmentShaderColorBufferTypeMatch(context))
{ {
return kDrawBufferTypeMismatch; return kDrawBufferTypeMismatch;
}
} }
const VertexArray *vao = context->getState().getVertexArray(); const VertexArray *vao = context->getState().getVertexArray();
......
...@@ -444,6 +444,16 @@ TEST_P(DrawBuffersWebGL2Test, TwoProgramsWithDifferentOutputsAndClear) ...@@ -444,6 +444,16 @@ TEST_P(DrawBuffersWebGL2Test, TwoProgramsWithDifferentOutputsAndClear)
setDrawBuffers(kMaxBuffers, allBufs); setDrawBuffers(kMaxBuffers, allBufs);
drawQuad(program, positionAttrib(), 0.5, 1.0f, true); drawQuad(program, positionAttrib(), 0.5, 1.0f, true);
ASSERT_GL_ERROR(GL_INVALID_OPERATION); ASSERT_GL_ERROR(GL_INVALID_OPERATION);
// Exception: when all 4 channels of color mask are set to false.
glColorMask(false, false, false, false);
drawQuad(program, positionAttrib(), 0.5, 1.0f, true);
ASSERT_GL_NO_ERROR();
glColorMask(false, true, false, false);
drawQuad(program, positionAttrib(), 0.5, 1.0f, true);
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
glColorMask(true, true, true, true);
drawQuad(program, positionAttrib(), 0.5, 1.0f, true);
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
// Clear again. All attachments should be cleared. // Clear again. All attachments should be cleared.
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
......
...@@ -3027,6 +3027,16 @@ void main() ...@@ -3027,6 +3027,16 @@ void main()
ASSERT_GL_NO_ERROR() << "Draw to float texture with invalid mask"; ASSERT_GL_NO_ERROR() << "Draw to float texture with invalid mask";
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_ERROR(GL_INVALID_OPERATION); EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// Set all 4 channels of color mask to false. Validate success.
glColorMask(false, false, false, false);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_NO_ERROR();
glColorMask(false, true, false, false);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glColorMask(true, true, true, true);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// Restore state. // Restore state.
glDrawBuffers(2, kColor0Enabled); glDrawBuffers(2, kColor0Enabled);
......
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