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)
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;
}
......@@ -342,8 +342,8 @@ angle::Result UtilsVk::ensureBufferCopyResourcesInitialized(ContextVk *context)
{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1},
};
return ensureResourcesInitialized(context, Function::BufferCopy, setSizes, ArraySize(setSizes),
sizeof(BufferUtilsShaderParams));
return ensureResourcesInitialized(context, Function::ConvertIndexBuffer, setSizes,
ArraySize(setSizes), sizeof(BufferUtilsShaderParams));
}
angle::Result UtilsVk::ensureConvertVertexResourcesInitialized(ContextVk *context)
......@@ -542,12 +542,12 @@ angle::Result UtilsVk::clearBuffer(ContextVk *context,
return angle::Result::Continue;
}
angle::Result UtilsVk::copyBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
const CopyParameters &params)
angle::Result UtilsVk::convertIndexBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
const ConvertIndexParameters &params)
{
ANGLE_TRY(ensureBufferCopyResourcesInitialized(context));
ANGLE_TRY(ensureConvertIndexResourcesInitialized(context));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
......@@ -572,8 +572,8 @@ angle::Result UtilsVk::copyBuffer(ContextVk *context,
VkDescriptorSet descriptorSet;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
ANGLE_TRY(mDescriptorPools[Function::BufferCopy].allocateSets(
context, mDescriptorSetLayouts[Function::BufferCopy][kSetIndex].get().ptr(), 1,
ANGLE_TRY(mDescriptorPools[Function::ConvertIndexBuffer].allocateSets(
context, mDescriptorSetLayouts[Function::ConvertIndexBuffer][kSetIndex].get().ptr(), 1,
&descriptorPoolBinding, &descriptorSet));
descriptorPoolBinding.get().updateSerial(context->getCurrentQueueSerial());
......@@ -598,7 +598,7 @@ angle::Result UtilsVk::copyBuffer(ContextVk *context,
vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
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,
sizeof(shaderParams), commandBuffer));
......
......@@ -8,11 +8,11 @@
// buffer clear and copy, image clear and copy, texture mip map generation, etc.
//
// - Buffer clear: Implemented, but no current users
// - Buffer copy:
// * Used by VertexArrayVk::updateIndexTranslation() to convert a ubyte index array to ushort
// - Convert vertex attribute:
// * Used by VertexArrayVk::convertVertexBuffer() to convert vertex attributes from unsupported
// formats to their fallbacks.
// - Convert index buffer:
// * Used by VertexArrayVk::convertIndexBufferGPU() to convert a ubyte element array to ushort
// - Convert vertex buffer:
// * Used by VertexArrayVk::convertVertexBufferGPU() to convert vertex attributes from
// unsupported formats to their fallbacks.
// - Image clear: Used by FramebufferVk::clearWithDraw().
// - Image copy: Used by TextureVk::copySubImageImplWithDraw().
// - Color resolve: Used by FramebufferVk::resolve() to implement multisample resolve on color
......@@ -46,7 +46,7 @@ class UtilsVk : angle::NonCopyable
size_t size;
};
struct CopyParameters
struct ConvertIndexParameters
{
size_t destOffset;
size_t srcOffset;
......@@ -115,10 +115,10 @@ class UtilsVk : angle::NonCopyable
angle::Result clearBuffer(ContextVk *context,
vk::BufferHelper *dest,
const ClearParameters &params);
angle::Result copyBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
const CopyParameters &params);
angle::Result convertIndexBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
const ConvertIndexParameters &params);
angle::Result convertVertexBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
......@@ -241,7 +241,7 @@ class UtilsVk : angle::NonCopyable
// Functions implemented in compute
ComputeStartIndex = 3, // Special value to separate draw and dispatch functions.
BufferClear = 3,
BufferCopy = 4,
ConvertIndexBuffer = 4,
ConvertVertexBuffer = 5,
ResolveStencilNoExport = 6,
......@@ -279,7 +279,7 @@ class UtilsVk : angle::NonCopyable
// Initializers corresponding to functions, calling into ensureResourcesInitialized with the
// appropriate parameters.
angle::Result ensureBufferClearResourcesInitialized(ContextVk *context);
angle::Result ensureBufferCopyResourcesInitialized(ContextVk *context);
angle::Result ensureConvertIndexResourcesInitialized(ContextVk *context);
angle::Result ensureConvertVertexResourcesInitialized(ContextVk *context);
angle::Result ensureImageClearResourcesInitialized(ContextVk *context);
angle::Result ensureImageCopyResourcesInitialized(ContextVk *context);
......
......@@ -167,11 +167,46 @@ void VertexArrayVk::destroy(const gl::Context *context)
mLineLoopHelper.release(contextVk);
}
angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
gl::DrawElementsType indexType,
size_t indexCount,
const void *sourcePointer,
vk::DynamicBuffer *dynamicBuffer)
angle::Result VertexArrayVk::convertIndexBufferGPU(ContextVk *contextVk,
BufferVk *bufferVk,
const void *indices)
{
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);
......@@ -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
// but the alternative of copying it piecemeal on each draw would have a lot more
// overhead.
angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
angle::Result VertexArrayVk::convertVertexBufferGPU(ContextVk *contextVk,
BufferVk *srcBuffer,
const gl::VertexBinding &binding,
size_t attribIndex,
......@@ -254,7 +289,7 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
return angle::Result::Continue;
}
angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
BufferVk *srcBuffer,
const gl::VertexBinding &binding,
size_t attribIndex,
......@@ -443,13 +478,13 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
if (bindingIsAligned)
{
ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex,
ANGLE_TRY(convertVertexBufferGPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat));
anyVertexBufferConvertedOnGpu = true;
}
else
{
ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex,
ANGLE_TRY(convertVertexBufferCPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat));
}
}
......@@ -648,43 +683,15 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
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);
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::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));
if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
{
ASSERT(type == gl::DrawElementsType::UnsignedByte);
ANGLE_TRY(convertIndexBufferGPU(contextVk, bufferVk, indices));
}
else
{
......@@ -702,7 +709,6 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
ASSERT(type == gl::DrawElementsType::UnsignedByte);
// Unsigned bytes don't have direct support in Vulkan so we have to expand the
// memory to a GLushort.
BufferVk *bufferVk = vk::GetImpl(glBuffer);
void *srcDataMapping = nullptr;
ASSERT(!glBuffer->isMapped());
ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
......@@ -710,9 +716,9 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
srcData += offsetIntoSrcData;
ANGLE_TRY(streamIndexData(contextVk, type,
static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
srcData, &mTranslatedByteIndexData));
ANGLE_TRY(convertIndexBufferCPU(
contextVk, type, static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData, srcData,
&mTranslatedByteIndexData));
ANGLE_TRY(bufferVk->unmapImpl(contextVk));
}
......
......@@ -84,17 +84,21 @@ class VertexArrayVk : public VertexArrayImpl
private:
void setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex);
angle::Result streamIndexData(ContextVk *contextVk,
gl::DrawElementsType indexType,
size_t indexCount,
const void *sourcePointer,
vk::DynamicBuffer *dynamicBuffer);
angle::Result convertVertexBufferGpu(ContextVk *contextVk,
angle::Result convertIndexBufferGPU(ContextVk *contextVk,
BufferVk *bufferVk,
const void *indices);
angle::Result convertIndexBufferCPU(ContextVk *contextVk,
gl::DrawElementsType indexType,
size_t indexCount,
const void *sourcePointer,
vk::DynamicBuffer *dynamicBuffer);
angle::Result convertVertexBufferGPU(ContextVk *contextVk,
BufferVk *srcBuffer,
const gl::VertexBinding &binding,
size_t attribIndex,
const vk::Format &vertexFormat);
angle::Result convertVertexBufferCpu(ContextVk *contextVk,
angle::Result convertVertexBufferCPU(ContextVk *contextVk,
BufferVk *srcBuffer,
const gl::VertexBinding &binding,
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