summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2019-07-25 13:04:56 -0400
committerGravatar GitHub2019-07-25 13:04:56 -0400
commitb0ff3179ef8f4ebb6ccd2bdc9bccc64e3212edee (patch)
tree66d350fdcc096ca621932f76349669cbe0e63a72
parentMerge pull request #2737 from FernandoS27/track-fix (diff)
parentvideo_core/control_flow: Provide operator!= for types with operator== (diff)
downloadyuzu-b0ff3179ef8f4ebb6ccd2bdc9bccc64e3212edee.tar.gz
yuzu-b0ff3179ef8f4ebb6ccd2bdc9bccc64e3212edee.tar.xz
yuzu-b0ff3179ef8f4ebb6ccd2bdc9bccc64e3212edee.zip
Merge pull request #2739 from lioncash/cflow
video_core/control_flow: Minor changes/warning cleanup
-rw-r--r--src/video_core/shader/control_flow.cpp47
-rw-r--r--src/video_core/shader/control_flow.h30
-rw-r--r--src/video_core/shader/decode.cpp4
-rw-r--r--src/video_core/texture_cache/surface_base.cpp5
4 files changed, 53 insertions, 33 deletions
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp
index fdcc970ff..ec3a76690 100644
--- a/src/video_core/shader/control_flow.cpp
+++ b/src/video_core/shader/control_flow.cpp
@@ -15,7 +15,7 @@
15#include "video_core/shader/shader_ir.h" 15#include "video_core/shader/shader_ir.h"
16 16
17namespace VideoCommon::Shader { 17namespace VideoCommon::Shader {
18 18namespace {
19using Tegra::Shader::Instruction; 19using Tegra::Shader::Instruction;
20using Tegra::Shader::OpCode; 20using Tegra::Shader::OpCode;
21 21
@@ -29,8 +29,7 @@ struct Query {
29 29
30struct BlockStack { 30struct BlockStack {
31 BlockStack() = default; 31 BlockStack() = default;
32 BlockStack(const BlockStack& b) = default; 32 explicit BlockStack(const Query& q) : ssy_stack{q.ssy_stack}, pbk_stack{q.pbk_stack} {}
33 BlockStack(const Query& q) : ssy_stack{q.ssy_stack}, pbk_stack{q.pbk_stack} {}
34 std::stack<u32> ssy_stack{}; 33 std::stack<u32> ssy_stack{};
35 std::stack<u32> pbk_stack{}; 34 std::stack<u32> pbk_stack{};
36}; 35};
@@ -58,7 +57,7 @@ struct BlockInfo {
58struct CFGRebuildState { 57struct CFGRebuildState {
59 explicit CFGRebuildState(const ProgramCode& program_code, const std::size_t program_size, 58 explicit CFGRebuildState(const ProgramCode& program_code, const std::size_t program_size,
60 const u32 start) 59 const u32 start)
61 : program_code{program_code}, program_size{program_size}, start{start} {} 60 : start{start}, program_code{program_code}, program_size{program_size} {}
62 61
63 u32 start{}; 62 u32 start{};
64 std::vector<BlockInfo> block_info{}; 63 std::vector<BlockInfo> block_info{};
@@ -85,7 +84,7 @@ std::pair<BlockCollision, u32> TryGetBlock(CFGRebuildState& state, u32 address)
85 return {BlockCollision::Inside, index}; 84 return {BlockCollision::Inside, index};
86 } 85 }
87 } 86 }
88 return {BlockCollision::None, -1}; 87 return {BlockCollision::None, 0xFFFFFFFF};
89} 88}
90 89
91struct ParseInfo { 90struct ParseInfo {
@@ -365,27 +364,29 @@ bool TryQuery(CFGRebuildState& state) {
365 const auto gather_end = labels.upper_bound(block.end); 364 const auto gather_end = labels.upper_bound(block.end);
366 while (gather_start != gather_end) { 365 while (gather_start != gather_end) {
367 cc.push(gather_start->second); 366 cc.push(gather_start->second);
368 gather_start++; 367 ++gather_start;
369 } 368 }
370 }; 369 };
371 if (state.queries.empty()) { 370 if (state.queries.empty()) {
372 return false; 371 return false;
373 } 372 }
373
374 Query& q = state.queries.front(); 374 Query& q = state.queries.front();
375 const u32 block_index = state.registered[q.address]; 375 const u32 block_index = state.registered[q.address];
376 BlockInfo& block = state.block_info[block_index]; 376 BlockInfo& block = state.block_info[block_index];
377 // If the block is visted, check if the stacks match, else gather the ssy/pbk 377 // If the block is visited, check if the stacks match, else gather the ssy/pbk
378 // labels into the current stack and look if the branch at the end of the block 378 // labels into the current stack and look if the branch at the end of the block
379 // consumes a label. Schedule new queries accordingly 379 // consumes a label. Schedule new queries accordingly
380 if (block.visited) { 380 if (block.visited) {
381 BlockStack& stack = state.stacks[q.address]; 381 BlockStack& stack = state.stacks[q.address];
382 const bool all_okay = (stack.ssy_stack.size() == 0 || q.ssy_stack == stack.ssy_stack) && 382 const bool all_okay = (stack.ssy_stack.empty() || q.ssy_stack == stack.ssy_stack) &&
383 (stack.pbk_stack.size() == 0 || q.pbk_stack == stack.pbk_stack); 383 (stack.pbk_stack.empty() || q.pbk_stack == stack.pbk_stack);
384 state.queries.pop_front(); 384 state.queries.pop_front();
385 return all_okay; 385 return all_okay;
386 } 386 }
387 block.visited = true; 387 block.visited = true;
388 state.stacks[q.address] = BlockStack{q}; 388 state.stacks.insert_or_assign(q.address, BlockStack{q});
389
389 Query q2(q); 390 Query q2(q);
390 state.queries.pop_front(); 391 state.queries.pop_front();
391 gather_labels(q2.ssy_stack, state.ssy_labels, block); 392 gather_labels(q2.ssy_stack, state.ssy_labels, block);
@@ -394,6 +395,7 @@ bool TryQuery(CFGRebuildState& state) {
394 q2.address = block.end + 1; 395 q2.address = block.end + 1;
395 state.queries.push_back(q2); 396 state.queries.push_back(q2);
396 } 397 }
398
397 Query conditional_query{q2}; 399 Query conditional_query{q2};
398 if (block.branch.is_sync) { 400 if (block.branch.is_sync) {
399 if (block.branch.address == unassigned_branch) { 401 if (block.branch.address == unassigned_branch) {
@@ -408,13 +410,15 @@ bool TryQuery(CFGRebuildState& state) {
408 conditional_query.pbk_stack.pop(); 410 conditional_query.pbk_stack.pop();
409 } 411 }
410 conditional_query.address = block.branch.address; 412 conditional_query.address = block.branch.address;
411 state.queries.push_back(conditional_query); 413 state.queries.push_back(std::move(conditional_query));
412 return true; 414 return true;
413} 415}
416} // Anonymous namespace
414 417
415std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size, 418std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
416 u32 start_address) { 419 std::size_t program_size, u32 start_address) {
417 CFGRebuildState state{program_code, program_size, start_address}; 420 CFGRebuildState state{program_code, program_size, start_address};
421
418 // Inspect Code and generate blocks 422 // Inspect Code and generate blocks
419 state.labels.clear(); 423 state.labels.clear();
420 state.labels.emplace(start_address); 424 state.labels.emplace(start_address);
@@ -424,10 +428,9 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u
424 return {}; 428 return {};
425 } 429 }
426 } 430 }
431
427 // Decompile Stacks 432 // Decompile Stacks
428 Query start_query{}; 433 state.queries.push_back(Query{state.start, {}, {}});
429 start_query.address = state.start;
430 state.queries.push_back(start_query);
431 bool decompiled = true; 434 bool decompiled = true;
432 while (!state.queries.empty()) { 435 while (!state.queries.empty()) {
433 if (!TryQuery(state)) { 436 if (!TryQuery(state)) {
@@ -435,14 +438,15 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u
435 break; 438 break;
436 } 439 }
437 } 440 }
441
438 // Sort and organize results 442 // Sort and organize results
439 std::sort(state.block_info.begin(), state.block_info.end(), 443 std::sort(state.block_info.begin(), state.block_info.end(),
440 [](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; }); 444 [](const BlockInfo& a, const BlockInfo& b) { return a.start < b.start; });
441 ShaderCharacteristics result_out{}; 445 ShaderCharacteristics result_out{};
442 result_out.decompilable = decompiled; 446 result_out.decompilable = decompiled;
443 result_out.start = start_address; 447 result_out.start = start_address;
444 result_out.end = start_address; 448 result_out.end = start_address;
445 for (auto& block : state.block_info) { 449 for (const auto& block : state.block_info) {
446 ShaderBlock new_block{}; 450 ShaderBlock new_block{};
447 new_block.start = block.start; 451 new_block.start = block.start;
448 new_block.end = block.end; 452 new_block.end = block.end;
@@ -457,8 +461,9 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u
457 } 461 }
458 if (result_out.decompilable) { 462 if (result_out.decompilable) {
459 result_out.labels = std::move(state.labels); 463 result_out.labels = std::move(state.labels);
460 return {result_out}; 464 return {std::move(result_out)};
461 } 465 }
466
462 // If it's not decompilable, merge the unlabelled blocks together 467 // If it's not decompilable, merge the unlabelled blocks together
463 auto back = result_out.blocks.begin(); 468 auto back = result_out.blocks.begin();
464 auto next = std::next(back); 469 auto next = std::next(back);
@@ -469,8 +474,8 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u
469 continue; 474 continue;
470 } 475 }
471 back = next; 476 back = next;
472 next++; 477 ++next;
473 } 478 }
474 return {result_out}; 479 return {std::move(result_out)};
475} 480}
476} // namespace VideoCommon::Shader 481} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/control_flow.h b/src/video_core/shader/control_flow.h
index 5e8ea3271..b0a5e4f8c 100644
--- a/src/video_core/shader/control_flow.h
+++ b/src/video_core/shader/control_flow.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstring>
8#include <list> 7#include <list>
9#include <optional> 8#include <optional>
10#include <unordered_set> 9#include <unordered_set>
@@ -26,27 +25,44 @@ struct Condition {
26 bool IsUnconditional() const { 25 bool IsUnconditional() const {
27 return predicate == Pred::UnusedIndex && cc == ConditionCode::T; 26 return predicate == Pred::UnusedIndex && cc == ConditionCode::T;
28 } 27 }
28
29 bool operator==(const Condition& other) const { 29 bool operator==(const Condition& other) const {
30 return std::tie(predicate, cc) == std::tie(other.predicate, other.cc); 30 return std::tie(predicate, cc) == std::tie(other.predicate, other.cc);
31 } 31 }
32
33 bool operator!=(const Condition& other) const {
34 return !operator==(other);
35 }
32}; 36};
33 37
34struct ShaderBlock { 38struct ShaderBlock {
35 u32 start{};
36 u32 end{};
37 bool ignore_branch{};
38 struct Branch { 39 struct Branch {
39 Condition cond{}; 40 Condition cond{};
40 bool kills{}; 41 bool kills{};
41 s32 address{}; 42 s32 address{};
43
42 bool operator==(const Branch& b) const { 44 bool operator==(const Branch& b) const {
43 return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address); 45 return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address);
44 } 46 }
45 } branch{}; 47
48 bool operator!=(const Branch& b) const {
49 return !operator==(b);
50 }
51 };
52
53 u32 start{};
54 u32 end{};
55 bool ignore_branch{};
56 Branch branch{};
57
46 bool operator==(const ShaderBlock& sb) const { 58 bool operator==(const ShaderBlock& sb) const {
47 return std::tie(start, end, ignore_branch, branch) == 59 return std::tie(start, end, ignore_branch, branch) ==
48 std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch); 60 std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch);
49 } 61 }
62
63 bool operator!=(const ShaderBlock& sb) const {
64 return !operator==(sb);
65 }
50}; 66};
51 67
52struct ShaderCharacteristics { 68struct ShaderCharacteristics {
@@ -57,7 +73,7 @@ struct ShaderCharacteristics {
57 std::unordered_set<u32> labels{}; 73 std::unordered_set<u32> labels{};
58}; 74};
59 75
60std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size, 76std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
61 u32 start_address); 77 std::size_t program_size, u32 start_address);
62 78
63} // namespace VideoCommon::Shader 79} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index afffd157f..b547d8323 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -47,14 +47,14 @@ void ShaderIR::Decode() {
47 if (shader_info.decompilable) { 47 if (shader_info.decompilable) {
48 disable_flow_stack = true; 48 disable_flow_stack = true;
49 const auto insert_block = [this](NodeBlock& nodes, u32 label) { 49 const auto insert_block = [this](NodeBlock& nodes, u32 label) {
50 if (label == exit_branch) { 50 if (label == static_cast<u32>(exit_branch)) {
51 return; 51 return;
52 } 52 }
53 basic_blocks.insert({label, nodes}); 53 basic_blocks.insert({label, nodes});
54 }; 54 };
55 const auto& blocks = shader_info.blocks; 55 const auto& blocks = shader_info.blocks;
56 NodeBlock current_block; 56 NodeBlock current_block;
57 u32 current_label = exit_branch; 57 u32 current_label = static_cast<u32>(exit_branch);
58 for (auto& block : blocks) { 58 for (auto& block : blocks) {
59 if (shader_info.labels.count(block.start) != 0) { 59 if (shader_info.labels.count(block.start) != 0) {
60 insert_block(current_block, current_label); 60 insert_block(current_block, current_label);
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp
index 6af9044ca..683c49207 100644
--- a/src/video_core/texture_cache/surface_base.cpp
+++ b/src/video_core/texture_cache/surface_base.cpp
@@ -24,9 +24,8 @@ StagingCache::StagingCache() = default;
24StagingCache::~StagingCache() = default; 24StagingCache::~StagingCache() = default;
25 25
26SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) 26SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params)
27 : params{params}, mipmap_sizes(params.num_levels), 27 : params{params}, host_memory_size{params.GetHostSizeInBytes()}, gpu_addr{gpu_addr},
28 mipmap_offsets(params.num_levels), gpu_addr{gpu_addr}, host_memory_size{ 28 mipmap_sizes(params.num_levels), mipmap_offsets(params.num_levels) {
29 params.GetHostSizeInBytes()} {
30 std::size_t offset = 0; 29 std::size_t offset = 0;
31 for (u32 level = 0; level < params.num_levels; ++level) { 30 for (u32 level = 0; level < params.num_levels; ++level) {
32 const std::size_t mipmap_size{params.GetGuestMipmapSize(level)}; 31 const std::size_t mipmap_size{params.GetGuestMipmapSize(level)};