Commit 98f21671 by Jamie Madill Committed by Commit Bot

Vulkan: Refactor index buffer convert functions.

This is a prepratory refactor for converting index buffers on the GPU using a more generic compute shader. No functional change. Bug: angleproject:3490 Change-Id: Iadf4b1429314db6850320aee33c4113f38577378 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1639057Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent c104b2d2
...@@ -330,9 +330,9 @@ angle::Result UtilsVk::ensureBufferClearResourcesInitialized(ContextVk *context) ...@@ -330,9 +330,9 @@ angle::Result UtilsVk::ensureBufferClearResourcesInitialized(ContextVk *context)
sizeof(BufferUtilsShaderParams)); sizeof(BufferUtilsShaderParams));
} }
angle::Result UtilsVk::ensureBufferCopyResourcesInitialized(ContextVk *context) angle::Result UtilsVk::ensureConvertIndexResourcesInitialized(ContextVk *context)
{ {
if (mPipelineLayouts[Function::BufferCopy].valid()) if (mPipelineLayouts[Function::ConvertIndexBuffer].valid())
{ {
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -342,8 +342,8 @@ angle::Result UtilsVk::ensureBufferCopyResourcesInitialized(ContextVk *context) ...@@ -342,8 +342,8 @@ angle::Result UtilsVk::ensureBufferCopyResourcesInitialized(ContextVk *context)
{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1},
}; };
return ensureResourcesInitialized(context, Function::BufferCopy, setSizes, ArraySize(setSizes), return ensureResourcesInitialized(context, Function::ConvertIndexBuffer, setSizes,
sizeof(BufferUtilsShaderParams)); ArraySize(setSizes), sizeof(BufferUtilsShaderParams));
} }
angle::Result UtilsVk::ensureConvertVertexResourcesInitialized(ContextVk *context) angle::Result UtilsVk::ensureConvertVertexResourcesInitialized(ContextVk *context)
...@@ -542,12 +542,12 @@ angle::Result UtilsVk::clearBuffer(ContextVk *context, ...@@ -542,12 +542,12 @@ angle::Result UtilsVk::clearBuffer(ContextVk *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result UtilsVk::copyBuffer(ContextVk *context, angle::Result UtilsVk::convertIndexBuffer(ContextVk *context,
vk::BufferHelper *dest, vk::BufferHelper *dest,
vk::BufferHelper *src, vk::BufferHelper *src,
const CopyParameters &params) const ConvertIndexParameters &params)
{ {
ANGLE_TRY(ensureBufferCopyResourcesInitialized(context)); ANGLE_TRY(ensureConvertIndexResourcesInitialized(context));
vk::CommandBuffer *commandBuffer; vk::CommandBuffer *commandBuffer;
ANGLE_TRY(dest->recordCommands(context, &commandBuffer)); ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
...@@ -572,8 +572,8 @@ angle::Result UtilsVk::copyBuffer(ContextVk *context, ...@@ -572,8 +572,8 @@ angle::Result UtilsVk::copyBuffer(ContextVk *context,
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding; vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
ANGLE_TRY(mDescriptorPools[Function::BufferCopy].allocateSets( ANGLE_TRY(mDescriptorPools[Function::ConvertIndexBuffer].allocateSets(
context, mDescriptorSetLayouts[Function::BufferCopy][kSetIndex].get().ptr(), 1, context, mDescriptorSetLayouts[Function::ConvertIndexBuffer][kSetIndex].get().ptr(), 1,
&descriptorPoolBinding, &descriptorSet)); &descriptorPoolBinding, &descriptorSet));
descriptorPoolBinding.get().updateSerial(context->getCurrentQueueSerial()); descriptorPoolBinding.get().updateSerial(context->getCurrentQueueSerial());
...@@ -598,7 +598,7 @@ angle::Result UtilsVk::copyBuffer(ContextVk *context, ...@@ -598,7 +598,7 @@ angle::Result UtilsVk::copyBuffer(ContextVk *context,
vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr; vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
ANGLE_TRY(context->getShaderLibrary().getBufferUtils_comp(context, flags, &shader)); ANGLE_TRY(context->getShaderLibrary().getBufferUtils_comp(context, flags, &shader));
ANGLE_TRY(setupProgram(context, Function::BufferCopy, shader, nullptr, ANGLE_TRY(setupProgram(context, Function::ConvertIndexBuffer, shader, nullptr,
&mBufferUtilsPrograms[flags], nullptr, descriptorSet, &shaderParams, &mBufferUtilsPrograms[flags], nullptr, descriptorSet, &shaderParams,
sizeof(shaderParams), commandBuffer)); sizeof(shaderParams), commandBuffer));
......
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
// buffer clear and copy, image clear and copy, texture mip map generation, etc. // buffer clear and copy, image clear and copy, texture mip map generation, etc.
// //
// - Buffer clear: Implemented, but no current users // - Buffer clear: Implemented, but no current users
// - Buffer copy: // - Convert index buffer:
// * Used by VertexArrayVk::updateIndexTranslation() to convert a ubyte index array to ushort // * Used by VertexArrayVk::convertIndexBufferGPU() to convert a ubyte element array to ushort
// - Convert vertex attribute: // - Convert vertex buffer:
// * Used by VertexArrayVk::convertVertexBuffer() to convert vertex attributes from unsupported // * Used by VertexArrayVk::convertVertexBufferGPU() to convert vertex attributes from
// formats to their fallbacks. // unsupported formats to their fallbacks.
// - Image clear: Used by FramebufferVk::clearWithDraw(). // - Image clear: Used by FramebufferVk::clearWithDraw().
// - Image copy: Used by TextureVk::copySubImageImplWithDraw(). // - Image copy: Used by TextureVk::copySubImageImplWithDraw().
// - Color resolve: Used by FramebufferVk::resolve() to implement multisample resolve on color // - Color resolve: Used by FramebufferVk::resolve() to implement multisample resolve on color
...@@ -46,7 +46,7 @@ class UtilsVk : angle::NonCopyable ...@@ -46,7 +46,7 @@ class UtilsVk : angle::NonCopyable
size_t size; size_t size;
}; };
struct CopyParameters struct ConvertIndexParameters
{ {
size_t destOffset; size_t destOffset;
size_t srcOffset; size_t srcOffset;
...@@ -115,10 +115,10 @@ class UtilsVk : angle::NonCopyable ...@@ -115,10 +115,10 @@ class UtilsVk : angle::NonCopyable
angle::Result clearBuffer(ContextVk *context, angle::Result clearBuffer(ContextVk *context,
vk::BufferHelper *dest, vk::BufferHelper *dest,
const ClearParameters &params); const ClearParameters &params);
angle::Result copyBuffer(ContextVk *context, angle::Result convertIndexBuffer(ContextVk *context,
vk::BufferHelper *dest, vk::BufferHelper *dest,
vk::BufferHelper *src, vk::BufferHelper *src,
const CopyParameters &params); const ConvertIndexParameters &params);
angle::Result convertVertexBuffer(ContextVk *context, angle::Result convertVertexBuffer(ContextVk *context,
vk::BufferHelper *dest, vk::BufferHelper *dest,
vk::BufferHelper *src, vk::BufferHelper *src,
...@@ -241,7 +241,7 @@ class UtilsVk : angle::NonCopyable ...@@ -241,7 +241,7 @@ class UtilsVk : angle::NonCopyable
// Functions implemented in compute // Functions implemented in compute
ComputeStartIndex = 3, // Special value to separate draw and dispatch functions. ComputeStartIndex = 3, // Special value to separate draw and dispatch functions.
BufferClear = 3, BufferClear = 3,
BufferCopy = 4, ConvertIndexBuffer = 4,
ConvertVertexBuffer = 5, ConvertVertexBuffer = 5,
ResolveStencilNoExport = 6, ResolveStencilNoExport = 6,
...@@ -279,7 +279,7 @@ class UtilsVk : angle::NonCopyable ...@@ -279,7 +279,7 @@ class UtilsVk : angle::NonCopyable
// Initializers corresponding to functions, calling into ensureResourcesInitialized with the // Initializers corresponding to functions, calling into ensureResourcesInitialized with the
// appropriate parameters. // appropriate parameters.
angle::Result ensureBufferClearResourcesInitialized(ContextVk *context); angle::Result ensureBufferClearResourcesInitialized(ContextVk *context);
angle::Result ensureBufferCopyResourcesInitialized(ContextVk *context); angle::Result ensureConvertIndexResourcesInitialized(ContextVk *context);
angle::Result ensureConvertVertexResourcesInitialized(ContextVk *context); angle::Result ensureConvertVertexResourcesInitialized(ContextVk *context);
angle::Result ensureImageClearResourcesInitialized(ContextVk *context); angle::Result ensureImageClearResourcesInitialized(ContextVk *context);
angle::Result ensureImageCopyResourcesInitialized(ContextVk *context); angle::Result ensureImageCopyResourcesInitialized(ContextVk *context);
......
...@@ -167,11 +167,46 @@ void VertexArrayVk::destroy(const gl::Context *context) ...@@ -167,11 +167,46 @@ void VertexArrayVk::destroy(const gl::Context *context)
mLineLoopHelper.release(contextVk); mLineLoopHelper.release(contextVk);
} }
angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk, angle::Result VertexArrayVk::convertIndexBufferGPU(ContextVk *contextVk,
gl::DrawElementsType indexType, BufferVk *bufferVk,
size_t indexCount, const void *indices)
const void *sourcePointer, {
vk::DynamicBuffer *dynamicBuffer) RendererVk *renderer = contextVk->getRenderer();
intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
mTranslatedByteIndexData.releaseRetainedBuffers(contextVk);
ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize, nullptr,
nullptr, &mCurrentElementArrayBufferOffset,
nullptr));
mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
vk::BufferHelper *src = &bufferVk->getBuffer();
ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
// Copy relevant section of the source into destination at allocated offset. Note that the
// offset returned by allocate() above is in bytes, while our allocated array is of
// GLushorts.
UtilsVk::ConvertIndexParameters params = {};
params.destOffset = static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
params.srcOffset = offsetIntoSrcData;
params.size = srcDataSize;
// Note: Once support for primitive restart is added, a specialized shader is needed to
// convert 0xFF -> 0xFFFF. http://anglebug.com/3215
return contextVk->getUtils().convertIndexBuffer(contextVk, dest, src, params);
}
angle::Result VertexArrayVk::convertIndexBufferCPU(ContextVk *contextVk,
gl::DrawElementsType indexType,
size_t indexCount,
const void *sourcePointer,
vk::DynamicBuffer *dynamicBuffer)
{ {
ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte); ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
...@@ -206,7 +241,7 @@ angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk, ...@@ -206,7 +241,7 @@ angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong // and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
// but the alternative of copying it piecemeal on each draw would have a lot more // but the alternative of copying it piecemeal on each draw would have a lot more
// overhead. // overhead.
angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk, angle::Result VertexArrayVk::convertVertexBufferGPU(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
...@@ -254,7 +289,7 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk, ...@@ -254,7 +289,7 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk, angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
...@@ -443,13 +478,13 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -443,13 +478,13 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
if (bindingIsAligned) if (bindingIsAligned)
{ {
ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex, ANGLE_TRY(convertVertexBufferGPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat)); vertexFormat));
anyVertexBufferConvertedOnGpu = true; anyVertexBufferConvertedOnGpu = true;
} }
else else
{ {
ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex, ANGLE_TRY(convertVertexBufferCPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat)); vertexFormat));
} }
} }
...@@ -648,43 +683,15 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk, ...@@ -648,43 +683,15 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
if (!glBuffer) if (!glBuffer)
{ {
ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData)); return convertIndexBufferCPU(contextVk, type, indexCount, indices, &mDynamicIndexData);
} }
else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
{
BufferVk *bufferVk = vk::GetImpl(glBuffer);
ASSERT(type == gl::DrawElementsType::UnsignedByte); BufferVk *bufferVk = vk::GetImpl(glBuffer);
intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices); if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData; {
ASSERT(type == gl::DrawElementsType::UnsignedByte);
mTranslatedByteIndexData.releaseRetainedBuffers(contextVk); ANGLE_TRY(convertIndexBufferGPU(contextVk, bufferVk, indices));
ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
nullptr, nullptr,
&mCurrentElementArrayBufferOffset, nullptr));
mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
vk::BufferHelper *src = &bufferVk->getBuffer();
ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
// Copy relevant section of the source into destination at allocated offset. Note that the
// offset returned by allocate() above is in bytes, while our allocated array is of
// GLushorts.
UtilsVk::CopyParameters params = {};
params.destOffset =
static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
params.srcOffset = offsetIntoSrcData;
params.size = srcDataSize;
// Note: this is a copy, which implicitly converts between formats. Once support for
// primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
// 0xFFFF.
ANGLE_TRY(contextVk->getUtils().copyBuffer(contextVk, dest, src, params));
} }
else else
{ {
...@@ -702,7 +709,6 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk, ...@@ -702,7 +709,6 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
ASSERT(type == gl::DrawElementsType::UnsignedByte); ASSERT(type == gl::DrawElementsType::UnsignedByte);
// Unsigned bytes don't have direct support in Vulkan so we have to expand the // Unsigned bytes don't have direct support in Vulkan so we have to expand the
// memory to a GLushort. // memory to a GLushort.
BufferVk *bufferVk = vk::GetImpl(glBuffer);
void *srcDataMapping = nullptr; void *srcDataMapping = nullptr;
ASSERT(!glBuffer->isMapped()); ASSERT(!glBuffer->isMapped());
ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping)); ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
...@@ -710,9 +716,9 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk, ...@@ -710,9 +716,9 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices); intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
srcData += offsetIntoSrcData; srcData += offsetIntoSrcData;
ANGLE_TRY(streamIndexData(contextVk, type, ANGLE_TRY(convertIndexBufferCPU(
static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData, contextVk, type, static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData, srcData,
srcData, &mTranslatedByteIndexData)); &mTranslatedByteIndexData));
ANGLE_TRY(bufferVk->unmapImpl(contextVk)); ANGLE_TRY(bufferVk->unmapImpl(contextVk));
} }
......
...@@ -84,17 +84,21 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -84,17 +84,21 @@ class VertexArrayVk : public VertexArrayImpl
private: private:
void setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex); void setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex);
angle::Result streamIndexData(ContextVk *contextVk, angle::Result convertIndexBufferGPU(ContextVk *contextVk,
gl::DrawElementsType indexType, BufferVk *bufferVk,
size_t indexCount, const void *indices);
const void *sourcePointer,
vk::DynamicBuffer *dynamicBuffer); angle::Result convertIndexBufferCPU(ContextVk *contextVk,
angle::Result convertVertexBufferGpu(ContextVk *contextVk, gl::DrawElementsType indexType,
size_t indexCount,
const void *sourcePointer,
vk::DynamicBuffer *dynamicBuffer);
angle::Result convertVertexBufferGPU(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
const vk::Format &vertexFormat); const vk::Format &vertexFormat);
angle::Result convertVertexBufferCpu(ContextVk *contextVk, angle::Result convertVertexBufferCPU(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
......
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