summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-10-22 13:22:43 -0400
committerGravatar GitHub2019-10-22 13:22:43 -0400
commitc4a0aa9207ee5d83535ecfa42ca526fb6c9e1e8b (patch)
treeb65e2a03400264d50cabb2d3f12239592fc4fdfb /src
parentMerge pull request #2983 from lioncash/fallthrough (diff)
parentshader_ir/memory: Ignore global memory when tracking fails (diff)
downloadyuzu-c4a0aa9207ee5d83535ecfa42ca526fb6c9e1e8b.tar.gz
yuzu-c4a0aa9207ee5d83535ecfa42ca526fb6c9e1e8b.tar.xz
yuzu-c4a0aa9207ee5d83535ecfa42ca526fb6c9e1e8b.zip
Merge pull request #2995 from ReinUsesLisp/ignore-gmem
shader_ir/memory: Ignore global memory when tracking fails
Diffstat (limited to '')
-rw-r--r--src/video_core/shader/decode/memory.cpp39
-rw-r--r--src/video_core/shader/shader_ir.h5
2 files changed, 26 insertions, 18 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 7923d4d69..335d78146 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -166,9 +166,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
166 }(); 166 }();
167 167
168 const auto [real_address_base, base_address, descriptor] = 168 const auto [real_address_base, base_address, descriptor] =
169 TrackAndGetGlobalMemory(bb, instr, false); 169 TrackGlobalMemory(bb, instr, false);
170 170
171 const u32 count = GetUniformTypeElementsCount(type); 171 const u32 count = GetUniformTypeElementsCount(type);
172 if (!real_address_base || !base_address) {
173 // Tracking failed, load zeroes.
174 for (u32 i = 0; i < count; ++i) {
175 SetRegister(bb, instr.gpr0.Value() + i, Immediate(0.0f));
176 }
177 break;
178 }
179
172 for (u32 i = 0; i < count; ++i) { 180 for (u32 i = 0; i < count; ++i) {
173 const Node it_offset = Immediate(i * 4); 181 const Node it_offset = Immediate(i * 4);
174 const Node real_address = 182 const Node real_address =
@@ -260,22 +268,19 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
260 }(); 268 }();
261 269
262 const auto [real_address_base, base_address, descriptor] = 270 const auto [real_address_base, base_address, descriptor] =
263 TrackAndGetGlobalMemory(bb, instr, true); 271 TrackGlobalMemory(bb, instr, true);
264 272 if (!real_address_base || !base_address) {
265 // Encode in temporary registers like this: real_base_address, {registers_to_be_written...} 273 // Tracking failed, skip the store.
266 SetTemporary(bb, 0, real_address_base); 274 break;
275 }
267 276
268 const u32 count = GetUniformTypeElementsCount(type); 277 const u32 count = GetUniformTypeElementsCount(type);
269 for (u32 i = 0; i < count; ++i) { 278 for (u32 i = 0; i < count; ++i) {
270 SetTemporary(bb, i + 1, GetRegister(instr.gpr0.Value() + i));
271 }
272 for (u32 i = 0; i < count; ++i) {
273 const Node it_offset = Immediate(i * 4); 279 const Node it_offset = Immediate(i * 4);
274 const Node real_address = 280 const Node real_address = Operation(OperationCode::UAdd, real_address_base, it_offset);
275 Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
276 const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); 281 const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
277 282 const Node value = GetRegister(instr.gpr0.Value() + i);
278 bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporary(i + 1))); 283 bb.push_back(Operation(OperationCode::Assign, gmem, value));
279 } 284 }
280 break; 285 break;
281 } 286 }
@@ -301,15 +306,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
301 return pc; 306 return pc;
302} 307}
303 308
304std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeBlock& bb, 309std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackGlobalMemory(NodeBlock& bb,
305 Instruction instr, 310 Instruction instr,
306 bool is_write) { 311 bool is_write) {
307 const auto addr_register{GetRegister(instr.gmem.gpr)}; 312 const auto addr_register{GetRegister(instr.gmem.gpr)};
308 const auto immediate_offset{static_cast<u32>(instr.gmem.offset)}; 313 const auto immediate_offset{static_cast<u32>(instr.gmem.offset)};
309 314
310 const auto [base_address, index, offset] = 315 const auto [base_address, index, offset] =
311 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size())); 316 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()));
312 ASSERT(base_address != nullptr); 317 ASSERT_OR_EXECUTE_MSG(base_address != nullptr,
318 { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); },
319 "Global memory tracking failed");
313 320
314 bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); 321 bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset)));
315 322
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 105981d67..91cd0a534 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -371,8 +371,9 @@ private:
371 std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code, 371 std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code,
372 s64 cursor) const; 372 s64 cursor) const;
373 373
374 std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory( 374 std::tuple<Node, Node, GlobalMemoryBase> TrackGlobalMemory(NodeBlock& bb,
375 NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write); 375 Tegra::Shader::Instruction instr,
376 bool is_write);
376 377
377 const ProgramCode& program_code; 378 const ProgramCode& program_code;
378 const u32 main_offset; 379 const u32 main_offset;