Commit 6ed167a9 by Luc Ferron Committed by Commit Bot

Vulkan: Implement conversion to uint16 for drawElements with ubytes

Bug: angleproject:2646 Bug: angleproject:2659 Change-Id: If3c7a2b77d6acd18c8ca2522a427a43e10ed6db2 Reviewed-on: https://chromium-review.googlesource.com/1099420 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c252d757
...@@ -125,6 +125,11 @@ gl::Error BufferVk::map(const gl::Context *context, GLenum access, void **mapPtr ...@@ -125,6 +125,11 @@ gl::Error BufferVk::map(const gl::Context *context, GLenum access, void **mapPtr
return gl::NoError(); return gl::NoError();
} }
GLint64 BufferVk::getSize()
{
return mState.getSize();
}
gl::Error BufferVk::mapRange(const gl::Context *context, gl::Error BufferVk::mapRange(const gl::Context *context,
size_t offset, size_t offset,
size_t length, size_t length,
......
...@@ -54,6 +54,7 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource ...@@ -54,6 +54,7 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource
size_t count, size_t count,
bool primitiveRestartEnabled, bool primitiveRestartEnabled,
gl::IndexRange *outRange) override; gl::IndexRange *outRange) override;
GLint64 getSize();
const vk::Buffer &getVkBuffer() const; const vk::Buffer &getVkBuffer() const;
......
...@@ -165,11 +165,10 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, ...@@ -165,11 +165,10 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
} }
else else
{ {
*shouldApplyVertexArrayOut = mVertexArrayBindingHasChanged; *shouldApplyVertexArrayOut = mVertexArrayBindingHasChanged;
mVertexArrayBindingHasChanged = false;
} }
mVertexArrayBindingHasChanged = false;
// Ensure any writes to the textures are flushed before we read from them. // Ensure any writes to the textures are flushed before we read from them.
if (mTexturesDirty) if (mTexturesDirty)
{ {
......
...@@ -37,6 +37,7 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend ...@@ -37,6 +37,7 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend
mCurrentElementArrayBufferResource(nullptr), mCurrentElementArrayBufferResource(nullptr),
mDynamicVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kDynamicVertexDataSize), mDynamicVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kDynamicVertexDataSize),
mDynamicIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize), mDynamicIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize),
mTranslatedByteIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize),
mLineLoopHelper(renderer), mLineLoopHelper(renderer),
mDirtyLineLoopTranslation(true), mDirtyLineLoopTranslation(true),
mVertexBuffersDirty(false), mVertexBuffersDirty(false),
...@@ -52,6 +53,7 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend ...@@ -52,6 +53,7 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend
mDynamicVertexData.init(1, renderer); mDynamicVertexData.init(1, renderer);
mDynamicIndexData.init(1, renderer); mDynamicIndexData.init(1, renderer);
mTranslatedByteIndexData.init(1, renderer);
} }
VertexArrayVk::~VertexArrayVk() VertexArrayVk::~VertexArrayVk()
...@@ -63,6 +65,7 @@ void VertexArrayVk::destroy(const gl::Context *context) ...@@ -63,6 +65,7 @@ void VertexArrayVk::destroy(const gl::Context *context)
VkDevice device = vk::GetImpl(context)->getRenderer()->getDevice(); VkDevice device = vk::GetImpl(context)->getRenderer()->getDevice();
mDynamicVertexData.destroy(device); mDynamicVertexData.destroy(device);
mDynamicIndexData.destroy(device); mDynamicIndexData.destroy(device);
mTranslatedByteIndexData.destroy(device);
mLineLoopHelper.destroy(device); mLineLoopHelper.destroy(device);
} }
...@@ -495,11 +498,11 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context, ...@@ -495,11 +498,11 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
{ {
ANGLE_TRY(onDraw(context, renderer, drawCallParams, commandBuffer, newCommandBuffer)); ANGLE_TRY(onDraw(context, renderer, drawCallParams, commandBuffer, newCommandBuffer));
bool isLineLoop = drawCallParams.mode() == gl::PrimitiveMode::LineLoop; bool isLineLoop = drawCallParams.mode() == gl::PrimitiveMode::LineLoop;
uintptr_t offset = mState.getElementArrayBuffer().get() && !isLineLoop gl::Buffer *glBuffer = mState.getElementArrayBuffer().get();
? reinterpret_cast<uintptr_t>(drawCallParams.indices()) uintptr_t offset =
: 0; glBuffer && !isLineLoop ? reinterpret_cast<uintptr_t>(drawCallParams.indices()) : 0;
if (!mState.getElementArrayBuffer().get() && !isLineLoop) if (!glBuffer && !isLineLoop)
{ {
ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context)); ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
ANGLE_TRY(streamIndexData(renderer, drawCallParams)); ANGLE_TRY(streamIndexData(renderer, drawCallParams));
...@@ -512,15 +515,52 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context, ...@@ -512,15 +515,52 @@ gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
if (drawCallParams.type() == GL_UNSIGNED_BYTE && if (drawCallParams.type() == GL_UNSIGNED_BYTE &&
drawCallParams.mode() != gl::PrimitiveMode::LineLoop) drawCallParams.mode() != gl::PrimitiveMode::LineLoop)
{ {
// TODO(fjhenigman): Index format translation for non line-loop calls. // Unsigned bytes don't have direct support in Vulkan so we have to expand the
UNIMPLEMENTED(); // memory to a GLushort.
return gl::InternalError() BufferVk *bufferVk = vk::GetImpl(glBuffer);
<< "Unsigned byte translation is not implemented for indices in a buffer object"; void *srcDataMapping = nullptr;
ASSERT(!glBuffer->isMapped());
ANGLE_TRY(bufferVk->map(context, 0, &srcDataMapping));
uint8_t *srcData = reinterpret_cast<uint8_t *>(srcDataMapping);
intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(drawCallParams.indices());
srcData += offsetIntoSrcData;
// Allocate a new buffer that's double the size of the buffer provided by the user to
// go from unsigned byte to unsigned short.
uint8_t *allocatedData = nullptr;
bool newBufferAllocated = false;
uint32_t expandedDataOffset = 0;
mTranslatedByteIndexData.allocate(
renderer, static_cast<size_t>(bufferVk->getSize()) * 2, &allocatedData,
&mCurrentElementArrayBufferHandle, &expandedDataOffset, &newBufferAllocated);
mCurrentElementArrayBufferOffset = static_cast<VkDeviceSize>(expandedDataOffset);
// Expand the source into the destination
ASSERT(!context->getGLState().isPrimitiveRestartEnabled());
uint16_t *expandedDst = reinterpret_cast<uint16_t *>(allocatedData);
for (GLsizei index = 0; index < bufferVk->getSize() - offsetIntoSrcData; index++)
{
expandedDst[index] = static_cast<GLushort>(srcData[index]);
}
// Make sure our writes are available.
mTranslatedByteIndexData.flush(renderer->getDevice());
GLboolean result = false;
ANGLE_TRY(bufferVk->unmap(context, &result));
// We do not add the offset from the drawCallParams here because we've already copied
// the source starting at the offset requested.
commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
mCurrentElementArrayBufferOffset,
gl_vk::GetIndexType(drawCallParams.type()));
}
else
{
commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
mCurrentElementArrayBufferOffset + offset,
gl_vk::GetIndexType(drawCallParams.type()));
} }
commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
mCurrentElementArrayBufferOffset + offset,
gl_vk::GetIndexType(drawCallParams.type()));
mLastIndexBufferOffset = offset; mLastIndexBufferOffset = offset;
const gl::State &glState = context->getGLState(); const gl::State &glState = context->getGLState();
......
...@@ -119,6 +119,7 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -119,6 +119,7 @@ class VertexArrayVk : public VertexArrayImpl
vk::DynamicBuffer mDynamicVertexData; vk::DynamicBuffer mDynamicVertexData;
vk::DynamicBuffer mDynamicIndexData; vk::DynamicBuffer mDynamicIndexData;
vk::DynamicBuffer mTranslatedByteIndexData;
vk::LineLoopHelper mLineLoopHelper; vk::LineLoopHelper mLineLoopHelper;
Optional<GLint> mLineLoopBufferFirstIndex; Optional<GLint> mLineLoopBufferFirstIndex;
......
...@@ -305,7 +305,6 @@ ...@@ -305,7 +305,6 @@
2444 VULKAN : dEQP-GLES2.functional.draw.draw_arrays.line_strip.default_attribute = SKIP 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_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.default_attribute = 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.points.default_attribute = SKIP
2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.triangles.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 2444 VULKAN : dEQP-GLES2.functional.draw.draw_elements.triangle_fan.default_attribute = SKIP
......
...@@ -179,6 +179,38 @@ TEST_P(IndexBufferOffsetTest, DrawAtDifferentOffsets) ...@@ -179,6 +179,38 @@ TEST_P(IndexBufferOffsetTest, DrawAtDifferentOffsets)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Uses index buffer offset and 2 drawElement calls one of the other with different counts,
// makes sure the second drawElement call will have its data available.
TEST_P(IndexBufferOffsetTest, DrawWithDifferentCountsSameOffset)
{
GLubyte indexData[] = {99, 0, 1, 2, 1, 2, 3};
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
size_t indexDataWidth = 7 * sizeof(GLubyte);
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);
// The first draw draws the first triangle, and the second draws a quad.
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(1));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(1));
// 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, ANGLE_INSTANTIATE_TEST(IndexBufferOffsetTest,
ES2_D3D9(), ES2_D3D9(),
ES2_D3D11(), ES2_D3D11(),
......
...@@ -375,7 +375,7 @@ TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset3) ...@@ -375,7 +375,7 @@ TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset3)
runTest(3, false); runTest(3, false);
} }
// TODO(lucferron): Diagnose and fix the UByte and UShort tests below for Vulkan. // TODO(lucferron): Diagnose and fix the UByte tests below for Vulkan.
// http://anglebug.com/2646 // http://anglebug.com/2646
// TODO(geofflang): Figure out why this test fails on Intel OpenGL // TODO(geofflang): Figure out why this test fails on Intel OpenGL
...@@ -383,12 +383,14 @@ ANGLE_INSTANTIATE_TEST(IndexedPointsTestUByte, ...@@ -383,12 +383,14 @@ ANGLE_INSTANTIATE_TEST(IndexedPointsTestUByte,
ES2_D3D11(), ES2_D3D11(),
ES2_D3D11_FL9_3(), ES2_D3D11_FL9_3(),
ES2_OPENGL(), ES2_OPENGL(),
ES2_OPENGLES()); ES2_OPENGLES(),
ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(IndexedPointsTestUShort, ANGLE_INSTANTIATE_TEST(IndexedPointsTestUShort,
ES2_D3D11(), ES2_D3D11(),
ES2_D3D11_FL9_3(), ES2_D3D11_FL9_3(),
ES2_OPENGL(), ES2_OPENGL(),
ES2_OPENGLES()); ES2_OPENGLES(),
ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(IndexedPointsTestUInt, ANGLE_INSTANTIATE_TEST(IndexedPointsTestUInt,
ES2_D3D11(), ES2_D3D11(),
ES2_D3D11_FL9_3(), ES2_D3D11_FL9_3(),
......
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