Commit c373dfd8 by Mohan Maiya Committed by Commit Bot

Vulkan : Handle dirty state correctly when there are muiltiple VAOs

If vertex array object binding is changed, we need to update the pipeline cache with the attribute information of the newly bound VAO. We cache the strides of attributes because emulated attributes will have strides that don't match the stride info cached in its binding struct. Also added a test case that switches between multiple VAOs. Bug: angleproject:4127 Test: angle_end2end_tests.exe --gtest_filter=SimpleStateChangeTestES31.MultipleVertexArrayObjectRendering Change-Id: I4f23aec33d5aa5988baa41f3c63db5534daf75ca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1917453Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Commit-Queue: Tobin Ehlis <tobine@google.com>
parent 88752889
...@@ -2333,6 +2333,7 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -2333,6 +2333,7 @@ angle::Result ContextVk::syncState(const gl::Context *context,
{ {
mVertexArray = vk::GetImpl(glState.getVertexArray()); mVertexArray = vk::GetImpl(glState.getVertexArray());
invalidateDefaultAttributes(context->getStateCache().getActiveDefaultAttribsMask()); invalidateDefaultAttributes(context->getStateCache().getActiveDefaultAttribsMask());
mVertexArray->updateActiveAttribInfo(this);
break; break;
} }
case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING: case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
......
...@@ -539,6 +539,23 @@ ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, siz ...@@ -539,6 +539,23 @@ ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, siz
contextVk->onVertexAttributeChange(attribIndex, 0, 0, format, 0); contextVk->onVertexAttributeChange(attribIndex, 0, 0, format, 0);
} }
void VertexArrayVk::updateActiveAttribInfo(ContextVk *contextVk)
{
const std::vector<gl::VertexAttribute> &attribs = mState.getVertexAttributes();
const std::vector<gl::VertexBinding> &bindings = mState.getVertexBindings();
// Update pipeline cache with current active attribute info
for (size_t attribIndex : mState.getEnabledAttributesMask())
{
const gl::VertexAttribute &attrib = attribs[attribIndex];
const gl::VertexBinding &binding = bindings[attribs[attribIndex].bindingIndex];
contextVk->onVertexAttributeChange(attribIndex, mCurrentArrayBufferStrides[attribIndex],
binding.getDivisor(), attrib.format->id,
attrib.relativeOffset);
}
}
angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib, const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
...@@ -638,6 +655,8 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -638,6 +655,8 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
{ {
contextVk->onVertexAttributeChange(attribIndex, stride, binding.getDivisor(), contextVk->onVertexAttributeChange(attribIndex, stride, binding.getDivisor(),
attrib.format->id, attrib.relativeOffset); attrib.format->id, attrib.relativeOffset);
// Cache the stride of the attribute
mCurrentArrayBufferStrides[attribIndex] = stride;
} }
if (anyVertexBufferConvertedOnGpu && if (anyVertexBufferConvertedOnGpu &&
...@@ -654,6 +673,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -654,6 +673,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBuffers[attribIndex] = &mTheNullBuffer; mCurrentArrayBuffers[attribIndex] = &mTheNullBuffer;
mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle(); mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = 0; mCurrentArrayBufferOffsets[attribIndex] = 0;
mCurrentArrayBufferStrides[attribIndex] = 0;
setDefaultPackedInput(contextVk, attribIndex); setDefaultPackedInput(contextVk, attribIndex);
} }
......
...@@ -32,6 +32,8 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -32,6 +32,8 @@ class VertexArrayVk : public VertexArrayImpl
gl::VertexArray::DirtyAttribBitsArray *attribBits, gl::VertexArray::DirtyAttribBitsArray *attribBits,
gl::VertexArray::DirtyBindingBitsArray *bindingBits) override; gl::VertexArray::DirtyBindingBitsArray *bindingBits) override;
void updateActiveAttribInfo(ContextVk *contextVk);
void updateDefaultAttrib(ContextVk *contextVk, void updateDefaultAttrib(ContextVk *contextVk,
size_t attribIndex, size_t attribIndex,
VkBuffer bufferHandle, VkBuffer bufferHandle,
...@@ -139,6 +141,8 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -139,6 +141,8 @@ class VertexArrayVk : public VertexArrayImpl
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles; gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets; gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
gl::AttribArray<vk::BufferHelper *> mCurrentArrayBuffers; gl::AttribArray<vk::BufferHelper *> mCurrentArrayBuffers;
// Cache strides of attributes for a fast pipeline cache update when VAOs are changed
gl::AttribArray<GLuint> mCurrentArrayBufferStrides;
VkDeviceSize mCurrentElementArrayBufferOffset; VkDeviceSize mCurrentElementArrayBufferOffset;
vk::BufferHelper *mCurrentElementArrayBuffer; vk::BufferHelper *mCurrentElementArrayBuffer;
......
...@@ -1364,6 +1364,9 @@ class SimpleStateChangeTestES3 : public SimpleStateChangeTest ...@@ -1364,6 +1364,9 @@ class SimpleStateChangeTestES3 : public SimpleStateChangeTest
{}; {};
class SimpleStateChangeTestES31 : public SimpleStateChangeTest class SimpleStateChangeTestES31 : public SimpleStateChangeTest
{};
class SimpleStateChangeTestComputeES31 : public SimpleStateChangeTest
{ {
protected: protected:
void testSetUp() override void testSetUp() override
...@@ -3067,8 +3070,97 @@ void main() ...@@ -3067,8 +3070,97 @@ void main()
EXPECT_EQ(s0LinearColors, s1LinearColors); EXPECT_EQ(s0LinearColors, s1LinearColors);
} }
// Tests that rendering works as expected with multiple VAOs.
TEST_P(SimpleStateChangeTestES31, MultipleVertexArrayObjectRendering)
{
constexpr char kVertexShader[] = R"(attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
void main()
{
gl_Position = a_position;
v_color = a_color;
})";
constexpr char kFragmentShader[] = R"(precision mediump float;
varying vec4 v_color;
void main()
{
gl_FragColor = v_color;
})";
ANGLE_GL_PROGRAM(mProgram, kVertexShader, kFragmentShader);
GLint positionLoc = glGetAttribLocation(mProgram, "a_position");
ASSERT_NE(-1, positionLoc);
GLint colorLoc = glGetAttribLocation(mProgram, "a_color");
ASSERT_NE(-1, colorLoc);
GLVertexArray VAOS[2];
GLBuffer positionBuffer;
GLBuffer colorBuffer;
const auto quadVertices = GetQuadVertices();
glBindVertexArray(VAOS[0]);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(positionLoc);
glVertexAttribPointer(positionLoc, 3, GL_BYTE, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
std::vector<GLColor32F> blueColor(6, kFloatBlue);
glBufferData(GL_ARRAY_BUFFER, blueColor.size() * sizeof(GLColor32F), blueColor.data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(colorLoc);
glVertexAttribPointer(colorLoc, 4, GL_BYTE, GL_FALSE, 0, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAOS[1]);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(positionLoc);
glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
std::vector<GLColor32F> greenColor(6, kFloatGreen);
glBufferData(GL_ARRAY_BUFFER, greenColor.size() * sizeof(GLColor32F), greenColor.data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(colorLoc);
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(mProgram);
ASSERT_GL_NO_ERROR();
glBindVertexArray(VAOS[1]);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
// This drawing should not affect the next drawing.
glBindVertexArray(VAOS[0]);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(VAOS[1]);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() / 2, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::green);
ASSERT_GL_NO_ERROR();
}
// Tests that deleting an in-flight image texture does not immediately delete the resource. // Tests that deleting an in-flight image texture does not immediately delete the resource.
TEST_P(SimpleStateChangeTestES31, DeleteImageTextureInUse) TEST_P(SimpleStateChangeTestComputeES31, DeleteImageTextureInUse)
{ {
std::array<GLColor, 4> colors = { std::array<GLColor, 4> colors = {
{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}}; {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
...@@ -3095,7 +3187,7 @@ TEST_P(SimpleStateChangeTestES31, DeleteImageTextureInUse) ...@@ -3095,7 +3187,7 @@ TEST_P(SimpleStateChangeTestES31, DeleteImageTextureInUse)
} }
// Tests that bind the same image texture all the time between different dispatch calls. // Tests that bind the same image texture all the time between different dispatch calls.
TEST_P(SimpleStateChangeTestES31, RebindImageTextureDispatchAgain) TEST_P(SimpleStateChangeTestComputeES31, RebindImageTextureDispatchAgain)
{ {
std::array<GLColor, 4> colors = {{GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}}; std::array<GLColor, 4> colors = {{GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}};
GLTexture texRead; GLTexture texRead;
...@@ -3118,7 +3210,7 @@ TEST_P(SimpleStateChangeTestES31, RebindImageTextureDispatchAgain) ...@@ -3118,7 +3210,7 @@ TEST_P(SimpleStateChangeTestES31, RebindImageTextureDispatchAgain)
// Tests that we can dispatch with an image texture, modify the image texture with a texSubImage, // Tests that we can dispatch with an image texture, modify the image texture with a texSubImage,
// and then dispatch again correctly. // and then dispatch again correctly.
TEST_P(SimpleStateChangeTestES31, DispatchWithImageTextureTexSubImageThenDispatchAgain) TEST_P(SimpleStateChangeTestComputeES31, DispatchWithImageTextureTexSubImageThenDispatchAgain)
{ {
std::array<GLColor, 4> colors = {{GLColor::red, GLColor::red, GLColor::red, GLColor::red}}; std::array<GLColor, 4> colors = {{GLColor::red, GLColor::red, GLColor::red, GLColor::red}};
std::array<GLColor, 4> subColors = { std::array<GLColor, 4> subColors = {
...@@ -3155,7 +3247,7 @@ TEST_P(SimpleStateChangeTestES31, DispatchWithImageTextureTexSubImageThenDispatc ...@@ -3155,7 +3247,7 @@ TEST_P(SimpleStateChangeTestES31, DispatchWithImageTextureTexSubImageThenDispatc
} }
// Test updating an image texture's contents while in use by GL works as expected. // Test updating an image texture's contents while in use by GL works as expected.
TEST_P(SimpleStateChangeTestES31, UpdateImageTextureInUse) TEST_P(SimpleStateChangeTestComputeES31, UpdateImageTextureInUse)
{ {
std::array<GLColor, 4> rgby = {{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}}; std::array<GLColor, 4> rgby = {{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
...@@ -3191,7 +3283,7 @@ TEST_P(SimpleStateChangeTestES31, UpdateImageTextureInUse) ...@@ -3191,7 +3283,7 @@ TEST_P(SimpleStateChangeTestES31, UpdateImageTextureInUse)
} }
// Test that we can alternate between image textures between different dispatchs. // Test that we can alternate between image textures between different dispatchs.
TEST_P(SimpleStateChangeTestES31, DispatchImageTextureAThenTextureBThenTextureA) TEST_P(SimpleStateChangeTestComputeES31, DispatchImageTextureAThenTextureBThenTextureA)
{ {
std::array<GLColor, 4> colorsTexA = { std::array<GLColor, 4> colorsTexA = {
{GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}}; {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}};
...@@ -4397,6 +4489,7 @@ ANGLE_INSTANTIATE_TEST_ES3(StateChangeTestES3); ...@@ -4397,6 +4489,7 @@ ANGLE_INSTANTIATE_TEST_ES3(StateChangeTestES3);
ANGLE_INSTANTIATE_TEST_ES2(SimpleStateChangeTest); ANGLE_INSTANTIATE_TEST_ES2(SimpleStateChangeTest);
ANGLE_INSTANTIATE_TEST_ES3(SimpleStateChangeTestES3); ANGLE_INSTANTIATE_TEST_ES3(SimpleStateChangeTestES3);
ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestES31); ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestES31);
ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31);
ANGLE_INSTANTIATE_TEST_ES3(ValidationStateChangeTest); ANGLE_INSTANTIATE_TEST_ES3(ValidationStateChangeTest);
ANGLE_INSTANTIATE_TEST_ES3(WebGL2ValidationStateChangeTest); ANGLE_INSTANTIATE_TEST_ES3(WebGL2ValidationStateChangeTest);
ANGLE_INSTANTIATE_TEST_ES31(ValidationStateChangeTestES31); ANGLE_INSTANTIATE_TEST_ES31(ValidationStateChangeTestES31);
......
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