From 2c785bd06c8f979fbb869d533204b29d93973d83 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 23 Mar 2018 18:56:27 -0500 Subject: 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. --- src/video_core/engines/maxwell_3d.cpp | 93 ++++++++++++++++++----------------- 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(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 Maxwell3D::GetStageTextures(Regs::ShaderStage stage) { + std::vector textures; + + auto& fragment_shader = state.shader_stages[static_cast(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 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 code); + + /// Returns a list of enabled textures for the specified shader stage. + std::vector GetStageTextures(Regs::ShaderStage stage); + private: MemoryManager& memory_manager; -- cgit v1.2.3