summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 {
217 Signed8 = 1, 217 Signed8 = 1,
218 Unsigned16 = 2, 218 Unsigned16 = 2,
219 Signed16 = 3, 219 Signed16 = 3,
220 Bytes32 = 4, 220 Bits32 = 4,
221 Bytes64 = 5, 221 Bits64 = 5,
222 Bytes128 = 6, 222 Bits128 = 6,
223}; 223};
224 224
225enum class IMinMaxExchange : u64 { 225enum 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) {
104 } 104 }
105 case OpCode::Id::LD_L: { 105 case OpCode::Id::LD_L: {
106 UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", 106 UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}",
107 static_cast<unsigned>(instr.ld_l.unknown.Value())); 107 static_cast<u32>(instr.ld_l.unknown.Value()));
108 108
109 const Node index = Operation(OperationCode::IAdd, GetRegister(instr.gpr8), 109 const auto GetLmem = [&](s32 offset) {
110 Immediate(static_cast<s32>(instr.smem_imm))); 110 ASSERT(offset % 4 == 0);
111 const Node lmem = GetLocalMemory(index); 111 const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
112 const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
113 immediate_offset);
114 return GetLocalMemory(address);
115 };
112 116
113 switch (instr.ldst_sl.type.Value()) { 117 switch (instr.ldst_sl.type.Value()) {
114 case Tegra::Shader::StoreType::Bytes32: 118 case Tegra::Shader::StoreType::Bits32:
115 SetRegister(bb, instr.gpr0, lmem); 119 case Tegra::Shader::StoreType::Bits64:
120 case Tegra::Shader::StoreType::Bits128: {
121 const u32 count = [&]() {
122 switch (instr.ldst_sl.type.Value()) {
123 case Tegra::Shader::StoreType::Bits32:
124 return 1;
125 case Tegra::Shader::StoreType::Bits64:
126 return 2;
127 case Tegra::Shader::StoreType::Bits128:
128 return 4;
129 default:
130 UNREACHABLE();
131 return 0;
132 }
133 }();
134 for (u32 i = 0; i < count; ++i)
135 SetTemporal(bb, i, GetLmem(i * 4));
136 for (u32 i = 0; i < count; ++i)
137 SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
116 break; 138 break;
139 }
117 default: 140 default:
118 UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", 141 UNIMPLEMENTED_MSG("LD_L Unhandled type: {}",
119 static_cast<unsigned>(instr.ldst_sl.type.Value())); 142 static_cast<u32>(instr.ldst_sl.type.Value()));
120 } 143 }
121 break; 144 break;
122 } 145 }
@@ -202,12 +225,20 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
202 UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", 225 UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}",
203 static_cast<u32>(instr.st_l.unknown.Value())); 226 static_cast<u32>(instr.st_l.unknown.Value()));
204 227
205 const Node index = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), 228 const auto GetLmemAddr = [&](s32 offset) {
206 Immediate(static_cast<s32>(instr.smem_imm))); 229 ASSERT(offset % 4 == 0);
230 const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset);
231 return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate);
232 };
207 233
208 switch (instr.ldst_sl.type.Value()) { 234 switch (instr.ldst_sl.type.Value()) {
209 case Tegra::Shader::StoreType::Bytes32: 235 case Tegra::Shader::StoreType::Bits128:
210 SetLocalMemory(bb, index, GetRegister(instr.gpr0)); 236 SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3));
237 SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2));
238 case Tegra::Shader::StoreType::Bits64:
239 SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1));
240 case Tegra::Shader::StoreType::Bits32:
241 SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0));
211 break; 242 break;
212 default: 243 default:
213 UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", 244 UNIMPLEMENTED_MSG("ST_L Unhandled type: {}",