diff options
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 9 | ||||
| -rw-r--r-- | src/core/core.h | 4 | ||||
| -rw-r--r-- | src/video_core/shader/decode/image.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 2 | ||||
| -rw-r--r-- | src/video_core/shader/track.cpp | 25 | 
8 files changed, 42 insertions, 42 deletions
| diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index b0ee7821a..97d5c2a8a 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -50,11 +50,14 @@ static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_  static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value,                                 void* user_data) { +    auto* const system = static_cast<System*>(user_data); +      ARM_Interface::ThreadContext ctx{}; -    Core::CurrentArmInterface().SaveContext(ctx); +    system->CurrentArmInterface().SaveContext(ctx);      ASSERT_MSG(false, "Attempted to read from unmapped memory: 0x{:X}, pc=0x{:X}, lr=0x{:X}", addr,                 ctx.pc, ctx.cpu_registers[30]); -    return {}; + +    return false;  }  ARM_Unicorn::ARM_Unicorn(System& system) : system{system} { @@ -65,7 +68,7 @@ ARM_Unicorn::ARM_Unicorn(System& system) : system{system} {      uc_hook hook{};      CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1)); -    CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, this, 0, -1)); +    CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0, -1));      if (GDBStub::IsServerEnabled()) {          CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, -1));          last_bkpt_hit = false; diff --git a/src/core/core.h b/src/core/core.h index 11e73278e..8ebb385ac 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -327,10 +327,6 @@ private:      static System s_instance;  }; -inline ARM_Interface& CurrentArmInterface() { -    return System::GetInstance().CurrentArmInterface(); -} -  inline Kernel::Process* CurrentProcess() {      return System::GetInstance().CurrentProcess();  } diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 24f022cc0..77151a24b 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -95,12 +95,8 @@ const Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::Image  const Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg,                                          Tegra::Shader::ImageType type) {      const Node image_register{GetRegister(reg)}; -    const Node base_image{ +    const auto [base_image, cbuf_index, cbuf_offset]{          TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))}; -    const auto cbuf{std::get_if<CbufNode>(&*base_image)}; -    const auto cbuf_offset_imm{std::get_if<ImmediateNode>(&*cbuf->GetOffset())}; -    const auto cbuf_offset{cbuf_offset_imm->GetValue()}; -    const auto cbuf_index{cbuf->GetIndex()};      const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)};      // If this image has already been used, return the existing mapping. diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 80fc0ccfc..ab207a33b 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -297,18 +297,13 @@ std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeB      const auto addr_register{GetRegister(instr.gmem.gpr)};      const auto immediate_offset{static_cast<u32>(instr.gmem.offset)}; -    const Node base_address{ -        TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()))}; -    const auto cbuf = std::get_if<CbufNode>(&*base_address); -    ASSERT(cbuf != nullptr); -    const auto cbuf_offset_imm = std::get_if<ImmediateNode>(&*cbuf->GetOffset()); -    ASSERT(cbuf_offset_imm != nullptr); -    const auto cbuf_offset = cbuf_offset_imm->GetValue(); - -    bb.push_back( -        Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset))); - -    const GlobalMemoryBase descriptor{cbuf->GetIndex(), cbuf_offset}; +    const auto [base_address, index, offset] = +        TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size())); +    ASSERT(base_address != nullptr); + +    bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); + +    const GlobalMemoryBase descriptor{index, offset};      const auto& [entry, is_new] = used_global_memory.try_emplace(descriptor);      auto& usage = entry->second;      if (is_write) { diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 323be3f14..e1ee5c190 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -308,13 +308,9 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, Textu  const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, TextureType type,                                              bool is_array, bool is_shadow) {      const Node sampler_register = GetRegister(reg); -    const Node base_sampler = +    const auto [base_sampler, cbuf_index, cbuf_offset] =          TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); -    const auto cbuf = std::get_if<CbufNode>(&*base_sampler); -    const auto cbuf_offset_imm = std::get_if<ImmediateNode>(&*cbuf->GetOffset()); -    ASSERT(cbuf_offset_imm != nullptr); -    const auto cbuf_offset = cbuf_offset_imm->GetValue(); -    const auto cbuf_index = cbuf->GetIndex(); +    ASSERT(base_sampler != nullptr);      const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset);      // If this sampler has already been used, return the existing mapping. diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index caa409788..78bd1cf1e 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -61,7 +61,16 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {      const auto [entry, is_new] = used_cbufs.try_emplace(index);      entry->second.MarkAsUsedIndirect(); -    const Node final_offset = Operation(OperationCode::UAdd, NO_PRECISE, node, Immediate(offset)); +    const Node final_offset = [&]() { +        // Attempt to inline constant buffer without a variable offset. This is done to allow +        // tracking LDC calls. +        if (const auto gpr = std::get_if<GprNode>(&*node)) { +            if (gpr->GetIndex() == Register::ZeroIndex) { +                return Immediate(offset); +            } +        } +        return Operation(OperationCode::UAdd, NO_PRECISE, node, Immediate(offset)); +    }();      return MakeNode<CbufNode>(index, final_offset);  } diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 03c888def..126c78136 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -328,7 +328,7 @@ private:      void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b,                                Node op_c, Node imm_lut, bool sets_cc); -    Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const; +    std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;      std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const; diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp index fc957d980..dc132a4a3 100644 --- a/src/video_core/shader/track.cpp +++ b/src/video_core/shader/track.cpp @@ -32,39 +32,44 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,      }      return {};  } -} // namespace +} // Anonymous namespace -Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const { +std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, +                                               s64 cursor) const {      if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { -        // Cbuf found, but it has to be immediate -        return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr; +        // Constant buffer found, test if it's an immediate +        const auto offset = cbuf->GetOffset(); +        if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) { +            return {tracked, cbuf->GetIndex(), immediate->GetValue()}; +        } +        return {};      }      if (const auto gpr = std::get_if<GprNode>(&*tracked)) {          if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) { -            return nullptr; +            return {};          }          // Reduce the cursor in one to avoid infinite loops when the instruction sets the same          // register that it uses as operand          const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1);          if (!source) { -            return nullptr; +            return {};          }          return TrackCbuf(source, code, new_cursor);      }      if (const auto operation = std::get_if<OperationNode>(&*tracked)) {          for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) { -            if (const auto found = TrackCbuf((*operation)[i], code, cursor)) { -                // Cbuf found in operand +            if (auto found = TrackCbuf((*operation)[i], code, cursor); std::get<0>(found)) { +                // Cbuf found in operand.                  return found;              }          } -        return nullptr; +        return {};      }      if (const auto conditional = std::get_if<ConditionalNode>(&*tracked)) {          const auto& conditional_code = conditional->GetCode();          return TrackCbuf(tracked, conditional_code, static_cast<s64>(conditional_code.size()));      } -    return nullptr; +    return {};  }  std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { | 
