mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
graphics: implement RDNA2 alignbyte shader opcode
This commit is contained in:
@@ -517,6 +517,8 @@ if(BUILD_TESTING)
|
|||||||
add_test(NAME sync_on_address COMMAND $<TARGET_FILE:sync_on_address_tests>)
|
add_test(NAME sync_on_address COMMAND $<TARGET_FILE:sync_on_address_tests>)
|
||||||
add_test(NAME audio_out2_port COMMAND $<TARGET_FILE:audio_out2_port_tests>)
|
add_test(NAME audio_out2_port COMMAND $<TARGET_FILE:audio_out2_port_tests>)
|
||||||
add_test(NAME shader_recompiler_compute COMMAND $<TARGET_FILE:shader_recompiler_compute_tests>)
|
add_test(NAME shader_recompiler_compute COMMAND $<TARGET_FILE:shader_recompiler_compute_tests>)
|
||||||
|
add_test(NAME shader_recompiler_alignbyte
|
||||||
|
COMMAND $<TARGET_FILE:shader_recompiler_compute_tests> --alignbyte-only)
|
||||||
add_test(NAME virtual_memory_allocation
|
add_test(NAME virtual_memory_allocation
|
||||||
COMMAND $<TARGET_FILE:virtual_memory_allocation_tests>)
|
COMMAND $<TARGET_FILE:virtual_memory_allocation_tests>)
|
||||||
add_test(NAME guest_red_zone_patcher
|
add_test(NAME guest_red_zone_patcher
|
||||||
|
|||||||
@@ -618,6 +618,7 @@ std::string OpcodeToString(Opcode opcode) {
|
|||||||
case Opcode::VBfeI32: return "v_bfe_i32";
|
case Opcode::VBfeI32: return "v_bfe_i32";
|
||||||
case Opcode::VBfiB32: return "v_bfi_b32";
|
case Opcode::VBfiB32: return "v_bfi_b32";
|
||||||
case Opcode::VAlignbitB32: return "v_alignbit_b32";
|
case Opcode::VAlignbitB32: return "v_alignbit_b32";
|
||||||
|
case Opcode::VAlignbyteB32: return "v_alignbyte_b32";
|
||||||
case Opcode::VMin3F32: return "v_min3_f32";
|
case Opcode::VMin3F32: return "v_min3_f32";
|
||||||
case Opcode::VMin3I32: return "v_min3_i32";
|
case Opcode::VMin3I32: return "v_min3_i32";
|
||||||
case Opcode::VMin3U32: return "v_min3_u32";
|
case Opcode::VMin3U32: return "v_min3_u32";
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ enum class Opcode {
|
|||||||
VBfeI32,
|
VBfeI32,
|
||||||
VBfiB32,
|
VBfiB32,
|
||||||
VAlignbitB32,
|
VAlignbitB32,
|
||||||
|
VAlignbyteB32,
|
||||||
VMin3F32,
|
VMin3F32,
|
||||||
VMin3I32,
|
VMin3I32,
|
||||||
VMin3U32,
|
VMin3U32,
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ constexpr OpcodeMap VOP3_OPS[] = {
|
|||||||
{0x371u, Opcode::VAndOrB32}, {0x372u, Opcode::VOr3B32},
|
{0x371u, Opcode::VAndOrB32}, {0x372u, Opcode::VOr3B32},
|
||||||
{0x377u, Opcode::VPermlane16B32}, {0x378u, Opcode::VPermlanex16B32},
|
{0x377u, Opcode::VPermlane16B32}, {0x378u, Opcode::VPermlanex16B32},
|
||||||
{0x34bu, Opcode::VFmaF16}, {0x36du, Opcode::VAdd3U32},
|
{0x34bu, Opcode::VFmaF16}, {0x36du, Opcode::VAdd3U32},
|
||||||
|
{0x14fu, Opcode::VAlignbyteB32},
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr OpcodeMap VOP3P_OPS[] = {
|
constexpr OpcodeMap VOP3P_OPS[] = {
|
||||||
|
|||||||
@@ -568,6 +568,19 @@ bool Translator::TranslateExtendedInteger(const IR::Instruction& inst) {
|
|||||||
result = ir.BitwiseOr(lo_part, hi_part);
|
result = ir.BitwiseOr(lo_part, hi_part);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IR::Opcode::AlignByteU32: {
|
||||||
|
const auto hi = ReadU32(inst.src[0]);
|
||||||
|
const auto lo = ReadU32(inst.src[1]);
|
||||||
|
const auto byte_offset = mask(ReadU32(inst.src[2]), 31u);
|
||||||
|
const auto bit_offset = ir.ShiftLeftLogical(byte_offset, imm(3));
|
||||||
|
const auto concatenated = ir.PackUint2x32(lo, hi);
|
||||||
|
const auto shifted = IR::U64(ir.Emit(IR::ValueOpcode::ShiftRightLogical64,
|
||||||
|
{concatenated, mask(bit_offset, 63u)}));
|
||||||
|
const auto in_range =
|
||||||
|
IR::U1(ir.Emit(IR::ValueOpcode::ULessThan32, {byte_offset, imm(8)}));
|
||||||
|
result = ir.Select(in_range, UnpackU64(shifted)[0], imm(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IR::Opcode::ShiftLeftAddU32:
|
case IR::Opcode::ShiftLeftAddU32:
|
||||||
result =
|
result =
|
||||||
ir.IAdd(ir.ShiftLeftLogical(ReadU32(inst.src[0]), mask(ReadU32(inst.src[1]), 31u)),
|
ir.IAdd(ir.ShiftLeftLogical(ReadU32(inst.src[0]), mask(ReadU32(inst.src[1]), 31u)),
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
|||||||
{Decoder::Opcode::VBfeI32, Opcode::BitFieldExtract3I32},
|
{Decoder::Opcode::VBfeI32, Opcode::BitFieldExtract3I32},
|
||||||
{Decoder::Opcode::VBfiB32, Opcode::BitFieldInsertSelectU32},
|
{Decoder::Opcode::VBfiB32, Opcode::BitFieldInsertSelectU32},
|
||||||
{Decoder::Opcode::VAlignbitB32, Opcode::AlignBitU32},
|
{Decoder::Opcode::VAlignbitB32, Opcode::AlignBitU32},
|
||||||
|
{Decoder::Opcode::VAlignbyteB32, Opcode::AlignByteU32},
|
||||||
{Decoder::Opcode::VMin3F32, Opcode::FMin3F32},
|
{Decoder::Opcode::VMin3F32, Opcode::FMin3F32},
|
||||||
{Decoder::Opcode::VMin3I32, Opcode::IMin3I32},
|
{Decoder::Opcode::VMin3I32, Opcode::IMin3I32},
|
||||||
{Decoder::Opcode::VMin3U32, Opcode::UMin3U32},
|
{Decoder::Opcode::VMin3U32, Opcode::UMin3U32},
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ IR_OPCODE(BitFieldInsertSelectU32, General, ExtendedInteger)
|
|||||||
IR_OPCODE(BitCompare0B32, General, ExtendedInteger)
|
IR_OPCODE(BitCompare0B32, General, ExtendedInteger)
|
||||||
IR_OPCODE(BitCompare1B32, General, ExtendedInteger)
|
IR_OPCODE(BitCompare1B32, General, ExtendedInteger)
|
||||||
IR_OPCODE(AlignBitU32, General, ExtendedInteger)
|
IR_OPCODE(AlignBitU32, General, ExtendedInteger)
|
||||||
|
IR_OPCODE(AlignByteU32, General, ExtendedInteger)
|
||||||
IR_OPCODE(ShiftLeftAddU32, General, ExtendedInteger)
|
IR_OPCODE(ShiftLeftAddU32, General, ExtendedInteger)
|
||||||
IR_OPCODE(AddShiftLeftU32, General, ExtendedInteger)
|
IR_OPCODE(AddShiftLeftU32, General, ExtendedInteger)
|
||||||
IR_OPCODE(XorAddU32, General, ExtendedInteger)
|
IR_OPCODE(XorAddU32, General, ExtendedInteger)
|
||||||
|
|||||||
@@ -11584,6 +11584,28 @@ TestCase VectorBfeI32ArithmeticShiftMasksField() {
|
|||||||
{O::VMovB32, O::VBfeI32, O::BufferStoreDword, O::SEndpgm}};
|
{O::VMovB32, O::VBfeI32, O::BufferStoreDword, O::SEndpgm}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase VectorAlignByteUsesFiveBitByteOffset() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
|
std::vector<u32> code;
|
||||||
|
AppendVMovLiteral(&code, 0, 0x11223344u);
|
||||||
|
AppendVMovLiteral(&code, 1, 0x55667788u);
|
||||||
|
constexpr u32 offsets[] = {0, 1, 3, 4, 5, 7, 8, 31};
|
||||||
|
for (u32 i = 0; i < static_cast<u32>(std::size(offsets)); i++) {
|
||||||
|
AppendVMovU32(&code, 2, offsets[i]);
|
||||||
|
AppendVop3(&code, 0x14f, 10u + i, Vgpr(0), Vgpr(1), Vgpr(2));
|
||||||
|
AppendStoreVgpr(&code, 10u + i, i);
|
||||||
|
}
|
||||||
|
AppendEnd(&code);
|
||||||
|
|
||||||
|
return {"VectorAlignByteUsesFiveBitByteOffset",
|
||||||
|
code,
|
||||||
|
{},
|
||||||
|
{0x55667788u, 0x44556677u, 0x22334455u, 0x11223344u, 0x00112233u,
|
||||||
|
0x00000011u, 0u, 0u},
|
||||||
|
{O::VMovB32, O::VAlignbyteB32, O::BufferStoreDword, O::SEndpgm}};
|
||||||
|
}
|
||||||
|
|
||||||
TestCase VectorCarryAndBitCountOps() {
|
TestCase VectorCarryAndBitCountOps() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -16901,6 +16923,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorShiftCountsMaskLowBits);
|
AddCase(VectorShiftCountsMaskLowBits);
|
||||||
AddCase(VectorVop3IntegerOps);
|
AddCase(VectorVop3IntegerOps);
|
||||||
AddCase(VectorBfeI32ArithmeticShiftMasksField);
|
AddCase(VectorBfeI32ArithmeticShiftMasksField);
|
||||||
|
AddCase(VectorAlignByteUsesFiveBitByteOffset);
|
||||||
AddCase(VectorCarryAndBitCountOps);
|
AddCase(VectorCarryAndBitCountOps);
|
||||||
AddCase(VectorMbcntUsesThreadMask);
|
AddCase(VectorMbcntUsesThreadMask);
|
||||||
AddCase(VectorAddcWritesPerLaneCarryOut);
|
AddCase(VectorAddcWritesPerLaneCarryOut);
|
||||||
@@ -20241,6 +20264,11 @@ int main(int argc, char **argv) {
|
|||||||
vulkan.CheckGpuCommandLane();
|
vulkan.CheckGpuCommandLane();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--alignbyte-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
RunCase(&vulkan, VectorAlignByteUsesFiveBitByteOffset());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
|
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
|
||||||
|
|||||||
@@ -1461,6 +1461,8 @@ void TestNewShaderRecompilerMoreAluFamilies() {
|
|||||||
EncodeVop3Word1(5 + 256, 6 + 256, 7 + 256),
|
EncodeVop3Word1(5 + 256, 6 + 256, 7 + 256),
|
||||||
EncodeVop3Word0(0x14e, 50),
|
EncodeVop3Word0(0x14e, 50),
|
||||||
EncodeVop3Word1(5 + 256, 6 + 256, 129),
|
EncodeVop3Word1(5 + 256, 6 + 256, 129),
|
||||||
|
EncodeVop3Word0(0x14f, 115),
|
||||||
|
EncodeVop3Word1(5 + 256, 6 + 256, 129),
|
||||||
EncodeVop3Word0(0x36d, 51),
|
EncodeVop3Word0(0x36d, 51),
|
||||||
EncodeVop3Word1(5 + 256, 6 + 256, 7 + 256),
|
EncodeVop3Word1(5 + 256, 6 + 256, 7 + 256),
|
||||||
EncodeVop3Word0(0x169, 52),
|
EncodeVop3Word0(0x169, 52),
|
||||||
@@ -1811,6 +1813,8 @@ void TestNewShaderRecompilerMoreAluFamilies() {
|
|||||||
"new decoder did not decode VOP3 bitfield insert-select");
|
"new decoder did not decode VOP3 bitfield insert-select");
|
||||||
Check(Common::ContainsStr(result.decoded_dump, "v_alignbit_b32 v50"),
|
Check(Common::ContainsStr(result.decoded_dump, "v_alignbit_b32 v50"),
|
||||||
"new decoder did not decode VOP3 alignbit");
|
"new decoder did not decode VOP3 alignbit");
|
||||||
|
Check(Common::ContainsStr(result.decoded_dump, "v_alignbyte_b32 v115"),
|
||||||
|
"new decoder did not decode VOP3 alignbyte");
|
||||||
Check(Common::ContainsStr(result.decoded_dump, "v_add3_u32 v51"),
|
Check(Common::ContainsStr(result.decoded_dump, "v_add3_u32 v51"),
|
||||||
"new decoder did not decode VOP3 add3");
|
"new decoder did not decode VOP3 add3");
|
||||||
Check(Common::ContainsStr(result.decoded_dump, "v_mul_lo_u32 v52, v5, v6"),
|
Check(Common::ContainsStr(result.decoded_dump, "v_mul_lo_u32 v52, v5, v6"),
|
||||||
@@ -2186,6 +2190,8 @@ void TestNewShaderRecompilerMoreAluFamilies() {
|
|||||||
"VOP3 bitfield insert-select did not lower to IR");
|
"VOP3 bitfield insert-select did not lower to IR");
|
||||||
Check(Common::ContainsStr(result.ir_dump, "AlignBitU32 v50"),
|
Check(Common::ContainsStr(result.ir_dump, "AlignBitU32 v50"),
|
||||||
"VOP3 alignbit did not lower to IR");
|
"VOP3 alignbit did not lower to IR");
|
||||||
|
Check(Common::ContainsStr(result.ir_dump, "AlignByteU32 v115"),
|
||||||
|
"VOP3 alignbyte did not lower to IR");
|
||||||
Check(Common::ContainsStr(result.ir_dump, "IAdd3U32 v51"),
|
Check(Common::ContainsStr(result.ir_dump, "IAdd3U32 v51"),
|
||||||
"VOP3 add3 did not lower to IR");
|
"VOP3 add3 did not lower to IR");
|
||||||
Check(Common::ContainsStr(result.ir_dump, "IMulU32 v52, v5, v6"),
|
Check(Common::ContainsStr(result.ir_dump, "IMulU32 v52, v5, v6"),
|
||||||
|
|||||||
Reference in New Issue
Block a user