| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // Copyright 2019 yuzu Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #pragma once
- #include <list>
- #include <optional>
- #include <set>
- #include <variant>
- #include "video_core/engines/shader_bytecode.h"
- #include "video_core/shader/ast.h"
- #include "video_core/shader/compiler_settings.h"
- #include "video_core/shader/registry.h"
- #include "video_core/shader/shader_ir.h"
- namespace VideoCommon::Shader {
- using Tegra::Shader::ConditionCode;
- using Tegra::Shader::Pred;
- constexpr s32 exit_branch = -1;
- struct Condition {
- Pred predicate{Pred::UnusedIndex};
- ConditionCode cc{ConditionCode::T};
- bool IsUnconditional() const {
- return predicate == Pred::UnusedIndex && cc == ConditionCode::T;
- }
- bool operator==(const Condition& other) const {
- return std::tie(predicate, cc) == std::tie(other.predicate, other.cc);
- }
- bool operator!=(const Condition& other) const {
- return !operator==(other);
- }
- };
- class SingleBranch {
- public:
- SingleBranch() = default;
- SingleBranch(Condition condition, s32 address, bool kill, bool is_sync, bool is_brk,
- bool ignore)
- : condition{condition}, address{address}, kill{kill}, is_sync{is_sync}, is_brk{is_brk},
- ignore{ignore} {}
- bool operator==(const SingleBranch& b) const {
- return std::tie(condition, address, kill, is_sync, is_brk, ignore) ==
- std::tie(b.condition, b.address, b.kill, b.is_sync, b.is_brk, b.ignore);
- }
- bool operator!=(const SingleBranch& b) const {
- return !operator==(b);
- }
- Condition condition{};
- s32 address{exit_branch};
- bool kill{};
- bool is_sync{};
- bool is_brk{};
- bool ignore{};
- };
- struct CaseBranch {
- CaseBranch(u32 cmp_value, u32 address) : cmp_value{cmp_value}, address{address} {}
- u32 cmp_value;
- u32 address;
- };
- class MultiBranch {
- public:
- MultiBranch(u32 gpr, std::vector<CaseBranch>&& branches)
- : gpr{gpr}, branches{std::move(branches)} {}
- u32 gpr{};
- std::vector<CaseBranch> branches{};
- };
- using BranchData = std::variant<SingleBranch, MultiBranch>;
- using BlockBranchInfo = std::shared_ptr<BranchData>;
- bool BlockBranchInfoAreEqual(BlockBranchInfo first, BlockBranchInfo second);
- struct ShaderBlock {
- u32 start{};
- u32 end{};
- bool ignore_branch{};
- BlockBranchInfo branch{};
- bool operator==(const ShaderBlock& sb) const {
- return std::tie(start, end, ignore_branch) ==
- std::tie(sb.start, sb.end, sb.ignore_branch) &&
- BlockBranchInfoAreEqual(branch, sb.branch);
- }
- bool operator!=(const ShaderBlock& sb) const {
- return !operator==(sb);
- }
- };
- struct ShaderCharacteristics {
- std::list<ShaderBlock> blocks{};
- std::set<u32> labels{};
- u32 start{};
- u32 end{};
- ASTManager manager{true, true};
- CompilerSettings settings{};
- };
- std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 start_address,
- const CompilerSettings& settings,
- Registry& registry);
- } // namespace VideoCommon::Shader
|