Commit 49aacad5 by Luc Ferron Committed by Commit Bot

Vulkan: Support the indices offset in drawElements calls

Also fixes an issue in buffer copy synchronization. Bug: angleproject:2645 Change-Id: Ibca7052daaf1e6fe37913c8a8216ec33c66426b6 Reviewed-on: https://chromium-review.googlesource.com/1096911Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Luc Ferron <lucferron@chromium.org>
parent f6e160fa
......@@ -223,7 +223,7 @@ vk::Error BufferVk::setDataImpl(ContextVk *contextVk,
bufferBarrier.size = static_cast<VkDeviceSize>(size);
commandBuffer->singleBufferBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, bufferBarrier);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, bufferBarrier);
VkBufferCopy copyRegion = {0, offset, size};
commandBuffer->copyBuffer(stagingBuffer.getBuffer(), mBuffer, 1, &copyRegion);
......
......@@ -166,9 +166,10 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
else
{
*shouldApplyVertexArrayOut = mVertexArrayBindingHasChanged;
mVertexArrayBindingHasChanged = false;
}
mVertexArrayBindingHasChanged = false;
// Ensure any writes to the textures are flushed before we read from them.
if (mTexturesDirty)
{
......
......@@ -40,7 +40,8 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend
mLineLoopHelper(renderer),
mDirtyLineLoopTranslation(true),
mVertexBuffersDirty(false),
mIndexBufferDirty(false)
mIndexBufferDirty(false),
mLastIndexBufferOffset(0)
{
mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
mCurrentArrayBufferOffsets.fill(0);
......@@ -493,9 +494,12 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
bool newCommandBuffer)
{
ANGLE_TRY(onDraw(context, renderer, drawCallParams, commandBuffer, newCommandBuffer));
bool isLineLoop = drawCallParams.mode() == gl::PrimitiveMode::LineLoop;
uintptr_t offset = mState.getElementArrayBuffer().get() && !isLineLoop
? reinterpret_cast<uintptr_t>(drawCallParams.indices())
: 0;
if (!mState.getElementArrayBuffer().get() &&
drawCallParams.mode() != gl::PrimitiveMode::LineLoop)
if (!mState.getElementArrayBuffer().get() && !isLineLoop)
{
ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
ANGLE_TRY(streamIndexData(renderer, drawCallParams));
......@@ -503,7 +507,7 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
mCurrentElementArrayBufferOffset,
gl_vk::GetIndexType(drawCallParams.type()));
}
else if (mIndexBufferDirty || newCommandBuffer)
else if (mIndexBufferDirty || newCommandBuffer || offset != mLastIndexBufferOffset)
{
if (drawCallParams.type() == GL_UNSIGNED_BYTE &&
drawCallParams.mode() != gl::PrimitiveMode::LineLoop)
......@@ -515,8 +519,9 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
}
commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
mCurrentElementArrayBufferOffset,
mCurrentElementArrayBufferOffset + offset,
gl_vk::GetIndexType(drawCallParams.type()));
mLastIndexBufferOffset = offset;
const gl::State &glState = context->getGLState();
vk::CommandGraphResource *drawFramebuffer = vk::GetImpl(glState.getDrawFramebuffer());
......
......@@ -128,6 +128,9 @@ class VertexArrayVk : public VertexArrayImpl
// Cache variable for determining whether or not to store new dependencies in the node.
bool mVertexBuffersDirty;
bool mIndexBufferDirty;
// The offset we had the last time we bound the index buffer.
uintptr_t mLastIndexBufferOffset;
};
} // namespace rx
......
......@@ -306,7 +306,7 @@
2444 VULKAN : dEQP-GLES2.functional.draw.draw_arrays.line_strip.default_attribute = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_arrays.line_loop.default_attribute = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.indices.default_attribute = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.indices.buffer.* = SKIP
2659 VULKAN : dEQP-GLES2.functional.draw.draw_elements.indices.buffer.index_byte = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.points.default_attribute = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.triangles.default_attribute = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.triangle_fan.default_attribute = SKIP
......
......@@ -129,9 +129,9 @@ TEST_P(IndexBufferOffsetTest, UInt8Index)
// Test using an offset for an UInt16 index buffer
TEST_P(IndexBufferOffsetTest, UInt16Index)
{
// TODO(lucferron): Diagnose and fix
// http://anglebug.com/2645
ANGLE_SKIP_TEST_IF(IsVulkan());
// TODO(lucferron): Figure out why this is failing only on intel with Vulkan.
// http://anglebug.com/2663
ANGLE_SKIP_TEST_IF(IsIntel() && IsVulkan());
GLushort indexData[] = {0, 1, 2, 1, 2, 3};
runTest(GL_UNSIGNED_SHORT, 2, indexData);
......@@ -147,6 +147,38 @@ TEST_P(IndexBufferOffsetTest, UInt32Index)
runTest(GL_UNSIGNED_INT, 4, indexData);
}
// Uses index buffer offset and 2 drawElement calls one of the other, makes sure the second
// drawElement call will use the correct offset.
TEST_P(IndexBufferOffsetTest, DrawAtDifferentOffsets)
{
GLushort indexData[] = {0, 1, 2, 1, 2, 3};
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
size_t indexDataWidth = 6 * sizeof(GLushort);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexDataWidth, indexData, GL_DYNAMIC_DRAW);
glUseProgram(mProgram);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glVertexAttribPointer(mPositionAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(mPositionAttributeLocation);
glUniform4f(mColorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT,
reinterpret_cast<void *>(indexDataWidth / 2));
// Check the upper left triangle
EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() / 4, GLColor::red);
// Check the down right triangle
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
EXPECT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(IndexBufferOffsetTest,
ES2_D3D9(),
ES2_D3D11(),
......
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