Commit d28758de by Jamie Madill Committed by Commit Bot

D3D11: Re-enable updateVertexBuffer dirty bits.

In some cases, when the app would call glBufferSubData to do a small data update in an existing vertex buffer, the sync code would not flush out the data to the native D3D11 buffer from the temporary staging buffer. Fix this problem by notifying the VertexArray11 class when buffer data is updated. Note that in the future we can improve this by using a different update notification for when the buffer data changes and when the underlying storage changes. For now take a very broad approach. BUG=angleproject:1156 Change-Id: I2e0fabc97c1f1d5a14d609247e61c602e9a5a85f Reviewed-on: https://chromium-review.googlesource.com/644208Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 57ae8c16
...@@ -393,6 +393,10 @@ gl::Error Buffer11::setSubData(const gl::Context * /*context*/, ...@@ -393,6 +393,10 @@ gl::Error Buffer11::setSubData(const gl::Context * /*context*/,
writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size); writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size);
writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1); writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1);
// Notify any vertex arrays that we have dirty data.
// TODO(jmadill): Use a more fine grained notification for data updates.
mDirectBroadcastChannel.signal();
} }
mSize = std::max(mSize, requiredSize); mSize = std::max(mSize, requiredSize);
......
...@@ -1920,12 +1920,10 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context, ...@@ -1920,12 +1920,10 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
mInputLayoutIsDirty = true; mInputLayoutIsDirty = true;
} }
// Currently buffer data updates sometimes won't get flushed if we short-circuit. if (!mInputLayoutIsDirty)
// TODO(jmadill): Re-enable once we fix updates. {
//if (!mInputLayoutIsDirty) return gl::NoError();
//{ }
// return gl::NoError();
//}
GLsizei numIndicesPerInstance = 0; GLsizei numIndicesPerInstance = 0;
if (instances > 0) if (instances > 0)
......
...@@ -601,6 +601,62 @@ TEST_P(StateChangeRenderTest, GenerateMipmap) ...@@ -601,6 +601,62 @@ TEST_P(StateChangeRenderTest, GenerateMipmap)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Tests that D3D11 dirty bit updates don't forget about BufferSubData attrib updates.
TEST_P(StateChangeTest, VertexBufferUpdatedAfterDraw)
{
const std::string vs =
"attribute vec2 position;\n"
"attribute vec4 color;\n"
"varying vec4 outcolor;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position, 0, 1);\n"
" outcolor = color;\n"
"}";
const std::string fs =
"varying mediump vec4 outcolor;\n"
"void main()\n"
"{\n"
" gl_FragColor = outcolor;\n"
"}";
ANGLE_GL_PROGRAM(program, vs, fs);
glUseProgram(program);
GLint colorLoc = glGetAttribLocation(program, "color");
ASSERT_NE(-1, colorLoc);
GLint positionLoc = glGetAttribLocation(program, "position");
ASSERT_NE(-1, positionLoc);
setupQuadVertexBuffer(0.5f, 1.0f);
glEnableVertexAttribArray(positionLoc);
glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
GLBuffer colorBuf;
glBindBuffer(GL_ARRAY_BUFFER, colorBuf);
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
glEnableVertexAttribArray(colorLoc);
// Fill with green.
std::vector<GLColor> colorData(6, GLColor::green);
glBufferData(GL_ARRAY_BUFFER, colorData.size() * sizeof(GLColor), colorData.data(),
GL_STATIC_DRAW);
// Draw, expect green.
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
ASSERT_GL_NO_ERROR();
// Update buffer with red.
std::fill(colorData.begin(), colorData.end(), GLColor::red);
glBufferSubData(GL_ARRAY_BUFFER, 0, colorData.size() * sizeof(GLColor), colorData.data());
// Draw, expect red.
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
ASSERT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL()); ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
ANGLE_INSTANTIATE_TEST(StateChangeRenderTest, ANGLE_INSTANTIATE_TEST(StateChangeRenderTest,
ES2_D3D9(), ES2_D3D9(),
......
...@@ -428,13 +428,16 @@ void ANGLETestBase::drawQuad(GLuint program, ...@@ -428,13 +428,16 @@ void ANGLETestBase::drawQuad(GLuint program,
glUseProgram(program); glUseProgram(program);
} }
GLint previousBuffer = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &previousBuffer);
GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str()); GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
if (useVertexBuffer) if (useVertexBuffer)
{ {
setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale); setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, previousBuffer);
} }
else else
{ {
...@@ -446,7 +449,15 @@ void ANGLETestBase::drawQuad(GLuint program, ...@@ -446,7 +449,15 @@ void ANGLETestBase::drawQuad(GLuint program,
vertex.z() = positionAttribZ; vertex.z() = positionAttribZ;
} }
if (previousBuffer != 0)
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data()); glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
if (previousBuffer != 0)
{
glBindBuffer(GL_ARRAY_BUFFER, previousBuffer);
}
} }
glEnableVertexAttribArray(positionLocation); glEnableVertexAttribArray(positionLocation);
......
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