summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
authorGravatar FernandoS272021-04-01 09:21:53 +0200
committerGravatar ameerj2021-07-22 21:51:25 -0400
commit12f5f320985824d1ebad587ebecb0f8406143ebc (patch)
treecce9a7c14619350d578a262a6a23da6b0c9461d6 /src/shader_recompiler
parentshader: Implement ViewportIndex (diff)
downloadyuzu-12f5f320985824d1ebad587ebecb0f8406143ebc.tar.gz
yuzu-12f5f320985824d1ebad587ebecb0f8406143ebc.tar.xz
yuzu-12f5f320985824d1ebad587ebecb0f8406143ebc.zip
shader: Mark SSBOs as written when they are
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp31
-rw-r--r--src/shader_recompiler/shader_info.h1
2 files changed, 30 insertions, 2 deletions
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
index 1faa1ec88..d4bae249b 100644
--- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
+++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
@@ -6,6 +6,7 @@
6#include <compare> 6#include <compare>
7#include <optional> 7#include <optional>
8#include <ranges> 8#include <ranges>
9#include <map>
9 10
10#include <boost/container/flat_set.hpp> 11#include <boost/container/flat_set.hpp>
11#include <boost/container/small_vector.hpp> 12#include <boost/container/small_vector.hpp>
@@ -45,6 +46,7 @@ using StorageBufferSet =
45using StorageInstVector = boost::container::small_vector<StorageInst, 24>; 46using StorageInstVector = boost::container::small_vector<StorageInst, 24>;
46using VisitedBlocks = boost::container::flat_set<IR::Block*, std::less<IR::Block*>, 47using VisitedBlocks = boost::container::flat_set<IR::Block*, std::less<IR::Block*>,
47 boost::container::small_vector<IR::Block*, 4>>; 48 boost::container::small_vector<IR::Block*, 4>>;
49using StorageWritesMap = std::map<StorageBufferAddr, bool>;
48 50
49/// Returns true when the instruction is a global memory instruction 51/// Returns true when the instruction is a global memory instruction
50bool IsGlobalMemory(const IR::Inst& inst) { 52bool IsGlobalMemory(const IR::Inst& inst) {
@@ -69,6 +71,22 @@ bool IsGlobalMemory(const IR::Inst& inst) {
69 } 71 }
70} 72}
71 73
74/// Returns true when the instruction is a global memory instruction
75bool IsGlobalMemoryWrite(const IR::Inst& inst) {
76 switch (inst.Opcode()) {
77 case IR::Opcode::WriteGlobalS8:
78 case IR::Opcode::WriteGlobalU8:
79 case IR::Opcode::WriteGlobalS16:
80 case IR::Opcode::WriteGlobalU16:
81 case IR::Opcode::WriteGlobal32:
82 case IR::Opcode::WriteGlobal64:
83 case IR::Opcode::WriteGlobal128:
84 return true;
85 default:
86 return false;
87 }
88}
89
72/// Converts a global memory opcode to its storage buffer equivalent 90/// Converts a global memory opcode to its storage buffer equivalent
73IR::Opcode GlobalToStorage(IR::Opcode opcode) { 91IR::Opcode GlobalToStorage(IR::Opcode opcode) {
74 switch (opcode) { 92 switch (opcode) {
@@ -248,7 +266,7 @@ std::optional<StorageBufferAddr> Track(IR::Block* block, const IR::Value& value,
248 266
249/// Collects the storage buffer used by a global memory instruction and the instruction itself 267/// Collects the storage buffer used by a global memory instruction and the instruction itself
250void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& storage_buffer_set, 268void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& storage_buffer_set,
251 StorageInstVector& to_replace) { 269 StorageInstVector& to_replace, StorageWritesMap& writes_map) {
252 // NVN puts storage buffers in a specific range, we have to bias towards these addresses to 270 // NVN puts storage buffers in a specific range, we have to bias towards these addresses to
253 // avoid getting false positives 271 // avoid getting false positives
254 static constexpr Bias nvn_bias{ 272 static constexpr Bias nvn_bias{
@@ -277,6 +295,13 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& s
277 } 295 }
278 } 296 }
279 // Collect storage buffer and the instruction 297 // Collect storage buffer and the instruction
298 const bool is_a_write = IsGlobalMemoryWrite(inst);
299 auto it = writes_map.find(*storage_buffer);
300 if (it == writes_map.end()) {
301 writes_map[*storage_buffer] = is_a_write;
302 } else {
303 it->second = it->second || is_a_write;
304 }
280 storage_buffer_set.insert(*storage_buffer); 305 storage_buffer_set.insert(*storage_buffer);
281 to_replace.push_back(StorageInst{ 306 to_replace.push_back(StorageInst{
282 .storage_buffer{*storage_buffer}, 307 .storage_buffer{*storage_buffer},
@@ -350,13 +375,14 @@ void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
350void GlobalMemoryToStorageBufferPass(IR::Program& program) { 375void GlobalMemoryToStorageBufferPass(IR::Program& program) {
351 StorageBufferSet storage_buffers; 376 StorageBufferSet storage_buffers;
352 StorageInstVector to_replace; 377 StorageInstVector to_replace;
378 StorageWritesMap writes_map;
353 379
354 for (IR::Block* const block : program.post_order_blocks) { 380 for (IR::Block* const block : program.post_order_blocks) {
355 for (IR::Inst& inst : block->Instructions()) { 381 for (IR::Inst& inst : block->Instructions()) {
356 if (!IsGlobalMemory(inst)) { 382 if (!IsGlobalMemory(inst)) {
357 continue; 383 continue;
358 } 384 }
359 CollectStorageBuffers(*block, inst, storage_buffers, to_replace); 385 CollectStorageBuffers(*block, inst, storage_buffers, to_replace, writes_map);
360 } 386 }
361 } 387 }
362 Info& info{program.info}; 388 Info& info{program.info};
@@ -366,6 +392,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program) {
366 .cbuf_index{storage_buffer.index}, 392 .cbuf_index{storage_buffer.index},
367 .cbuf_offset{storage_buffer.offset}, 393 .cbuf_offset{storage_buffer.offset},
368 .count{1}, 394 .count{1},
395 .is_written{writes_map[storage_buffer]},
369 }); 396 });
370 ++storage_index; 397 ++storage_index;
371 } 398 }
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index a5bff40bb..d4d039eaf 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -59,6 +59,7 @@ struct StorageBufferDescriptor {
59 u32 cbuf_index; 59 u32 cbuf_index;
60 u32 cbuf_offset; 60 u32 cbuf_offset;
61 u32 count; 61 u32 count;
62 bool is_written;
62}; 63};
63 64
64struct Info { 65struct Info {