Commit 006ab354 by Jamie Madill

D3D11: Fix bug with static vertex attributes.

In some specific cases after binding a zero size buffer we could end up trying to use a buffer storage that was no longer valid. Fix this by ensuring we don't flush dirty bits when we have an early exit due to a zero size buffer. Also adds a regression test. Bug: chromium:1107433 Change-Id: I9db560e8dd3699abed2bb7fe6d91060148ba1817 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2335022Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 034a8b3f
...@@ -252,8 +252,6 @@ angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context, ...@@ -252,8 +252,6 @@ angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context,
for (size_t dirtyAttribIndex : activeDirtyAttribs) for (size_t dirtyAttribIndex : activeDirtyAttribs)
{ {
mAttribsToTranslate.reset(dirtyAttribIndex);
auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex]; auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex];
const auto &currentValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex); const auto &currentValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex);
...@@ -281,6 +279,9 @@ angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context, ...@@ -281,6 +279,9 @@ angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context,
UNREACHABLE(); UNREACHABLE();
break; break;
} }
// Make sure we reset the dirty bit after the switch because STATIC can early exit.
mAttribsToTranslate.reset(dirtyAttribIndex);
} }
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -3574,6 +3574,19 @@ class WebGLComputeValidationStateChangeTest : public ANGLETest ...@@ -3574,6 +3574,19 @@ class WebGLComputeValidationStateChangeTest : public ANGLETest
WebGLComputeValidationStateChangeTest() { setWebGLCompatibilityEnabled(true); } WebGLComputeValidationStateChangeTest() { setWebGLCompatibilityEnabled(true); }
}; };
class RobustBufferAccessWebGL2ValidationStateChangeTest : public WebGL2ValidationStateChangeTest
{
protected:
RobustBufferAccessWebGL2ValidationStateChangeTest()
{
// SwS/OSX GL do not support robustness.
if (!isSwiftshader() && !IsOSX())
{
setRobustAccess(true);
}
}
};
// Tests that mapping and unmapping an array buffer in various ways causes rendering to fail. // Tests that mapping and unmapping an array buffer in various ways causes rendering to fail.
// This isn't guaranteed to produce an error by GL. But we assume ANGLE always errors. // This isn't guaranteed to produce an error by GL. But we assume ANGLE always errors.
TEST_P(ValidationStateChangeTest, MapBufferAndDraw) TEST_P(ValidationStateChangeTest, MapBufferAndDraw)
...@@ -5129,6 +5142,7 @@ TEST_P(ImageRespecificationTest, ImageTarget2DOESSwitch) ...@@ -5129,6 +5142,7 @@ TEST_P(ImageRespecificationTest, ImageTarget2DOESSwitch)
eglDestroyImageKHR(window->getDisplay(), secondEGLImage); eglDestroyImageKHR(window->getDisplay(), secondEGLImage);
} }
// Covers a bug where sometimes we wouldn't catch invalid element buffer sizes.
TEST_P(WebGL2ValidationStateChangeTest, DeleteElementArrayBufferValidation) TEST_P(WebGL2ValidationStateChangeTest, DeleteElementArrayBufferValidation)
{ {
GLushort indexData[] = {0, 1, 2, 3}; GLushort indexData[] = {0, 1, 2, 3};
...@@ -5148,6 +5162,50 @@ TEST_P(WebGL2ValidationStateChangeTest, DeleteElementArrayBufferValidation) ...@@ -5148,6 +5162,50 @@ TEST_P(WebGL2ValidationStateChangeTest, DeleteElementArrayBufferValidation)
glDrawElements(GL_POINTS, 4, GL_UNSIGNED_SHORT, reinterpret_cast<const void *>(0x4)); glDrawElements(GL_POINTS, 4, GL_UNSIGNED_SHORT, reinterpret_cast<const void *>(0x4));
EXPECT_GL_ERROR(GL_INVALID_OPERATION); EXPECT_GL_ERROR(GL_INVALID_OPERATION);
} }
// Covers a bug in the D3D11 back-end related to how buffers are translated.
TEST_P(RobustBufferAccessWebGL2ValidationStateChangeTest, BindZeroSizeBufferThenDeleteBufferBug)
{
// SwiftShader does not currently support robustness.
ANGLE_SKIP_TEST_IF(isSwiftshader());
// http://anglebug.com/4872
ANGLE_SKIP_TEST_IF(IsAndroid() && IsVulkan());
// no intent to follow up on this failure.
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL());
// no intent to follow up on this failure.
ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
// no intent to follow up on this failure.
ANGLE_SKIP_TEST_IF(IsOSX());
std::vector<GLubyte> data(48, 1);
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
glUseProgram(program);
// First bind and draw with a buffer with a format we know to be "Direct" in D3D11.
GLBuffer arrayBuffer;
glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
glBufferData(GL_ARRAY_BUFFER, 48, data.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
// Then bind a zero size buffer and draw.
GLBuffer secondBuffer;
glBindBuffer(GL_ARRAY_BUFFER, secondBuffer);
glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 1, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
// Finally delete the original buffer. This triggers the bug.
arrayBuffer.reset();
glDrawArrays(GL_TRIANGLES, 0, 3);
ASSERT_GL_NO_ERROR();
}
} // anonymous namespace } // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2(StateChangeTest); ANGLE_INSTANTIATE_TEST_ES2(StateChangeTest);
...@@ -5162,5 +5220,6 @@ ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31); ...@@ -5162,5 +5220,6 @@ ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31);
ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31PPO); ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31PPO);
ANGLE_INSTANTIATE_TEST_ES3(ValidationStateChangeTest); ANGLE_INSTANTIATE_TEST_ES3(ValidationStateChangeTest);
ANGLE_INSTANTIATE_TEST_ES3(WebGL2ValidationStateChangeTest); ANGLE_INSTANTIATE_TEST_ES3(WebGL2ValidationStateChangeTest);
ANGLE_INSTANTIATE_TEST_ES3(RobustBufferAccessWebGL2ValidationStateChangeTest);
ANGLE_INSTANTIATE_TEST_ES31(ValidationStateChangeTestES31); ANGLE_INSTANTIATE_TEST_ES31(ValidationStateChangeTestES31);
ANGLE_INSTANTIATE_TEST_ES31(WebGLComputeValidationStateChangeTest); ANGLE_INSTANTIATE_TEST_ES31(WebGLComputeValidationStateChangeTest);
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