diff options
Diffstat (limited to '')
| -rw-r--r-- | src/common/hash.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/const_buffer_engine_interface.h | 9 | ||||
| -rw-r--r-- | src/video_core/shader/const_buffer_locker.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/const_buffer_locker.h | 7 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.h | 6 | ||||
| -rw-r--r-- | src/video_core/shader/decode.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 38 | ||||
| -rw-r--r-- | src/video_core/shader/expr.h | 4 |
9 files changed, 66 insertions, 56 deletions
diff --git a/src/common/hash.h b/src/common/hash.h index c939709bc..ebd4125e2 100644 --- a/src/common/hash.h +++ b/src/common/hash.h | |||
| @@ -72,7 +72,7 @@ struct HashableStruct { | |||
| 72 | 72 | ||
| 73 | struct PairHash { | 73 | struct PairHash { |
| 74 | template <class T1, class T2> | 74 | template <class T1, class T2> |
| 75 | std::size_t operator()(const std::pair<T1, T2>& pair) const { | 75 | std::size_t operator()(const std::pair<T1, T2>& pair) const noexcept { |
| 76 | std::size_t seed = std::hash<T1>()(pair.first); | 76 | std::size_t seed = std::hash<T1>()(pair.first); |
| 77 | boost::hash_combine(seed, std::hash<T2>()(pair.second)); | 77 | boost::hash_combine(seed, std::hash<T2>()(pair.second)); |
| 78 | return seed; | 78 | return seed; |
diff --git a/src/video_core/engines/const_buffer_engine_interface.h b/src/video_core/engines/const_buffer_engine_interface.h index 80f470777..ac27b6cbe 100644 --- a/src/video_core/engines/const_buffer_engine_interface.h +++ b/src/video_core/engines/const_buffer_engine_interface.h | |||
| @@ -34,6 +34,10 @@ struct SamplerDescriptor { | |||
| 34 | return raw == rhs.raw; | 34 | return raw == rhs.raw; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | bool operator!=(const SamplerDescriptor& rhs) const noexcept { | ||
| 38 | return !operator==(rhs); | ||
| 39 | } | ||
| 40 | |||
| 37 | static SamplerDescriptor FromTicTexture(Tegra::Texture::TextureType tic_texture_type) { | 41 | static SamplerDescriptor FromTicTexture(Tegra::Texture::TextureType tic_texture_type) { |
| 38 | SamplerDescriptor result; | 42 | SamplerDescriptor result; |
| 39 | switch (tic_texture_type) { | 43 | switch (tic_texture_type) { |
| @@ -73,13 +77,12 @@ struct SamplerDescriptor { | |||
| 73 | result.is_buffer.Assign(0); | 77 | result.is_buffer.Assign(0); |
| 74 | result.is_shadow.Assign(0); | 78 | result.is_shadow.Assign(0); |
| 75 | return result; | 79 | return result; |
| 76 | case Tegra::Texture::TextureType::Texture1DBuffer: { | 80 | case Tegra::Texture::TextureType::Texture1DBuffer: |
| 77 | result.texture_type.Assign(Tegra::Shader::TextureType::Texture1D); | 81 | result.texture_type.Assign(Tegra::Shader::TextureType::Texture1D); |
| 78 | result.is_array.Assign(0); | 82 | result.is_array.Assign(0); |
| 79 | result.is_buffer.Assign(1); | 83 | result.is_buffer.Assign(1); |
| 80 | result.is_shadow.Assign(0); | 84 | result.is_shadow.Assign(0); |
| 81 | return result; | 85 | return result; |
| 82 | } | ||
| 83 | case Tegra::Texture::TextureType::Texture2DNoMipmap: | 86 | case Tegra::Texture::TextureType::Texture2DNoMipmap: |
| 84 | result.texture_type.Assign(Tegra::Shader::TextureType::Texture2D); | 87 | result.texture_type.Assign(Tegra::Shader::TextureType::Texture2D); |
| 85 | result.is_array.Assign(0); | 88 | result.is_array.Assign(0); |
| @@ -105,7 +108,7 @@ static_assert(std::is_trivially_copyable_v<SamplerDescriptor>); | |||
| 105 | 108 | ||
| 106 | class ConstBufferEngineInterface { | 109 | class ConstBufferEngineInterface { |
| 107 | public: | 110 | public: |
| 108 | virtual ~ConstBufferEngineInterface() {} | 111 | virtual ~ConstBufferEngineInterface() = default; |
| 109 | virtual u32 AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const = 0; | 112 | virtual u32 AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const = 0; |
| 110 | virtual SamplerDescriptor AccessBoundSampler(ShaderType stage, u64 offset) const = 0; | 113 | virtual SamplerDescriptor AccessBoundSampler(ShaderType stage, u64 offset) const = 0; |
| 111 | virtual SamplerDescriptor AccessBindlessSampler(ShaderType stage, u64 const_buffer, | 114 | virtual SamplerDescriptor AccessBindlessSampler(ShaderType stage, u64 const_buffer, |
diff --git a/src/video_core/shader/const_buffer_locker.cpp b/src/video_core/shader/const_buffer_locker.cpp index 592bbf657..fe467608e 100644 --- a/src/video_core/shader/const_buffer_locker.cpp +++ b/src/video_core/shader/const_buffer_locker.cpp | |||
| @@ -22,6 +22,8 @@ ConstBufferLocker::ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, | |||
| 22 | Tegra::Engines::ConstBufferEngineInterface& engine) | 22 | Tegra::Engines::ConstBufferEngineInterface& engine) |
| 23 | : stage{shader_stage}, engine{&engine} {} | 23 | : stage{shader_stage}, engine{&engine} {} |
| 24 | 24 | ||
| 25 | ConstBufferLocker::~ConstBufferLocker() = default; | ||
| 26 | |||
| 25 | std::optional<u32> ConstBufferLocker::ObtainKey(u32 buffer, u32 offset) { | 27 | std::optional<u32> ConstBufferLocker::ObtainKey(u32 buffer, u32 offset) { |
| 26 | const std::pair<u32, u32> key = {buffer, offset}; | 28 | const std::pair<u32, u32> key = {buffer, offset}; |
| 27 | const auto iter = keys.find(key); | 29 | const auto iter = keys.find(key); |
| @@ -29,7 +31,7 @@ std::optional<u32> ConstBufferLocker::ObtainKey(u32 buffer, u32 offset) { | |||
| 29 | return iter->second; | 31 | return iter->second; |
| 30 | } | 32 | } |
| 31 | if (!engine) { | 33 | if (!engine) { |
| 32 | return {}; | 34 | return std::nullopt; |
| 33 | } | 35 | } |
| 34 | const u32 value = engine->AccessConstBuffer32(stage, buffer, offset); | 36 | const u32 value = engine->AccessConstBuffer32(stage, buffer, offset); |
| 35 | keys.emplace(key, value); | 37 | keys.emplace(key, value); |
| @@ -43,7 +45,7 @@ std::optional<SamplerDescriptor> ConstBufferLocker::ObtainBoundSampler(u32 offse | |||
| 43 | return iter->second; | 45 | return iter->second; |
| 44 | } | 46 | } |
| 45 | if (!engine) { | 47 | if (!engine) { |
| 46 | return {}; | 48 | return std::nullopt; |
| 47 | } | 49 | } |
| 48 | const SamplerDescriptor value = engine->AccessBoundSampler(stage, offset); | 50 | const SamplerDescriptor value = engine->AccessBoundSampler(stage, offset); |
| 49 | bound_samplers.emplace(key, value); | 51 | bound_samplers.emplace(key, value); |
| @@ -58,7 +60,7 @@ std::optional<Tegra::Engines::SamplerDescriptor> ConstBufferLocker::ObtainBindle | |||
| 58 | return iter->second; | 60 | return iter->second; |
| 59 | } | 61 | } |
| 60 | if (!engine) { | 62 | if (!engine) { |
| 61 | return {}; | 63 | return std::nullopt; |
| 62 | } | 64 | } |
| 63 | const SamplerDescriptor value = engine->AccessBindlessSampler(stage, buffer, offset); | 65 | const SamplerDescriptor value = engine->AccessBindlessSampler(stage, buffer, offset); |
| 64 | bindless_samplers.emplace(key, value); | 66 | bindless_samplers.emplace(key, value); |
diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 966537fd6..600e2f3c3 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h | |||
| @@ -16,6 +16,11 @@ using BoundSamplerMap = std::unordered_map<u32, Tegra::Engines::SamplerDescripto | |||
| 16 | using BindlessSamplerMap = | 16 | using BindlessSamplerMap = |
| 17 | std::unordered_map<std::pair<u32, u32>, Tegra::Engines::SamplerDescriptor, Common::PairHash>; | 17 | std::unordered_map<std::pair<u32, u32>, Tegra::Engines::SamplerDescriptor, Common::PairHash>; |
| 18 | 18 | ||
| 19 | /** | ||
| 20 | * The ConstBufferLocker is a class use to interface the 3D and compute engines with the shader | ||
| 21 | * compiler. with it, the shader can obtain required data from GPU state and store it for disk | ||
| 22 | * shader compilation. | ||
| 23 | **/ | ||
| 19 | class ConstBufferLocker { | 24 | class ConstBufferLocker { |
| 20 | public: | 25 | public: |
| 21 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); | 26 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); |
| @@ -23,6 +28,8 @@ public: | |||
| 23 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, | 28 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, |
| 24 | Tegra::Engines::ConstBufferEngineInterface& engine); | 29 | Tegra::Engines::ConstBufferEngineInterface& engine); |
| 25 | 30 | ||
| 31 | ~ConstBufferLocker(); | ||
| 32 | |||
| 26 | /// Retrieves a key from the locker, if it's registered, it will give the registered value, if | 33 | /// Retrieves a key from the locker, if it's registered, it will give the registered value, if |
| 27 | /// not it will obtain it from maxwell3d and register it. | 34 | /// not it will obtain it from maxwell3d and register it. |
| 28 | std::optional<u32> ObtainKey(u32 buffer, u32 offset); | 35 | std::optional<u32> ObtainKey(u32 buffer, u32 offset); |
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index 6c698bcff..d47c63d9f 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp | |||
| @@ -41,14 +41,10 @@ BlockBranchInfo MakeBranchInfo(Args&&... args) { | |||
| 41 | return std::make_shared<BranchData>(T(std::forward<Args>(args)...)); | 41 | return std::make_shared<BranchData>(T(std::forward<Args>(args)...)); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | bool BlockBranchInfoAreEqual(BlockBranchInfo first, BlockBranchInfo second) { | ||
| 45 | return false; //(*first) == (*second); | ||
| 46 | } | ||
| 47 | |||
| 48 | bool BlockBranchIsIgnored(BlockBranchInfo first) { | 44 | bool BlockBranchIsIgnored(BlockBranchInfo first) { |
| 49 | bool ignore = false; | 45 | bool ignore = false; |
| 50 | if (std::holds_alternative<SingleBranch>(*first)) { | 46 | if (std::holds_alternative<SingleBranch>(*first)) { |
| 51 | auto branch = std::get_if<SingleBranch>(first.get()); | 47 | const auto branch = std::get_if<SingleBranch>(first.get()); |
| 52 | ignore = branch->ignore; | 48 | ignore = branch->ignore; |
| 53 | } | 49 | } |
| 54 | return ignore; | 50 | return ignore; |
| @@ -151,10 +147,10 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 151 | const Instruction instr = {state.program_code[pos]}; | 147 | const Instruction instr = {state.program_code[pos]}; |
| 152 | const auto opcode = OpCode::Decode(instr); | 148 | const auto opcode = OpCode::Decode(instr); |
| 153 | if (opcode->get().GetId() != OpCode::Id::BRX) { | 149 | if (opcode->get().GetId() != OpCode::Id::BRX) { |
| 154 | return {}; | 150 | return std::nullopt; |
| 155 | } | 151 | } |
| 156 | if (instr.brx.constant_buffer != 0) { | 152 | if (instr.brx.constant_buffer != 0) { |
| 157 | return {}; | 153 | return std::nullopt; |
| 158 | } | 154 | } |
| 159 | track_register = instr.gpr8.Value(); | 155 | track_register = instr.gpr8.Value(); |
| 160 | result.relative_position = instr.brx.GetBranchExtend(); | 156 | result.relative_position = instr.brx.GetBranchExtend(); |
| @@ -172,8 +168,8 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 172 | if (opcode->get().GetId() == OpCode::Id::LD_C) { | 168 | if (opcode->get().GetId() == OpCode::Id::LD_C) { |
| 173 | if (instr.gpr0.Value() == track_register && | 169 | if (instr.gpr0.Value() == track_register && |
| 174 | instr.ld_c.type.Value() == Tegra::Shader::UniformType::Single) { | 170 | instr.ld_c.type.Value() == Tegra::Shader::UniformType::Single) { |
| 175 | result.buffer = instr.cbuf36.index; | 171 | result.buffer = instr.cbuf36.index.Value(); |
| 176 | result.offset = instr.cbuf36.GetOffset(); | 172 | result.offset = static_cast<u32>(instr.cbuf36.GetOffset()); |
| 177 | track_register = instr.gpr8.Value(); | 173 | track_register = instr.gpr8.Value(); |
| 178 | pos--; | 174 | pos--; |
| 179 | found_track = true; | 175 | found_track = true; |
| @@ -184,7 +180,7 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 184 | } | 180 | } |
| 185 | 181 | ||
| 186 | if (!found_track) { | 182 | if (!found_track) { |
| 187 | return {}; | 183 | return std::nullopt; |
| 188 | } | 184 | } |
| 189 | found_track = false; | 185 | found_track = false; |
| 190 | 186 | ||
| @@ -194,7 +190,7 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 194 | pos--; | 190 | pos--; |
| 195 | continue; | 191 | continue; |
| 196 | } | 192 | } |
| 197 | const Instruction instr = {state.program_code[pos]}; | 193 | const Instruction instr = state.program_code[pos]; |
| 198 | const auto opcode = OpCode::Decode(instr); | 194 | const auto opcode = OpCode::Decode(instr); |
| 199 | if (opcode->get().GetId() == OpCode::Id::SHL_IMM) { | 195 | if (opcode->get().GetId() == OpCode::Id::SHL_IMM) { |
| 200 | if (instr.gpr0.Value() == track_register) { | 196 | if (instr.gpr0.Value() == track_register) { |
| @@ -208,7 +204,7 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 208 | } | 204 | } |
| 209 | 205 | ||
| 210 | if (!found_track) { | 206 | if (!found_track) { |
| 211 | return {}; | 207 | return std::nullopt; |
| 212 | } | 208 | } |
| 213 | found_track = false; | 209 | found_track = false; |
| 214 | 210 | ||
| @@ -218,7 +214,7 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 218 | pos--; | 214 | pos--; |
| 219 | continue; | 215 | continue; |
| 220 | } | 216 | } |
| 221 | const Instruction instr = {state.program_code[pos]}; | 217 | const Instruction instr = state.program_code[pos]; |
| 222 | const auto opcode = OpCode::Decode(instr); | 218 | const auto opcode = OpCode::Decode(instr); |
| 223 | if (opcode->get().GetId() == OpCode::Id::IMNMX_IMM) { | 219 | if (opcode->get().GetId() == OpCode::Id::IMNMX_IMM) { |
| 224 | if (instr.gpr0.Value() == track_register) { | 220 | if (instr.gpr0.Value() == track_register) { |
| @@ -233,9 +229,9 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 233 | } | 229 | } |
| 234 | 230 | ||
| 235 | if (!found_track) { | 231 | if (!found_track) { |
| 236 | return {}; | 232 | return std::nullopt; |
| 237 | } | 233 | } |
| 238 | return {result}; | 234 | return result; |
| 239 | } | 235 | } |
| 240 | 236 | ||
| 241 | std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) { | 237 | std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) { |
| @@ -440,8 +436,8 @@ std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) | |||
| 440 | branches.emplace_back(value, target); | 436 | branches.emplace_back(value, target); |
| 441 | } | 437 | } |
| 442 | parse_info.end_address = offset; | 438 | parse_info.end_address = offset; |
| 443 | parse_info.branch_info = | 439 | parse_info.branch_info = MakeBranchInfo<MultiBranch>( |
| 444 | MakeBranchInfo<MultiBranch>(static_cast<u32>(instr.gpr8.Value()), branches); | 440 | static_cast<u32>(instr.gpr8.Value()), std::move(branches)); |
| 445 | 441 | ||
| 446 | return {ParseResult::ControlCaught, parse_info}; | 442 | return {ParseResult::ControlCaught, parse_info}; |
| 447 | } else { | 443 | } else { |
| @@ -486,7 +482,7 @@ bool TryInspectAddress(CFGRebuildState& state) { | |||
| 486 | current_block.end = address - 1; | 482 | current_block.end = address - 1; |
| 487 | new_block.branch = current_block.branch; | 483 | new_block.branch = current_block.branch; |
| 488 | BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>(); | 484 | BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>(); |
| 489 | auto branch = std::get_if<SingleBranch>(forward_branch.get()); | 485 | const auto branch = std::get_if<SingleBranch>(forward_branch.get()); |
| 490 | branch->address = address; | 486 | branch->address = address; |
| 491 | branch->ignore = true; | 487 | branch->ignore = true; |
| 492 | current_block.branch = forward_branch; | 488 | current_block.branch = forward_branch; |
| @@ -504,7 +500,7 @@ bool TryInspectAddress(CFGRebuildState& state) { | |||
| 504 | BlockInfo& block_info = CreateBlockInfo(state, address, parse_info.end_address); | 500 | BlockInfo& block_info = CreateBlockInfo(state, address, parse_info.end_address); |
| 505 | block_info.branch = parse_info.branch_info; | 501 | block_info.branch = parse_info.branch_info; |
| 506 | if (std::holds_alternative<SingleBranch>(*block_info.branch)) { | 502 | if (std::holds_alternative<SingleBranch>(*block_info.branch)) { |
| 507 | auto branch = std::get_if<SingleBranch>(block_info.branch.get()); | 503 | const auto branch = std::get_if<SingleBranch>(block_info.branch.get()); |
| 508 | if (branch->condition.IsUnconditional()) { | 504 | if (branch->condition.IsUnconditional()) { |
| 509 | return true; | 505 | return true; |
| 510 | } | 506 | } |
| @@ -550,7 +546,7 @@ bool TryQuery(CFGRebuildState& state) { | |||
| 550 | gather_labels(q2.ssy_stack, state.ssy_labels, block); | 546 | gather_labels(q2.ssy_stack, state.ssy_labels, block); |
| 551 | gather_labels(q2.pbk_stack, state.pbk_labels, block); | 547 | gather_labels(q2.pbk_stack, state.pbk_labels, block); |
| 552 | if (std::holds_alternative<SingleBranch>(*block.branch)) { | 548 | if (std::holds_alternative<SingleBranch>(*block.branch)) { |
| 553 | auto branch = std::get_if<SingleBranch>(block.branch.get()); | 549 | const auto branch = std::get_if<SingleBranch>(block.branch.get()); |
| 554 | if (!branch->condition.IsUnconditional()) { | 550 | if (!branch->condition.IsUnconditional()) { |
| 555 | q2.address = block.end + 1; | 551 | q2.address = block.end + 1; |
| 556 | state.queries.push_back(q2); | 552 | state.queries.push_back(q2); |
| @@ -573,8 +569,8 @@ bool TryQuery(CFGRebuildState& state) { | |||
| 573 | state.queries.push_back(std::move(conditional_query)); | 569 | state.queries.push_back(std::move(conditional_query)); |
| 574 | return true; | 570 | return true; |
| 575 | } | 571 | } |
| 576 | auto multi_branch = std::get_if<MultiBranch>(block.branch.get()); | 572 | const auto multi_branch = std::get_if<MultiBranch>(block.branch.get()); |
| 577 | for (auto& branch_case : multi_branch->branches) { | 573 | for (const auto& branch_case : multi_branch->branches) { |
| 578 | Query conditional_query{q2}; | 574 | Query conditional_query{q2}; |
| 579 | conditional_query.address = branch_case.address; | 575 | conditional_query.address = branch_case.address; |
| 580 | state.queries.push_back(std::move(conditional_query)); | 576 | state.queries.push_back(std::move(conditional_query)); |
| @@ -612,7 +608,7 @@ void InsertBranch(ASTManager& mm, const BlockBranchInfo& branch_info) { | |||
| 612 | return MakeExpr<ExprBoolean>(true); | 608 | return MakeExpr<ExprBoolean>(true); |
| 613 | }); | 609 | }); |
| 614 | if (std::holds_alternative<SingleBranch>(*branch_info)) { | 610 | if (std::holds_alternative<SingleBranch>(*branch_info)) { |
| 615 | auto branch = std::get_if<SingleBranch>(branch_info.get()); | 611 | const auto branch = std::get_if<SingleBranch>(branch_info.get()); |
| 616 | if (branch->address < 0) { | 612 | if (branch->address < 0) { |
| 617 | if (branch->kill) { | 613 | if (branch->kill) { |
| 618 | mm.InsertReturn(get_expr(branch->condition), true); | 614 | mm.InsertReturn(get_expr(branch->condition), true); |
| @@ -624,8 +620,8 @@ void InsertBranch(ASTManager& mm, const BlockBranchInfo& branch_info) { | |||
| 624 | mm.InsertGoto(get_expr(branch->condition), branch->address); | 620 | mm.InsertGoto(get_expr(branch->condition), branch->address); |
| 625 | return; | 621 | return; |
| 626 | } | 622 | } |
| 627 | auto multi_branch = std::get_if<MultiBranch>(branch_info.get()); | 623 | const auto multi_branch = std::get_if<MultiBranch>(branch_info.get()); |
| 628 | for (auto& branch_case : multi_branch->branches) { | 624 | for (const auto& branch_case : multi_branch->branches) { |
| 629 | mm.InsertGoto(MakeExpr<ExprGprEqual>(multi_branch->gpr, branch_case.cmp_value), | 625 | mm.InsertGoto(MakeExpr<ExprGprEqual>(multi_branch->gpr, branch_case.cmp_value), |
| 630 | branch_case.address); | 626 | branch_case.address); |
| 631 | } | 627 | } |
diff --git a/src/video_core/shader/control_flow.h b/src/video_core/shader/control_flow.h index 288ee68af..5304998b9 100644 --- a/src/video_core/shader/control_flow.h +++ b/src/video_core/shader/control_flow.h | |||
| @@ -51,6 +51,10 @@ public: | |||
| 51 | std::tie(b.condition, b.address, b.kill, b.is_sync, b.is_brk, b.ignore); | 51 | std::tie(b.condition, b.address, b.kill, b.is_sync, b.is_brk, b.ignore); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | bool operator!=(const SingleBranch& b) const { | ||
| 55 | return !operator==(b); | ||
| 56 | } | ||
| 57 | |||
| 54 | Condition condition{}; | 58 | Condition condition{}; |
| 55 | s32 address{exit_branch}; | 59 | s32 address{exit_branch}; |
| 56 | bool kill{}; | 60 | bool kill{}; |
| @@ -67,7 +71,7 @@ struct CaseBranch { | |||
| 67 | 71 | ||
| 68 | class MultiBranch { | 72 | class MultiBranch { |
| 69 | public: | 73 | public: |
| 70 | MultiBranch(u32 gpr, std::vector<CaseBranch>& branches) | 74 | MultiBranch(u32 gpr, std::vector<CaseBranch>&& branches) |
| 71 | : gpr{gpr}, branches{std::move(branches)} {} | 75 | : gpr{gpr}, branches{std::move(branches)} {} |
| 72 | 76 | ||
| 73 | u32 gpr{}; | 77 | u32 gpr{}; |
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index e1afa4582..21fb9cb83 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp | |||
| @@ -155,7 +155,7 @@ void ShaderIR::Decode() { | |||
| 155 | [[fallthrough]]; | 155 | [[fallthrough]]; |
| 156 | case CompileDepth::BruteForce: { | 156 | case CompileDepth::BruteForce: { |
| 157 | coverage_begin = main_offset; | 157 | coverage_begin = main_offset; |
| 158 | const u32 shader_end = program_code.size(); | 158 | const std::size_t shader_end = program_code.size(); |
| 159 | coverage_end = shader_end; | 159 | coverage_end = shader_end; |
| 160 | for (u32 label = main_offset; label < shader_end; label++) { | 160 | for (u32 label = main_offset; label < shader_end; label++) { |
| 161 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); | 161 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index c369e23ad..f33e9c67c 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -284,7 +284,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 284 | 284 | ||
| 285 | const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | 285 | const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, |
| 286 | std::optional<SamplerInfo> sampler_info) { | 286 | std::optional<SamplerInfo> sampler_info) { |
| 287 | const auto offset = static_cast<std::size_t>(sampler.index.Value()); | 287 | const auto offset = static_cast<u32>(sampler.index.Value()); |
| 288 | 288 | ||
| 289 | Tegra::Shader::TextureType type; | 289 | Tegra::Shader::TextureType type; |
| 290 | bool is_array; | 290 | bool is_array; |
| @@ -293,17 +293,14 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | |||
| 293 | type = sampler_info->type; | 293 | type = sampler_info->type; |
| 294 | is_array = sampler_info->is_array; | 294 | is_array = sampler_info->is_array; |
| 295 | is_shadow = sampler_info->is_shadow; | 295 | is_shadow = sampler_info->is_shadow; |
| 296 | } else if (auto sampler = locker.ObtainBoundSampler(offset); sampler) { | ||
| 297 | type = sampler->texture_type.Value(); | ||
| 298 | is_array = sampler->is_array.Value() != 0; | ||
| 299 | is_shadow = sampler->is_shadow.Value() != 0; | ||
| 296 | } else { | 300 | } else { |
| 297 | auto sampler = locker.ObtainBoundSampler(offset); | 301 | type = Tegra::Shader::TextureType::Texture2D; |
| 298 | if (sampler) { | 302 | is_array = false; |
| 299 | type = sampler->texture_type.Value(); | 303 | is_shadow = false; |
| 300 | is_array = sampler->is_array.Value() != 0; | ||
| 301 | is_shadow = sampler->is_shadow.Value() != 0; | ||
| 302 | } else { | ||
| 303 | type = Tegra::Shader::TextureType::Texture2D; | ||
| 304 | is_array = false; | ||
| 305 | is_shadow = false; | ||
| 306 | } | ||
| 307 | } | 304 | } |
| 308 | 305 | ||
| 309 | // If this sampler has already been used, return the existing mapping. | 306 | // If this sampler has already been used, return the existing mapping. |
| @@ -320,7 +317,7 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | |||
| 320 | const std::size_t next_index = used_samplers.size(); | 317 | const std::size_t next_index = used_samplers.size(); |
| 321 | const Sampler entry{offset, next_index, type, is_array, is_shadow}; | 318 | const Sampler entry{offset, next_index, type, is_array, is_shadow}; |
| 322 | return *used_samplers.emplace(entry).first; | 319 | return *used_samplers.emplace(entry).first; |
| 323 | } | 320 | } // namespace VideoCommon::Shader |
| 324 | 321 | ||
| 325 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, | 322 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, |
| 326 | std::optional<SamplerInfo> sampler_info) { | 323 | std::optional<SamplerInfo> sampler_info) { |
| @@ -336,17 +333,14 @@ const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, | |||
| 336 | type = sampler_info->type; | 333 | type = sampler_info->type; |
| 337 | is_array = sampler_info->is_array; | 334 | is_array = sampler_info->is_array; |
| 338 | is_shadow = sampler_info->is_shadow; | 335 | is_shadow = sampler_info->is_shadow; |
| 336 | } else if (auto sampler = locker.ObtainBindlessSampler(cbuf_index, cbuf_offset); sampler) { | ||
| 337 | type = sampler->texture_type.Value(); | ||
| 338 | is_array = sampler->is_array.Value() != 0; | ||
| 339 | is_shadow = sampler->is_shadow.Value() != 0; | ||
| 339 | } else { | 340 | } else { |
| 340 | auto sampler = locker.ObtainBindlessSampler(cbuf_index, cbuf_offset); | 341 | type = Tegra::Shader::TextureType::Texture2D; |
| 341 | if (sampler) { | 342 | is_array = false; |
| 342 | type = sampler->texture_type.Value(); | 343 | is_shadow = false; |
| 343 | is_array = sampler->is_array.Value() != 0; | ||
| 344 | is_shadow = sampler->is_shadow.Value() != 0; | ||
| 345 | } else { | ||
| 346 | type = Tegra::Shader::TextureType::Texture2D; | ||
| 347 | is_array = false; | ||
| 348 | is_shadow = false; | ||
| 349 | } | ||
| 350 | } | 344 | } |
| 351 | 345 | ||
| 352 | // If this sampler has already been used, return the existing mapping. | 346 | // If this sampler has already been used, return the existing mapping. |
diff --git a/src/video_core/shader/expr.h b/src/video_core/shader/expr.h index e41d23e93..4e8264367 100644 --- a/src/video_core/shader/expr.h +++ b/src/video_core/shader/expr.h | |||
| @@ -127,6 +127,10 @@ public: | |||
| 127 | return gpr == b.gpr && value == b.value; | 127 | return gpr == b.gpr && value == b.value; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | bool operator!=(const ExprGprEqual& b) const { | ||
| 131 | return !operator==(b); | ||
| 132 | } | ||
| 133 | |||
| 130 | u32 gpr; | 134 | u32 gpr; |
| 131 | u32 value; | 135 | u32 value; |
| 132 | }; | 136 | }; |