diff options
| author | Subv <subv2112@gmail.com> | 2018-03-23 18:56:27 -0500 | 
|---|---|---|
| committer | Subv <subv2112@gmail.com> | 2018-03-24 11:31:53 -0500 | 
| commit | 2c785bd06c8f979fbb869d533204b29d93973d83 (patch) | |
| tree | c5f800ae155cddb0b36c3ac54febbf8169c709e5 | |
| parent | 39e60cfeb10ef317521ff1685df3d265d2c9d5ef (diff) | |
GPU: Added a function to retrieve the active textures for a shader stage.
TODO: A shader may not use all of these textures at the same time, shader analysis should be performed to determine which textures are actually sampled.
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 93 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 16 | 
2 files changed, 59 insertions, 50 deletions
| diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index aa375f51f..c962887ca 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -174,53 +174,13 @@ void Maxwell3D::ProcessQueryGet() {  void Maxwell3D::DrawArrays() {      LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring");      if (Tegra::g_debug_context) { -        Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, nullptr); -    } - -    auto& fragment_shader = state.shader_stages[static_cast<size_t>(Regs::ShaderStage::Fragment)]; -    auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; -    ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); - -    GPUVAddr tic_base_address = regs.tic.TICAddress(); - -    GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; - -    for (GPUVAddr current_texture = tex_info_buffer.address + 0x20; -         current_texture < tex_info_buffer_end; current_texture += 4) { - -        Texture::TextureHandle tex_info{ -            Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; - -        if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) { -            GPUVAddr tic_address_gpu = -                tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry); -            VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); - -            Texture::TICEntry tic_entry; -            Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); - -            auto r_type = tic_entry.r_type.Value(); -            auto g_type = tic_entry.g_type.Value(); -            auto b_type = tic_entry.b_type.Value(); -            auto a_type = tic_entry.a_type.Value(); - -            // TODO(Subv): Different data types for separate components are not supported -            ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); - -            auto format = tic_entry.format.Value(); - -            auto texture = Texture::UnswizzleTexture( -                memory_manager.PhysicalToVirtualAddress(tic_entry.Address()), -                tic_entry.format.Value(), tic_entry.Width(), tic_entry.Height()); - -            LOG_CRITICAL(HW_GPU, -                         "Fragment shader using texture TIC %08X TSC %08X at address %016" PRIX64, -                         tex_info.tic_id.Value(), tex_info.tsc_id.Value(), tic_entry.Address()); -        } +        Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, +                                        nullptr);      }      if (Tegra::g_debug_context) { -        Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); +        Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, +                                        nullptr);      }  } @@ -332,5 +292,50 @@ void Maxwell3D::ProcessCBData(u32 value) {      regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;  } +std::vector<Texture::TICEntry> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) { +    std::vector<Texture::TICEntry> textures; + +    auto& fragment_shader = state.shader_stages[static_cast<size_t>(stage)]; +    auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; +    ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); + +    GPUVAddr tic_base_address = regs.tic.TICAddress(); + +    GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; + +    // Offset into the texture constbuffer where the texture info begins. +    static constexpr size_t TextureInfoOffset = 0x20; + +    for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; +         current_texture < tex_info_buffer_end; current_texture += 4) { + +        Texture::TextureHandle tex_info{ +            Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; + +        if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) { +            GPUVAddr tic_address_gpu = +                tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry); +            VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); + +            Texture::TICEntry tic_entry; +            Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); + +            auto r_type = tic_entry.r_type.Value(); +            auto g_type = tic_entry.g_type.Value(); +            auto b_type = tic_entry.b_type.Value(); +            auto a_type = tic_entry.a_type.Value(); + +            // TODO(Subv): Different data types for separate components are not supported +            ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); + +            auto format = tic_entry.format.Value(); + +            textures.push_back(tic_entry); +        } +    } + +    return textures; +} +  } // namespace Engines  } // namespace Tegra diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 545d7ff35..441cc0c19 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -12,6 +12,7 @@  #include "common/common_funcs.h"  #include "common/common_types.h"  #include "video_core/memory_manager.h" +#include "video_core/textures/texture.h"  namespace Tegra {  namespace Engines { @@ -21,12 +22,6 @@ public:      explicit Maxwell3D(MemoryManager& memory_manager);      ~Maxwell3D() = default; -    /// Write the value to the register identified by method. -    void WriteReg(u32 method, u32 value, u32 remaining_params); - -    /// Uploads the code for a GPU macro program associated with the specified entry. -    void SubmitMacroCode(u32 entry, std::vector<u32> code); -      /// Register structure of the Maxwell3D engine.      /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.      struct Regs { @@ -430,6 +425,15 @@ public:      State state{}; +    /// Write the value to the register identified by method. +    void WriteReg(u32 method, u32 value, u32 remaining_params); + +    /// Uploads the code for a GPU macro program associated with the specified entry. +    void SubmitMacroCode(u32 entry, std::vector<u32> code); + +    /// Returns a list of enabled textures for the specified shader stage. +    std::vector<Texture::TICEntry> GetStageTextures(Regs::ShaderStage stage); +  private:      MemoryManager& memory_manager; | 
