mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 03:16:54 +02:00
shader: took fixes from PR 427
- apply c8f34f9's ResourceTracking portability fix
- complete V_CMP_LT_U64 and S_FLBIT_I32_B32 support
- add the sceAmprCommandBufferWaitOnAddress NID from f625a47
- add decoder and compute tests for both shader operations
Co-authored-by: Mac <me@itsmemac.com>
This commit is contained in:
@@ -45,6 +45,7 @@ constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
|
||||
{0x10u, Opcode::S_BCNT1_I32_B64},
|
||||
{0x13u, Opcode::S_FF1_I32_B32},
|
||||
{0x14u, Opcode::S_FF1_I32_B64},
|
||||
{0x15u, Opcode::S_FLBIT_I32_B32},
|
||||
{0x16u, Opcode::S_FLBIT_I32_B64},
|
||||
{0x1bu, Opcode::S_BITSET0_B32},
|
||||
{0x1du, Opcode::S_BITSET1_B32},
|
||||
|
||||
@@ -476,6 +476,7 @@ std::string InstructionToString(const Instruction& inst) {
|
||||
case Opcode::S_ABS_I32:
|
||||
case Opcode::S_BREV_B32:
|
||||
case Opcode::S_BCNT1_I32_B32:
|
||||
case Opcode::S_FLBIT_I32_B32:
|
||||
case Opcode::S_FF1_I32_B32:
|
||||
case Opcode::S_FF1_I32_B64:
|
||||
case Opcode::S_NOT_B64:
|
||||
|
||||
@@ -45,6 +45,7 @@ enum class Opcode {
|
||||
S_BCNT1_I32_B64,
|
||||
S_FF1_I32_B32,
|
||||
S_FF1_I32_B64,
|
||||
S_FLBIT_I32_B32,
|
||||
S_FLBIT_I32_B64,
|
||||
S_BITREPLICATE_B64_B32,
|
||||
S_QUADMASK_B64,
|
||||
@@ -395,6 +396,7 @@ enum class Opcode {
|
||||
V_CMP_GE_U32,
|
||||
V_CMP_T_U32,
|
||||
V_CMP_EQ_I64,
|
||||
V_CMP_LT_U64,
|
||||
V_CMP_EQ_U64,
|
||||
V_CMP_GT_U64,
|
||||
V_CMP_NE_U64,
|
||||
|
||||
@@ -240,8 +240,9 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
|
||||
{0xb5u, Opcode::V_CMPX_NE_I64, false}, {0xd1u, Opcode::V_CMPX_LT_U32},
|
||||
{0xd2u, Opcode::V_CMPX_EQ_U32}, {0xd3u, Opcode::V_CMPX_LE_U32},
|
||||
{0xd4u, Opcode::V_CMPX_GT_U32}, {0xd5u, Opcode::V_CMPX_NE_U32},
|
||||
{0xd6u, Opcode::V_CMPX_GE_U32}, {0xe2u, Opcode::V_CMP_EQ_U64, false},
|
||||
{0xe4u, Opcode::V_CMP_GT_U64, false}, {0xe5u, Opcode::V_CMP_NE_U64, false},
|
||||
{0xd6u, Opcode::V_CMPX_GE_U32}, {0xe1u, Opcode::V_CMP_LT_U64, false},
|
||||
{0xe2u, Opcode::V_CMP_EQ_U64, false}, {0xe4u, Opcode::V_CMP_GT_U64, false},
|
||||
{0xe5u, Opcode::V_CMP_NE_U64, false},
|
||||
{0xf5u, Opcode::V_CMPX_NE_U64, false}, {0xc9u, Opcode::V_CMP_LT_F16},
|
||||
{0xcau, Opcode::V_CMP_EQ_F16}, {0xcbu, Opcode::V_CMP_LE_F16},
|
||||
{0xccu, Opcode::V_CMP_GT_F16}, {0xcdu, Opcode::V_CMP_LG_F16},
|
||||
|
||||
@@ -181,6 +181,7 @@ bool Translator::EmitScalar(const Decoder::Instruction& inst) {
|
||||
case O::S_XNOR_B32:
|
||||
return ComposedIntegerBinary(inst, IR::ValueOpcode::BitwiseXor32, false, true, true);
|
||||
case O::S_FF1_I32_B64: return S_FF1_I32_B64(inst);
|
||||
case O::S_FLBIT_I32_B32: return V_FFBH_32(inst, false);
|
||||
case O::S_FLBIT_I32_B64: return S_FLBIT_I32_B64(inst);
|
||||
|
||||
case O::S_BITSET0_B32: return S_BITSET_B32(inst, false);
|
||||
|
||||
@@ -99,6 +99,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) {
|
||||
case O::V_CMP_EQ_U64:
|
||||
EmitIntegerCompare(inst, IR::ValueOpcode::IEqual64, IR::Type::U64, false, false);
|
||||
return true;
|
||||
case O::V_CMP_LT_U64:
|
||||
EmitIntegerCompare(inst, IR::ValueOpcode::ULessThan64, IR::Type::U64, false, false);
|
||||
return true;
|
||||
case O::V_CMP_GT_U64:
|
||||
EmitIntegerCompare(inst, IR::ValueOpcode::UGreaterThan64, IR::Type::U64, false, false);
|
||||
return true;
|
||||
|
||||
@@ -139,7 +139,8 @@ public:
|
||||
}
|
||||
std::erase_if(m_program.dynamic_reads, [&](Value value) {
|
||||
const auto* inst = value.Resolve().TryInstruction();
|
||||
return std::ranges::any_of(m_indirect_images, [&](const IndirectImagePlan& plan) {
|
||||
return std::any_of(m_indirect_images.begin(), m_indirect_images.end(),
|
||||
[&](const IndirectImagePlan& plan) {
|
||||
return std::ranges::find(plan.reads, inst) != plan.reads.end();
|
||||
});
|
||||
});
|
||||
@@ -432,14 +433,16 @@ private:
|
||||
|
||||
const IndirectImagePlan* FindIndirectImage(const Inst& handle) const {
|
||||
const auto found =
|
||||
std::ranges::find_if(m_indirect_images, [&](const IndirectImagePlan& plan) {
|
||||
std::find_if(m_indirect_images.begin(), m_indirect_images.end(),
|
||||
[&](const IndirectImagePlan& plan) {
|
||||
return plan.handle == &handle;
|
||||
});
|
||||
return found == m_indirect_images.end() ? nullptr : &*found;
|
||||
}
|
||||
|
||||
bool IsIndirectPlanningMemory(uint32_t index) const {
|
||||
return std::ranges::any_of(m_indirect_images, [&](const IndirectImagePlan& plan) {
|
||||
return std::any_of(m_indirect_images.begin(), m_indirect_images.end(),
|
||||
[&](const IndirectImagePlan& plan) {
|
||||
return std::ranges::find(plan.memory, index) != plan.memory.end();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2665,6 +2665,7 @@ LIB_DEFINE(InitAmpr_1_Ampr) {
|
||||
LIB_FUNC("dXPaz65HNmk", Ampr::CommandBufferPushMarker);
|
||||
LIB_FUNC("mv0O8Zg0woU", Ampr::CommandBufferPopMarker);
|
||||
LIB_FUNC("DLfoNxTFNVk", Ampr::CommandBufferWaitOnAddress);
|
||||
LIB_FUNC("V7GQTEeUfhw", Ampr::CommandBufferWaitOnAddress);
|
||||
LIB_FUNC("cQb8Zr8Q0Y0", Ampr::CommandBufferWaitOnCounter);
|
||||
LIB_FUNC("j0+3uJMxYJY", Ampr::CommandBufferWriteAddress);
|
||||
LIB_FUNC("sJXyWHjP-F8", Ampr::CommandBufferWriteAddressOnCompletion);
|
||||
|
||||
@@ -12960,6 +12960,36 @@ TestCase ScalarFlbitI32B64Gpu() {
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase ScalarFlbitI32B32Gpu() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendSMovLiteral(&code, 0, 0x00000000u);
|
||||
code.push_back(EncodeSop1(0x15, 20, 0));
|
||||
|
||||
AppendSMovLiteral(&code, 0, 0x0000ccccu);
|
||||
code.push_back(EncodeSop1(0x15, 21, 0));
|
||||
|
||||
AppendSMovLiteral(&code, 0, 0x80000000u);
|
||||
code.push_back(EncodeSop1(0x15, 22, 0));
|
||||
|
||||
AppendSMovLiteral(&code, 0, 0x7fffffffu);
|
||||
code.push_back(EncodeSop1(0x15, 23, 0));
|
||||
|
||||
AppendStoreSgpr(&code, 20, 0);
|
||||
AppendStoreSgpr(&code, 21, 1);
|
||||
AppendStoreSgpr(&code, 22, 2);
|
||||
AppendStoreSgpr(&code, 23, 3);
|
||||
AppendEnd(&code);
|
||||
|
||||
return {"ScalarFlbitI32B32Gpu",
|
||||
code,
|
||||
{},
|
||||
{0xffffffffu, 16, 0, 1},
|
||||
{O::S_MOV_B32, O::S_FLBIT_I32_B32, O::V_MOV_B32,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase ScalarSaveExecOps() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -16091,6 +16121,36 @@ TestCase VectorVop3CompareGtU64OnGpu() {
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase VectorVopcCompareLtU64OnGpu() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendVMovU32(&code, 0, 5);
|
||||
AppendVMovU32(&code, 1, 0);
|
||||
AppendVMovU32(&code, 2, 1);
|
||||
|
||||
AppendSMovLiteral(&code, 4, 4);
|
||||
AppendSMovLiteral(&code, 5, 0);
|
||||
code.push_back(EncodeVopc(0xe1, 4, 0));
|
||||
code.push_back(EncodeVop2(0x01, 3, InlineU32(0), 2));
|
||||
AppendStoreVgpr(&code, 3, 0);
|
||||
|
||||
AppendSMovLiteral(&code, 4, 6);
|
||||
code.push_back(EncodeVopc(0xe1, 4, 0));
|
||||
code.push_back(EncodeVop2(0x01, 4, InlineU32(0), 2));
|
||||
AppendStoreVgpr(&code, 4, 1);
|
||||
AppendEnd(&code);
|
||||
|
||||
TestCase test{"VectorVopcCompareLtU64OnGpu",
|
||||
code,
|
||||
{},
|
||||
{1, 0},
|
||||
{O::V_MOV_B32, O::S_MOV_B32, O::V_CMP_LT_U64,
|
||||
O::V_CNDMASK_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
test.decoded_counts = {{"V_CMP_LT_U64 vcc_lo, s4, v0", 2}};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase VectorVop3CompareEqI64OnGpu() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -21148,6 +21208,7 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(ScalarMovB32SpecialAliases);
|
||||
AddCase(ScalarQuadmaskB64);
|
||||
AddCase(ScalarFlbitI32B64Gpu);
|
||||
AddCase(ScalarFlbitI32B32Gpu);
|
||||
AddCase(ScalarSaveExecOps);
|
||||
AddCase(ScalarOrn2SaveexecUsesSourceOrNotExec);
|
||||
AddCase(ScalarGetpcWritesNextInstructionPc);
|
||||
@@ -21238,6 +21299,7 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(VectorVop3CompareEqI64OnGpu);
|
||||
AddCase(VectorVop3CompareEqU64OnGpu);
|
||||
AddCase(VectorVop3CompareGtU64OnGpu);
|
||||
AddCase(VectorVopcCompareLtU64OnGpu);
|
||||
AddCase(VectorVop3CompareNeU64OnGpu);
|
||||
AddCase(VectorVopcCmpxNeU64CapturedExecMask);
|
||||
AddCase(VectorVop3CmpxNeI64CapturedExecMask);
|
||||
|
||||
@@ -3969,6 +3969,37 @@ void TestNewShaderDecoderArchitecture() {
|
||||
cmp_eq_u64.src1.kind == OperandKind::VccLo,
|
||||
"decoder rejected the captured VOP3 V_CMP_EQ_U64 instruction");
|
||||
|
||||
const uint32_t completed_pr_opcodes[] = {
|
||||
EncodeSop1(0x15, 0, 1), // s_flbit_i32_b32 s0, s1
|
||||
EncodeVopc(0xe1, 128, 0), // v_cmp_lt_u64 vcc, 0, v[0:1]
|
||||
EncodeSopp(0x01, 0),
|
||||
};
|
||||
Instruction flbit_i32_b32;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(completed_pr_opcodes, 0u,
|
||||
flbit_i32_b32);
|
||||
Instruction cmp_lt_u64;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(completed_pr_opcodes, 1u,
|
||||
cmp_lt_u64);
|
||||
Check(flbit_i32_b32.family == Family::SOP1 &&
|
||||
flbit_i32_b32.opcode == Opcode::S_FLBIT_I32_B32 &&
|
||||
flbit_i32_b32.dst.kind == OperandKind::Sgpr &&
|
||||
flbit_i32_b32.dst.reg == 0u &&
|
||||
flbit_i32_b32.src0.kind == OperandKind::Sgpr &&
|
||||
flbit_i32_b32.src0.reg == 1u &&
|
||||
cmp_lt_u64.family == Family::VOPC &&
|
||||
cmp_lt_u64.opcode == Opcode::V_CMP_LT_U64 &&
|
||||
cmp_lt_u64.dst.kind == OperandKind::VccLo,
|
||||
"decoder rejected completed PR #427 scalar/vector opcodes");
|
||||
|
||||
const auto completed_options = MakeCompileOptions(ShaderType::Compute);
|
||||
const auto completed_result =
|
||||
ShaderRecompiler::Recompile(completed_pr_opcodes, completed_options);
|
||||
Check(Common::ContainsStr(completed_result.decoded_dump,
|
||||
"S_FLBIT_I32_B32 s0, s1") &&
|
||||
Common::ContainsStr(completed_result.decoded_dump,
|
||||
"V_CMP_LT_U64 vcc_lo, 0, v0"),
|
||||
"completed PR #427 opcodes were absent from the decoded shader");
|
||||
|
||||
const uint32_t ffbh_i32_code[] = {0x7e1c770eu};
|
||||
Instruction ffbh_i32;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(ffbh_i32_code, 0u, ffbh_i32);
|
||||
|
||||
Reference in New Issue
Block a user