mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: add S_MEMREALTIME opcode
Co-authored-by: Maxime Allanic <maxime@allanic.me> Co-authored-by: Mac <me@itsmemac.com>
This commit is contained in:
@@ -21,6 +21,7 @@ constexpr MemoryOpcodeInfo SMEM_OPCODE_LIST[] = {
|
|||||||
{0x04u, Opcode::S_LOAD_DWORDX16, 16, 32}, {0x08u, Opcode::S_BUFFER_LOAD_DWORD, 1, 32},
|
{0x04u, Opcode::S_LOAD_DWORDX16, 16, 32}, {0x08u, Opcode::S_BUFFER_LOAD_DWORD, 1, 32},
|
||||||
{0x09u, Opcode::S_BUFFER_LOAD_DWORDX2, 2, 32}, {0x0au, Opcode::S_BUFFER_LOAD_DWORDX4, 4, 32},
|
{0x09u, Opcode::S_BUFFER_LOAD_DWORDX2, 2, 32}, {0x0au, Opcode::S_BUFFER_LOAD_DWORDX4, 4, 32},
|
||||||
{0x0bu, Opcode::S_BUFFER_LOAD_DWORDX8, 8, 32}, {0x0cu, Opcode::S_BUFFER_LOAD_DWORDX16, 16, 32},
|
{0x0bu, Opcode::S_BUFFER_LOAD_DWORDX8, 8, 32}, {0x0cu, Opcode::S_BUFFER_LOAD_DWORDX16, 16, 32},
|
||||||
|
{0x25u, Opcode::S_MEMREALTIME, 2, 32},
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
|
constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
|
||||||
@@ -245,6 +246,10 @@ void DecodeSmem(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecodeScalarDestination(sdst, pc, inst.dst);
|
DecodeScalarDestination(sdst, pc, inst.dst);
|
||||||
|
if (inst.opcode == Opcode::S_MEMREALTIME) {
|
||||||
|
inst.src_count = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// SMEM encodes SBASE in SGPR pairs. Scalar-buffer loads still use the same
|
// SMEM encodes SBASE in SGPR pairs. Scalar-buffer loads still use the same
|
||||||
// pair index; their descriptor operand consumes four SGPRs from that base.
|
// pair index; their descriptor operand consumes four SGPRs from that base.
|
||||||
DecodeScalarSource(sbase * 2u, pc, inst.src0);
|
DecodeScalarSource(sbase * 2u, pc, inst.src0);
|
||||||
|
|||||||
@@ -439,6 +439,7 @@ enum class Opcode {
|
|||||||
S_BUFFER_LOAD_DWORDX4,
|
S_BUFFER_LOAD_DWORDX4,
|
||||||
S_BUFFER_LOAD_DWORDX8,
|
S_BUFFER_LOAD_DWORDX8,
|
||||||
S_BUFFER_LOAD_DWORDX16,
|
S_BUFFER_LOAD_DWORDX16,
|
||||||
|
S_MEMREALTIME,
|
||||||
BUFFER_LOAD_FORMAT_X,
|
BUFFER_LOAD_FORMAT_X,
|
||||||
BUFFER_LOAD_FORMAT_XY,
|
BUFFER_LOAD_FORMAT_XY,
|
||||||
BUFFER_LOAD_FORMAT_XYZ,
|
BUFFER_LOAD_FORMAT_XYZ,
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
#include "common/logging/log.h"
|
||||||
#include "graphics/shader/recompiler/frontend/translate/Translator.h"
|
#include "graphics/shader/recompiler/frontend/translate/Translator.h"
|
||||||
#include "graphics/shader/recompiler/frontend/decode/ImageOps.h"
|
#include "graphics/shader/recompiler/frontend/decode/ImageOps.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace Libs::Graphics::ShaderRecompiler::Frontend {
|
namespace Libs::Graphics::ShaderRecompiler::Frontend {
|
||||||
|
|
||||||
@@ -891,6 +893,17 @@ bool Translator::EmitMemory(const Decoder::Instruction& inst) {
|
|||||||
case Decoder::Opcode::S_BUFFER_LOAD_DWORDX4:
|
case Decoder::Opcode::S_BUFFER_LOAD_DWORDX4:
|
||||||
case Decoder::Opcode::S_BUFFER_LOAD_DWORDX8:
|
case Decoder::Opcode::S_BUFFER_LOAD_DWORDX8:
|
||||||
case Decoder::Opcode::S_BUFFER_LOAD_DWORDX16: return S_LOAD(inst, false);
|
case Decoder::Opcode::S_BUFFER_LOAD_DWORDX16: return S_LOAD(inst, false);
|
||||||
|
case Decoder::Opcode::S_MEMREALTIME: {
|
||||||
|
static std::atomic_flag warned = ATOMIC_FLAG_INIT;
|
||||||
|
if (!warned.test_and_set(std::memory_order_relaxed)) {
|
||||||
|
Log::WriteToConsoleAndLog(
|
||||||
|
"Warning: S_MEMREALTIME uses placeholder UINT64_MAX; real-time clock not implemented.\n");
|
||||||
|
}
|
||||||
|
for (uint32_t component = 0; component < 2; component++) {
|
||||||
|
WriteOperand(ScalarDestinationOperand(inst.dst, component), IR::Value(UINT32_MAX));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case Decoder::Opcode::BUFFER_LOAD_UBYTE:
|
case Decoder::Opcode::BUFFER_LOAD_UBYTE:
|
||||||
case Decoder::Opcode::BUFFER_LOAD_SBYTE:
|
case Decoder::Opcode::BUFFER_LOAD_SBYTE:
|
||||||
|
|||||||
@@ -22783,6 +22783,31 @@ TestCase BranchVccnzUsesWaveMask() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase ScalarMemRealtimeCapturedPlaceholder() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
namespace D = ShaderRecompiler::Decoder;
|
||||||
|
|
||||||
|
std::vector<u32> code = {0xf4940300u, 0xfa000000u};
|
||||||
|
D::Instruction decoded;
|
||||||
|
D::DecodeInstruction(code, 0, decoded);
|
||||||
|
Require("ScalarMemRealtimeCapturedPlaceholder", "decode",
|
||||||
|
decoded.opcode == O::S_MEMREALTIME && decoded.word_count == 2 &&
|
||||||
|
decoded.dst.kind == D::OperandKind::Sgpr && decoded.dst.reg == 12 &&
|
||||||
|
decoded.data_dwords == 2 && decoded.src_count == 0 &&
|
||||||
|
decoded.src0.kind == D::OperandKind::Unknown &&
|
||||||
|
decoded.src1.kind == D::OperandKind::Unknown,
|
||||||
|
"captured clock instruction must write s12:s13 without memory operands");
|
||||||
|
AppendStoreSgprPair(&code, 12, 0);
|
||||||
|
code.insert(code.end(), {0xf4940300u, 0xfa000000u});
|
||||||
|
AppendStoreSgprPair(&code, 12, 2);
|
||||||
|
AppendEnd(&code);
|
||||||
|
return {"ScalarMemRealtimeCapturedPlaceholder",
|
||||||
|
code,
|
||||||
|
{},
|
||||||
|
{UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX},
|
||||||
|
{O::S_MEMREALTIME, O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||||
|
}
|
||||||
|
|
||||||
TestCase ScalarMemoryLoadVariants() {
|
TestCase ScalarMemoryLoadVariants() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -28436,6 +28461,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(SharedReturnKeepsSelectedValues);
|
AddCase(SharedReturnKeepsSelectedValues);
|
||||||
AddCase(BranchVccnzUsesWaveMask);
|
AddCase(BranchVccnzUsesWaveMask);
|
||||||
AddCase(BranchVccnzUsesCarryProducedWaveMask);
|
AddCase(BranchVccnzUsesCarryProducedWaveMask);
|
||||||
|
AddCase(ScalarMemRealtimeCapturedPlaceholder);
|
||||||
AddCase(ScalarMemoryLoadVariants);
|
AddCase(ScalarMemoryLoadVariants);
|
||||||
AddCase(ScalarLoadSignedImmediateOffsetAddsSoffset);
|
AddCase(ScalarLoadSignedImmediateOffsetAddsSoffset);
|
||||||
AddCase(ScalarLoadAlignsComponentsAndMasksAddress);
|
AddCase(ScalarLoadAlignsComponentsAndMasksAddress);
|
||||||
@@ -33172,6 +33198,11 @@ int main(int argc, char **argv) {
|
|||||||
std::setvbuf(stdout, nullptr, _IONBF, 0);
|
std::setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
EnsureConfigInitialized();
|
EnsureConfigInitialized();
|
||||||
CheckLeastRecentlyUsedCacheOrdering();
|
CheckLeastRecentlyUsedCacheOrdering();
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--s-memrealtime-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
RunCase(&vulkan, ScalarMemRealtimeCapturedPlaceholder());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--packed-integer-neg-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--packed-integer-neg-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, Vop3pIntegerNegationCapturedAndSelectedHalves());
|
RunCase(&vulkan, Vop3pIntegerNegationCapturedAndSelectedHalves());
|
||||||
|
|||||||
Reference in New Issue
Block a user