Prevent extra vertices from being processed
Extra vertices are added at the end of the vertex list when
processing a batch in order to avoid SIMD width overrun.
A single comparison can prevent us from processing these
vertices by disabling them in the stores and atomics mask.
This would fix the following tests:
dEQP-VK.synchronization.op.single_queue.*
when enabling the vertexPipelineStoresAndAtomics feature.
Note that these tests are affected because they wrongly
assume vertices won't be processed more than once. These
tests should still get fixed.
Bug b/140294254
Change-Id: I04185b899a9770537c3d10bcfd87e00e314582de
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/36368
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/VertexProgram.cpp b/src/Pipeline/VertexProgram.cpp
index dedf800..5bb3918 100644
--- a/src/Pipeline/VertexProgram.cpp
+++ b/src/Pipeline/VertexProgram.cpp
@@ -63,7 +63,7 @@
{
}
- void VertexProgram::program(Pointer<UInt> &batch)
+ void VertexProgram::program(Pointer<UInt> &batch, UInt& vertexCount)
{
auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex);
if (it != spirvShader->inputBuiltins.end())
@@ -80,7 +80,8 @@
}
auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
- spirvShader->emit(&routine, activeLaneMask, activeLaneMask, descriptorSets);
+ Int4 storesAndAtomicsMask = CmpGE(UInt4(vertexCount), UInt4(1, 2, 3, 4));
+ spirvShader->emit(&routine, activeLaneMask, storesAndAtomicsMask, descriptorSets);
spirvShader->emitEpilog(&routine);
}
diff --git a/src/Pipeline/VertexProgram.hpp b/src/Pipeline/VertexProgram.hpp
index 3c8a664..7baee79 100644
--- a/src/Pipeline/VertexProgram.hpp
+++ b/src/Pipeline/VertexProgram.hpp
@@ -34,7 +34,7 @@
virtual ~VertexProgram();
private:
- void program(Pointer<UInt> &batch) override;
+ void program(Pointer<UInt> &batch, UInt& vertexCount) override;
const vk::DescriptorSet::Bindings &descriptorSets;
};
diff --git a/src/Pipeline/VertexRoutine.cpp b/src/Pipeline/VertexRoutine.cpp
index e43e96b..be84300 100644
--- a/src/Pipeline/VertexRoutine.cpp
+++ b/src/Pipeline/VertexRoutine.cpp
@@ -60,7 +60,7 @@
If(tagCache[cacheIndex] != index)
{
readInput(batch);
- program(batch);
+ program(batch, vertexCount);
computeClipFlags();
writeCache(vertexCache, tagCache, batch);
diff --git a/src/Pipeline/VertexRoutine.hpp b/src/Pipeline/VertexRoutine.hpp
index dc22ecb..5a0a6e2 100644
--- a/src/Pipeline/VertexRoutine.hpp
+++ b/src/Pipeline/VertexRoutine.hpp
@@ -62,7 +62,7 @@
SpirvShader const * const spirvShader;
private:
- virtual void program(Pointer<UInt> &batch) = 0;
+ virtual void program(Pointer<UInt> &batch, UInt& vertexCount) = 0;
typedef VertexProcessor::State::Input Stream;