mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 16:51:20 +00:00
shader: support S_QUADMASK_B32
This commit is contained in:
1 parent
963aaeb3b6
commit
138d5b86c4
8 files changed
+69
-9
No files matched your search
@@ -694,6 +694,8 @@ if(BUILD_TESTING)
|
||||
COMMAND $<TARGET_FILE:shader_recompiler_compute_tests> --float-min-max-only)
|
||||
add_test(NAME shader_recompiler_vop3_conversions
|
||||
COMMAND $<TARGET_FILE:shader_recompiler_compute_tests> --vop3-conversions-only)
|
||||
add_test(NAME shader_recompiler_quadmask
|
||||
COMMAND $<TARGET_FILE:shader_recompiler_compute_tests> --quadmask-only)
|
||||
add_test(NAME shader_recompiler_alignbyte
|
||||
COMMAND $<TARGET_FILE:shader_recompiler_compute_tests> --alignbyte-only)
|
||||
add_test(NAME graphics_pipeline_rasterization
|
||||
|
||||
@@ -70,6 +70,7 @@ constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
|
||||
{0x21u, Opcode::S_SWAPPC_B64},
|
||||
{0x24u, Opcode::S_AND_SAVEEXEC_B64},
|
||||
{0x28u, Opcode::S_ORN2_SAVEEXEC_B64},
|
||||
{0x2cu, Opcode::S_QUADMASK_B32},
|
||||
{0x2du, Opcode::S_QUADMASK_B64},
|
||||
{0x34u, Opcode::S_ABS_I32},
|
||||
{0x37u, Opcode::S_ANDN1_SAVEEXEC_B64},
|
||||
|
||||
@@ -517,6 +517,7 @@ std::string InstructionToString(const Instruction& inst) {
|
||||
case Opcode::S_NOT_B64:
|
||||
case Opcode::S_WQM_B32:
|
||||
case Opcode::S_WQM_B64:
|
||||
case Opcode::S_QUADMASK_B32:
|
||||
case Opcode::S_QUADMASK_B64:
|
||||
case Opcode::S_AND_SAVEEXEC_B32:
|
||||
case Opcode::S_ORN2_SAVEEXEC_B32:
|
||||
|
||||
@@ -63,6 +63,7 @@ enum class Opcode {
|
||||
S_FLBIT_I32,
|
||||
S_FLBIT_I32_I64,
|
||||
S_BITREPLICATE_B64_B32,
|
||||
S_QUADMASK_B32,
|
||||
S_QUADMASK_B64,
|
||||
S_GETPC_B64,
|
||||
S_SETPC_B64,
|
||||
|
||||
@@ -375,7 +375,7 @@ void Translator::S_BITREPLICATE_B64_B32(const Decoder::Instruction& inst) {
|
||||
WriteOperand(DestinationOperand(inst), ir.ConstructU64(replicate(low), replicate(high)));
|
||||
}
|
||||
|
||||
void Translator::S_QUADMASK_B64(const Decoder::Instruction& inst) {
|
||||
void Translator::S_QUADMASK(const Decoder::Instruction& inst, bool is64) {
|
||||
const auto compact = [&](IR::U32 value) {
|
||||
auto bits = ir.BitwiseOr(value, ir.ShiftRightLogical(value, IR::U32(IR::Value(1u))));
|
||||
bits = ir.BitwiseOr(bits, ir.ShiftRightLogical(bits, IR::U32(IR::Value(2u))));
|
||||
@@ -388,12 +388,17 @@ void Translator::S_QUADMASK_B64(const Decoder::Instruction& inst) {
|
||||
ir.BitwiseOr(bits, ir.ShiftRightLogical(bits, IR::U32(IR::Value(12u)))),
|
||||
IR::U32(IR::Value(0xffu)));
|
||||
};
|
||||
const auto source = ReadU32Pair(inst.src0);
|
||||
const auto quads = ir.BitwiseOr(
|
||||
compact(source[0]), ir.ShiftLeftLogical(compact(source[1]), IR::U32(IR::Value(8u))));
|
||||
const auto result = ir.ConstructU64(quads, IR::U32(IR::Value(0u)));
|
||||
WriteOperand(DestinationOperand(inst), result);
|
||||
ir.SetScc(IR::U1(ir.Emit(IR::ValueOpcode::INotEqual64, {result, IR::Value(uint64_t {0})})));
|
||||
IR::U32 quads;
|
||||
if (is64) {
|
||||
const auto source = ReadU32Pair(inst.src0);
|
||||
quads = ir.BitwiseOr(
|
||||
compact(source[0]), ir.ShiftLeftLogical(compact(source[1]), IR::U32(IR::Value(8u))));
|
||||
WriteOperand(DestinationOperand(inst), ir.ConstructU64(quads, IR::U32(IR::Value(0u))));
|
||||
} else {
|
||||
quads = compact(ReadU32(inst.src0));
|
||||
WriteOperand(DestinationOperand(inst), quads);
|
||||
}
|
||||
ir.SetScc(ir.INotEqual(quads, IR::U32(IR::Value(0u))));
|
||||
}
|
||||
|
||||
void Translator::BFM_B32(const Decoder::Instruction& inst) {
|
||||
|
||||
@@ -248,7 +248,8 @@ void Translator::EmitScalar(const Decoder::Instruction& inst) {
|
||||
case O::S_BITSET0_B64: return S_BITSET_B64(inst, false);
|
||||
case O::S_BITSET1_B64: return S_BITSET_B64(inst, true);
|
||||
case O::S_BITREPLICATE_B64_B32: return S_BITREPLICATE_B64_B32(inst);
|
||||
case O::S_QUADMASK_B64: return S_QUADMASK_B64(inst);
|
||||
case O::S_QUADMASK_B32: return S_QUADMASK(inst, false);
|
||||
case O::S_QUADMASK_B64: return S_QUADMASK(inst, true);
|
||||
case O::S_BFM_B32: return BFM_B32(inst);
|
||||
case O::S_BFM_B64: return S_BFM_B64(inst);
|
||||
case O::S_BFE_U32: return S_BFE_U32(inst, false);
|
||||
|
||||
@@ -196,7 +196,7 @@ private:
|
||||
void V_BCNT_U32_B32(const Decoder::Instruction& inst);
|
||||
void V_MBCNT_U32_B32(const Decoder::Instruction& inst, bool low);
|
||||
void S_BITREPLICATE_B64_B32(const Decoder::Instruction& inst);
|
||||
void S_QUADMASK_B64(const Decoder::Instruction& inst);
|
||||
void S_QUADMASK(const Decoder::Instruction& inst, bool is64);
|
||||
void BFM_B32(const Decoder::Instruction& inst);
|
||||
IR::U32 RightMask32(IR::U32 count);
|
||||
void S_BFM_B64(const Decoder::Instruction& inst);
|
||||
|
||||
@@ -23748,6 +23748,46 @@ TestCase ScalarNotB64UpdatesScc() {
|
||||
O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase ScalarQuadmaskB32(u32 wave_size) {
|
||||
using O = ShaderOpcode;
|
||||
TestCase test;
|
||||
test.name = wave_size == 32 ? "ScalarQuadmaskB32Wave32" : "ScalarQuadmaskB32Wave64";
|
||||
test.initial = {0, 0xffffffffu, 0x80000011u, 0x01010101u};
|
||||
for (u32 bit = 0; bit < 32; ++bit) test.initial.push_back(1u << bit);
|
||||
test.expected = test.initial;
|
||||
auto &code = test.code;
|
||||
for (u32 i = 0; i < test.initial.size(); ++i) {
|
||||
u32 quads = 0;
|
||||
for (u32 q = 0; q < 8; ++q) {
|
||||
if ((test.initial[i] >> (4 * q)) & 15u) quads |= 1u << q;
|
||||
}
|
||||
AppendVMovU32(&code, 30, i * sizeof(u32));
|
||||
AppendBufferLoadDword(&code, 2, 30);
|
||||
for (u32 dst : {12u, 106u}) {
|
||||
code.push_back(EncodeVop1(0x02, dst, Vgpr(2)));
|
||||
AppendSMovLiteral(&code, dst + 1, 0xdeadbeefu);
|
||||
code.push_back(EncodeSopc(0x06, InlineU32(quads == 0), InlineU32(1)));
|
||||
code.push_back(EncodeSop1(0x2c, dst, dst));
|
||||
code.push_back(EncodeSop2(0x0a, 14, InlineU32(1), InlineU32(0)));
|
||||
AppendStoreSgpr(&code, dst, static_cast<u32>(test.expected.size()));
|
||||
AppendStoreSgpr(&code, dst + 1, static_cast<u32>(test.expected.size()) + 1);
|
||||
AppendStoreSgpr(&code, 14, static_cast<u32>(test.expected.size()) + 2);
|
||||
test.expected.insert(test.expected.end(), {quads, 0xdeadbeefu, quads != 0});
|
||||
}
|
||||
}
|
||||
code.push_back(EncodeSop1(0x2c, 12, 255));
|
||||
code.push_back(0x000f000fu);
|
||||
AppendStoreSgpr(&code, 12, static_cast<u32>(test.expected.size()));
|
||||
test.expected.push_back(0x11u);
|
||||
AppendEnd(&code);
|
||||
test.opcodes = {O::S_QUADMASK_B32, O::S_CMP_EQ_U32, O::S_CSELECT_B32, O::S_MOV_B32,
|
||||
O::V_READFIRSTLANE_B32, O::V_MOV_B32, O::BUFFER_LOAD_DWORD,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.compute_info.wave_size = wave_size;
|
||||
test.has_compute_info = true;
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase ScalarQuadmaskB64() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -46047,6 +46087,8 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(ScalarCompareOps);
|
||||
AddCase(ScalarShiftAddAndMaskOps);
|
||||
AddCase(ScalarNotB64UpdatesScc);
|
||||
cases.push_back(ScalarQuadmaskB32(32));
|
||||
cases.push_back(ScalarQuadmaskB32(64));
|
||||
AddCase(ScalarQuadmaskB64);
|
||||
AddCase(ScalarFlbitI32B64Gpu);
|
||||
AddCase(ScalarFlbitI32B32Gpu);
|
||||
@@ -52562,6 +52604,13 @@ int main(int argc, char **argv) {
|
||||
std::setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
EnsureConfigInitialized();
|
||||
CheckLeastRecentlyUsedCacheOrdering();
|
||||
if (argc == 2 && std::strcmp(argv[1], "--quadmask-only") == 0) {
|
||||
VulkanHarness vulkan;
|
||||
RunCase(&vulkan, ScalarQuadmaskB32(32));
|
||||
RunCase(&vulkan, ScalarQuadmaskB32(64));
|
||||
RunCase(&vulkan, ScalarQuadmaskB64());
|
||||
return 0;
|
||||
}
|
||||
if (argc == 2 && std::strcmp(argv[1], "--vop3-conversions-only") == 0) {
|
||||
VulkanHarness vulkan;
|
||||
RunCase(&vulkan, Vop3FloatConversions(32));
|
||||
|
||||
Reference in new issue
Block a user