Commit c713abfd by Tobin Ehlis Committed by Commit Bot

Vulkan:Transform/feedback instanced draw support

These fixes allow dEQP 3.1 KHR-GLES31.core.vertex_attrib_binding.basic-input* test cases to pass. This fixes a bug in instanced drawing with transform feedback buffers where we were overwriting the initial transform feedback output as new instances were drawn. To fix this, the vertices in each draw are passed into a uniform value and the output is offset based on the current instance and the number of vertices in the draw. It also fixes a validation error where transform feedback descriptor was sometimes setting a buffer range of 0. This is not allowed, so in the 0 case we pull the actual buffer size from the bufferHelper object. Bug: angleproject:4236 Change-Id: Ib72898a0e6caab96c446c1e996a6124d2c001193 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1979600 Commit-Queue: Tobin Ehlis <tobine@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com>
parent 67d8b63a
......@@ -168,14 +168,15 @@ constexpr const char kHalfRenderAreaHeight[] = "halfRenderAreaHeight";
constexpr const char kViewportYScale[] = "viewportYScale";
constexpr const char kNegViewportYScale[] = "negViewportYScale";
constexpr const char kXfbActiveUnpaused[] = "xfbActiveUnpaused";
constexpr const char kXfbVerticesPerDraw[] = "xfbVerticesPerDraw";
constexpr const char kXfbBufferOffsets[] = "xfbBufferOffsets";
constexpr const char kAcbBufferOffsets[] = "acbBufferOffsets";
constexpr const char kDepthRange[] = "depthRange";
constexpr size_t kNumGraphicsDriverUniforms = 8;
constexpr size_t kNumGraphicsDriverUniforms = 9;
constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = {
{kViewport, kHalfRenderAreaHeight, kViewportYScale, kNegViewportYScale, kXfbActiveUnpaused,
kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange}};
kXfbVerticesPerDraw, kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange}};
constexpr size_t kNumComputeDriverUniforms = 1;
constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
......@@ -376,6 +377,8 @@ const TVariable *AddGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTa
new TType(EbtFloat),
new TType(EbtFloat),
new TType(EbtUInt),
new TType(EbtUInt),
// NOTE: There's a vec3 gap here that can be used in the future
new TType(EbtInt, 4),
new TType(EbtUInt, 4),
emulatedDepthRangeType,
......
......@@ -444,8 +444,11 @@ std::string GenerateTransformFeedbackVaryingOutput(const gl::TransformFeedbackVa
for (int row = 0; row < info.rowCount; ++row)
{
result << "xfbOut" << bufferIndex << "[ANGLEUniforms.xfbBufferOffsets["
<< bufferIndex << "] + gl_VertexIndex * " << stride << " + " << offset
<< "] = " << info.glslAsFloat << "(" << varying.mappedName;
<< bufferIndex
<< "] + (gl_VertexIndex + gl_InstanceIndex * "
"ANGLEUniforms.xfbVerticesPerDraw) * "
<< stride << " + " << offset << "] = " << info.glslAsFloat << "("
<< varying.mappedName;
if (varying.isArray())
{
......
......@@ -381,6 +381,9 @@ class ContextMtl : public ContextImpl, public mtl::Context
// NOTE(hqle): Transform feedsback is not supported yet.
uint32_t xfbActiveUnpaused;
uint32_t xfbVerticesPerDraw;
// NOTE: Explicit padding. Fill in with useful data when needed in the future.
int32_t padding[3];
int32_t xfbBufferOffsets[4];
uint32_t acbBufferOffsets[4];
......
......@@ -55,6 +55,9 @@ struct GraphicsDriverUniforms
float viewportYScale;
float negViewportYScale;
uint32_t xfbActiveUnpaused;
uint32_t xfbVerticesPerDraw;
// NOTE: Explicit padding. Fill in with useful data when needed in the future.
std::array<int32_t, 3> padding;
std::array<int32_t, 4> xfbBufferOffsets;
......@@ -514,6 +517,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mLastIndexBufferOffset(0),
mCurrentDrawElementsType(gl::DrawElementsType::InvalidEnum),
mXfbBaseVertex(0),
mXfbVertexCountPerInstance(0),
mClearColorMask(kAllColorChannelsMask),
mFlipYForCurrentSurface(false),
mIsAnyHostVisibleBufferWritten(false),
......@@ -813,7 +817,8 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
if (mState.isTransformFeedbackActiveUnpaused())
{
ASSERT(firstVertexOrInvalid != -1);
mXfbBaseVertex = firstVertexOrInvalid;
mXfbBaseVertex = firstVertexOrInvalid;
mXfbVertexCountPerInstance = vertexOrIndexCount;
invalidateGraphicsDriverUniforms();
}
......@@ -2923,6 +2928,8 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co
scaleY,
-scaleY,
xfbActiveUnpaused,
mXfbVertexCountPerInstance,
{},
{},
{},
{depthRangeNear, depthRangeFar, depthRangeDiff, 0.0f}};
......
......@@ -714,6 +714,8 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
// not yet ubiquitous, which would have otherwise removed the need for this value to be passed
// as a uniform.
GLint mXfbBaseVertex;
// Cache the current draw call's vertex count as well to support instanced draw calls
GLuint mXfbVertexCountPerInstance;
// Cached clear value/mask for color and depth/stencil.
VkClearValue mClearColorValue;
......
......@@ -252,7 +252,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
std::array<VkDescriptorBufferInfo, gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>
descriptorBufferInfo;
// Write default uniforms for each shader type.
// Update buffer descriptor binding info for output buffers
for (size_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{
VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[bufferIndex];
......@@ -268,8 +268,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
bufferInfo.range = mTransformFeedbackBufferRange.sizes[bufferIndex] +
(mTransformFeedbackBufferRange.offsets[bufferIndex] -
mTransformFeedbackBufferRange.alignedOffsets[bufferIndex]);
// This is a tmp fix for VK validation error that will be improved in follow-on
bufferInfo.range = (bufferInfo.range == 0) ? VK_WHOLE_SIZE : bufferInfo.range;
bufferInfo.range = (bufferInfo.range == 0) ? bufferHelper.getSize() : bufferInfo.range;
}
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo.data(), descSet);
......
......@@ -73,11 +73,6 @@
3569 : KHR-GLES31.core.shader_bitfield_operation.umulExtended.* = SKIP
3569 : KHR-GLES31.core.shader_bitfield_operation.imulExtended.* = SKIP
// Trigger Vulkan validation errors:
4145 VULKAN : KHR-GLES31.core.vertex_attrib_binding.basic-input-case9 = FAIL
4145 VULKAN : KHR-GLES31.core.vertex_attrib_binding.basic-input-case11 = FAIL
4145 VULKAN : KHR-GLES31.core.vertex_attrib_binding.basic-inputI-case2 = FAIL
// Crashes in libnvidia-glvkspirv.so, fixed in newer drivers
4128 VULKAN NVIDIA : KHR-GLES31.core.shader_storage_buffer_object.advanced-unsizedArrayLength-cs-*-matC* = SKIP
4128 VULKAN NVIDIA : KHR-GLES31.core.shader_storage_buffer_object.advanced-unsizedArrayLength-vs-*-matC* = 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