test(agc): cover NGG vertex programs routed to the mesh path
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a48b39e933
commit
0a1b31f5c4
|
|
@ -468,6 +468,36 @@ void ShaderStageTests() {
|
|||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "missing register");
|
||||
}
|
||||
|
||||
void NggVertexWorkgroupTests() {
|
||||
auto queue = makeState();
|
||||
queue.context[0x2d5] = 0x12010;
|
||||
queue.userConfig[0x242] = 4;
|
||||
queue.userConfig[0x25b] = 0x10080;
|
||||
queue.context[0x1ff] = 0x80;
|
||||
queue.context[0x2ce] = 0;
|
||||
queue.context[0x29b] = 2;
|
||||
queue.context[0x2ab] = 1;
|
||||
queue.shader[0x8a] = 0x222c0009;
|
||||
queue.shader[0x8b] = 0x43001e;
|
||||
queue.context[0x1b3] = 2;
|
||||
queue.context[0x1b4] = 2;
|
||||
Require(AgcDriver::Graphics::DecodeState(queue).stages.path == AgcDriver::Graphics::ShaderPath::Vertex, "an NGG vertex program without a workgroup left the vertex path");
|
||||
auto state = AgcDriver::Graphics::DecodeState(queue, true);
|
||||
Require(state.stages.path == AgcDriver::Graphics::ShaderPath::Geometry && state.stages.mesh, "an NGG vertex program that needs a workgroup did not take the mesh path");
|
||||
auto mesh = *state.stages.mesh;
|
||||
Require(mesh.inputPrimitive == 4 && mesh.primitivesPerGroup == 42 && mesh.verticesPerGroup == 126 && mesh.maxVertices == 128 && mesh.maxPrimitives == 128 && mesh.threadsPerGroup == 128 && mesh.ldsSizeDwords == 1024 && mesh.esgsItemSize == 1, "the NGG vertex subgroup of a triangle list changed");
|
||||
queue.userConfig[0x242] = 6;
|
||||
mesh = *AgcDriver::Graphics::DecodeState(queue, true).stages.mesh;
|
||||
Require(mesh.primitivesPerGroup == 126 && mesh.verticesPerGroup == 128 && mesh.maxPrimitives == 128, "the NGG vertex subgroup of a triangle strip is not bounded by its vertex budget");
|
||||
queue.context[0x1ff] = 2;
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue, true); }, "invalid geometry subgroup output");
|
||||
queue.context[0x1ff] = 0x80;
|
||||
for (const auto stages : {0x02012010u, 0x00012030u, 0x00010010u}) {
|
||||
queue.context[0x2d5] = stages;
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue, true); }, "requires PRIMGEN_EN without GS_EN, PRIMGEN_PASSTHRU_EN or tessellation");
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::array<std::uint8_t, 8> IdentityExports{0xe4u, 0xe4u, 0xe4u, 0xe4u, 0xe4u, 0xe4u, 0xe4u, 0xe4u};
|
||||
|
||||
std::vector<spv::BuiltIn> pixelBuiltinsRead(std::uint32_t ena, std::uint32_t addr, std::uint32_t source) {
|
||||
|
|
@ -4043,6 +4073,7 @@ int main() {
|
|||
uint16ExportTests();
|
||||
uint8x4TargetTests();
|
||||
ShaderStageTests();
|
||||
NggVertexWorkgroupTests();
|
||||
TuningFieldTests();
|
||||
PixelInputLayoutTests();
|
||||
ColorPipeBankXorTests();
|
||||
|
|
|
|||
|
|
@ -602,6 +602,21 @@ void testProgramSnapshots() {
|
|||
check(AgcDriver::DriverDetail::DecodeProgramsCurrent(decode, shaders), "a decode with the rewritten program was not current");
|
||||
}
|
||||
|
||||
void testProgramWorkgroupUse() {
|
||||
const auto snapshot = [](std::vector<std::uint32_t> code) {
|
||||
AgcDriver::DriverDetail::ShaderSnapshot result{0x1000, 0, 2, std::move(code), {}};
|
||||
return result;
|
||||
};
|
||||
const auto plain = snapshot({0xbf800000, 0xbf810000});
|
||||
check(!AgcDriver::DriverDetail::ProgramUsesWorkgroup(plain, 0) && !AgcDriver::DriverDetail::ProgramUsesWorkgroup(plain, 0), "a program without LDS or barriers needs a workgroup");
|
||||
const auto barrier = snapshot({0xbf8a0000, 0xbf810000});
|
||||
check(AgcDriver::DriverDetail::ProgramUsesWorkgroup(barrier, 0), "an s_barrier did not need a workgroup");
|
||||
const auto lds = snapshot({0xd8340000, 0x00000100, 0xbf810000});
|
||||
check(AgcDriver::DriverDetail::ProgramUsesWorkgroup(lds, 0) && AgcDriver::DriverDetail::ProgramUsesWorkgroup(lds, 0), "an LDS write did not need a workgroup");
|
||||
const auto entry = snapshot({0xbf8a0000, 0xbf810000, 0xbf800000, 0xbf810000});
|
||||
check(!AgcDriver::DriverDetail::ProgramUsesWorkgroup(entry, 2) && AgcDriver::DriverDetail::ProgramUsesWorkgroup(entry, 0), "the workgroup check did not start at the program's entry");
|
||||
}
|
||||
|
||||
void testWorkerFailure() {
|
||||
std::array<std::uint32_t, 5> words{0xc0031500, 1, 1, 1, 0x41};
|
||||
Packet packet{words.data(), static_cast<std::uint32_t>(words.size()), 0, {}};
|
||||
|
|
@ -694,6 +709,7 @@ int main() {
|
|||
check(!unterminated.empty() && bounded->code.size() == 64, "raw compute crossed inaccessible memory or missed its last instruction");
|
||||
#endif
|
||||
testProgramSnapshots();
|
||||
testProgramWorkgroupUse();
|
||||
testEvents();
|
||||
testValidation();
|
||||
testClearState();
|
||||
|
|
|
|||
Loading…
Reference in New Issue