Commit 90df527f by Alexis Hetu Committed by Alexis Hétu

Negative baseVertex support

baseVertex is a signed integer that's allowed have a negative value. In order to support it, the offset was moved from being applied on the index buffer memory pointer directly to being applied to the indices from the index buffer inside the Vertex routine. Fixes all issues in the following subcategory using SwANGLE: dEQP-GLES31.functional.draw_indirect.* Bug: b/144353667 Change-Id: Ia70c258eab25c274553c4955dc2336a42d43f005 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38148 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent b2407dd7
...@@ -70,13 +70,9 @@ namespace sw ...@@ -70,13 +70,9 @@ namespace sw
{ {
assert(it->second.SizeInComponents == 1); assert(it->second.SizeInComponents == 1);
Int4 indices;
indices = Insert(indices, As<Int>(batch[0]), 0);
indices = Insert(indices, As<Int>(batch[1]), 1);
indices = Insert(indices, As<Int>(batch[2]), 2);
indices = Insert(indices, As<Int>(batch[3]), 3);
routine.getVariable(it->second.Id)[it->second.FirstComponent] = routine.getVariable(it->second.Id)[it->second.FirstComponent] =
As<Float4>(indices + Int4(*Pointer<Int>(data + OFFSET(DrawData, baseVertex)))); As<Float4>(*Pointer<Int4>(As<Pointer<Int4>>(batch)) +
Int4(*Pointer<Int>(data + OFFSET(DrawData, baseVertex))));
} }
auto activeLaneMask = SIMD::Int(0xFFFFFFFF); auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
......
...@@ -94,13 +94,14 @@ namespace sw ...@@ -94,13 +94,14 @@ namespace sw
{ {
Pointer<Byte> input = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, input) + sizeof(void*) * (i / 4)); Pointer<Byte> input = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, input) + sizeof(void*) * (i / 4));
UInt stride = *Pointer<UInt>(data + OFFSET(DrawData, stride) + sizeof(uint32_t) * (i / 4)); UInt stride = *Pointer<UInt>(data + OFFSET(DrawData, stride) + sizeof(uint32_t) * (i / 4));
Int baseVertex = *Pointer<Int>(data + OFFSET(DrawData, baseVertex));
UInt robustnessSize(0); UInt robustnessSize(0);
if(state.robustBufferAccess) if(state.robustBufferAccess)
{ {
robustnessSize = *Pointer<UInt>(data + OFFSET(DrawData, robustnessSize) + sizeof(uint32_t) * (i / 4)); robustnessSize = *Pointer<UInt>(data + OFFSET(DrawData, robustnessSize) + sizeof(uint32_t) * (i / 4));
} }
auto value = readStream(input, stride, state.input[i / 4], batch, state.robustBufferAccess, robustnessSize); auto value = readStream(input, stride, state.input[i / 4], batch, state.robustBufferAccess, robustnessSize, baseVertex);
routine.inputs[i + 0] = value.x; routine.inputs[i + 0] = value.x;
routine.inputs[i + 1] = value.y; routine.inputs[i + 1] = value.y;
routine.inputs[i + 2] = value.z; routine.inputs[i + 2] = value.z;
...@@ -143,10 +144,15 @@ namespace sw ...@@ -143,10 +144,15 @@ namespace sw
} }
Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const Stream &stream, Pointer<UInt> &batch, Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const Stream &stream, Pointer<UInt> &batch,
bool robustBufferAccess, UInt & robustnessSize) bool robustBufferAccess, UInt & robustnessSize, Int baseVertex)
{ {
Vector4f v; Vector4f v;
UInt4 offsets = *Pointer<UInt4>(As<Pointer<UInt4>>(batch)) * UInt4(stride); // Because of the following rule in the Vulkan spec, we do not care if a very large negative
// baseVertex would overflow all the way back into a valid region of the index buffer:
// "Out-of-bounds buffer loads will return any of the following values :
// - Values from anywhere within the memory range(s) bound to the buffer (possibly including
// bytes of memory past the end of the buffer, up to the end of the bound range)."
UInt4 offsets = (*Pointer<UInt4>(As<Pointer<UInt4>>(batch)) + As<UInt4>(Int4(baseVertex))) * UInt4(stride);
Pointer<Byte> source0 = buffer + offsets.x; Pointer<Byte> source0 = buffer + offsets.x;
Pointer<Byte> source1 = buffer + offsets.y; Pointer<Byte> source1 = buffer + offsets.y;
......
...@@ -67,7 +67,7 @@ namespace sw ...@@ -67,7 +67,7 @@ namespace sw
typedef VertexProcessor::State::Input Stream; typedef VertexProcessor::State::Input Stream;
Vector4f readStream(Pointer<Byte> &buffer, UInt &stride, const Stream &stream, Pointer<UInt> &batch, Vector4f readStream(Pointer<Byte> &buffer, UInt &stride, const Stream &stream, Pointer<UInt> &batch,
bool robustBufferAccess, UInt& robustnessSize); bool robustBufferAccess, UInt& robustnessSize, Int baseVertex);
void readInput(Pointer<UInt> &batch); void readInput(Pointer<UInt> &batch);
void computeClipFlags(); void computeClipFlags();
void writeCache(Pointer<Byte> &vertexCache, Pointer<UInt> &tagCache, Pointer<UInt> &batch); void writeCache(Pointer<Byte> &vertexCache, Pointer<UInt> &tagCache, Pointer<UInt> &batch);
......
...@@ -411,7 +411,7 @@ private: ...@@ -411,7 +411,7 @@ private:
uint32_t reference; uint32_t reference;
}; };
void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int firstVertex, int firstInstance) void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int firstInstance)
{ {
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++) for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
{ {
...@@ -420,7 +420,6 @@ void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int f ...@@ -420,7 +420,6 @@ void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int f
{ {
const auto &vertexInput = vertexInputBindings[attrib.binding]; const auto &vertexInput = vertexInputBindings[attrib.binding];
VkDeviceSize offset = attrib.offset + vertexInput.offset + VkDeviceSize offset = attrib.offset + vertexInput.offset +
attrib.vertexStride * firstVertex +
attrib.instanceStride * firstInstance; attrib.instanceStride * firstInstance;
attrib.buffer = vertexInput.buffer ? vertexInput.buffer->getOffsetPointer(offset) : nullptr; attrib.buffer = vertexInput.buffer ? vertexInput.buffer->getOffsetPointer(offset) : nullptr;
...@@ -524,7 +523,7 @@ struct DrawBase : public CommandBuffer::Command ...@@ -524,7 +523,7 @@ struct DrawBase : public CommandBuffer::Command
sw::Context context = pipeline->getContext(); sw::Context context = pipeline->getContext();
executionState.bindVertexInputs(context, vertexOffset, firstInstance); executionState.bindVertexInputs(context, firstInstance);
context.descriptorSets = pipelineState.descriptorSets; context.descriptorSets = pipelineState.descriptorSets;
context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets; context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
......
...@@ -180,7 +180,7 @@ public: ...@@ -180,7 +180,7 @@ public:
uint32_t subpassIndex = 0; uint32_t subpassIndex = 0;
void bindAttachments(sw::Context& context); void bindAttachments(sw::Context& context);
void bindVertexInputs(sw::Context& context, int firstVertex, int firstInstance); void bindVertexInputs(sw::Context& context, int firstInstance);
}; };
void submit(CommandBuffer::ExecutionState& executionState); void submit(CommandBuffer::ExecutionState& executionState);
......
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