Commit 2806a898 by James Dong Committed by Commit Bot

Vulkan: implement primitive restart

Implements ES 3.0 feature GL_PRIMITIVE_RESTART_FIXED_INDEX, which allows the application to use a fixed "restart" index to restart the primitive during a single draw call. This change does't handle GL_LINE_LOOP primitives, which requires a bit of special handling. Bug: angleproject:3215 Change-Id: I2388852683fd17328a6a76c48d70a24d67ce8b67 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1650301Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
parent 4316e064
......@@ -274,7 +274,9 @@
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/BufferUtils.comp.0000000B.inc":
"065aaa20cdad29b5f5d2916eb3d096fc",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000000.inc":
"449ed947f0a7923a26b9fe1fa9c02a47",
"7ab9d6aa6dba8271f68df9c6f5355e44",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000001.inc":
"4726c9620a56bee224983d28d979fd39",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000000.inc":
"d4e48d64aa66fcf3c09330c4234ba349",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000001.inc":
......@@ -400,7 +402,7 @@
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp":
"0c8c050841543da0d7faca2559212aa8",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ConvertIndex.comp":
"f7675f4b3c966022e5bd222823b5a094",
"ca35df77d258baa0636529d1f0f446a9",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ConvertVertex.comp":
"93649f61036c2fa4739988ad71f413df",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/FullScreenQuad.vert":
......@@ -410,9 +412,9 @@
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ImageCopy.frag":
"20c83ade1efb48a802dc34ca838a2be6",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp":
"75538dc8198ce0c1c3f41d351fb6f5a2",
"7891716bf0c429ddacfbb2823f166dc6",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h":
"bb6cb68410a9e8f0143046f1e034ceaf",
"63e63b37508787d66a0e4aab7e36ffd8",
"Vulkan internal shader programs:tools/glslang/glslang_validator.exe.sha1":
"9f1f0fc61116a657e065c40f9296e5ab",
"Vulkan internal shader programs:tools/glslang/glslang_validator.sha1":
......
......@@ -1504,6 +1504,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getLineWidth());
break;
case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
mGraphicsPipelineDesc->updatePrimitiveRestartEnabled(
&mGraphicsPipelineTransition, glState.isPrimitiveRestartEnabled());
break;
case gl::State::DIRTY_BIT_CLEAR_COLOR:
mClearColorValue.color.float32[0] = glState.getColorClearValue().red;
......
......@@ -647,11 +647,17 @@ angle::Result UtilsVk::convertIndexBuffer(ContextVk *contextVk,
ConvertIndexShaderParams shaderParams = {params.srcOffset, params.dstOffset >> 2,
params.maxIndex, 0};
uint32_t flags = 0;
if (contextVk->getState().isPrimitiveRestartEnabled())
{
flags |= vk::InternalShader::ConvertIndex_comp::kIsPrimitiveRestartEnabled;
}
vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
ANGLE_TRY(contextVk->getShaderLibrary().getConvertIndex_comp(contextVk, 0, &shader));
ANGLE_TRY(contextVk->getShaderLibrary().getConvertIndex_comp(contextVk, flags, &shader));
ANGLE_TRY(setupProgram(contextVk, Function::ConvertIndexBuffer, shader, nullptr,
&mConvertIndexPrograms[0], nullptr, descriptorSet, &shaderParams,
&mConvertIndexPrograms[flags], nullptr, descriptorSet, &shaderParams,
sizeof(ConvertIndexShaderParams), commandBuffer));
constexpr uint32_t kInvocationsPerGroup = 64;
......
......@@ -189,13 +189,37 @@ angle::Result VertexArrayVk::convertIndexBufferCPU(ContextVk *contextVk,
// memory to a GLushort.
const GLubyte *in = static_cast<const GLubyte *>(sourcePointer);
GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
for (size_t index = 0; index < indexCount; index++)
bool primitiveRestart = contextVk->getState().isPrimitiveRestartEnabled();
constexpr GLubyte kUnsignedByteRestartValue = 0xFF;
constexpr GLushort kUnsignedShortRestartValue = 0xFFFF;
if (primitiveRestart)
{
expandedDst[index] = static_cast<GLushort>(in[index]);
for (size_t index = 0; index < indexCount; index++)
{
GLushort value = static_cast<GLushort>(in[index]);
if (in[index] == kUnsignedByteRestartValue)
{
// Convert from 8-bit restart value to 16-bit restart value
value = kUnsignedShortRestartValue;
}
expandedDst[index] = value;
}
}
else
{
// Fast path for common case.
for (size_t index = 0; index < indexCount; index++)
{
expandedDst[index] = static_cast<GLushort>(in[index]);
}
}
}
else
{
// The primitive restart value is the same for OpenGL and Vulkan,
// so there's no need to perform any conversion.
memcpy(dst, sourcePointer, amount);
}
ANGLE_TRY(dynamicBuffer->flush(contextVk));
......
......@@ -7,7 +7,9 @@
//
// The following defines tweak the functionality, and a different shader is built based on these.
//
// (Currently no parameters)
// - Flags:
// * IsPrimitiveRestartEnabled: enables conversion from 0xFF to 0xFFFF,
// the restart indices for 8-bit and 16-bit indices.
//
#version 450 core
......@@ -34,7 +36,7 @@ layout (push_constant) uniform PushConstants
uint dstOffsetDiv4;
// Maximum size of the read buffer. The highest index value we will convert.
uint maxIndex;
// Not used in the shader. Kept to pad "PushContants" to the size of a vec4.
// Not used in the shader. Kept to pad "PushConstants" to the size of a vec4.
uint _padding;
};
......@@ -44,7 +46,14 @@ uint PullIndex(uint index)
uint srcBlock = srcData[srcIndex >> 2];
uint srcComponent = (srcIndex & 3);
return (srcBlock >> (srcComponent << 3)) & 0xFF;
uint value = (srcBlock >> (srcComponent << 3)) & 0xFF;
#if IsPrimitiveRestartEnabled
// convert 0xFF (restart value for 8-bit indices)
// to 0xFFFF (restart value for 16-bit indices).
if (value == 0xFF)
value = 0xFFFF;
#endif
return value;
}
void PackIndexValue(uint srcValue, uint indexIndex, inout uint dstValue)
......@@ -53,9 +62,6 @@ void PackIndexValue(uint srcValue, uint indexIndex, inout uint dstValue)
dstValue |= srcValue << (indexIndex << 4);
}
// Note: Once support for primitive restart is added, the shader needs to
// convert 0xFF -> 0xFFFF. http://anglebug.com/3215
void main()
{
// The element index is simply the invocation ID times two.
......
......@@ -5,5 +5,8 @@
"found in the LICENSE file.",
"",
"ConvertIndex.comp.json: Build parameters for ConvertIndex.comp."
],
"Flags": [
"IsPrimitiveRestartEnabled"
]
}
......@@ -830,6 +830,14 @@ void GraphicsPipelineDesc::updateTopology(GraphicsPipelineTransitionBits *transi
transition->set(ANGLE_GET_TRANSITION_BIT(mInputAssemblyAndColorBlendStateInfo, primitive));
}
void GraphicsPipelineDesc::updatePrimitiveRestartEnabled(GraphicsPipelineTransitionBits *transition,
bool primitiveRestartEnabled)
{
mInputAssemblyAndColorBlendStateInfo.primitive.restartEnable =
static_cast<uint16_t>(primitiveRestartEnabled);
transition->set(ANGLE_GET_TRANSITION_BIT(mInputAssemblyAndColorBlendStateInfo, primitive));
}
void GraphicsPipelineDesc::updateCullMode(GraphicsPipelineTransitionBits *transition,
const gl::RasterizerState &rasterState)
{
......
......@@ -375,6 +375,8 @@ class GraphicsPipelineDesc final
// Input assembly info
void updateTopology(GraphicsPipelineTransitionBits *transition, gl::PrimitiveMode drawMode);
void updatePrimitiveRestartEnabled(GraphicsPipelineTransitionBits *transition,
bool primitiveRestartEnabled);
// Raster states
void updateCullMode(GraphicsPipelineTransitionBits *transition,
......
......@@ -57,6 +57,7 @@ namespace
#include "libANGLE/renderer/vulkan/shaders/gen/BufferUtils.comp.0000000A.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/BufferUtils.comp.0000000B.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertIndex.comp.00000001.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"
......@@ -172,6 +173,7 @@ constexpr ShaderBlob kBufferUtils_comp_shaders[] = {
};
constexpr ShaderBlob kConvertIndex_comp_shaders[] = {
{kConvertIndex_comp_00000000, sizeof(kConvertIndex_comp_00000000)},
{kConvertIndex_comp_00000001, sizeof(kConvertIndex_comp_00000001)},
};
constexpr ShaderBlob kConvertVertex_comp_shaders[] = {
{kConvertVertex_comp_00000000, sizeof(kConvertVertex_comp_00000000)},
......
......@@ -50,6 +50,7 @@ angle_vulkan_internal_shaders = [
"shaders/gen/BufferUtils.comp.0000000A.inc",
"shaders/gen/BufferUtils.comp.0000000B.inc",
"shaders/gen/ConvertIndex.comp.00000000.inc",
"shaders/gen/ConvertIndex.comp.00000001.inc",
"shaders/gen/ConvertVertex.comp.00000000.inc",
"shaders/gen/ConvertVertex.comp.00000001.inc",
"shaders/gen/ConvertVertex.comp.00000002.inc",
......
......@@ -70,7 +70,11 @@ constexpr size_t kArrayLen = 0x0000000C;
namespace ConvertIndex_comp
{
constexpr size_t kArrayLen = 0x00000001;
enum flags
{
kIsPrimitiveRestartEnabled = 0x00000001,
};
constexpr size_t kArrayLen = 0x00000002;
} // namespace ConvertIndex_comp
namespace ConvertVertex_comp
......
......@@ -657,8 +657,15 @@
// - FramebufferVk::invalidate*:
2950 VULKAN : dEQP-GLES3.functional.fbo.invalidate.* = SKIP
// - Primitive restart:
2950 VULKAN : dEQP-GLES3.functional.primitive_restart.* = SKIP
// - Primitive restart with line loops:
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.basic.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.duplicate_restarts.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.end_restart.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.end_restart_duplicate_restarts.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.begin_restart.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.begin_restart_duplicate_restarts.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.begin_restart_end_restart.line_loop.* = SKIP
3215 VULKAN : dEQP-GLES3.functional.primitive_restart.begin_restart_end_restart_duplicate_restarts.line_loop.* = SKIP
// - BufferVk::copySubData:
2950 VULKAN : dEQP-GLES3.functional.negative_api.buffer.copy_buffer_sub_data = SKIP
......
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