fix(agc): accept valid hardware screen offset values

This commit is contained in:
boykopovar committed 2026-09-23 16:22:20 +03:00
1 parent 069ee78158
commit f129f6cde5
3 files changed
+25 -2

No files matched your search

+2 -1
View File
@@ -13,7 +13,8 @@ Execution reaches `_start`, [stack unwinding](core/libs/prx/libc/src/exception/U
The [shader recompiler](core/shader/recompiler/Recompiler.cpp) successfully produces validated via [Spirv-Tools](3rdparty/SPIRV-Tools) SPIR-V.
The application reaches the render loop and **successfully presents its first frame** (logo).
Current exception: `AGC graphics: unsupported primitive type 17`.
Current exception: `AGC graphics: unsupported SPIR-V memory model` on 6 frame.
## Build
@@ -159,7 +159,7 @@ State DecodeState(const QueueState& queue) {
zero(cx, 0x292, ~2u, "scan conversion mode");
zero(cx, 0x293, ~0x06003fffu, "sample iteration, primitive discard or out-of-order rasterization");
zero(cx, 0x80, ~0u, "window offset");
zero(cx, 0x8d, ~0u, "hardware screen offset");
zero(cx, 0x8d, ~0x01ff01ffu, "reserved PA_SU_HARDWARE_SCREEN_OFFSET bits");
Require(read(cx, 0x83) == 0xffffu, "clip rectangles are unsupported");
Require((read(cx, 0x8c) & 0xfu) == 0xau, "nonstandard triangle edge rules are unsupported");
Require(read(cx, 0x2f9) == 0x2du, "nonstandard pixel center or vertex quantization is unsupported");
@@ -116,6 +116,27 @@ void stateTests() {
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "non-finite");
}
void hardwareScreenOffsetTests() {
auto queue = makeState();
queue.context[0x90] = 0x80010003;
queue.context[0x91] = 0x30020;
const auto reference = AgcDriver::Graphics::DecodeState(queue);
for (const auto offset : {0u, 1u, 0x10000u, 0x0020003cu, 0x01ff0000u, 0x000001ffu, 0x01ff01ffu}) {
queue.context[0x8d] = offset;
const auto state = AgcDriver::Graphics::DecodeState(queue);
Require(state.viewport.x == reference.viewport.x && state.viewport.y == reference.viewport.y && state.viewport.width == reference.viewport.width && state.viewport.height == reference.viewport.height && state.viewport.minDepth == reference.viewport.minDepth && state.viewport.maxDepth == reference.viewport.maxDepth, "hardware guard-band offset changed the viewport");
Require(state.scissor.offset.x == reference.scissor.offset.x && state.scissor.offset.y == reference.scissor.offset.y && state.scissor.extent.width == reference.scissor.extent.width && state.scissor.extent.height == reference.scissor.extent.height, "hardware guard-band offset changed the scissor");
Require(state.renderExtent.width == reference.renderExtent.width && state.renderExtent.height == reference.renderExtent.height, "hardware guard-band offset changed the framebuffer extent");
}
for (std::uint32_t bit = 0; bit < 32; ++bit) {
if (bit < 9 || (bit >= 16 && bit < 25)) continue;
queue.context[0x8d] = 1u << bit;
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "reserved PA_SU_HARDWARE_SCREEN_OFFSET bits");
}
queue.context.erase(0x8d);
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "missing register");
}
void ShaderStageTests() {
auto queue = makeState();
for (const auto routing : {0x2000u, 0x2010u, 0x02002000u, 0x02002010u}) {
@@ -1121,6 +1142,7 @@ int main() {
expectFailure([&] { AgcDriver::Graphics::Draw(context, state, draw, {}); }, "draw modifiers");
}
stateTests();
hardwareScreenOffsetTests();
DepthClipTests();
DisabledColorTests();
ShaderStageTests();