shader: support FP64 conversions used by FighterZ (#884)

shader: support float and unsigned widening to FP64

Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
gohansharma79-svg
2026-09-28 19:09:31 +05:30
committed by GitHub
parent 0791f921f6
commit 0a5774be7b
9 changed files with 104 additions and 3 deletions
+80
View File
@@ -16709,6 +16709,8 @@ CoverageClass ClassifyOpcode(ShaderOpcode opcode,
case Opcode::V_DOT2C_F32_F16:
case Opcode::V_CVT_F64_I32:
case Opcode::V_CVT_F32_F64:
case Opcode::V_CVT_F64_F32:
case Opcode::V_CVT_F64_U32:
case Opcode::V_RCP_F64:
case Opcode::V_MUL_F64:
case Opcode::V_FMA_F64:
@@ -22122,6 +22124,83 @@ TestCase VectorF64CapturedScreenSpaceShadows() {
return test;
}
TestCase VectorF64WideningConversions() {
using O = ShaderOpcode;
TestCase test;
test.name = "VectorF64WideningConversions";
const auto store_pair = [&](u32 reg, uint64_t bits) {
AppendStoreVgpr(&test.code, reg, static_cast<u32>(test.expected.size()));
AppendStoreVgpr(&test.code, reg + 1,
static_cast<u32>(test.expected.size() + 1));
test.expected.insert(test.expected.end(), {static_cast<u32>(bits),
static_cast<u32>(bits >> 32)});
};
for (const u32 bits :
{0u, 0x80000000u, 0x3f800001u, 0xbf800001u, 0x00800000u, 0x7f7fffffu,
0xff7fffffu, 0x7f800000u, 0xff800000u, 1u, 0x80000001u}) {
AppendSMovLiteral(&test.code, 8, bits);
test.code.push_back(0x7e002008u);
const auto source = (bits & 0x7f800000u) == 0 ? bits & 0x80000000u : bits;
store_pair(0, std::bit_cast<uint64_t>(
static_cast<double>(std::bit_cast<float>(source))));
}
for (const u32 bits : {0x7fc12345u, 0x7f812345u}) {
AppendSMovLiteral(&test.code, 8, bits);
test.code.push_back(0x7e002008u);
AppendVMovLiteral(&test.code, 3, 0x7ff80000u);
test.code.push_back(EncodeVop2(0x1b, 1, Vgpr(3), 1));
AppendStoreVgpr(&test.code, 1, static_cast<u32>(test.expected.size()));
test.expected.push_back(0x7ff80000u);
}
AppendVMovLiteral(&test.code, 1, std::bit_cast<u32>(-3.5f));
AppendVop3(&test.code, 0x190, 1, Vgpr(1), 0, 0, 1, 0, false, 0, 1);
store_pair(1, std::bit_cast<uint64_t>(-3.5));
for (const u32 value :
{0u, 1u, 16777217u, 0x7fffffffu, 0x80000000u, 0xffffffffu}) {
AppendVMovLiteral(&test.code, 1, value);
test.code.push_back(EncodeVop1(0x16, 1, Vgpr(1)));
store_pair(1, std::bit_cast<uint64_t>(static_cast<double>(value)));
}
AppendSMovLiteral(&test.code, 8, 0xffffffffu);
AppendVop3(&test.code, 0x196, 1, 8u, 0);
store_pair(1, std::bit_cast<uint64_t>(4294967295.0));
test.code.push_back(EncodeSop1(0x04, 12, 126));
test.code.push_back(EncodeSop1(0x04, 126, InlineU32(0)));
test.code.push_back(EncodeVop1(0x10, 1, InlineU32(0)));
test.code.push_back(EncodeVop1(0x16, 1, InlineU32(0)));
test.code.push_back(EncodeSop1(0x04, 126, 12));
store_pair(1, std::bit_cast<uint64_t>(4294967295.0));
AppendEnd(&test.code);
test.opcodes = {O::S_MOV_B32, O::S_MOV_B64, O::V_MOV_B32,
O::V_AND_B32, O::V_CVT_F64_F32, O::V_CVT_F64_U32,
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
test.required_spirv = {"OpCapability Float64", "OpTypeFloat 64", "OpFConvert",
"OpConvertUToF"};
std::vector<u32> vertex_code;
AppendSMovLiteral(&vertex_code, 8, std::bit_cast<u32>(2.0f));
vertex_code.insert(vertex_code.end(),
{0x7e002008u, 0x7e005f00u, 0x7e401f00u});
vertex_code.push_back(EncodeExp0(0x0c, 0xf));
vertex_code.push_back(EncodeExp1(32, 32, 32, 32));
AppendEnd(&vertex_code);
ShaderVertexInputInfo vertex{};
ShaderRecompiler::CompileOptions options;
options.stage = ShaderType::Vertex;
options.input_info.vertex = &vertex;
auto translated = ShaderRecompiler::TranslateProgram(vertex_code, options);
auto result =
ShaderRecompiler::CompileProgram(std::move(translated), options, {});
ValidateSpirv(test.name, result.spirv);
Require(test.name, "captured vertex conversion chain",
result.ir_dump.find("ConvertF64F32") != std::string::npos &&
result.ir_dump.find("FPRecip64") != std::string::npos &&
result.ir_dump.find("ConvertF32F64") != std::string::npos,
"vertex compilation lost the captured widening/reciprocal/narrowing "
"sequence");
return test;
}
TestCase VectorF64ModesModifiersAndExec() {
using O = ShaderOpcode;
TestCase test;
@@ -29876,6 +29955,7 @@ std::vector<TestCase> MakeCases() {
AddCase(VectorRcpIflagF32IntegerReciprocal);
AddCase(VectorF64CapturedScreenSpaceShadows);
AddCase(VectorF64ModesModifiersAndExec);
AddCase(VectorF64WideningConversions);
AddCase(VectorSinCosMaxFiniteSpecialCases);
AddCase(VectorCompareF32ExposureGuard);
for (const auto mode : {0xc0u, 0xe0u}) {