mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: support packed D16 XYZW formatted buffer stores
Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
@@ -815,18 +815,23 @@ void StoreFormattedPrepared(ValueEmitContext& ctx, const IR::Inst& inst,
|
||||
uint32_t components) {
|
||||
if (resource.object_pointer == 0u) return;
|
||||
// RDNA2 formatted stores transfer the entire format, zero-filling missing VGPRs.
|
||||
const auto count = mem.data_bits == 16u ? mem.component_count : components;
|
||||
const auto plan = PrepareFormattedMemory(ctx, inst, mem, resource, info);
|
||||
EmitIfCondition(ctx.state, plan.in_bounds, [&]() {
|
||||
auto packed = ConstantU32(ctx.state, 0);
|
||||
for (uint32_t component = 0; component < info.component_count; component++) {
|
||||
auto value = ConstantU32(ctx.state, 0);
|
||||
if (component < components) {
|
||||
if (component < count) {
|
||||
const auto word = mem.data_bits == 16u ? component / 2u : component;
|
||||
value = data;
|
||||
if (components != 1u) {
|
||||
value = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction(spv::OpCompositeExtract, TypeU32(ctx.state),
|
||||
value, data, component);
|
||||
value, data, word);
|
||||
}
|
||||
if (mem.data_bits == 16u && (component & 1u) != 0u)
|
||||
value = Binary(ctx.state, spv::OpShiftRightLogical, TypeU32(ctx.state), value,
|
||||
ConstantU32(ctx.state, 16u));
|
||||
}
|
||||
value = EncodeFormattedStoreComponent(ctx.state, info, component, value, mem.data_bits);
|
||||
const auto bits = info.component_bits[component];
|
||||
|
||||
@@ -70,6 +70,7 @@ constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
|
||||
{0x80u, Opcode::BUFFER_LOAD_FORMAT_D16_X, 1, 16, false, false, true},
|
||||
{0x83u, Opcode::BUFFER_LOAD_FORMAT_D16_XYZW, 2, 16, false, false, true},
|
||||
{0x84u, Opcode::BUFFER_STORE_FORMAT_D16_X, 1, 16, false, false, true},
|
||||
{0x87u, Opcode::BUFFER_STORE_FORMAT_D16_XYZW, 2, 16, false, false, true},
|
||||
};
|
||||
|
||||
constexpr MemoryOpcodeInfo MTBUF_OPCODE_LIST[] = {
|
||||
@@ -307,7 +308,8 @@ void DecodeMubuf(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
|
||||
}
|
||||
|
||||
DecodeVectorGpr(vdata, inst.dst);
|
||||
if (inst.opcode == Opcode::BUFFER_LOAD_FORMAT_D16_XYZW) {
|
||||
if (inst.opcode == Opcode::BUFFER_LOAD_FORMAT_D16_XYZW ||
|
||||
inst.opcode == Opcode::BUFFER_STORE_FORMAT_D16_XYZW) {
|
||||
inst.data_components = 4u;
|
||||
}
|
||||
if (inst.opcode == Opcode::BUFFER_LOAD_FORMAT_D16_X ||
|
||||
|
||||
@@ -637,6 +637,7 @@ std::string InstructionToString(const Instruction& inst) {
|
||||
case Opcode::BUFFER_STORE_FORMAT_XYZ:
|
||||
case Opcode::BUFFER_STORE_FORMAT_XYZW:
|
||||
case Opcode::BUFFER_STORE_FORMAT_D16_X:
|
||||
case Opcode::BUFFER_STORE_FORMAT_D16_XYZW:
|
||||
case Opcode::BUFFER_LOAD_UBYTE:
|
||||
case Opcode::BUFFER_LOAD_UBYTE_D16:
|
||||
case Opcode::BUFFER_LOAD_USHORT:
|
||||
|
||||
@@ -553,6 +553,7 @@ enum class Opcode {
|
||||
BUFFER_STORE_FORMAT_XYZ,
|
||||
BUFFER_STORE_FORMAT_XYZW,
|
||||
BUFFER_STORE_FORMAT_D16_X,
|
||||
BUFFER_STORE_FORMAT_D16_XYZW,
|
||||
BUFFER_LOAD_UBYTE,
|
||||
BUFFER_LOAD_UBYTE_D16,
|
||||
BUFFER_LOAD_SBYTE,
|
||||
|
||||
@@ -187,7 +187,7 @@ Decoder::Operand MemorySourceAt(const Decoder::Instruction& decoded, uint32_t in
|
||||
if (decoded.family == Decoder::Family::MUBUF || decoded.family == Decoder::Family::MTBUF) {
|
||||
const bool store_or_atomic =
|
||||
(decoded.opcode >= Decoder::Opcode::BUFFER_STORE_FORMAT_X &&
|
||||
decoded.opcode <= Decoder::Opcode::BUFFER_STORE_FORMAT_D16_X) ||
|
||||
decoded.opcode <= Decoder::Opcode::BUFFER_STORE_FORMAT_D16_XYZW) ||
|
||||
(decoded.opcode >= Decoder::Opcode::BUFFER_STORE_BYTE &&
|
||||
decoded.opcode <= Decoder::Opcode::BUFFER_STORE_DWORDX4) ||
|
||||
(decoded.opcode >= Decoder::Opcode::TBUFFER_STORE_FORMAT_X &&
|
||||
@@ -1006,6 +1006,7 @@ void Translator::EmitMemory(const Decoder::Instruction& inst) {
|
||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZ:
|
||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZW:
|
||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_X:
|
||||
case Decoder::Opcode::BUFFER_STORE_FORMAT_D16_XYZW:
|
||||
case Decoder::Opcode::TBUFFER_STORE_FORMAT_X:
|
||||
case Decoder::Opcode::TBUFFER_STORE_FORMAT_XY:
|
||||
case Decoder::Opcode::TBUFFER_STORE_FORMAT_XYZ:
|
||||
|
||||
@@ -474,11 +474,12 @@ void ValidateProgram(const Program& program, bool require_ssa) {
|
||||
return Fail("indirect buffer requires a scalar, raw 8/16-bit, raw DWORD x1/x2/x3/x4, "
|
||||
"or formatted X load");
|
||||
}
|
||||
const bool packed_formatted_load =
|
||||
BufferAccessOf(inst.GetOpcode()) == BufferAccess::Read && memory.formatted &&
|
||||
const auto access = BufferAccessOf(inst.GetOpcode());
|
||||
const bool packed_formatted =
|
||||
(access == BufferAccess::Read || access == BufferAccess::Write) && memory.formatted &&
|
||||
memory.data_bits == 16u && memory.component_count == 4u && buffer_components == 2u;
|
||||
if (buffer_components > 1u &&
|
||||
(!vector_buffer || (memory.data_bits != 32u && !packed_formatted_load) ||
|
||||
(!vector_buffer || (memory.data_bits != 32u && !packed_formatted) ||
|
||||
memory.data_dwords != buffer_components || memory.component_index != 0u)) {
|
||||
return Fail(fmt::format("{} has inconsistent native-wide metadata",
|
||||
ValueOpcodeName(inst.GetOpcode())));
|
||||
|
||||
Reference in New Issue
Block a user