mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-26 12:56:54 +01:00
shader: support D16 XY and XYZ formatted buffer loads and stores
This commit is contained in:
@@ -74,8 +74,12 @@ constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
|
|||||||
{0x71u, Opcode::BUFFER_GL0_INV, 0, 0},
|
{0x71u, Opcode::BUFFER_GL0_INV, 0, 0},
|
||||||
{0x72u, Opcode::BUFFER_GL1_INV, 0, 0},
|
{0x72u, Opcode::BUFFER_GL1_INV, 0, 0},
|
||||||
{0x80u, Opcode::BUFFER_LOAD_FORMAT_D16_X, 1, 16, false, false, true},
|
{0x80u, Opcode::BUFFER_LOAD_FORMAT_D16_X, 1, 16, false, false, true},
|
||||||
|
{0x81u, Opcode::BUFFER_LOAD_FORMAT_D16_XY, 1, 16, false, false, true, 2},
|
||||||
|
{0x82u, Opcode::BUFFER_LOAD_FORMAT_D16_XYZ, 2, 16, false, false, true, 3},
|
||||||
{0x83u, Opcode::BUFFER_LOAD_FORMAT_D16_XYZW, 2, 16, false, false, true, 4},
|
{0x83u, Opcode::BUFFER_LOAD_FORMAT_D16_XYZW, 2, 16, false, false, true, 4},
|
||||||
{0x84u, Opcode::BUFFER_STORE_FORMAT_D16_X, 1, 16, false, false, true},
|
{0x84u, Opcode::BUFFER_STORE_FORMAT_D16_X, 1, 16, false, false, true},
|
||||||
|
{0x85u, Opcode::BUFFER_STORE_FORMAT_D16_XY, 1, 16, false, false, true, 2},
|
||||||
|
{0x86u, Opcode::BUFFER_STORE_FORMAT_D16_XYZ, 2, 16, false, false, true, 3},
|
||||||
{0x87u, Opcode::BUFFER_STORE_FORMAT_D16_XYZW, 2, 16, false, false, true, 4},
|
{0x87u, Opcode::BUFFER_STORE_FORMAT_D16_XYZW, 2, 16, false, false, true, 4},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -636,6 +636,8 @@ std::string InstructionToString(const Instruction& inst) {
|
|||||||
case Opcode::BUFFER_LOAD_FORMAT_XYZ:
|
case Opcode::BUFFER_LOAD_FORMAT_XYZ:
|
||||||
case Opcode::BUFFER_LOAD_FORMAT_XYZW:
|
case Opcode::BUFFER_LOAD_FORMAT_XYZW:
|
||||||
case Opcode::BUFFER_LOAD_FORMAT_D16_X:
|
case Opcode::BUFFER_LOAD_FORMAT_D16_X:
|
||||||
|
case Opcode::BUFFER_LOAD_FORMAT_D16_XY:
|
||||||
|
case Opcode::BUFFER_LOAD_FORMAT_D16_XYZ:
|
||||||
case Opcode::BUFFER_LOAD_FORMAT_D16_XYZW:
|
case Opcode::BUFFER_LOAD_FORMAT_D16_XYZW:
|
||||||
case Opcode::BUFFER_STORE_FORMAT_X:
|
case Opcode::BUFFER_STORE_FORMAT_X:
|
||||||
case Opcode::BUFFER_STORE_FORMAT_XY:
|
case Opcode::BUFFER_STORE_FORMAT_XY:
|
||||||
@@ -643,6 +645,8 @@ std::string InstructionToString(const Instruction& inst) {
|
|||||||
case Opcode::BUFFER_STORE_FORMAT_XYZW:
|
case Opcode::BUFFER_STORE_FORMAT_XYZW:
|
||||||
case Opcode::BUFFER_STORE_FORMAT_D16_X:
|
case Opcode::BUFFER_STORE_FORMAT_D16_X:
|
||||||
case Opcode::BUFFER_STORE_FORMAT_D16_HI_X:
|
case Opcode::BUFFER_STORE_FORMAT_D16_HI_X:
|
||||||
|
case Opcode::BUFFER_STORE_FORMAT_D16_XY:
|
||||||
|
case Opcode::BUFFER_STORE_FORMAT_D16_XYZ:
|
||||||
case Opcode::BUFFER_STORE_FORMAT_D16_XYZW:
|
case Opcode::BUFFER_STORE_FORMAT_D16_XYZW:
|
||||||
case Opcode::BUFFER_LOAD_UBYTE:
|
case Opcode::BUFFER_LOAD_UBYTE:
|
||||||
case Opcode::BUFFER_LOAD_UBYTE_D16:
|
case Opcode::BUFFER_LOAD_UBYTE_D16:
|
||||||
|
|||||||
@@ -547,6 +547,8 @@ enum class Opcode {
|
|||||||
BUFFER_LOAD_FORMAT_XYZ,
|
BUFFER_LOAD_FORMAT_XYZ,
|
||||||
BUFFER_LOAD_FORMAT_XYZW,
|
BUFFER_LOAD_FORMAT_XYZW,
|
||||||
BUFFER_LOAD_FORMAT_D16_X,
|
BUFFER_LOAD_FORMAT_D16_X,
|
||||||
|
BUFFER_LOAD_FORMAT_D16_XY,
|
||||||
|
BUFFER_LOAD_FORMAT_D16_XYZ,
|
||||||
BUFFER_LOAD_FORMAT_D16_XYZW,
|
BUFFER_LOAD_FORMAT_D16_XYZW,
|
||||||
BUFFER_STORE_FORMAT_X,
|
BUFFER_STORE_FORMAT_X,
|
||||||
BUFFER_STORE_FORMAT_XY,
|
BUFFER_STORE_FORMAT_XY,
|
||||||
@@ -554,6 +556,8 @@ enum class Opcode {
|
|||||||
BUFFER_STORE_FORMAT_XYZW,
|
BUFFER_STORE_FORMAT_XYZW,
|
||||||
BUFFER_STORE_FORMAT_D16_X,
|
BUFFER_STORE_FORMAT_D16_X,
|
||||||
BUFFER_STORE_FORMAT_D16_HI_X,
|
BUFFER_STORE_FORMAT_D16_HI_X,
|
||||||
|
BUFFER_STORE_FORMAT_D16_XY,
|
||||||
|
BUFFER_STORE_FORMAT_D16_XYZ,
|
||||||
BUFFER_STORE_FORMAT_D16_XYZW,
|
BUFFER_STORE_FORMAT_D16_XYZW,
|
||||||
BUFFER_LOAD_UBYTE,
|
BUFFER_LOAD_UBYTE,
|
||||||
BUFFER_LOAD_UBYTE_D16,
|
BUFFER_LOAD_UBYTE_D16,
|
||||||
|
|||||||
@@ -997,6 +997,8 @@ void Translator::EmitMemory(const Decoder::Instruction& inst) {
|
|||||||
case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZ:
|
case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZ:
|
||||||
case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZW:
|
case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZW:
|
||||||
case Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_X:
|
case Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_X:
|
||||||
|
case Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_XY:
|
||||||
|
case Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_XYZ:
|
||||||
case Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_XYZW:
|
case Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_XYZW:
|
||||||
case Decoder::Opcode::TBUFFER_LOAD_FORMAT_X:
|
case Decoder::Opcode::TBUFFER_LOAD_FORMAT_X:
|
||||||
case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XY:
|
case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XY:
|
||||||
@@ -1017,6 +1019,8 @@ void Translator::EmitMemory(const Decoder::Instruction& inst) {
|
|||||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZW:
|
case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZW:
|
||||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_X:
|
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_X:
|
||||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_HI_X:
|
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_HI_X:
|
||||||
|
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_XY:
|
||||||
|
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_XYZ:
|
||||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_XYZW:
|
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_XYZW:
|
||||||
case Decoder::Opcode::TBUFFER_STORE_FORMAT_X:
|
case Decoder::Opcode::TBUFFER_STORE_FORMAT_X:
|
||||||
case Decoder::Opcode::TBUFFER_STORE_FORMAT_XY:
|
case Decoder::Opcode::TBUFFER_STORE_FORMAT_XY:
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ void ValidateProgram(const Program& program, bool require_ssa) {
|
|||||||
const auto access = BufferAccessOf(inst.GetOpcode());
|
const auto access = BufferAccessOf(inst.GetOpcode());
|
||||||
const bool packed_formatted =
|
const bool packed_formatted =
|
||||||
(access == BufferAccess::Read || access == BufferAccess::Write) && memory.formatted &&
|
(access == BufferAccess::Read || access == BufferAccess::Write) && memory.formatted &&
|
||||||
memory.data_bits == 16u && memory.component_count == 4u && buffer_components == 2u;
|
memory.data_bits == 16u && (memory.component_count + 1u) / 2u == buffer_components;
|
||||||
if (buffer_components > 1u &&
|
if (buffer_components > 1u &&
|
||||||
(!vector_buffer || (memory.data_bits != 32u && !packed_formatted) ||
|
(!vector_buffer || (memory.data_bits != 32u && !packed_formatted) ||
|
||||||
memory.data_dwords != buffer_components || memory.component_index != 0u)) {
|
memory.data_dwords != buffer_components || memory.component_index != 0u)) {
|
||||||
|
|||||||
@@ -33076,7 +33076,7 @@ std::vector<TestCase> BufferLoadFormatD16XCases() {
|
|||||||
return cases;
|
return cases;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TestCase> BufferLoadFormatD16XyzwCases() {
|
std::vector<TestCase> BufferLoadFormatD16VectorCases() {
|
||||||
using F = Prospero::BufferFormat;
|
using F = Prospero::BufferFormat;
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
struct LoadCase {
|
struct LoadCase {
|
||||||
@@ -33089,6 +33089,7 @@ std::vector<TestCase> BufferLoadFormatD16XyzwCases() {
|
|||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
bool active = true;
|
bool active = true;
|
||||||
bool overlap = false;
|
bool overlap = false;
|
||||||
|
u32 opcode = 0x83u;
|
||||||
};
|
};
|
||||||
constexpr LoadCase inputs[] = {
|
constexpr LoadCase inputs[] = {
|
||||||
{"BufferLoadFormatD16XyzwFloat32", F::k32_32_32_32Float,
|
{"BufferLoadFormatD16XyzwFloat32", F::k32_32_32_32Float,
|
||||||
@@ -33118,7 +33119,26 @@ std::vector<TestCase> BufferLoadFormatD16XyzwCases() {
|
|||||||
{"BufferLoadFormatD16XyzwOverlappingAddress", F::k32_32_32_32Float,
|
{"BufferLoadFormatD16XyzwOverlappingAddress", F::k32_32_32_32Float,
|
||||||
{0x3f800000u, 0x3f000000u, 0u, 0xc0000000u},
|
{0x3f800000u, 0x3f000000u, 0u, 0xc0000000u},
|
||||||
{0x38003c00u, 0xc0000000u}, DstSel(4, 5, 6, 7), 16, 0, true, true},
|
{0x38003c00u, 0xc0000000u}, DstSel(4, 5, 6, 7), 16, 0, true, true},
|
||||||
|
{"BufferLoadFormatD16XyFloat32", F::k32_32_32_32Float,
|
||||||
|
{0x3f800000u, 0x3f000000u, 0u, 0xc0000000u},
|
||||||
|
{0x38003c00u, 0xbeef5678u}, DstSel(4, 5, 6, 7), 16, 0, true, false, 0x81u},
|
||||||
|
{"BufferLoadFormatD16XyUintSaturates", F::k32_32UInt,
|
||||||
|
{0x10000u, 7u}, {0x0007ffffu, 0xbeef5678u}, DstSel(4, 5, 6, 7), 8, 0, true, false, 0x81u},
|
||||||
|
{"BufferLoadFormatD16XyzFloat32", F::k32_32_32_32Float,
|
||||||
|
{0x3f800000u, 0x3f000000u, 0xc0000000u, 0x3e800000u},
|
||||||
|
{0x38003c00u, 0xbeefc000u}, DstSel(4, 5, 6, 7), 16, 0, true, false, 0x82u},
|
||||||
|
{"BufferLoadFormatD16XyzSintSaturates", F::k32_32_32_32SInt,
|
||||||
|
{0xffff7fffu, 7u, 0x8000u, 0xffff8000u},
|
||||||
|
{0x00078000u, 0xbeef7fffu}, DstSel(4, 5, 6, 7), 16, 0, true, false, 0x82u},
|
||||||
|
{"BufferLoadFormatD16XyzOobOne", F::k32_32_32_32Float,
|
||||||
|
{}, {0x3c00u, 0xbeef3c00u}, DstSel(1, 4, 1, 4), 16, 1, true, false, 0x82u},
|
||||||
|
{"BufferLoadFormatD16XyzZeroStrideFloatOne", F::k32_32_32_32Float,
|
||||||
|
{}, {0x3c003c00u, 0xbeef0000u}, DstSel(1, 1, 4, 1), 0, 0, true, false, 0x82u},
|
||||||
|
{"BufferLoadFormatD16XyzInactive", F::k32_32_32_32Float,
|
||||||
|
{}, {0xabcd1234u, 0xbeef5678u}, DstSel(4, 5, 6, 7), 16, 0, false, false, 0x82u},
|
||||||
};
|
};
|
||||||
|
constexpr O formats[] = {O::BUFFER_LOAD_FORMAT_D16_XY, O::BUFFER_LOAD_FORMAT_D16_XYZ,
|
||||||
|
O::BUFFER_LOAD_FORMAT_D16_XYZW};
|
||||||
std::vector<TestCase> cases;
|
std::vector<TestCase> cases;
|
||||||
for (const auto &input : inputs) {
|
for (const auto &input : inputs) {
|
||||||
TestCase test;
|
TestCase test;
|
||||||
@@ -33128,8 +33148,8 @@ std::vector<TestCase> BufferLoadFormatD16XyzwCases() {
|
|||||||
AppendVMovLiteral(&test.code, 18, 0xcafef00du);
|
AppendVMovLiteral(&test.code, 18, 0xcafef00du);
|
||||||
AppendVMovU32(&test.code, 12, input.index);
|
AppendVMovU32(&test.code, 12, input.index);
|
||||||
if (!input.active) test.code.push_back(EncodeSop1(0x04, 126, InlineU32(0)));
|
if (!input.active) test.code.push_back(EncodeSop1(0x04, 126, InlineU32(0)));
|
||||||
// Captured b21e373811f28e31 pc 0x1914: e20c2000 8001100c.
|
// Captured XYZW b21e373811f28e31 pc 0x1914: e20c2000 8001100c.
|
||||||
test.code.push_back(EncodeMubuf0(0x83u, 0, true, false));
|
test.code.push_back(EncodeMubuf0(input.opcode, 0, true, false));
|
||||||
test.code.push_back(EncodeMubuf1(16, 1, input.overlap ? 16 : 12));
|
test.code.push_back(EncodeMubuf1(16, 1, input.overlap ? 16 : 12));
|
||||||
if (!input.active) {
|
if (!input.active) {
|
||||||
test.code.push_back(EncodeSMovB32(126, InlineU32(1)));
|
test.code.push_back(EncodeSMovB32(126, InlineU32(1)));
|
||||||
@@ -33151,7 +33171,7 @@ std::vector<TestCase> BufferLoadFormatD16XyzwCases() {
|
|||||||
if (input.stride != 0 && input.active) {
|
if (input.stride != 0 && input.active) {
|
||||||
test.storage_buffer_ranges = {{0, input.stride}, {0, 32}};
|
test.storage_buffer_ranges = {{0, input.stride}, {0, 32}};
|
||||||
}
|
}
|
||||||
test.opcodes = {O::V_MOV_B32, O::BUFFER_LOAD_FORMAT_D16_XYZW,
|
test.opcodes = {O::V_MOV_B32, formats[input.opcode - 0x81u],
|
||||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||||
cases.push_back(std::move(test));
|
cases.push_back(std::move(test));
|
||||||
}
|
}
|
||||||
@@ -33195,12 +33215,23 @@ std::vector<TestCase> BufferStoreFormatD16Cases() {
|
|||||||
{0xff80ff7fu, 0x0080007fu}, {0x7f7f8080u}, 1, 0x87u},
|
{0xff80ff7fu, 0x0080007fu}, {0x7f7f8080u}, 1, 0x87u},
|
||||||
{"BufferStoreFormatD16XyzwUnorm8", F::k8_8_8_8UNorm,
|
{"BufferStoreFormatD16XyzwUnorm8", F::k8_8_8_8UNorm,
|
||||||
{0x3800c000u, 0x40003c00u}, {0xffff8000u}, 1, 0x87u},
|
{0x3800c000u, 0x40003c00u}, {0xffff8000u}, 1, 0x87u},
|
||||||
|
{"BufferStoreFormatD16XyFloat32", F::k32_32Float,
|
||||||
|
{0x3800c000u}, {0xc0000000u, 0x3f000000u}, 2, 0x85u},
|
||||||
|
{"BufferStoreFormatD16XyUint16", F::k16_16UInt, {0xfffe0001u}, {0xfffe0001u}, 1, 0x85u},
|
||||||
|
{"BufferStoreFormatD16XyzFloat32", F::k32_32_32Float,
|
||||||
|
{0xc0003c00u, 0xdead3800u}, {0x3f800000u, 0xc0000000u, 0x3f000000u}, 3, 0x86u},
|
||||||
|
{"BufferStoreFormatD16XyzZeroFillsW", F::k16_16_16_16Float,
|
||||||
|
{0xc0003c00u, 0xdead3800u}, {0xc0003c00u, 0x00003800u}, 2, 0x86u},
|
||||||
|
{"BufferStoreFormatD16XyzUint8", F::k8_8_8_8UInt,
|
||||||
|
{0x00020001u, 0xdead0003u}, {0x00030201u}, 1, 0x86u},
|
||||||
};
|
};
|
||||||
|
constexpr O formats[] = {O::BUFFER_STORE_FORMAT_D16_X, O::BUFFER_STORE_FORMAT_D16_XY,
|
||||||
|
O::BUFFER_STORE_FORMAT_D16_XYZ, O::BUFFER_STORE_FORMAT_D16_XYZW};
|
||||||
std::vector<TestCase> cases;
|
std::vector<TestCase> cases;
|
||||||
for (const auto &input : inputs)
|
for (const auto &input : inputs)
|
||||||
for (const u32 wave : {32u, 64u})
|
for (const u32 wave : {32u, 64u})
|
||||||
for (u32 mask = 0; mask < (input.opcode == 0x27u ? 2u : 1u); ++mask) {
|
for (u32 mask = 0; mask < (input.opcode == 0x27u ? 2u : 1u); ++mask) {
|
||||||
const bool wide = input.opcode == 0x87u;
|
const bool wide = input.opcode >= 0x85u;
|
||||||
const bool high = input.opcode == 0x27u;
|
const bool high = input.opcode == 0x27u;
|
||||||
const bool multi_lane = wide || high;
|
const bool multi_lane = wide || high;
|
||||||
const bool masked = wide || mask != 0;
|
const bool masked = wide || mask != 0;
|
||||||
@@ -33253,9 +33284,9 @@ std::vector<TestCase> BufferStoreFormatD16Cases() {
|
|||||||
test.user_data = MakeStructuredStorageBufferData(stride, multi_lane ? wave : 3u,
|
test.user_data = MakeStructuredStorageBufferData(stride, multi_lane ? wave : 3u,
|
||||||
false, BufferFormat(input.format));
|
false, BufferFormat(input.format));
|
||||||
test.has_user_data = true;
|
test.has_user_data = true;
|
||||||
test.opcodes = {O::V_MOV_B32, high ? O::BUFFER_STORE_FORMAT_D16_HI_X :
|
test.opcodes = {O::V_MOV_B32,
|
||||||
wide ? O::BUFFER_STORE_FORMAT_D16_XYZW :
|
high ? O::BUFFER_STORE_FORMAT_D16_HI_X : formats[input.opcode & 3u],
|
||||||
O::BUFFER_STORE_FORMAT_D16_X, O::S_ENDPGM};
|
O::S_ENDPGM};
|
||||||
if (high) test.decoded_counts = {{"BUFFER_STORE_FORMAT_D16_HI_X", 3u}};
|
if (high) test.decoded_counts = {{"BUFFER_STORE_FORMAT_D16_HI_X", 3u}};
|
||||||
cases.push_back(std::move(test));
|
cases.push_back(std::move(test));
|
||||||
}
|
}
|
||||||
@@ -43310,7 +43341,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
for (auto &test : BufferLoadFormatD16XCases()) {
|
for (auto &test : BufferLoadFormatD16XCases()) {
|
||||||
cases.push_back(std::move(test));
|
cases.push_back(std::move(test));
|
||||||
}
|
}
|
||||||
for (auto &test : BufferLoadFormatD16XyzwCases()) {
|
for (auto &test : BufferLoadFormatD16VectorCases()) {
|
||||||
cases.push_back(std::move(test));
|
cases.push_back(std::move(test));
|
||||||
}
|
}
|
||||||
for (auto &test : BufferStoreFormatD16Cases()) {
|
for (auto &test : BufferStoreFormatD16Cases()) {
|
||||||
@@ -49288,7 +49319,7 @@ int main(int argc, char **argv) {
|
|||||||
for (const auto &test : BufferLoadFormatD16XCases()) {
|
for (const auto &test : BufferLoadFormatD16XCases()) {
|
||||||
RunCase(&vulkan, test);
|
RunCase(&vulkan, test);
|
||||||
}
|
}
|
||||||
for (const auto &test : BufferLoadFormatD16XyzwCases()) {
|
for (const auto &test : BufferLoadFormatD16VectorCases()) {
|
||||||
RunCase(&vulkan, test);
|
RunCase(&vulkan, test);
|
||||||
}
|
}
|
||||||
for (const auto &test : BufferStoreFormatD16Cases()) {
|
for (const auto &test : BufferStoreFormatD16Cases()) {
|
||||||
|
|||||||
@@ -16085,6 +16085,23 @@ void TestCapturedBufferLoadD16XyzwDecode() {
|
|||||||
"captured D16 XYZW load lost its full destination VGPRs or index");
|
"captured D16 XYZW load lost its full destination VGPRs or index");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCapturedBufferLoadD16XyDecode() {
|
||||||
|
namespace Decoder = ShaderRecompiler::Decoder;
|
||||||
|
const uint32_t code[] = {0xe2042000u, 0x80090600u};
|
||||||
|
Decoder::Instruction inst;
|
||||||
|
Decoder::DecodeInstruction(code, 0, inst);
|
||||||
|
Check(inst.opcode == Decoder::Opcode::BUFFER_LOAD_FORMAT_D16_XY &&
|
||||||
|
inst.word_count == 2 && inst.data_dwords == 1 && inst.data_bits == 16 &&
|
||||||
|
inst.data_components == 2 && inst.formatted && !inst.typed,
|
||||||
|
"captured D16 XY load lost its two components in one packed VGPR");
|
||||||
|
Check(inst.dst.kind == Decoder::OperandKind::Vgpr && inst.dst.reg == 6 &&
|
||||||
|
inst.dst.sdwa_sel == 6 &&
|
||||||
|
inst.src0.kind == Decoder::OperandKind::Vgpr && inst.src0.reg == 0 &&
|
||||||
|
inst.src1.kind == Decoder::OperandKind::Sgpr && inst.src1.reg == 36 &&
|
||||||
|
inst.idxen && !inst.offen,
|
||||||
|
"captured D16 XY load lost its destination VGPR or index");
|
||||||
|
}
|
||||||
|
|
||||||
void TestCapturedBufferStoreD16XyzwDecode() {
|
void TestCapturedBufferStoreD16XyzwDecode() {
|
||||||
namespace Decoder = ShaderRecompiler::Decoder;
|
namespace Decoder = ShaderRecompiler::Decoder;
|
||||||
const uint32_t code[] = {0xe21c6000u, 0x8002000eu};
|
const uint32_t code[] = {0xe21c6000u, 0x8002000eu};
|
||||||
@@ -16900,6 +16917,7 @@ int main() {
|
|||||||
TestCapturedBufferLoadUbyteD16Decode();
|
TestCapturedBufferLoadUbyteD16Decode();
|
||||||
TestCapturedBufferStoreShortD16HiDecode();
|
TestCapturedBufferStoreShortD16HiDecode();
|
||||||
TestCapturedBufferStoreFormatD16HiXDecode();
|
TestCapturedBufferStoreFormatD16HiXDecode();
|
||||||
|
TestCapturedBufferLoadD16XyDecode();
|
||||||
TestCapturedBufferLoadD16XyzwDecode();
|
TestCapturedBufferLoadD16XyzwDecode();
|
||||||
TestCapturedBufferStoreD16XyzwDecode();
|
TestCapturedBufferStoreD16XyzwDecode();
|
||||||
TestNewShaderRecompilerUnsupportedMemoryDecode();
|
TestNewShaderRecompilerUnsupportedMemoryDecode();
|
||||||
|
|||||||
Reference in New Issue
Block a user