mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
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:
committed by
GitHub
parent
0791f921f6
commit
0a5774be7b
@@ -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}) {
|
||||
|
||||
Reference in New Issue
Block a user