Cull zero homogeneous vertex positions before rasterization

Fix Playroom top right artifact on Nvidia by clipping zero-position vertices.
This commit is contained in:
nmzik
2026-09-15 09:50:12 +04:00
parent a1fbc41146
commit 86414760e6
8 changed files with 135 additions and 17 deletions
+21 -7
View File
@@ -10106,10 +10106,10 @@ void TestNewShaderRecompilerAuxPositionExports() {
std::vector<uint32_t>({UINT32_MAX}),
"MISC point-size/layer stores are missing");
Check(SpirvStoredBuiltInElements(all.spirv, 3u) ==
std::vector<uint32_t>({0u, 3u}) &&
std::vector<uint32_t>({0u, 3u, 4u}) &&
SpirvStoredBuiltInElements(all.spirv, 4u) ==
std::vector<uint32_t>({0u, 1u, 2u}),
"partial clip/cull exports used the wrong dense elements");
"partial clip/cull exports or the appended clipping-error plane used the wrong elements");
Check(SpirvHasDecorationValue(all.spirv, 11u, 1u) &&
SpirvHasDecorationValue(all.spirv, 11u, 3u) &&
SpirvHasDecorationValue(all.spirv, 11u, 4u) &&
@@ -10143,7 +10143,7 @@ void TestNewShaderRecompilerAuxPositionExports() {
CheckSpirvBinaryValidates(dense.spirv);
Check(SpirvStoredBuiltInElements(dense.spirv, 0u).size() == 1u &&
SpirvStoredBuiltInElements(dense.spirv, 3u) ==
std::vector<uint32_t>({1u}) &&
std::vector<uint32_t>({1u, 2u}) &&
SpirvStoredBuiltInElements(dense.spirv, 4u) ==
std::vector<uint32_t>({0u}),
"CCDIST1 was not densely packed into POS1");
@@ -10158,11 +10158,24 @@ void TestNewShaderRecompilerAuxPositionExports() {
CheckSpirvBinaryValidates(shifted.spirv);
Check(SpirvStoredBuiltInElements(shifted.spirv, 1u).size() == 1u &&
SpirvStoredBuiltInElements(shifted.spirv, 3u) ==
std::vector<uint32_t>({0u}) &&
std::vector<uint32_t>({0u, 1u}) &&
SpirvStoredBuiltInElements(shifted.spirv, 4u) ==
std::vector<uint32_t>({0u}),
"CCDIST1 did not shift across a disabled CCDIST0 vector");
const uint32_t full_distances[] = {
EncodeExp0(0x0c, 0xf, false), EncodeExp1(0, 1, 2, 3),
EncodeExp0(0x0d, 0xf, false), EncodeExp1(4, 5, 6, 7),
EncodeExp0(0x0e, 0xf), EncodeExp1(8, 9, 10, 11), 0xbf810000u,
};
const auto full = compile(full_distances, 0x00c0f00fu);
CheckSpirvBinaryValidates(full.spirv);
Check(SpirvStoredBuiltInElements(full.spirv, 3u) ==
std::vector<uint32_t>({0u, 1u, 2u, 3u}) &&
SpirvStoredBuiltInElements(full.spirv, 4u) ==
std::vector<uint32_t>({0u, 1u, 2u, 3u}),
"clipping-error plane exceeded eight combined components or replaced a guest distance");
const uint32_t unmapped[] = {
EncodeExp0(0x0d, 0x4, false), EncodeExp1(0, 0, 8, 0),
EncodeExp0(0x0c, 0xf), EncodeExp1(0, 1, 2, 3),
@@ -13035,7 +13048,8 @@ void TestRepeatedExportsHaveOneInterface() {
}
offset += result.spirv[offset] >> spv::WordCountShift;
}
Check(outputs == 1, "repeated exports produced duplicate output variables");
Check(outputs == 2 && SpirvHasDecorationValue(result.spirv, 11u, 3u),
"repeated exports duplicated Position or its clipping-error plane");
}
void TestNewShaderRecompilerSpirvSizeBaselines() {
@@ -13251,10 +13265,10 @@ void TestNewShaderRecompilerSpirvSizeBaselines() {
};
const auto wqm_result = compile("wqm", wqm,
{.words = 407,
.instructions = 98,
.instructions = 99,
.variables = 4,
.loads = 3,
.stores = 1,
.stores = 2,
.labels = 6,
.selection_merges = 1,
.branches = 4,