mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 07:52:39 +00:00
shader: support 64-bit buffer atomic minimum
This commit is contained in:
1 parent
b2053c2861
commit
95a507a8ff
10 files changed
+50
No files matched your search
@@ -291,6 +291,7 @@ inline constexpr auto EmitBufferAtomicIAdd32 = EmitAtomic32;
|
||||
inline constexpr auto EmitBufferAtomicISub32 = EmitAtomic32;
|
||||
inline constexpr auto EmitBufferAtomicSMin32 = EmitAtomic32;
|
||||
inline constexpr auto EmitBufferAtomicUMin32 = EmitAtomic32;
|
||||
inline constexpr auto EmitBufferAtomicUMin64 = EmitBufferAtomic64;
|
||||
inline constexpr auto EmitBufferAtomicSMax32 = EmitAtomic32;
|
||||
inline constexpr auto EmitBufferAtomicUMax32 = EmitAtomic32;
|
||||
inline constexpr auto EmitBufferAtomicAnd32 = EmitAtomic32;
|
||||
|
||||
@@ -585,6 +585,7 @@ spv::Op SpirvAtomicOpcode(IR::ValueOpcode opcode) {
|
||||
case IR::ValueOpcode::ImageAtomicUMin32:
|
||||
case IR::ValueOpcode::ImageAtomicUMin64:
|
||||
case IR::ValueOpcode::BufferAtomicUMin32:
|
||||
case IR::ValueOpcode::BufferAtomicUMin64:
|
||||
case IR::ValueOpcode::SharedAtomicUMin32: return spv::OpAtomicUMin;
|
||||
case IR::ValueOpcode::ImageAtomicSMax32:
|
||||
case IR::ValueOpcode::BufferAtomicSMax32:
|
||||
|
||||
@@ -69,6 +69,7 @@ constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
|
||||
{0x40u, Opcode::BUFFER_ATOMIC_FMAX, 1, 32},
|
||||
{0x50u, Opcode::BUFFER_ATOMIC_SWAP_X2, 2, 32},
|
||||
{0x52u, Opcode::BUFFER_ATOMIC_ADD_X2, 2, 32},
|
||||
{0x56u, Opcode::BUFFER_ATOMIC_UMIN_X2, 2, 32},
|
||||
{0x59u, Opcode::BUFFER_ATOMIC_AND_X2, 2, 32},
|
||||
{0x5au, Opcode::BUFFER_ATOMIC_OR_X2, 2, 32},
|
||||
{0x71u, Opcode::BUFFER_GL0_INV, 0, 0},
|
||||
|
||||
@@ -664,6 +664,7 @@ std::string InstructionToString(const Instruction& inst) {
|
||||
case Opcode::BUFFER_ATOMIC_SUB:
|
||||
case Opcode::BUFFER_ATOMIC_SMIN:
|
||||
case Opcode::BUFFER_ATOMIC_UMIN:
|
||||
case Opcode::BUFFER_ATOMIC_UMIN_X2:
|
||||
case Opcode::BUFFER_ATOMIC_SMAX:
|
||||
case Opcode::BUFFER_ATOMIC_UMAX:
|
||||
case Opcode::BUFFER_ATOMIC_AND:
|
||||
|
||||
@@ -596,6 +596,7 @@ enum class Opcode {
|
||||
BUFFER_ATOMIC_SUB,
|
||||
BUFFER_ATOMIC_SMIN,
|
||||
BUFFER_ATOMIC_UMIN,
|
||||
BUFFER_ATOMIC_UMIN_X2,
|
||||
BUFFER_ATOMIC_SMAX,
|
||||
BUFFER_ATOMIC_UMAX,
|
||||
BUFFER_ATOMIC_AND,
|
||||
|
||||
@@ -1029,6 +1029,8 @@ void Translator::EmitMemory(const Decoder::Instruction& inst) {
|
||||
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicSMin32);
|
||||
case Decoder::Opcode::BUFFER_ATOMIC_UMIN:
|
||||
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicUMin32);
|
||||
case Decoder::Opcode::BUFFER_ATOMIC_UMIN_X2:
|
||||
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicUMin64);
|
||||
case Decoder::Opcode::BUFFER_ATOMIC_SMAX:
|
||||
return BUFFER_ATOMIC(inst, IR::ValueOpcode::BufferAtomicSMax32);
|
||||
case Decoder::Opcode::BUFFER_ATOMIC_UMAX:
|
||||
|
||||
@@ -123,6 +123,7 @@ BufferAccess BufferAccessOf(ValueOpcode opcode) {
|
||||
case ValueOpcode::BufferAtomicISub32:
|
||||
case ValueOpcode::BufferAtomicSMin32:
|
||||
case ValueOpcode::BufferAtomicUMin32:
|
||||
case ValueOpcode::BufferAtomicUMin64:
|
||||
case ValueOpcode::BufferAtomicSMax32:
|
||||
case ValueOpcode::BufferAtomicUMax32:
|
||||
case ValueOpcode::BufferAtomicAnd32:
|
||||
@@ -140,6 +141,7 @@ uint32_t BufferComponentCount(ValueOpcode opcode) {
|
||||
switch (opcode) {
|
||||
case ValueOpcode::BufferAtomicSwap64:
|
||||
case ValueOpcode::BufferAtomicIAdd64:
|
||||
case ValueOpcode::BufferAtomicUMin64:
|
||||
case ValueOpcode::BufferAtomicAnd64:
|
||||
case ValueOpcode::BufferAtomicOr64:
|
||||
case ValueOpcode::LoadBufferU32x2:
|
||||
|
||||
@@ -269,6 +269,7 @@ VALUE_OPCODE(BufferAtomicIAdd64, U64, BufferResource, U32, U32, U32, U64, U1)
|
||||
VALUE_OPCODE(BufferAtomicISub32, U32, BufferResource, U32, U32, U32, U32, U1)
|
||||
VALUE_OPCODE(BufferAtomicSMin32, U32, BufferResource, U32, U32, U32, U32, U1)
|
||||
VALUE_OPCODE(BufferAtomicUMin32, U32, BufferResource, U32, U32, U32, U32, U1)
|
||||
VALUE_OPCODE(BufferAtomicUMin64, U64, BufferResource, U32, U32, U32, U64, U1)
|
||||
VALUE_OPCODE(BufferAtomicSMax32, U32, BufferResource, U32, U32, U32, U32, U1)
|
||||
VALUE_OPCODE(BufferAtomicUMax32, U32, BufferResource, U32, U32, U32, U32, U1)
|
||||
VALUE_OPCODE(BufferAtomicAnd32, U32, BufferResource, U32, U32, U32, U32, U1)
|
||||
|
||||
@@ -22674,6 +22674,7 @@ CoverageClass ClassifyOpcode(ShaderOpcode opcode,
|
||||
case Opcode::BUFFER_ATOMIC_SUB:
|
||||
case Opcode::BUFFER_ATOMIC_SMIN:
|
||||
case Opcode::BUFFER_ATOMIC_UMIN:
|
||||
case Opcode::BUFFER_ATOMIC_UMIN_X2:
|
||||
case Opcode::BUFFER_ATOMIC_SMAX:
|
||||
case Opcode::BUFFER_ATOMIC_UMAX:
|
||||
case Opcode::BUFFER_ATOMIC_AND:
|
||||
@@ -38260,6 +38261,41 @@ TestCase BufferAtomicAddX2GlcAndExec() {
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase BufferAtomicUMinX2GlcAndExec() {
|
||||
using O = ShaderOpcode;
|
||||
TestCase test;
|
||||
test.name = "BufferAtomicUMinX2GlcAndExec";
|
||||
auto &code = test.code;
|
||||
code.push_back(EncodeSop1(0x04, 12, 126));
|
||||
AppendVMovU32(&code, 20, 0);
|
||||
const u32 values[][2] = {{0xffffffffu, 0x80000000u},
|
||||
{0xffffffffu, 0x7fffffffu},
|
||||
{0xfffffffeu, 0x7fffffffu},
|
||||
{0u, 0u}};
|
||||
for (u32 i = 0; i < std::size(values); ++i) {
|
||||
AppendVMovLiteral(&code, 2, values[i][0]);
|
||||
AppendVMovLiteral(&code, 3, values[i][1]);
|
||||
if (i == 3) {
|
||||
code.push_back(EncodeSop1(0x04, 126, InlineU32(0)));
|
||||
}
|
||||
AppendBufferStoreOpcode(&code, 0x56, 2, 20, i != 1);
|
||||
code.push_back(EncodeSop1(0x04, 126, 12));
|
||||
AppendStoreVgpr(&code, 2, 2 + i * 2);
|
||||
AppendStoreVgpr(&code, 3, 3 + i * 2);
|
||||
}
|
||||
AppendEnd(&code);
|
||||
test.initial = {0u, 0x80000001u, 0, 0, 0, 0, 0, 0, 1, 1};
|
||||
// The high dwords decide the first two mins, the second only when compared
|
||||
// unsigned, and the low dwords the third. GLC returns the old value, the
|
||||
// second min keeps its operand, and EXEC = 0 suppresses the fourth min.
|
||||
test.expected = {0xfffffffeu, 0x7fffffffu, 0u, 0x80000001u,
|
||||
0xffffffffu, 0x7fffffffu, 0xffffffffu, 0x7fffffffu, 0, 0};
|
||||
test.opcodes = {O::V_MOV_B32, O::S_MOV_B64, O::BUFFER_ATOMIC_UMIN_X2,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.required_spirv = {"OpAtomicUMin %ulong", "Int64Atomics"};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase BufferAtomicCmpSwapExactRaw() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -46013,6 +46049,7 @@ std::vector<TestCase> MakeCases() {
|
||||
}
|
||||
AddCase(BufferAtomicAndX2GlcAndExec);
|
||||
AddCase(BufferAtomicAddX2GlcAndExec);
|
||||
AddCase(BufferAtomicUMinX2GlcAndExec);
|
||||
AddCase(ImageAtomicSignedMinMax<false>);
|
||||
AddCase(ImageAtomicSignedMinMax<true>);
|
||||
AddCase(ImageAtomicSignedMinMax<false, true>);
|
||||
@@ -52221,6 +52258,7 @@ int main(int argc, char **argv) {
|
||||
RunCase(&vulkan, DsAtomicReturn64());
|
||||
RunCase(&vulkan, BufferAtomicAndX2GlcAndExec());
|
||||
RunCase(&vulkan, BufferAtomicAddX2GlcAndExec());
|
||||
RunCase(&vulkan, BufferAtomicUMinX2GlcAndExec());
|
||||
RunCase(&vulkan, ImageAtomicSignedMinMax<false>());
|
||||
RunCase(&vulkan, ImageAtomicSignedMinMax<true>());
|
||||
return 0;
|
||||
|
||||
@@ -10809,6 +10809,8 @@ void TestCapturedBufferAtomicsX2() {
|
||||
"BufferAtomicIAdd64", "OpAtomicIAdd", ValueOpcode::BufferAtomicIAdd64},
|
||||
{{0xe1680018u, 0x80000000u}, 0u, 241u, "BUFFER_ATOMIC_OR_X2",
|
||||
"BufferAtomicOr64", "OpAtomicOr", ValueOpcode::BufferAtomicOr64},
|
||||
{{0xe1582000u, 0x8003092au}, 9u, 237u, "BUFFER_ATOMIC_UMIN_X2",
|
||||
"BufferAtomicUMin64", "OpAtomicUMin", ValueOpcode::BufferAtomicUMin64},
|
||||
{{0xe1402000u, 0x80000913u}, 9u, 229u, "BUFFER_ATOMIC_SWAP_X2",
|
||||
"BufferAtomicSwap64", "OpAtomicExchange", ValueOpcode::BufferAtomicSwap64},
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user