From c0a98e3a6a09e68c5bec9976c1b8ff39d09c99bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Franch?= Date: Mon, 5 Oct 2026 04:45:57 +0200 Subject: [PATCH] fix(shader): refuse s_setpc_b64 after s_sub with the immediate first Co-Authored-By: Claude --- .../tests/execution/ScalarSetpc.cpp | 316 ++++++++++++++++++ .../ControlFlow/src/GraphBuilder.cpp | 2 +- 2 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 core/libs/prx/libSceAgcDriver/tests/execution/ScalarSetpc.cpp diff --git a/core/libs/prx/libSceAgcDriver/tests/execution/ScalarSetpc.cpp b/core/libs/prx/libSceAgcDriver/tests/execution/ScalarSetpc.cpp new file mode 100644 index 000000000..bc390fee3 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/tests/execution/ScalarSetpc.cpp @@ -0,0 +1,316 @@ +#include "prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp" +#include "prx/libSceAgcDriver/Graphics/include/Draw.hpp" +#include "Recompiler.hpp" +#include "VulkanTestDevice.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +using AgcDriver::Graphics::Require; +using ShaderRecompiler::ShaderStage; + +constexpr std::uint32_t MaxThreads = 64; +constexpr std::uint32_t Inputs = 4; +constexpr std::uint32_t Results = 16; +constexpr std::uint32_t Checked = 5; +alignas(256) std::array Input{}; +alignas(256) std::array Output{}; + +alignas(256) constexpr std::array Wave32Code{ + 0x34020084, 0x34060086, 0xe0381000, 0x80000401, 0xbf8c3f70, 0x7e1402ff, 0xdeadbeef, 0x7e1602ff, + 0xdeadbeef, 0x7e1802ff, 0xdeadbeef, 0x7e1a02ff, 0xdeadbeef, 0x7e1c02ff, 0xdeadbeef, 0xbe940380, + 0xd7600008, 0x02002904, 0xd760000b, 0x02002905, 0xd760000a, 0x02002906, 0xbe930308, 0x83888308, + 0x8f088308, 0xbe8c1f00, 0x800cff0c, 0x00000178, 0x820d800d, 0xf4040386, 0x10000000, 0xbf8cc07f, + 0xbe901f00, 0x80100e10, 0x82110f11, 0xbe802010, 0x8009ff0a, 0x11110000, 0xbf820008, 0x8009ff0a, + 0x22220000, 0xbf820005, 0x8009ff0a, 0x33330000, 0xbf820002, 0x8009ff0a, 0x44440000, 0xd761000a, + 0x02002809, 0xbe880313, 0x83888208, 0x8f088308, 0xbe981f00, 0x8018ff18, 0x00000124, 0x82198019, + 0xf404068c, 0x10000008, 0xbf8cc07f, 0xbe9c1f00, 0x801c1a1c, 0x821d1b1d, 0xbe80201c, 0x8909ff0a, + 0x0000a000, 0xbf820006, 0x8909ff0a, 0x0000b000, 0xbf820003, 0x8909ff0a, 0x0000c000, 0xbf820000, + 0xd761000b, 0x02002809, 0xbe89030a, 0xbe901f00, 0x8010ff10, 0x00000018, 0xbe802010, 0xbe8903ff, + 0x00000bad, 0x8909c109, 0x80098109, 0xd761000c, 0x02002809, 0x8712870b, 0xbe890380, 0x80090a09, + 0x80928112, 0xbf06c112, 0xbf850004, 0xbe901f00, 0x8110ff10, 0xffffffec, 0xbe802010, 0xd761000d, + 0x02002809, 0x9012840b, 0x87128312, 0xbe89030a, 0x8f098109, 0x8909ff09, 0x9e3779b9, 0xbf068012, + 0xbf850005, 0x80928112, 0xbe901f00, 0x8090ff10, 0x0000001c, 0xbe802010, 0xd761000e, 0x02002809, + 0x80148114, 0xbf0aa014, 0xbf85ff9d, 0xe0781000, 0x80010a03, 0xe0781010, 0x80010e03, 0xbf810000, + 0x0000000c, 0x00000000, 0x00000018, 0x00000000, 0x00000024, 0x00000000, 0x00000030, 0x00000000, + 0x0000000c, 0x00000000, 0x00000018, 0x00000000, 0x00000024, 0x00000000, +}; + +alignas(256) constexpr std::array Wave64Code{ + 0x34020084, 0x34060086, 0xe0381000, 0x80000401, 0xbf8c3f70, 0x7e1402ff, 0xdeadbeef, 0x7e1602ff, + 0xdeadbeef, 0x7e1802ff, 0xdeadbeef, 0x7e1a02ff, 0xdeadbeef, 0x7e1c02ff, 0xdeadbeef, 0xbe940380, + 0xd7600008, 0x02002904, 0xd760000b, 0x02002905, 0xd760000a, 0x02002906, 0xbe930308, 0x83888308, + 0x8f088308, 0xbe8c1f00, 0x800cff0c, 0x00000178, 0x820d800d, 0xf4040386, 0x10000000, 0xbf8cc07f, + 0xbe901f00, 0x80100e10, 0x82110f11, 0xbe802010, 0x8009ff0a, 0x11110000, 0xbf820008, 0x8009ff0a, + 0x22220000, 0xbf820005, 0x8009ff0a, 0x33330000, 0xbf820002, 0x8009ff0a, 0x44440000, 0xd761000a, + 0x02002809, 0xbe880313, 0x83888208, 0x8f088308, 0xbe981f00, 0x8018ff18, 0x00000124, 0x82198019, + 0xf404068c, 0x10000008, 0xbf8cc07f, 0xbe9c1f00, 0x801c1a1c, 0x821d1b1d, 0xbe80201c, 0x8909ff0a, + 0x0000a000, 0xbf820006, 0x8909ff0a, 0x0000b000, 0xbf820003, 0x8909ff0a, 0x0000c000, 0xbf820000, + 0xd761000b, 0x02002809, 0xbe89030a, 0xbe901f00, 0x8010ff10, 0x00000018, 0xbe802010, 0xbe8903ff, + 0x00000bad, 0x8909c109, 0x80098109, 0xd761000c, 0x02002809, 0x8712870b, 0xbe890380, 0x80090a09, + 0x80928112, 0xbf06c112, 0xbf850004, 0xbe901f00, 0x8110ff10, 0xffffffec, 0xbe802010, 0xd761000d, + 0x02002809, 0x9012840b, 0x87128312, 0xbe89030a, 0x8f098109, 0x8909ff09, 0x9e3779b9, 0xbf068012, + 0xbf850005, 0x80928112, 0xbe901f00, 0x8090ff10, 0x0000001c, 0xbe802010, 0xd761000e, 0x02002809, + 0x80148114, 0xbf0ac014, 0xbf85ff9d, 0xe0781000, 0x80010a03, 0xe0781010, 0x80010e03, 0xbf810000, + 0x0000000c, 0x00000000, 0x00000018, 0x00000000, 0x00000024, 0x00000000, 0x00000030, 0x00000000, + 0x0000000c, 0x00000000, 0x00000018, 0x00000000, 0x00000024, 0x00000000, +}; + +alignas(256) constexpr std::array ReversedSubtractCode{ + 0xbe901f00, 0x809010c0, 0xbe802010, 0xbf810000, +}; + +constexpr std::uint32_t Rows[64][4] = { + {0x00000000u, 0x1e7ea419u, 0x51c9bc70u, 0x00000000u}, + {0x00000001u, 0x80a4df5au, 0xf38b2ffcu, 0x00000000u}, + {0x00000002u, 0x8306d03bu, 0xa5aec797u, 0x00000000u}, + {0x00000003u, 0xdc28ff90u, 0xf3f49249u, 0x00000000u}, + {0x00000004u, 0x1a466884u, 0xe255accbu, 0x00000000u}, + {0x00000005u, 0x39292d22u, 0xe5121482u, 0x00000000u}, + {0x00000007u, 0x99dd251du, 0x9f199504u, 0x00000000u}, + {0x00000008u, 0x8e7aa6e9u, 0x6bad6be2u, 0x00000000u}, + {0x00000010u, 0xc88b2875u, 0x9293de8fu, 0x00000000u}, + {0x7fffffffu, 0x8c3d5f16u, 0xd7a7a3ccu, 0x00000000u}, + {0x80000000u, 0xbb049a79u, 0xc6cd75e9u, 0x00000000u}, + {0xfffffff8u, 0xc4a334bfu, 0x7dabe929u, 0x00000000u}, + {0xffffffffu, 0xc0433cbdu, 0xc5e818fau, 0x00000000u}, + {0x00000000u, 0x96263ae6u, 0x70eb9a0au, 0x00000000u}, + {0x00000001u, 0x3d6c51e3u, 0x00a61f93u, 0x00000000u}, + {0x00000002u, 0x9d3c7decu, 0x14aa4e71u, 0x00000000u}, + {0x00000003u, 0x1c593af5u, 0x49889310u, 0x00000000u}, + {0x00000004u, 0xd11745adu, 0x1919e93au, 0x00000000u}, + {0x00000005u, 0x731c9452u, 0x02f0ee99u, 0x00000000u}, + {0x00000007u, 0xd0944996u, 0xe4163207u, 0x00000000u}, + {0x00000008u, 0xaf67d461u, 0x7d836e77u, 0x00000000u}, + {0x00000010u, 0xadec6f11u, 0x5071950eu, 0x00000000u}, + {0x7fffffffu, 0x35d14880u, 0x65b00a2du, 0x00000000u}, + {0x80000000u, 0x406329bcu, 0x59001ac9u, 0x00000000u}, + {0xfffffff8u, 0xfadb8908u, 0xffb88309u, 0x00000000u}, + {0xffffffffu, 0xede7bd0cu, 0x5b4c8012u, 0x00000000u}, + {0xffffffffu, 0x60581ccau, 0xffe976abu, 0x00000000u}, + {0xfffffff8u, 0x837a7935u, 0xa341738cu, 0x00000000u}, + {0x00000001u, 0xb91dddd9u, 0x57241955u, 0x00000000u}, + {0x00000001u, 0x8eb5140fu, 0x89be9c1cu, 0x00000000u}, + {0x00000004u, 0x49a047dcu, 0x751b4c83u, 0x00000000u}, + {0x00000002u, 0xe060a724u, 0xa51149bbu, 0x00000000u}, + {0xfffffff8u, 0xb766ff10u, 0x93d20470u, 0x00000000u}, + {0x00000004u, 0x06555096u, 0xd9090b89u, 0x00000000u}, + {0xfffffff8u, 0x5e6c9992u, 0x5d111a9du, 0x00000000u}, + {0x00000008u, 0x6c167229u, 0x17371472u, 0x00000000u}, + {0x00000007u, 0xe41686cdu, 0x95f19a51u, 0x00000000u}, + {0x00000010u, 0x7f9ac098u, 0xde0279e1u, 0x00000000u}, + {0x00000001u, 0x6ce9da66u, 0x81a0ba05u, 0x00000000u}, + {0xffffffffu, 0xc0099ebau, 0xdde3a361u, 0x00000000u}, + {0x7fffffffu, 0xe01c683eu, 0x7db4304du, 0x00000000u}, + {0x00000007u, 0xeab06e9bu, 0x864fa3f3u, 0x00000000u}, + {0x00000004u, 0xd82fb0f1u, 0x6b82e6c9u, 0x00000000u}, + {0x7fffffffu, 0xed1d9d16u, 0xfb759e0fu, 0x00000000u}, + {0x00000008u, 0x8350a73fu, 0x849acfb5u, 0x00000000u}, + {0xffffffffu, 0x067f0cfcu, 0x93550840u, 0x00000000u}, + {0x00000003u, 0xc40d31b5u, 0x2106119eu, 0x00000000u}, + {0x00000000u, 0xf675299bu, 0xb464c554u, 0x00000000u}, + {0x00000010u, 0xe306f0c4u, 0xaba4c70eu, 0x00000000u}, + {0x00000001u, 0xb7a1774fu, 0x9f4fb02bu, 0x00000000u}, + {0x00000007u, 0x78549014u, 0x2475263cu, 0x00000000u}, + {0x00000008u, 0xe261e34au, 0x3a9afa39u, 0x00000000u}, + {0x00000001u, 0xa06d7a69u, 0xb3618e1cu, 0x00000000u}, + {0x00000008u, 0xac9f21dfu, 0x782afe6bu, 0x00000000u}, + {0xfffffff8u, 0xedf165dau, 0xf5a9ca5fu, 0x00000000u}, + {0x00000010u, 0x4041f5eeu, 0x8f4ecb4fu, 0x00000000u}, + {0x00000007u, 0xab74fe57u, 0xff8b2a6au, 0x00000000u}, + {0x00000004u, 0x8c53765fu, 0xccbfd2ecu, 0x00000000u}, + {0x80000000u, 0x807c7e30u, 0xb2c55523u, 0x00000000u}, + {0x00000008u, 0xce0d8d87u, 0xe26b524au, 0x00000000u}, + {0x00000007u, 0x6edd77d8u, 0x33d91808u, 0x00000000u}, + {0x00000004u, 0xd4f398eeu, 0x44df8a13u, 0x00000000u}, + {0x00000000u, 0x0879d955u, 0x265c28eau, 0x00000000u}, + {0x80000000u, 0xe1cd7be8u, 0x98e6e5b7u, 0x00000000u} +}; + +constexpr std::uint32_t Expected32[32][5] = { + {0x62dabc70u, 0x51c91c70u, 0x51c9bc71u, 0xa39378e0u, 0xe57f7b0bu}, + {0x15ad2ffcu, 0xf38b9ffcu, 0xf38b2ffdu, 0xdaa18ff4u, 0x6c75353bu}, + {0xd8e1c797u, 0xa5ae0797u, 0xa5aec798u, 0x96bb1e5cu, 0x71d3d897u}, + {0x38389249u, 0xf3f45249u, 0xf3f4924au, 0xf3f49249u, 0x6d8bc3efu}, + {0x2699accbu, 0xe2556ccbu, 0xe255acccu, 0x6bac5ff7u, 0x5a9c202fu}, + {0x29561482u, 0xe512d482u, 0xe5121483u, 0xaf363d86u, 0xf214c83fu}, + {0xe35d9504u, 0x9f195504u, 0x9f199505u, 0xba997e18u, 0xde3fdedbu}, + {0xaff16be2u, 0x6badabe2u, 0x6bad6be3u, 0xd75ad7c4u, 0x87ef333fu}, + {0xd6d7de8fu, 0x92931e8fu, 0x9293de90u, 0x6f77375au, 0x02024917u}, + {0x1beba3ccu, 0xd7a763ccu, 0xd7a7a3cdu, 0xe5957a94u, 0xfcc705fbu}, + {0x0b1175e9u, 0xc6cdb5e9u, 0xc6cd75eau, 0x8d9aebd2u, 0x47e8ff77u}, + {0xc1efe929u, 0x7dab2929u, 0x7dabe92au, 0xed5f4948u, 0xf1813377u}, + {0x0a2c18fau, 0xc5e8d8fau, 0xc5e818fbu, 0xa37095dcu, 0x75be2e47u}, + {0x81fc9a0au, 0x70eb3a0au, 0x70eb9a0bu, 0x16713646u, 0x5dd8bc7fu}, + {0x22c81f93u, 0x00a6af93u, 0x00a61f94u, 0x02987e4cu, 0xdfb490b7u}, + {0x47dd4e71u, 0x14aa8e71u, 0x14aa4e72u, 0x67538835u, 0x7fd61fa7u}, + {0x8dcc9310u, 0x49885310u, 0x49889311u, 0xb9337260u, 0xb3b690e7u}, + {0x5d5de93au, 0x1919293au, 0x1919e93bu, 0x969b775cu, 0x124b25ffu}, + {0x4734ee99u, 0x02f02e99u, 0x02f0ee9au, 0x08d2cbcbu, 0xa99a30afu}, + {0x285a3207u, 0xe416f207u, 0xe4163208u, 0x3c9b5e31u, 0x320142d7u}, + {0xc1c76e77u, 0x7d83ae77u, 0x7d836e78u, 0xfb06dceeu, 0x369f1f97u}, + {0x94b5950eu, 0x5071550eu, 0x5071950fu, 0xa0e32a1cu, 0xe39fdef3u}, + {0xa9f40a2du, 0x65b0ca2du, 0x65b00a2eu, 0x65b00a2du, 0x55576de3u}, + {0x9d441ac9u, 0x5900dac9u, 0x59001acau, 0xbd0085edu, 0xbb3e0d77u}, + {0x43fc8309u, 0xffb84309u, 0xffb8830au, 0xffb88309u, 0x61467fabu}, + {0x9f908012u, 0x5b4c4012u, 0x5b4c8013u, 0xc87e805au, 0x28ae799du}, + {0x442d76abu, 0xffe9b6abu, 0xffe976acu, 0xffbc6401u, 0x61e594efu}, + {0xe785738cu, 0xa341b38cu, 0xa341738du, 0xd388b548u, 0x1f289927u}, + {0x79461955u, 0x5724a955u, 0x57241956u, 0xae4832aau, 0xfec9ef9fu}, + {0xabe09c1cu, 0x89be2c1cu, 0x89be9c1du, 0x4df4e0e0u, 0x8d4a4181u}, + {0xb95f4c83u, 0x751b8c83u, 0x751b4c84u, 0x49887e8fu, 0x7634b8c7u}, + {0xd84449bbu, 0xa51189bbu, 0xa51149bcu, 0x395670a7u, 0xf20e21f7u} +}; +constexpr std::uint32_t Expected64[64][5] = { + {0x62dabc70u, 0x51c91c70u, 0x51c9bc71u, 0xa39378e0u, 0xe57f7b0bu}, + {0x15ad2ffcu, 0xf38b9ffcu, 0xf38b2ffdu, 0xdaa18ff4u, 0x6c75353bu}, + {0xd8e1c797u, 0xa5ae0797u, 0xa5aec798u, 0x96bb1e5cu, 0x71d3d897u}, + {0x38389249u, 0xf3f45249u, 0xf3f4924au, 0xf3f49249u, 0x6d8bc3efu}, + {0x2699accbu, 0xe2556ccbu, 0xe255acccu, 0x6bac5ff7u, 0x5a9c202fu}, + {0x29561482u, 0xe512d482u, 0xe5121483u, 0xaf363d86u, 0xf214c83fu}, + {0xe35d9504u, 0x9f195504u, 0x9f199505u, 0xba997e18u, 0xde3fdedbu}, + {0xaff16be2u, 0x6badabe2u, 0x6bad6be3u, 0xd75ad7c4u, 0x87ef333fu}, + {0xd6d7de8fu, 0x92931e8fu, 0x9293de90u, 0x6f77375au, 0x02024917u}, + {0x1beba3ccu, 0xd7a763ccu, 0xd7a7a3cdu, 0xe5957a94u, 0xfcc705fbu}, + {0x0b1175e9u, 0xc6cdb5e9u, 0xc6cd75eau, 0x8d9aebd2u, 0x47e8ff77u}, + {0xc1efe929u, 0x7dab2929u, 0x7dabe92au, 0xed5f4948u, 0xf1813377u}, + {0x0a2c18fau, 0xc5e8d8fau, 0xc5e818fbu, 0xa37095dcu, 0x75be2e47u}, + {0x81fc9a0au, 0x70eb3a0au, 0x70eb9a0bu, 0x16713646u, 0x5dd8bc7fu}, + {0x22c81f93u, 0x00a6af93u, 0x00a61f94u, 0x02987e4cu, 0xdfb490b7u}, + {0x47dd4e71u, 0x14aa8e71u, 0x14aa4e72u, 0x67538835u, 0x7fd61fa7u}, + {0x8dcc9310u, 0x49885310u, 0x49889311u, 0xb9337260u, 0xb3b690e7u}, + {0x5d5de93au, 0x1919293au, 0x1919e93bu, 0x969b775cu, 0x124b25ffu}, + {0x4734ee99u, 0x02f02e99u, 0x02f0ee9au, 0x08d2cbcbu, 0xa99a30afu}, + {0x285a3207u, 0xe416f207u, 0xe4163208u, 0x3c9b5e31u, 0x320142d7u}, + {0xc1c76e77u, 0x7d83ae77u, 0x7d836e78u, 0xfb06dceeu, 0x369f1f97u}, + {0x94b5950eu, 0x5071550eu, 0x5071950fu, 0xa0e32a1cu, 0xe39fdef3u}, + {0xa9f40a2du, 0x65b0ca2du, 0x65b00a2eu, 0x65b00a2du, 0x55576de3u}, + {0x9d441ac9u, 0x5900dac9u, 0x59001acau, 0xbd0085edu, 0xbb3e0d77u}, + {0x43fc8309u, 0xffb84309u, 0xffb8830au, 0xffb88309u, 0x61467fabu}, + {0x9f908012u, 0x5b4c4012u, 0x5b4c8013u, 0xc87e805au, 0x28ae799du}, + {0x442d76abu, 0xffe9b6abu, 0xffe976acu, 0xffbc6401u, 0x61e594efu}, + {0xe785738cu, 0xa341b38cu, 0xa341738du, 0xd388b548u, 0x1f289927u}, + {0x79461955u, 0x5724a955u, 0x57241956u, 0xae4832aau, 0xfec9ef9fu}, + {0xabe09c1cu, 0x89be2c1cu, 0x89be9c1du, 0x4df4e0e0u, 0x8d4a4181u}, + {0xb95f4c83u, 0x751b8c83u, 0x751b4c84u, 0x49887e8fu, 0x7634b8c7u}, + {0xd84449bbu, 0xa51189bbu, 0xa51149bcu, 0x395670a7u, 0xf20e21f7u}, + {0xd8160470u, 0x93d2c470u, 0x93d20471u, 0x93d20470u, 0xed119b0bu}, + {0x1d4d0b89u, 0xd909cb89u, 0xd9090b8au, 0xef3f50bfu, 0xc67da4efu}, + {0xa1551a9du, 0x5d11da9du, 0x5d111a9eu, 0x17334fd7u, 0xd61de0bfu}, + {0x5b7b1472u, 0x1737d472u, 0x17371473u, 0x2e6e28e4u, 0x633ccfbfu}, + {0xda359a51u, 0x95f15a51u, 0x95f19a52u, 0x83a99de6u, 0xb5d44d1bu}, + {0x224679e1u, 0xde02b9e1u, 0xde0279e2u, 0xde0279e1u, 0xda506d4fu}, + {0xa3c2ba05u, 0x81a00a05u, 0x81a0ba06u, 0x8b651623u, 0xd781bc07u}, + {0x2227a361u, 0xdde36361u, 0xdde3a362u, 0x99aaea23u, 0xf50597f7u}, + {0xc1f8304du, 0x7db4f04du, 0x7db4304eu, 0x6fed521bu, 0xf07ca537u}, + {0xca93a3f3u, 0x864f63f3u, 0x864fa3f4u, 0x193e8fccu, 0xbb670507u}, + {0xafc6e6c9u, 0x6b8226c9u, 0x6b82e6cau, 0xd705cd92u, 0x9311cd77u}, + {0x3fb99e0fu, 0xfb755e0fu, 0xfb759e10u, 0xe0375269u, 0x4f8ff2f7u}, + {0xc8decfb5u, 0x849a0fb5u, 0x849acfb6u, 0x24d67da8u, 0x62935ab7u}, + {0xd7990840u, 0x9355c840u, 0x93550841u, 0xe0a92940u, 0x1e6f25e7u}, + {0x654a119eu, 0x2106d19eu, 0x2106119fu, 0xc62469b4u, 0x3b5eb807u}, + {0xc575c554u, 0xb4646554u, 0xb464c555u, 0xd1931550u, 0x73ca9f9bu}, + {0xefe8c70eu, 0xaba4070eu, 0xaba4c70fu, 0x5a37e346u, 0xc97ef7a5u}, + {0xc171b02bu, 0x9f4f002bu, 0x9f4fb02cu, 0xfa7d8158u, 0xa0a819efu}, + {0x68b9263cu, 0x2475e63cu, 0x2475263du, 0xb649bf2cu, 0x338d123bu}, + {0x7edefa39u, 0x3a9a3a39u, 0x3a9afa3au, 0xafd0eeabu, 0xeb028dcbu}, + {0xd5838e1cu, 0xb3613e1cu, 0xb3618e1du, 0x66c31c38u, 0x41881ccfu}, + {0xbc6efe6bu, 0x782a3e6bu, 0x782afe6cu, 0xc157f358u, 0x42f27367u}, + {0x39edca5fu, 0xf5a90a5fu, 0xf5a9ca60u, 0xe0fd5f1du, 0x74fea3b7u}, + {0xd392cb4fu, 0x8f4e0b4fu, 0x8f4ecb50u, 0xeb278f29u, 0xa0f23657u}, + {0x43cf2a6au, 0xff8bea6au, 0xff8b2a6bu, 0xfc595350u, 0x5c752363u}, + {0x1103d2ecu, 0xccbf12ecu, 0xccbfd2edu, 0x65fe9760u, 0x90a6c17bu}, + {0xf7095523u, 0xb2c59523u, 0xb2c55524u, 0xb2c55523u, 0x076af3d7u}, + {0x26af524au, 0xe26b924au, 0xe26b524bu, 0x135a9250u, 0x5ae1dd2du}, + {0x781d1808u, 0x33d9d808u, 0x33d91809u, 0x33d91808u, 0x6d3deaebu}, + {0x89238a13u, 0x44df4a13u, 0x44df8a14u, 0xe21cc685u, 0xfc783cb7u}, + {0x376d28eau, 0x265c88eau, 0x265c28ebu, 0xe628f57cu, 0x3b292963u}, + {0xdd2ae5b7u, 0x98e625b7u, 0x98e6e5b8u, 0x98e6e5b7u, 0x1db34197u} +}; + +constexpr const char* Names[Checked] = {"jump_table", "jump_table_offset", "skip_forward", "loop_add_negative", "loop_sub"}; + +std::array BufferDescriptor(const void* data, std::uint32_t bytes) { + const auto address = reinterpret_cast(data); + return {static_cast(address), static_cast((address >> 32u) & 0xffffu), bytes, 0x01016facu}; +} + +std::string Hex(std::uint32_t value) { + char text[16]; + std::snprintf(text, sizeof(text), "0x%08x", value); + return text; +} + +ShaderRecompiler::RecompileResult Compile(std::span code, std::uint32_t waveSize, const ShaderRecompiler::SpirvTarget& target) { + std::vector userData(8, 0u); + const auto input = BufferDescriptor(Input.data(), static_cast(Input.size() * 4u)); + const auto output = BufferDescriptor(Output.data(), static_cast(Output.size() * 4u)); + std::copy(input.begin(), input.end(), userData.begin()); + std::copy(output.begin(), output.end(), userData.begin() + 4); + const std::array memory{{{reinterpret_cast(code.data()), std::as_bytes(code)}}}; + const ShaderRecompiler::ShaderComputeStageInfo compute{{waveSize, 1, 1}, 0u, {false, false, false}, false, 1}; + ShaderRecompiler::RecompileRequest request{ + {ShaderStage::Compute, reinterpret_cast(code.data()), code, 0, {}}, + {waveSize, 0, userData, compute, std::nullopt, std::nullopt, memory}, + target, + {0, 0, 0, 128} + }; + request.useCache = false; + return ShaderRecompiler::Recompile(request); +} + +void Run(AgcDriver::VulkanDevice& device, std::span code, std::uint32_t waveSize, const ShaderRecompiler::SpirvTarget& target) { + for (std::uint32_t tid = 0; tid < MaxThreads; ++tid) std::copy(std::begin(Rows[tid]), std::end(Rows[tid]), &Input[tid * Inputs]); + Output.fill(0xdeadbeefu); + const auto result = Compile(code, waveSize, target); + device.Dispatch(result, 1, 1, 1, {}, reinterpret_cast(code.data())); + device.WaitIdle(); +} + +void CheckReversedSubtractRefused(AgcDriver::VulkanDevice& device) { + std::string refusal; + try { + static_cast(Compile(ReversedSubtractCode, 32, device.ComputeTarget(32))); + } catch (const std::exception& error) { + refusal = error.what(); + } + Require(refusal.find("unsupported dynamic s_setpc_b64") != std::string::npos, "s_setpc_b64 after s_sub_u32 with the immediate first was not refused"); +} + +template +void Check(const std::uint32_t (&expected)[Lanes][Checked]) { + for (std::uint32_t tid = 0; tid < Lanes; ++tid) { + for (std::uint32_t index = 0; index < Checked; ++index) { + const auto actual = Output[tid * Results + index]; + Require(actual == expected[tid][index], "setpc wave" + std::to_string(Lanes) + ": lane " + std::to_string(tid) + " " + Names[index] + " is " + Hex(actual) + ", expected " + Hex(expected[tid][index])); + } + } +} + +} + +int main() { + try { + const auto device = OpenVulkanTestDevice(); + if (!device) return VulkanTestSkipped; + Run(*device, Wave32Code, 32, device->ComputeTarget(32)); + Check(Expected32); + Run(*device, Wave64Code, 64, device->Target()); + Check(Expected64); + Run(*device, Wave64Code, 64, device->ComputeTarget(32)); + Check(Expected64); + CheckReversedSubtractRefused(*device); + std::puts("setpc tests passed"); + return 0; + } catch (const std::exception& error) { + std::cerr << error.what() << '\n'; + return 1; + } +} diff --git a/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp b/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp index 9d9ef50cb..bfbd51cce 100644 --- a/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp +++ b/core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp @@ -126,7 +126,7 @@ bool resolveSetpcTarget(const RdnaProgram& program, std::uint32_t setpcIndex, st if (getProgramCounter.op == RdnaOpcode::SGetpcB64 && getProgramCounter.destination.kind == RdnaOperandKind::ScalarRegister && getProgramCounter.destination.reg == pcRegister && arithmetic.destination.kind == RdnaOperandKind::ScalarRegister && arithmetic.destination.reg == pcRegister) { std::uint32_t immediate = 0; const bool adds = arithmetic.op == RdnaOpcode::SAddU32 || arithmetic.op == RdnaOpcode::SAddI32; - const bool subtracts = arithmetic.op == RdnaOpcode::SSubU32 || arithmetic.op == RdnaOpcode::SSubI32; + const bool subtracts = (arithmetic.op == RdnaOpcode::SSubU32 || arithmetic.op == RdnaOpcode::SSubI32) && isRegister(arithmetic.source0, RdnaOperandKind::ScalarRegister, pcRegister); if ((adds || subtracts) && (isRegister(arithmetic.source0, RdnaOperandKind::ScalarRegister, pcRegister) || isRegister(arithmetic.source1, RdnaOperandKind::ScalarRegister, pcRegister)) && (isImmediate(arithmetic.source0, immediate) || isImmediate(arithmetic.source1, immediate))) { const auto base = instructionEndProgramCounter(getProgramCounter); target = (adds ? base + immediate : base - immediate) & ~3u;