summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-06-27 09:24:40 -0400
committerGravatar FernandoS272019-07-09 08:14:43 -0400
commite7c6045a03584ac5cd93e9030cdf4f47867f9ee3 (patch)
treeda6e23ee501dfce3fb493730b0acd6f906e6ac92 /src
parentcontrol_flow: Assert shaders bigger than limit. (diff)
downloadyuzu-e7c6045a03584ac5cd93e9030cdf4f47867f9ee3.tar.gz
yuzu-e7c6045a03584ac5cd93e9030cdf4f47867f9ee3.tar.xz
yuzu-e7c6045a03584ac5cd93e9030cdf4f47867f9ee3.zip
control_flow: Correct block breaking algorithm.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/control_flow.cpp34
1 files changed, 17 insertions, 17 deletions
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp
index bdf9d4dd4..fdcc970ff 100644
--- a/src/video_core/shader/control_flow.cpp
+++ b/src/video_core/shader/control_flow.cpp
@@ -75,19 +75,17 @@ struct CFGRebuildState {
75 75
76enum class BlockCollision : u32 { None, Found, Inside }; 76enum class BlockCollision : u32 { None, Found, Inside };
77 77
78std::pair<BlockCollision, std::vector<BlockInfo>::iterator> TryGetBlock(CFGRebuildState& state, 78std::pair<BlockCollision, u32> TryGetBlock(CFGRebuildState& state, u32 address) {
79 u32 address) { 79 const auto& blocks = state.block_info;
80 auto it = state.block_info.begin(); 80 for (u32 index = 0; index < blocks.size(); index++) {
81 while (it != state.block_info.end()) { 81 if (blocks[index].start == address) {
82 if (it->start == address) { 82 return {BlockCollision::Found, index};
83 return {BlockCollision::Found, it};
84 } 83 }
85 if (it->IsInside(address)) { 84 if (blocks[index].IsInside(address)) {
86 return {BlockCollision::Inside, it}; 85 return {BlockCollision::Inside, index};
87 } 86 }
88 it++;
89 } 87 }
90 return {BlockCollision::None, it}; 88 return {BlockCollision::None, -1};
91} 89}
92 90
93struct ParseInfo { 91struct ParseInfo {
@@ -318,24 +316,26 @@ bool TryInspectAddress(CFGRebuildState& state) {
318 if (state.inspect_queries.empty()) { 316 if (state.inspect_queries.empty()) {
319 return false; 317 return false;
320 } 318 }
319
321 const u32 address = state.inspect_queries.front(); 320 const u32 address = state.inspect_queries.front();
322 state.inspect_queries.pop_front(); 321 state.inspect_queries.pop_front();
323 const auto search_result = TryGetBlock(state, address); 322 const auto [result, block_index] = TryGetBlock(state, address);
324 switch (search_result.first) { 323 switch (result) {
325 case BlockCollision::Found: { 324 case BlockCollision::Found: {
326 return true; 325 return true;
327 } 326 }
328 case BlockCollision::Inside: { 327 case BlockCollision::Inside: {
329 // This case is the tricky one: 328 // This case is the tricky one:
330 // We need to Split the block in 2 sepparate blocks 329 // We need to Split the block in 2 sepparate blocks
331 const auto it = search_result.second; 330 const u32 end = state.block_info[block_index].end;
332 BlockInfo& block_info = CreateBlockInfo(state, address, it->end); 331 BlockInfo& new_block = CreateBlockInfo(state, address, end);
333 it->end = address - 1; 332 BlockInfo& current_block = state.block_info[block_index];
334 block_info.branch = it->branch; 333 current_block.end = address - 1;
334 new_block.branch = current_block.branch;
335 BlockBranchInfo forward_branch{}; 335 BlockBranchInfo forward_branch{};
336 forward_branch.address = address; 336 forward_branch.address = address;
337 forward_branch.ignore = true; 337 forward_branch.ignore = true;
338 it->branch = forward_branch; 338 current_block.branch = forward_branch;
339 return true; 339 return true;
340 } 340 }
341 default: 341 default: