summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h6
-rw-r--r--src/video_core/shader/decode/memory.cpp55
2 files changed, 46 insertions, 15 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 8e915e2ae..269df9437 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -217,9 +217,9 @@ enum class StoreType : u64 {
Signed8 = 1,
Unsigned16 = 2,
Signed16 = 3,
- Bytes32 = 4,
- Bytes64 = 5,
- Bytes128 = 6,
+ Bits32 = 4,
+ Bits64 = 5,
+ Bits128 = 6,
};
enum class IMinMaxExchange : u64 {
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 1f418b4e6..3dd26da20 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -104,19 +104,42 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
}
case OpCode::Id::LD_L: {
UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}",
- static_cast<unsigned>(instr.ld_l.unknown.Value()));
-
- const Node index = Operation(OperationCode::IAdd, GetRegister(instr.gpr8),
- Immediate(static_cast<s32>(instr.smem_imm)));
- const Node lmem = GetLocalMemory(index);
+ static_cast<u32>(instr.ld_l.unknown.Value()));
+
+ const auto GetLmem = [&](s32 offset) {
+ ASSERT(offset % 4 == 0);
+ const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
+ const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
+ immediate_offset);
+ return GetLocalMemory(address);
+ };
switch (instr.ldst_sl.type.Value()) {
- case Tegra::Shader::StoreType::Bytes32:
- SetRegister(bb, instr.gpr0, lmem);
+ case Tegra::Shader::StoreType::Bits32:
+ case Tegra::Shader::StoreType::Bits64:
+ case Tegra::Shader::StoreType::Bits128: {
+ const u32 count = [&]() {
+ switch (instr.ldst_sl.type.Value()) {
+ case Tegra::Shader::StoreType::Bits32:
+ return 1;
+ case Tegra::Shader::StoreType::Bits64:
+ return 2;
+ case Tegra::Shader::StoreType::Bits128:
+ return 4;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+ }();
+ for (u32 i = 0; i < count; ++i)
+ SetTemporal(bb, i, GetLmem(i * 4));
+ for (u32 i = 0; i < count; ++i)
+ SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
break;
+ }
default:
UNIMPLEMENTED_MSG("LD_L Unhandled type: {}",
- static_cast<unsigned>(instr.ldst_sl.type.Value()));
+ static_cast<u32>(instr.ldst_sl.type.Value()));
}
break;
}
@@ -202,12 +225,20 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}",
static_cast<u32>(instr.st_l.unknown.Value()));
- const Node index = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
- Immediate(static_cast<s32>(instr.smem_imm)));
+ const auto GetLmemAddr = [&](s32 offset) {
+ ASSERT(offset % 4 == 0);
+ const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset);
+ return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate);
+ };
switch (instr.ldst_sl.type.Value()) {
- case Tegra::Shader::StoreType::Bytes32:
- SetLocalMemory(bb, index, GetRegister(instr.gpr0));
+ case Tegra::Shader::StoreType::Bits128:
+ SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3));
+ SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2));
+ case Tegra::Shader::StoreType::Bits64:
+ SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1));
+ case Tegra::Shader::StoreType::Bits32:
+ SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0));
break;
default:
UNIMPLEMENTED_MSG("ST_L Unhandled type: {}",