diff options
| author | 2019-07-25 13:04:56 -0400 | |
|---|---|---|
| committer | 2019-07-25 13:04:56 -0400 | |
| commit | b0ff3179ef8f4ebb6ccd2bdc9bccc64e3212edee (patch) | |
| tree | 66d350fdcc096ca621932f76349669cbe0e63a72 | |
| parent | Merge pull request #2737 from FernandoS27/track-fix (diff) | |
| parent | video_core/control_flow: Provide operator!= for types with operator== (diff) | |
| download | yuzu-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.cpp | 47 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.h | 30 | ||||
| -rw-r--r-- | src/video_core/shader/decode.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/texture_cache/surface_base.cpp | 5 |
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 | ||
| 17 | namespace VideoCommon::Shader { | 17 | namespace VideoCommon::Shader { |
| 18 | 18 | namespace { | |
| 19 | using Tegra::Shader::Instruction; | 19 | using Tegra::Shader::Instruction; |
| 20 | using Tegra::Shader::OpCode; | 20 | using Tegra::Shader::OpCode; |
| 21 | 21 | ||
| @@ -29,8 +29,7 @@ struct Query { | |||
| 29 | 29 | ||
| 30 | struct BlockStack { | 30 | struct 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 { | |||
| 58 | struct CFGRebuildState { | 57 | struct 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 | ||
| 91 | struct ParseInfo { | 90 | struct 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 | ||
| 415 | std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size, | 418 | std::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 | ||
| 34 | struct ShaderBlock { | 38 | struct 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 | ||
| 52 | struct ShaderCharacteristics { | 68 | struct ShaderCharacteristics { |
| @@ -57,7 +73,7 @@ struct ShaderCharacteristics { | |||
| 57 | std::unordered_set<u32> labels{}; | 73 | std::unordered_set<u32> labels{}; |
| 58 | }; | 74 | }; |
| 59 | 75 | ||
| 60 | std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size, | 76 | std::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; | |||
| 24 | StagingCache::~StagingCache() = default; | 24 | StagingCache::~StagingCache() = default; |
| 25 | 25 | ||
| 26 | SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) | 26 | SurfaceBaseImpl::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)}; |