summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar bunnei2019-09-18 16:26:05 -0400
committerGravatar GitHub2019-09-18 16:26:05 -0400
commitb31880dc5e0d9aab1171d3476453ad2db00cfd3a (patch)
treeb1ec38b1d4be6f1f61d987608d99d1f6ee428a83 /src/video_core/shader/decode
parentMerge pull request #2851 from ReinUsesLisp/srgb (diff)
parentgl_shader_decompiler: Implement shared memory (diff)
downloadyuzu-b31880dc5e0d9aab1171d3476453ad2db00cfd3a.tar.gz
yuzu-b31880dc5e0d9aab1171d3476453ad2db00cfd3a.tar.xz
yuzu-b31880dc5e0d9aab1171d3476453ad2db00cfd3a.zip
Merge pull request #2784 from ReinUsesLisp/smem
shader_ir: Implement shared memory
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/memory.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index ed108bea8..7923d4d69 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -35,7 +35,7 @@ u32 GetUniformTypeElementsCount(Tegra::Shader::UniformType uniform_type) {
35 return 1; 35 return 1;
36 } 36 }
37} 37}
38} // namespace 38} // Anonymous namespace
39 39
40u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { 40u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
41 const Instruction instr = {program_code[pc]}; 41 const Instruction instr = {program_code[pc]};
@@ -106,16 +106,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
106 } 106 }
107 break; 107 break;
108 } 108 }
109 case OpCode::Id::LD_L: { 109 case OpCode::Id::LD_L:
110 LOG_DEBUG(HW_GPU, "LD_L cache management mode: {}", 110 LOG_DEBUG(HW_GPU, "LD_L cache management mode: {}", static_cast<u64>(instr.ld_l.unknown));
111 static_cast<u64>(instr.ld_l.unknown.Value())); 111 [[fallthrough]];
112 112 case OpCode::Id::LD_S: {
113 const auto GetLmem = [&](s32 offset) { 113 const auto GetMemory = [&](s32 offset) {
114 ASSERT(offset % 4 == 0); 114 ASSERT(offset % 4 == 0);
115 const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); 115 const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
116 const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), 116 const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
117 immediate_offset); 117 immediate_offset);
118 return GetLocalMemory(address); 118 return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address)
119 : GetLocalMemory(address);
119 }; 120 };
120 121
121 switch (instr.ldst_sl.type.Value()) { 122 switch (instr.ldst_sl.type.Value()) {
@@ -135,14 +136,16 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
135 return 0; 136 return 0;
136 } 137 }
137 }(); 138 }();
138 for (u32 i = 0; i < count; ++i) 139 for (u32 i = 0; i < count; ++i) {
139 SetTemporary(bb, i, GetLmem(i * 4)); 140 SetTemporary(bb, i, GetMemory(i * 4));
140 for (u32 i = 0; i < count; ++i) 141 }
142 for (u32 i = 0; i < count; ++i) {
141 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); 143 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
144 }
142 break; 145 break;
143 } 146 }
144 default: 147 default:
145 UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", 148 UNIMPLEMENTED_MSG("{} Unhandled type: {}", opcode->get().GetName(),
146 static_cast<u32>(instr.ldst_sl.type.Value())); 149 static_cast<u32>(instr.ldst_sl.type.Value()));
147 } 150 }
148 break; 151 break;
@@ -209,27 +212,34 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
209 212
210 break; 213 break;
211 } 214 }
212 case OpCode::Id::ST_L: { 215 case OpCode::Id::ST_L:
213 LOG_DEBUG(HW_GPU, "ST_L cache management mode: {}", 216 LOG_DEBUG(HW_GPU, "ST_L cache management mode: {}",
214 static_cast<u64>(instr.st_l.cache_management.Value())); 217 static_cast<u64>(instr.st_l.cache_management.Value()));
215 218 [[fallthrough]];
216 const auto GetLmemAddr = [&](s32 offset) { 219 case OpCode::Id::ST_S: {
220 const auto GetAddress = [&](s32 offset) {
217 ASSERT(offset % 4 == 0); 221 ASSERT(offset % 4 == 0);
218 const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset); 222 const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset);
219 return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate); 223 return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate);
220 }; 224 };
221 225
226 const auto set_memory = opcode->get().GetId() == OpCode::Id::ST_L
227 ? &ShaderIR::SetLocalMemory
228 : &ShaderIR::SetSharedMemory;
229
222 switch (instr.ldst_sl.type.Value()) { 230 switch (instr.ldst_sl.type.Value()) {
223 case Tegra::Shader::StoreType::Bits128: 231 case Tegra::Shader::StoreType::Bits128:
224 SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3)); 232 (this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3));
225 SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2)); 233 (this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2));
234 [[fallthrough]];
226 case Tegra::Shader::StoreType::Bits64: 235 case Tegra::Shader::StoreType::Bits64:
227 SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1)); 236 (this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1));
237 [[fallthrough]];
228 case Tegra::Shader::StoreType::Bits32: 238 case Tegra::Shader::StoreType::Bits32:
229 SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0)); 239 (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));
230 break; 240 break;
231 default: 241 default:
232 UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", 242 UNIMPLEMENTED_MSG("{} unhandled type: {}", opcode->get().GetName(),
233 static_cast<u32>(instr.ldst_sl.type.Value())); 243 static_cast<u32>(instr.ldst_sl.type.Value()));
234 } 244 }
235 break; 245 break;