Commit bf3d9333 by James Dong Committed by Commit Bot

Vulkan: support relative offset in attrib bindings

Handles the ES 3.1 relative offset parameter in vertex attributes by adding it to the binding offset. Test: ./angle_deqp_gles31_no_gtest --deqp-egl-display-type=angle-vulkan -n dEQP-GLES31.functional.vertex_attribute_binding.usage.single_binding.unaligned_offset_elements_1_aligned_elements Bug: angleproject:3598 Change-Id: Idbbd5ba4868a4dfc8f99188a84a5cd1374e09065 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1724453Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: James Dong <dongja@google.com>
parent 758b12fa
...@@ -29,17 +29,19 @@ constexpr size_t kDynamicIndexDataSize = 1024 * 8; ...@@ -29,17 +29,19 @@ constexpr size_t kDynamicIndexDataSize = 1024 * 8;
ANGLE_INLINE bool BindingIsAligned(const gl::VertexBinding &binding, ANGLE_INLINE bool BindingIsAligned(const gl::VertexBinding &binding,
const angle::Format &angleFormat, const angle::Format &angleFormat,
unsigned int attribSize) unsigned int attribSize,
GLuint relativeOffset)
{ {
GLintptr totalOffset = binding.getOffset() + relativeOffset;
GLuint mask = angleFormat.componentAlignmentMask; GLuint mask = angleFormat.componentAlignmentMask;
if (mask != std::numeric_limits<GLuint>::max()) if (mask != std::numeric_limits<GLuint>::max())
{ {
return ((binding.getOffset() & mask) == 0 && (binding.getStride() & mask) == 0); return ((totalOffset & mask) == 0 && (binding.getStride() & mask) == 0);
} }
else else
{ {
unsigned int formatSize = angleFormat.pixelBytes; unsigned int formatSize = angleFormat.pixelBytes;
return ((binding.getOffset() * attribSize) % formatSize == 0) && return ((totalOffset * attribSize) % formatSize == 0) &&
((binding.getStride() * attribSize) % formatSize == 0); ((binding.getStride() * attribSize) % formatSize == 0);
} }
} }
...@@ -233,7 +235,8 @@ angle::Result VertexArrayVk::convertVertexBufferGPU(ContextVk *contextVk, ...@@ -233,7 +235,8 @@ angle::Result VertexArrayVk::convertVertexBufferGPU(ContextVk *contextVk,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
const vk::Format &vertexFormat, const vk::Format &vertexFormat,
ConversionBuffer *conversion) ConversionBuffer *conversion,
GLuint relativeOffset)
{ {
const angle::Format &srcFormat = vertexFormat.angleFormat(); const angle::Format &srcFormat = vertexFormat.angleFormat();
const angle::Format &destFormat = vertexFormat.bufferFormat(); const angle::Format &destFormat = vertexFormat.bufferFormat();
...@@ -264,7 +267,7 @@ angle::Result VertexArrayVk::convertVertexBufferGPU(ContextVk *contextVk, ...@@ -264,7 +267,7 @@ angle::Result VertexArrayVk::convertVertexBufferGPU(ContextVk *contextVk,
params.srcFormat = &srcFormat; params.srcFormat = &srcFormat;
params.destFormat = &destFormat; params.destFormat = &destFormat;
params.srcStride = binding.getStride(); params.srcStride = binding.getStride();
params.srcOffset = binding.getOffset(); params.srcOffset = binding.getOffset() + relativeOffset;
params.destOffset = static_cast<size_t>(conversion->lastAllocationOffset); params.destOffset = static_cast<size_t>(conversion->lastAllocationOffset);
ANGLE_TRY(contextVk->getUtils().convertVertexBuffer( ANGLE_TRY(contextVk->getUtils().convertVertexBuffer(
...@@ -278,7 +281,8 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk, ...@@ -278,7 +281,8 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
const vk::Format &vertexFormat, const vk::Format &vertexFormat,
ConversionBuffer *conversion) ConversionBuffer *conversion,
GLuint relativeOffset)
{ {
ANGLE_TRACE_EVENT0("gpu.angle", "VertexArrayVk::convertVertexBufferCpu"); ANGLE_TRACE_EVENT0("gpu.angle", "VertexArrayVk::convertVertexBufferCpu");
// Needed before reading buffer or we could get stale data. // Needed before reading buffer or we could get stale data.
...@@ -298,7 +302,7 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk, ...@@ -298,7 +302,7 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
void *src = nullptr; void *src = nullptr;
ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src)); ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src); const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
srcBytes += binding.getOffset(); srcBytes += binding.getOffset() + relativeOffset;
ASSERT(GetVertexInputAlignment(vertexFormat) <= vk::kVertexBufferAlignment); ASSERT(GetVertexInputAlignment(vertexFormat) <= vk::kVertexBufferAlignment);
ANGLE_TRY(StreamVertexData(contextVk, &conversion->data, srcBytes, numVertices * dstFormatSize, ANGLE_TRY(StreamVertexData(contextVk, &conversion->data, srcBytes, numVertices * dstFormatSize,
0, numVertices, binding.getStride(), vertexFormat.vertexLoadFunction, 0, numVertices, binding.getStride(), vertexFormat.vertexLoadFunction,
...@@ -434,35 +438,38 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -434,35 +438,38 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
{ {
BufferVk *bufferVk = vk::GetImpl(bufferGL); BufferVk *bufferVk = vk::GetImpl(bufferGL);
const angle::Format &angleFormat = vertexFormat.angleFormat(); const angle::Format &angleFormat = vertexFormat.angleFormat();
bool bindingIsAligned = bool bindingIsAligned = BindingIsAligned(binding, angleFormat, angleFormat.channelCount,
BindingIsAligned(binding, angleFormat, angleFormat.channelCount); attrib.relativeOffset);
if (vertexFormat.vertexLoadRequiresConversion || !bindingIsAligned) if (vertexFormat.vertexLoadRequiresConversion || !bindingIsAligned)
{ {
stride = vertexFormat.bufferFormat().pixelBytes; stride = vertexFormat.bufferFormat().pixelBytes;
// This will require supporting relativeOffset in ES 3.1.
ConversionBuffer *conversion = bufferVk->getVertexConversionBuffer( ConversionBuffer *conversion = bufferVk->getVertexConversionBuffer(
renderer, angleFormat.id, binding.getStride(), binding.getOffset()); renderer, angleFormat.id, binding.getStride(),
binding.getOffset() + attrib.relativeOffset);
if (conversion->dirty) if (conversion->dirty)
{ {
if (bindingIsAligned) if (bindingIsAligned)
{ {
ANGLE_TRY(convertVertexBufferGPU(contextVk, bufferVk, binding, attribIndex, ANGLE_TRY(convertVertexBufferGPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat, conversion)); vertexFormat, conversion,
attrib.relativeOffset));
anyVertexBufferConvertedOnGpu = true; anyVertexBufferConvertedOnGpu = true;
} }
else else
{ {
ANGLE_TRY(convertVertexBufferCPU(contextVk, bufferVk, binding, attribIndex, ANGLE_TRY(convertVertexBufferCPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat, conversion)); vertexFormat, conversion,
attrib.relativeOffset));
} }
} }
mCurrentArrayBuffers[attribIndex] = conversion->data.getCurrentBuffer(); mCurrentArrayBuffers[attribIndex] = conversion->data.getCurrentBuffer();
mCurrentArrayBufferHandles[attribIndex] = mCurrentArrayBufferHandles[attribIndex] =
mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle(); mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = conversion->lastAllocationOffset; mCurrentArrayBufferOffsets[attribIndex] =
conversion->lastAllocationOffset - attrib.relativeOffset;
} }
else else
{ {
......
...@@ -95,13 +95,15 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -95,13 +95,15 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex, size_t attribIndex,
const vk::Format &vertexFormat, const vk::Format &vertexFormat,
ConversionBuffer *conversion); ConversionBuffer *conversion,
GLuint relativeOffset);
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,
const vk::Format &vertexFormat, const vk::Format &vertexFormat,
ConversionBuffer *conversion); ConversionBuffer *conversion,
GLuint relativeOffset);
angle::Result syncDirtyAttrib(ContextVk *contextVk, angle::Result syncDirtyAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib, const gl::VertexAttribute &attrib,
......
...@@ -735,5 +735,3 @@ ...@@ -735,5 +735,3 @@
// Validation errors: // Validation errors:
// Optimal tiling not supported for format: // Optimal tiling not supported for format:
3520 VULKAN : dEQP-GLES31.functional.state_query.texture_level.texture* = SKIP 3520 VULKAN : dEQP-GLES31.functional.state_query.texture_level.texture* = SKIP
// Invalid vertex attribute alignment:
3520 VULKAN : dEQP-GLES31.functional.vertex_attribute_binding.usage.single_binding.unaligned_offset_elements_1_aligned_elements = 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