Commit 7f418fc2 by Courtney Goeltzenleuchter Committed by Commit Bot

Vulkan: lineloop support for DrawArrayIndirect

Add support for lineloops. Includes a compute shader for generating an index buffer to draw lineloop. Instancing turns out to be a special case for indirect draws if we have vertex attributes that need to be emulated (e.g. divisor too large or native vertex format not available). Test: dEQP.GLES31/functional_draw_indirect_* angle_end2end_tests --gtest_filter=LineLoopIndirectTest.*/* dEQP.GLES3/functional_draw_* Bug: angleproject:3564 Change-Id: I1fdabe2c8a690c8b6df9e252e1e839e08796bcca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1834682 Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 299bea64
......@@ -82,17 +82,19 @@
"src/libANGLE/renderer/vulkan/shaders/gen/BufferUtils.comp.0000000B.inc":
"7e13d5325d35f96045e920a1cb3598bc",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000000.inc":
"b3877393750a16efd1d6805a0327a9e7",
"2eb01d29bfbe67165fe2ac22f889b65e",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000001.inc":
"66d7868159587d000ef41d84489780bc",
"88ec915ed8519a5b49f1d022774d2655",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000002.inc":
"db98380613bc3f032037b4a096756975",
"4b5290a0c127e1375ec6b5dcec46893c",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000003.inc":
"e676bdff5c3b596eccba13a4e52d3875",
"0d3eb0f82f328837ef4c0fe5f978ef3f",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndexIndirectLineLoop.comp.00000000.inc":
"d99b638b0b2efa9726350869fe6b9b10",
"76d8265a6ccec813fb7f7ad1b503947e",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndexIndirectLineLoop.comp.00000001.inc":
"8f27f7634724189ce2bd63820e96ee63",
"a1964fd9d0b75701a384a11ac23242fb",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndirectLineLoop.comp.00000000.inc":
"523d3207d424614197ace9601ce56950",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000000.inc":
"f5ef892346ee10e5d0d9f8cba2a491b2",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000001.inc":
......@@ -290,9 +292,11 @@
"src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp":
"b7c20e019199f8328ef37b11c6fbcadd",
"src/libANGLE/renderer/vulkan/shaders/src/ConvertIndex.comp":
"083e2b6ed2cf40f036287413c449e675",
"a46b48d7d5b19c74eb377f275525ab8d",
"src/libANGLE/renderer/vulkan/shaders/src/ConvertIndexIndirectLineLoop.comp":
"a543a28fc1fe53eefd5949ee3b4428f3",
"63418a915d0a63a26c17fea3091cd42d",
"src/libANGLE/renderer/vulkan/shaders/src/ConvertIndirectLineLoop.comp":
"c4fe0f463b41cd59bae33f9711e0b67b",
"src/libANGLE/renderer/vulkan/shaders/src/ConvertVertex.comp":
"6d034ff271e17c0a4f8a12b8eec2970d",
"src/libANGLE/renderer/vulkan/shaders/src/FullScreenQuad.vert":
......@@ -306,9 +310,9 @@
"src/libANGLE/renderer/vulkan/shaders/src/OverlayDraw.comp":
"dcc246b398b2e07a869a264666499362",
"src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp":
"39bcc07efd2fe05c1eb0a9d9e34567d3",
"5991a86d00cf2b40989e92cc0e9f2519",
"src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h":
"cfeb07579c1ba5051450f76f06e47d05",
"64b710329f099176d53899fb4d8c816a",
"tools/glslang/glslang_validator.exe.sha1":
"289f30598865a987a21b79ae525fc66f",
"tools/glslang/glslang_validator.sha1":
......
......@@ -506,27 +506,31 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
angle::Result setupIndirectDraw(const gl::Context *context,
gl::PrimitiveMode mode,
DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut,
vk::Buffer **indirectBufferOut);
angle::Result setupIndirectDrawHelper(const gl::Context *context,
gl::PrimitiveMode mode,
DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut);
vk::BufferHelper *indirectBuffer,
VkDeviceSize indirectBufferOffset,
vk::CommandBuffer **commandBufferOut);
angle::Result setupIndexedIndirectDraw(const gl::Context *context,
gl::PrimitiveMode mode,
gl::DrawElementsType indexType,
vk::CommandBuffer **commandBufferOut,
vk::Buffer **indirectBufferOut);
vk::BufferHelper *indirectBuffer,
VkDeviceSize indirectBufferOffset,
vk::CommandBuffer **commandBufferOut);
angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context,
gl::PrimitiveMode mode,
gl::DrawElementsType indexType,
const gl::Buffer *indirectBuffer,
vk::BufferHelper *srcIndirectBuf,
VkDeviceSize indirectBufferOffset,
const gl::Buffer *indexBuffer,
vk::CommandBuffer **commandBufferOut,
vk::Buffer **indirectBufferOut,
vk::BufferHelper **indirectBufferOut,
VkDeviceSize *indirectBufferOffsetOut);
angle::Result setupLineLoopIndirectDraw(const gl::Context *context,
gl::PrimitiveMode mode,
vk::BufferHelper *indirectBuffer,
VkDeviceSize indirectBufferOffset,
vk::CommandBuffer **commandBufferOut,
vk::BufferHelper **indirectBufferOut,
VkDeviceSize *indirectBufferOffsetOut);
angle::Result setupLineLoopDraw(const gl::Context *context,
gl::PrimitiveMode mode,
......
......@@ -56,9 +56,10 @@ class UtilsVk : angle::NonCopyable
struct ConvertIndexIndirectParameters
{
uint32_t indirectBufferOffset = 0;
uint32_t dstOffset = 0;
uint32_t srcIndirectBufOffset = 0;
uint32_t dstIndexBufOffset = 0;
uint32_t maxIndex = 0;
uint32_t dstIndirectBufOffset = 0;
};
struct ConvertLineLoopIndexIndirectParameters
......@@ -69,6 +70,13 @@ class UtilsVk : angle::NonCopyable
uint32_t is32Bit = 0;
};
struct ConvertLineLoopArrayIndirectParameters
{
uint32_t indirectBufferOffset = 0;
uint32_t dstIndirectBufferOffset = 0;
uint32_t dstIndexBufferOffset = 0;
};
struct ConvertVertexParameters
{
size_t vertexCount;
......@@ -154,19 +162,27 @@ class UtilsVk : angle::NonCopyable
vk::BufferHelper *src,
const ConvertIndexParameters &params);
angle::Result convertIndexIndirectBuffer(ContextVk *contextVk,
vk::BufferHelper *cmdBufferVk,
vk::BufferHelper *dest,
vk::BufferHelper *src,
vk::BufferHelper *srcIndirectBuf,
vk::BufferHelper *srcIndexBuf,
vk::BufferHelper *dstIndirectBuf,
vk::BufferHelper *dstIndexBuf,
const ConvertIndexIndirectParameters &params);
angle::Result convertLineLoopIndexIndirectBuffer(
ContextVk *contextVk,
vk::BufferHelper *cmdBufferVk,
vk::BufferHelper *destCmdBufferVk,
vk::BufferHelper *dest,
vk::BufferHelper *src,
vk::BufferHelper *srcIndirectBuffer,
vk::BufferHelper *destIndirectBuffer,
vk::BufferHelper *destIndexBuffer,
vk::BufferHelper *srcIndexBuffer,
const ConvertLineLoopIndexIndirectParameters &params);
angle::Result convertLineLoopArrayIndirectBuffer(
ContextVk *contextVk,
vk::BufferHelper *srcIndirectBuffer,
vk::BufferHelper *destIndirectBuffer,
vk::BufferHelper *destIndexBuffer,
const ConvertLineLoopArrayIndirectParameters &params);
angle::Result convertVertexBuffer(ContextVk *contextVk,
vk::BufferHelper *dest,
vk::BufferHelper *src,
......@@ -242,10 +258,10 @@ class UtilsVk : angle::NonCopyable
struct ConvertIndexIndirectShaderParams
{
uint32_t cmdOffsetDiv4 = 0;
uint32_t dstOffsetDiv4 = 0;
uint32_t maxIndex = 0;
uint32_t _padding = 0;
uint32_t srcIndirectOffsetDiv4 = 0;
uint32_t dstOffsetDiv4 = 0;
uint32_t maxIndex = 0;
uint32_t dstIndirectOffsetDiv4 = 0;
};
struct ConvertIndexIndirectLineLoopShaderParams
......@@ -256,6 +272,13 @@ class UtilsVk : angle::NonCopyable
uint32_t isRestartEnabled = 0;
};
struct ConvertIndirectLineLoopShaderParams
{
uint32_t cmdOffsetDiv4 = 0;
uint32_t dstCmdOffsetDiv4 = 0;
uint32_t dstOffsetDiv4 = 0;
};
struct ConvertVertexShaderParams
{
ConvertVertexShaderParams();
......@@ -358,9 +381,10 @@ class UtilsVk : angle::NonCopyable
OverlayDraw = 8,
ConvertIndexIndirectBuffer = 9,
ConvertIndexIndirectLineLoopBuffer = 10,
ConvertIndirectLineLoopBuffer = 11,
InvalidEnum = 11,
EnumCount = 11,
InvalidEnum = 12,
EnumCount = 12,
};
// Common function that creates the pipeline for the specified function, binds it and prepares
......@@ -396,6 +420,7 @@ class UtilsVk : angle::NonCopyable
angle::Result ensureConvertIndexResourcesInitialized(ContextVk *contextVk);
angle::Result ensureConvertIndexIndirectResourcesInitialized(ContextVk *contextVk);
angle::Result ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
angle::Result ensureConvertIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
angle::Result ensureConvertVertexResourcesInitialized(ContextVk *contextVk);
angle::Result ensureImageClearResourcesInitialized(ContextVk *contextVk);
angle::Result ensureImageCopyResourcesInitialized(ContextVk *contextVk);
......@@ -434,6 +459,10 @@ class UtilsVk : angle::NonCopyable
vk::ShaderProgramHelper mBufferUtilsPrograms[vk::InternalShader::BufferUtils_comp::kArrayLen];
vk::ShaderProgramHelper mConvertIndexPrograms[vk::InternalShader::ConvertIndex_comp::kArrayLen];
vk::ShaderProgramHelper mConvertIndexIndirectLineLoopPrograms
[vk::InternalShader::ConvertIndexIndirectLineLoop_comp::kArrayLen];
vk::ShaderProgramHelper mConvertIndirectLineLoopPrograms
[vk::InternalShader::ConvertIndirectLineLoop_comp::kArrayLen];
vk::ShaderProgramHelper
mConvertVertexPrograms[vk::InternalShader::ConvertVertex_comp::kArrayLen];
vk::ShaderProgramHelper mImageClearProgramVSOnly;
......
......@@ -52,12 +52,18 @@ class VertexArrayVk : public VertexArrayImpl
const void *indices,
uint32_t *indexCountOut);
angle::Result handleLineLoopIndirect(ContextVk *contextVk,
BufferVk *indirectBufferVk,
gl::DrawElementsType glIndexType,
VkDeviceSize indirectBufferOffset,
vk::BufferHelper **indirectBufferOut,
VkDeviceSize *indirectBufferOffsetOut);
angle::Result handleLineLoopIndexIndirect(ContextVk *contextVk,
gl::DrawElementsType glIndexType,
vk::BufferHelper *srcIndirectBuf,
VkDeviceSize indirectBufferOffset,
vk::BufferHelper **indirectBufferOut,
VkDeviceSize *indirectBufferOffsetOut);
angle::Result handleLineLoopIndirectDraw(const gl::Context *context,
vk::BufferHelper *indirectBufferVk,
VkDeviceSize indirectBufferOffset,
vk::BufferHelper **indirectBufferOut,
VkDeviceSize *indirectBufferOffsetOut);
const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const
{
......@@ -91,9 +97,10 @@ class VertexArrayVk : public VertexArrayImpl
const void *indices);
angle::Result convertIndexBufferIndirectGPU(ContextVk *contextVk,
BufferVk *cmdBufferVk,
BufferVk *indexBufferVk,
const void *indices);
vk::BufferHelper *srcIndirectBuf,
VkDeviceSize srcIndirectBufOffset,
vk::BufferHelper **indirectBufferVkOut,
VkDeviceSize *indirectBufferVkOffsetOut);
angle::Result convertIndexBufferCPU(ContextVk *contextVk,
gl::DrawElementsType indexType,
......@@ -138,6 +145,7 @@ class VertexArrayVk : public VertexArrayImpl
vk::DynamicBuffer mDynamicVertexData;
vk::DynamicBuffer mDynamicIndexData;
vk::DynamicBuffer mTranslatedByteIndexData;
vk::DynamicBuffer mTranslatedByteIndirectData;
vk::LineLoopHelper mLineLoopHelper;
Optional<GLint> mLineLoopBufferFirstIndex;
......
......@@ -39,18 +39,18 @@ const uint32_t kConvertIndexIndirectLineLoop_comp_00000000[] = {
0x000000c6,0x00000000,0x00040047,0x00000012,0x00000006,0x00000004,0x00040048,0x00000013,
0x00000000,0x00000018,0x00050048,0x00000013,0x00000000,0x00000023,0x00000000,0x00030047,
0x00000013,0x00000003,0x00040047,0x00000015,0x00000022,0x00000000,0x00040047,0x00000015,
0x00000021,0x00000003,0x00050048,0x00000030,0x00000000,0x00000023,0x00000000,0x00050048,
0x00000021,0x00000001,0x00050048,0x00000030,0x00000000,0x00000023,0x00000000,0x00050048,
0x00000030,0x00000001,0x00000023,0x00000004,0x00050048,0x00000030,0x00000002,0x00000023,
0x00000008,0x00050048,0x00000030,0x00000003,0x00000023,0x0000000c,0x00030047,0x00000030,
0x00000002,0x00040047,0x0000003b,0x00000006,0x00000004,0x00050048,0x0000003c,0x00000000,
0x00000023,0x00000000,0x00030047,0x0000003c,0x00000003,0x00040047,0x0000003e,0x00000022,
0x00000000,0x00040047,0x0000003e,0x00000021,0x00000002,0x00040047,0x00000056,0x00000006,
0x00000000,0x00040047,0x0000003e,0x00000021,0x00000000,0x00040047,0x00000056,0x00000006,
0x00000004,0x00040048,0x00000057,0x00000000,0x00000018,0x00050048,0x00000057,0x00000000,
0x00000023,0x00000000,0x00030047,0x00000057,0x00000003,0x00040047,0x00000059,0x00000022,
0x00000000,0x00040047,0x00000059,0x00000021,0x00000000,0x00040047,0x0000006b,0x0000000b,
0x00000000,0x00040047,0x00000059,0x00000021,0x00000002,0x00040047,0x0000006b,0x0000000b,
0x0000001c,0x00040047,0x000000c3,0x00000006,0x00000004,0x00050048,0x000000c4,0x00000000,
0x00000023,0x00000000,0x00030047,0x000000c4,0x00000003,0x00040047,0x000000c6,0x00000022,
0x00000000,0x00040047,0x000000c6,0x00000021,0x00000001,0x00040047,0x000000ed,0x0000000b,
0x00000000,0x00040047,0x000000c6,0x00000021,0x00000003,0x00040047,0x000000ed,0x0000000b,
0x00000019,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,
0x00000020,0x00000000,0x00040020,0x00000007,0x00000007,0x00000006,0x00040021,0x00000008,
0x00000006,0x00000007,0x00050021,0x0000000c,0x00000002,0x00000007,0x00000007,0x0003001d,
......@@ -207,28 +207,28 @@ const uint32_t kConvertIndexIndirectLineLoop_comp_00000000[] = {
//
// layout(local_size_x = 64, local_size_y = 1, local_size_z = 1)in;
//
// layout(set = 0, binding = 0)readonly buffer cmd
// layout(set = 0, binding = 0)buffer dst
// {
//
// uint cmdData[];
// uint dstData[];
// };
//
// layout(set = 0, binding = 1)buffer dstCmd
// layout(set = 0, binding = 1)readonly buffer src
// {
//
// uint dstCmdData[];
// uint srcData[];
// };
//
// layout(set = 0, binding = 2)buffer dst
// layout(set = 0, binding = 2)readonly buffer cmd
// {
//
// uint dstData[];
// uint cmdData[];
// };
//
// layout(set = 0, binding = 3)readonly buffer src
// layout(set = 0, binding = 3)buffer dstCmd
// {
//
// uint srcData[];
// uint dstCmdData[];
// };
//
// layout(push_constant)uniform PushConstants
......
......@@ -34,18 +34,18 @@ const uint32_t kConvertIndexIndirectLineLoop_comp_00000001[] = {
0x6144646d,0x00006174,0x00030005,0x000000a1,0x00000000,0x00040047,0x00000011,0x00000006,
0x00000004,0x00040048,0x00000012,0x00000000,0x00000018,0x00050048,0x00000012,0x00000000,
0x00000023,0x00000000,0x00030047,0x00000012,0x00000003,0x00040047,0x00000014,0x00000022,
0x00000000,0x00040047,0x00000014,0x00000021,0x00000003,0x00040047,0x0000001d,0x00000006,
0x00000000,0x00040047,0x00000014,0x00000021,0x00000001,0x00040047,0x0000001d,0x00000006,
0x00000004,0x00050048,0x0000001e,0x00000000,0x00000023,0x00000000,0x00030047,0x0000001e,
0x00000003,0x00040047,0x00000020,0x00000022,0x00000000,0x00040047,0x00000020,0x00000021,
0x00000002,0x00050048,0x00000021,0x00000000,0x00000023,0x00000000,0x00050048,0x00000021,
0x00000000,0x00050048,0x00000021,0x00000000,0x00000023,0x00000000,0x00050048,0x00000021,
0x00000001,0x00000023,0x00000004,0x00050048,0x00000021,0x00000002,0x00000023,0x00000008,
0x00050048,0x00000021,0x00000003,0x00000023,0x0000000c,0x00030047,0x00000021,0x00000002,
0x00040047,0x0000002e,0x00000006,0x00000004,0x00040048,0x0000002f,0x00000000,0x00000018,
0x00050048,0x0000002f,0x00000000,0x00000023,0x00000000,0x00030047,0x0000002f,0x00000003,
0x00040047,0x00000031,0x00000022,0x00000000,0x00040047,0x00000031,0x00000021,0x00000000,
0x00040047,0x00000031,0x00000022,0x00000000,0x00040047,0x00000031,0x00000021,0x00000002,
0x00040047,0x00000043,0x0000000b,0x0000001c,0x00040047,0x0000009e,0x00000006,0x00000004,
0x00050048,0x0000009f,0x00000000,0x00000023,0x00000000,0x00030047,0x0000009f,0x00000003,
0x00040047,0x000000a1,0x00000022,0x00000000,0x00040047,0x000000a1,0x00000021,0x00000001,
0x00040047,0x000000a1,0x00000022,0x00000000,0x00040047,0x000000a1,0x00000021,0x00000003,
0x00040047,0x000000c8,0x0000000b,0x00000019,0x00020013,0x00000002,0x00030021,0x00000003,
0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00040020,0x00000007,0x00000007,
0x00000006,0x00040021,0x00000008,0x00000006,0x00000007,0x00050021,0x0000000c,0x00000002,
......@@ -178,28 +178,28 @@ const uint32_t kConvertIndexIndirectLineLoop_comp_00000001[] = {
//
// layout(local_size_x = 64, local_size_y = 1, local_size_z = 1)in;
//
// layout(set = 0, binding = 0)readonly buffer cmd
// layout(set = 0, binding = 0)buffer dst
// {
//
// uint cmdData[];
// uint dstData[];
// };
//
// layout(set = 0, binding = 1)buffer dstCmd
// layout(set = 0, binding = 1)readonly buffer src
// {
//
// uint dstCmdData[];
// uint srcData[];
// };
//
// layout(set = 0, binding = 2)buffer dst
// layout(set = 0, binding = 2)readonly buffer cmd
// {
//
// uint dstData[];
// uint cmdData[];
// };
//
// layout(set = 0, binding = 3)readonly buffer src
// layout(set = 0, binding = 3)buffer dstCmd
// {
//
// uint srcData[];
// uint dstCmdData[];
// };
//
// layout(push_constant)uniform PushConstants
......
......@@ -20,43 +20,49 @@ layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout (set = 0, binding = 0) buffer dst
{
// Shader invocations output one packed 32-bit value with up to two 16-bit indices.
uint dstData[];
uint dstIndexBuf[];
};
layout (set = 0, binding = 1) readonly buffer src
{
// Shader invocations read at most 16 bits of one packed 32-bit value. (Two 8-bit indices.)
uint srcData[];
uint srcIndexBuf[];
};
#if IsIndirect
layout (set = 0, binding = 2) readonly buffer cmd
layout (set = 0, binding = 2) readonly buffer srcIndirect
{
// Shader invocations read from the cmdData buffer to determine what indices to convert
// The command data starts at offset cmdOffsetDiv4 of the cmdData buffer.
uint cmdData[];
// Shader invocations read from the srcIndirectBuf buffer to determine what indices to convert
// The command data starts at offset srcIndirectOffsetDiv4 of the srcIndirectBuf buffer.
uint srcIndirectBuf[];
};
layout (set = 0, binding = 3) buffer dstIndirect
{
// output indirect buffer data, data starts at dstIndirectBufOffsetDiv4
uint dstIndirectBuf[];
};
layout (push_constant) uniform PushConstants
{
// Read offset in bytes into the cmdData array, divided by four.
uint cmdOffsetDiv4;
// Write offset in bytes into the dstData array, divided by four.
uint dstOffsetDiv4;
// Read offset in bytes into the srcIndirectBuf array, divided by four.
uint srcIndirectOffsetDiv4;
// Write offset in bytes into the dstIndexBuf array, divided by four.
uint dstIndexBufOffsetDiv4;
// Maximum size of the read buffer. The highest index value we will convert.
uint maxIndex;
// Not used in the shader. Kept to pad "PushConstants" to the size of a vec4.
uint _padding;
// Write offset in bytes/4 of destinatio indirect buffer
uint dstIndirectBufOffsetDiv4;
};
#else
layout (push_constant) uniform PushConstants
{
// Read offset in bytes into the srcData array.
uint srcOffset;
// Write offset in bytes into the dstData array, divided by four.
uint dstOffsetDiv4;
// Read offset in bytes into the srcIndexBuf array.
uint srcIndexOffset;
// Write offset in bytes into the dstIndexBuf array, divided by four.
uint dstIndexBufOffsetDiv4;
// Maximum size of the read buffer. The highest index value we will convert.
uint maxIndex;
// Not used in the shader. Kept to pad "PushConstants" to the size of a vec4.
......@@ -69,9 +75,9 @@ uint PullIndex(uint index)
#if IsIndirect
uint srcIndex = index;
#else
uint srcIndex = index + srcOffset;
uint srcIndex = index + srcIndexOffset;
#endif
uint srcBlock = srcData[srcIndex >> 2];
uint srcBlock = srcIndexBuf[srcIndex >> 2];
uint srcComponent = (srcIndex & 3);
uint value = (srcBlock >> (srcComponent << 3)) & 0xFF;
......@@ -93,8 +99,8 @@ void PackIndexValue(uint srcValue, uint indexIndex, inout uint dstValue)
void main()
{
#if IsIndirect
uint indexCount = cmdData[cmdOffsetDiv4];
uint firstIndex = cmdData[cmdOffsetDiv4 + 2];
uint indexCount = srcIndirectBuf[srcIndirectOffsetDiv4];
uint firstIndex = srcIndirectBuf[srcIndirectOffsetDiv4 + 2];
uint endIndex = firstIndex + indexCount;
#else
uint firstIndex = 0;
......@@ -128,5 +134,30 @@ void main()
PackIndexValue(srcValue, 1, dstValue);
}
dstData[dstOffsetDiv4 + gl_GlobalInvocationID.x] = dstValue;
dstIndexBuf[dstIndexBufOffsetDiv4 + gl_GlobalInvocationID.x] = dstValue;
#if IsIndirect
// Copy the source indirect draw info (DrawElementsIndirectCommand) to the destination
// indirect draw buffer adjusting the firstIndex to account for the offset into dstIndirectBuf
// typedef struct {
// uint count;
// uint instanceCount;
// uint firstIndex;
// int baseVertex;
// uint reservedMustBeZero;
// } DrawElementsIndirectCommand;
if (gl_GlobalInvocationID.x == 0)
{
dstIndirectBuf[dstIndirectBufOffsetDiv4] = srcIndirectBuf[srcIndirectOffsetDiv4]; // count
// instanceCount
dstIndirectBuf[dstIndirectBufOffsetDiv4 + 1] = srcIndirectBuf[srcIndirectOffsetDiv4 + 1];
// ANGLE will supply dstIndexBufOffset when binding the index buffer so don't
// need to worry about that as part of firstIndex for the new indirect buffer command.
// firstIndex can be in 2nd half of word so add one if incoming firstIndex is odd
dstIndirectBuf[dstIndirectBufOffsetDiv4 + 2] = firstIndex & 1; // firstIndex
// baseVertex
dstIndirectBuf[dstIndirectBufOffsetDiv4 + 3] = srcIndirectBuf[srcIndirectOffsetDiv4 + 3];
dstIndirectBuf[dstIndirectBufOffsetDiv4 + 4] = 0; // reservedMustBeZero
}
#endif
}
......@@ -16,29 +16,29 @@
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout (set = 0, binding = 0) readonly buffer cmd
layout (set = 0, binding = 0) buffer dst
{
// Shader invocations read the cmd data to determine what indices to convert
// Command data at offset cmdOffset of buffer
uint cmdData[];
// Shader invocation outputs linelist(s) here.
uint dstData[];
};
layout (set = 0, binding = 1) buffer dstCmd
layout (set = 0, binding = 1) readonly buffer src
{
// Shader outputs updated indirect buffer here.
uint dstCmdData[];
// Source index buffer
uint srcData[];
};
layout (set = 0, binding = 2) buffer dst
layout (set = 0, binding = 2) readonly buffer cmd
{
// Shader invocation outputs linelist(s) here.
uint dstData[];
// Shader invocations read the cmd data to determine what indices to convert
// Command data at offset cmdOffset of buffer
uint cmdData[];
};
layout (set = 0, binding = 3) readonly buffer src
layout (set = 0, binding = 3) buffer dstCmd
{
// Source index buffer
uint srcData[];
// Shader outputs updated indirect buffer here.
uint dstCmdData[];
};
layout (push_constant) uniform PushConstants
......
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ConvertArrayIndirectLineloop.comp: Construct an index buffer for an indirect
// draw that draws all the specified vertices and repeats the last vertex at
// the end to give lineloop behavior.
// Will also output a new indirect "command" buffer with adjusted index values.
//
//
#version 450 core
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout (set = 0, binding = 0) readonly buffer srcIndirectBuf
{
// Shader invocations read the cmd data to determine what indices to convert
// Command data at offset cmdOffset of buffer
uint indirectBuf[];
};
layout (set = 0, binding = 1) buffer dstIndirectBuf
{
// Shader outputs updated indirect buffer here.
uint indexIndirectBuf[];
};
layout (set = 0, binding = 2) buffer dstIndexBuf
{
// Shader invocation outputs linelist(s) here.
uint dstData[];
};
layout (push_constant) uniform PushConstants
{
// Read offset in bytes into the indirectBuf, divided by four.
uint indirectBufferOffsetDiv4;
// Dst command offset in bytes into the indexIndirectBuff, divided by four.
uint indexIndirectBufOffsetDiv4;
// Write offset in bytes into the dstData array, divided by four.
uint dstDataOffsetDiv4;
};
// Structure of command data loaded at offset indirectBufferOffsetDiv4 of the indirectBuf buffer
// struct VkDrawIndirectCommand {
// uint32_t vertexCount;
// uint32_t instanceCount;
// uint32_t firstVertex;
// uint32_t firstInstance;
// };
// Structure of command data loaded at offset indexIndirectBufferOffsetDiv4 of the
// indexIndirectBuf buffer
// struct VkDrawIndexedIndirectCommand {
// uint32_t indexCount;
// uint32_t instanceCount;
// uint32_t firstIndex;
// int32_t vertexOffset;
// uint32_t firstInstance;
// };
void main()
{
// Load the relevant command info from cmdData
uint vertexCount = indirectBuf[indirectBufferOffsetDiv4];
uint firstVertex = indirectBuf[indirectBufferOffsetDiv4 + 2];
// Only first invocation does the work
if (gl_GlobalInvocationID.x >= 1)
return;
for (uint i = 0; i < vertexCount; i++)
{
dstData[dstDataOffsetDiv4 + i] = firstVertex + i;
}
if (vertexCount > 1)
{
dstData[dstDataOffsetDiv4 + vertexCount] = firstVertex;
vertexCount++;
}
// Write new indirect data in indexIndirectBuf.
indexIndirectBuf[indexIndirectBufOffsetDiv4] = vertexCount;
indexIndirectBuf[indexIndirectBufOffsetDiv4 + 1] = indirectBuf[indirectBufferOffsetDiv4 + 1];
indexIndirectBuf[indexIndirectBufOffsetDiv4 + 2] = 0;
indexIndirectBuf[indexIndirectBufOffsetDiv4 + 3] = 0;
indexIndirectBuf[indexIndirectBufOffsetDiv4 + 4] = indirectBuf[indirectBufferOffsetDiv4 + 3];
}
{
"Description": [
"Copyright 2019 The ANGLE Project Authors. All rights reserved.",
"Use of this source code is governed by a BSD-style license that can be",
"found in the LICENSE file.",
"",
"ConvertArrayIndirectLineLoop.comp.json: Build parameters for ConvertArrayIndirectLineLoop.comp."
],
"Flags": [
]
}
......@@ -1300,6 +1300,46 @@ angle::Result LineLoopHelper::streamIndicesIndirect(ContextVk *contextVk,
return angle::Result::Continue;
}
angle::Result LineLoopHelper::streamArrayIndirect(ContextVk *contextVk,
size_t vertexCount,
vk::BufferHelper *arrayIndirectBuffer,
VkDeviceSize arrayIndirectBufferOffset,
vk::BufferHelper **indexBufferOut,
VkDeviceSize *indexBufferOffsetOut,
vk::BufferHelper **indexIndirectBufferOut,
VkDeviceSize *indexIndirectBufferOffsetOut)
{
auto unitSize = sizeof(uint32_t);
size_t allocateBytes = static_cast<size_t>((vertexCount + 1) * unitSize);
mDynamicIndexBuffer.releaseInFlightBuffers(contextVk);
mDynamicIndirectBuffer.releaseInFlightBuffers(contextVk);
ANGLE_TRY(mDynamicIndexBuffer.allocate(contextVk, allocateBytes, nullptr, nullptr,
indexBufferOffsetOut, nullptr));
*indexBufferOut = mDynamicIndexBuffer.getCurrentBuffer();
ANGLE_TRY(mDynamicIndirectBuffer.allocate(contextVk, sizeof(VkDrawIndexedIndirectCommand),
nullptr, nullptr, indexIndirectBufferOffsetOut,
nullptr));
*indexIndirectBufferOut = mDynamicIndirectBuffer.getCurrentBuffer();
vk::BufferHelper *destIndexBuffer = mDynamicIndexBuffer.getCurrentBuffer();
vk::BufferHelper *destIndirectBuffer = mDynamicIndirectBuffer.getCurrentBuffer();
// Copy relevant section of the source into destination at allocated offset. Note that the
// offset returned by allocate() above is in bytes. As is the indices offset pointer.
UtilsVk::ConvertLineLoopArrayIndirectParameters params = {};
params.indirectBufferOffset = static_cast<uint32_t>(arrayIndirectBufferOffset);
params.dstIndirectBufferOffset = static_cast<uint32_t>(*indexIndirectBufferOffsetOut);
params.dstIndexBufferOffset = static_cast<uint32_t>(*indexBufferOffsetOut);
ANGLE_TRY(contextVk->getUtils().convertLineLoopArrayIndirectBuffer(
contextVk, arrayIndirectBuffer, destIndirectBuffer, destIndexBuffer, params));
return angle::Result::Continue;
}
void LineLoopHelper::release(ContextVk *contextVk)
{
mDynamicIndexBuffer.release(contextVk->getRenderer());
......
......@@ -25,8 +25,11 @@ constexpr VkBufferUsageFlags kVertexBufferUsageFlags =
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
constexpr VkBufferUsageFlags kIndexBufferUsageFlags =
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
constexpr size_t kVertexBufferAlignment = 4;
constexpr size_t kIndexBufferAlignment = 4;
constexpr VkBufferUsageFlags kIndirectBufferUsageFlags =
VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
constexpr size_t kVertexBufferAlignment = 4;
constexpr size_t kIndexBufferAlignment = 4;
constexpr size_t kIndirectBufferAlignment = 4;
constexpr VkBufferUsageFlags kStagingBufferFlags =
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
......@@ -432,6 +435,15 @@ class LineLoopHelper final : angle::NonCopyable
vk::BufferHelper **indirectBufferOut,
VkDeviceSize *indirectBufferOffsetOut);
angle::Result streamArrayIndirect(ContextVk *contextVk,
size_t vertexCount,
vk::BufferHelper *arrayIndirectBuffer,
VkDeviceSize arrayIndirectBufferOffset,
vk::BufferHelper **indexBufferOut,
VkDeviceSize *indexBufferOffsetOut,
vk::BufferHelper **indexIndirectBufferOut,
VkDeviceSize *indexIndirectBufferOffsetOut);
void release(ContextVk *contextVk);
void destroy(VkDevice device);
......
......@@ -62,6 +62,7 @@ namespace
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000003.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertIndexIndirectLineLoop.comp.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertIndexIndirectLineLoop.comp.00000001.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertIndirectLineLoop.comp.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000001.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000002.inc"
......@@ -223,6 +224,9 @@ constexpr ShaderBlob kConvertIndexIndirectLineLoop_comp_shaders[] = {
{kConvertIndexIndirectLineLoop_comp_00000001,
sizeof(kConvertIndexIndirectLineLoop_comp_00000001)},
};
constexpr ShaderBlob kConvertIndirectLineLoop_comp_shaders[] = {
{kConvertIndirectLineLoop_comp_00000000, sizeof(kConvertIndirectLineLoop_comp_00000000)},
};
constexpr ShaderBlob kConvertVertex_comp_shaders[] = {
{kConvertVertex_comp_00000000, sizeof(kConvertVertex_comp_00000000)},
{kConvertVertex_comp_00000001, sizeof(kConvertVertex_comp_00000001)},
......@@ -385,6 +389,10 @@ void ShaderLibrary::destroy(VkDevice device)
{
shader.get().destroy(device);
}
for (RefCounted<ShaderAndSerial> &shader : mConvertIndirectLineLoop_comp_shaders)
{
shader.get().destroy(device);
}
for (RefCounted<ShaderAndSerial> &shader : mConvertVertex_comp_shaders)
{
shader.get().destroy(device);
......@@ -455,6 +463,16 @@ angle::Result ShaderLibrary::getConvertIndexIndirectLineLoop_comp(
ArraySize(kConvertIndexIndirectLineLoop_comp_shaders), shaderFlags, shaderOut);
}
angle::Result ShaderLibrary::getConvertIndirectLineLoop_comp(
Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut)
{
return GetShader(context, mConvertIndirectLineLoop_comp_shaders,
kConvertIndirectLineLoop_comp_shaders,
ArraySize(kConvertIndirectLineLoop_comp_shaders), shaderFlags, shaderOut);
}
angle::Result ShaderLibrary::getConvertVertex_comp(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut)
......
......@@ -55,6 +55,7 @@ angle_vulkan_internal_shaders = [
"shaders/gen/ConvertIndex.comp.00000003.inc",
"shaders/gen/ConvertIndexIndirectLineLoop.comp.00000000.inc",
"shaders/gen/ConvertIndexIndirectLineLoop.comp.00000001.inc",
"shaders/gen/ConvertIndirectLineLoop.comp.00000000.inc",
"shaders/gen/ConvertVertex.comp.00000000.inc",
"shaders/gen/ConvertVertex.comp.00000001.inc",
"shaders/gen/ConvertVertex.comp.00000002.inc",
......
......@@ -87,6 +87,11 @@ enum flags
constexpr size_t kArrayLen = 0x00000002;
} // namespace ConvertIndexIndirectLineLoop_comp
namespace ConvertIndirectLineLoop_comp
{
constexpr size_t kArrayLen = 0x00000001;
} // namespace ConvertIndirectLineLoop_comp
namespace ConvertVertex_comp
{
enum flags
......@@ -220,6 +225,9 @@ class ShaderLibrary final : angle::NonCopyable
angle::Result getConvertIndexIndirectLineLoop_comp(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut);
angle::Result getConvertIndirectLineLoop_comp(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut);
angle::Result getConvertVertex_comp(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut);
......@@ -250,6 +258,8 @@ class ShaderLibrary final : angle::NonCopyable
mConvertIndex_comp_shaders[InternalShader::ConvertIndex_comp::kArrayLen];
RefCounted<ShaderAndSerial> mConvertIndexIndirectLineLoop_comp_shaders
[InternalShader::ConvertIndexIndirectLineLoop_comp::kArrayLen];
RefCounted<ShaderAndSerial> mConvertIndirectLineLoop_comp_shaders
[InternalShader::ConvertIndirectLineLoop_comp::kArrayLen];
RefCounted<ShaderAndSerial>
mConvertVertex_comp_shaders[InternalShader::ConvertVertex_comp::kArrayLen];
RefCounted<ShaderAndSerial>
......
......@@ -623,10 +623,6 @@
// Block name matching failure:
3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
// Indirect draw:
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.draw_arrays_indirect.line_loop.* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.random.* = SKIP
// Tessellation geometry interaction:
3572 VULKAN : dEQP-GLES31.functional.tessellation_geometry_interaction.* = FAIL
......
......@@ -549,13 +549,6 @@
// Flat shading:
3430 VULKAN : dEQP-GLES3.functional.rasterization.flatshading.* = FAIL
// Instanced rendering:
2672 VULKAN : dEQP-GLES3.functional.draw.draw_arrays_instanced.line_loop.* = SKIP
2672 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.line_loop.* = SKIP
2672 VULKAN : dEQP-GLES3.functional.draw.random.* = SKIP
// - Primitive restart with line loops:
2672 VULKAN : dEQP-GLES3.functional.primitive_restart.*.line_loop.*instanced = SKIP
// Misc unimplemented:
// Failures on newer NVIDIA drivers (411.95) and passes on older drivers (388.16). Passes on 418.12 on Linux.
......@@ -570,5 +563,10 @@
2830 ANDROID VULKAN : dEQP-GLES3.functional.rasterization.primitives.line* = FAIL
2808 ANDROID VULKAN : dEQP-GLES3.functional.shaders.builtin_variable.fragcoord_w = FAIL
// Pixel driver issues
4024 PIXEL2 VULKAN : dEQP-GLES3.functional.draw.random.5 = SKIP
4024 PIXEL2 VULKAN : dEQP-GLES3.functional.draw.random.49 = SKIP
4024 PIXEL2 VULKAN : dEQP-GLES3.functional.draw.random.96 = FAIL
// Fixed in later driver versions.
2727 VULKAN ANDROID : dEQP-GLES3.functional.shaders.builtin_variable.pointcoord = FAIL
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