diff options
| author | 2018-03-23 18:56:27 -0500 | |
|---|---|---|
| committer | 2018-03-24 11:31:53 -0500 | |
| commit | 2c785bd06c8f979fbb869d533204b29d93973d83 (patch) | |
| tree | c5f800ae155cddb0b36c3ac54febbf8169c709e5 /src | |
| parent | Frontend: Updated the surface view debug widget to work with Maxwell surfaces. (diff) | |
| download | yuzu-2c785bd06c8f979fbb869d533204b29d93973d83.tar.gz yuzu-2c785bd06c8f979fbb869d533204b29d93973d83.tar.xz yuzu-2c785bd06c8f979fbb869d533204b29d93973d83.zip | |
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.
Diffstat (limited to 'src')
| -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() { | |||
| 174 | void Maxwell3D::DrawArrays() { | 174 | void Maxwell3D::DrawArrays() { |
| 175 | LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); | 175 | LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); |
| 176 | if (Tegra::g_debug_context) { | 176 | if (Tegra::g_debug_context) { |
| 177 | Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, nullptr); | 177 | Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, |
| 178 | } | 178 | nullptr); |
| 179 | |||
| 180 | auto& fragment_shader = state.shader_stages[static_cast<size_t>(Regs::ShaderStage::Fragment)]; | ||
| 181 | auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; | ||
| 182 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | ||
| 183 | |||
| 184 | GPUVAddr tic_base_address = regs.tic.TICAddress(); | ||
| 185 | |||
| 186 | GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; | ||
| 187 | |||
| 188 | for (GPUVAddr current_texture = tex_info_buffer.address + 0x20; | ||
| 189 | current_texture < tex_info_buffer_end; current_texture += 4) { | ||
| 190 | |||
| 191 | Texture::TextureHandle tex_info{ | ||
| 192 | Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; | ||
| 193 | |||
| 194 | if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) { | ||
| 195 | GPUVAddr tic_address_gpu = | ||
| 196 | tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry); | ||
| 197 | VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); | ||
| 198 | |||
| 199 | Texture::TICEntry tic_entry; | ||
| 200 | Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); | ||
| 201 | |||
| 202 | auto r_type = tic_entry.r_type.Value(); | ||
| 203 | auto g_type = tic_entry.g_type.Value(); | ||
| 204 | auto b_type = tic_entry.b_type.Value(); | ||
| 205 | auto a_type = tic_entry.a_type.Value(); | ||
| 206 | |||
| 207 | // TODO(Subv): Different data types for separate components are not supported | ||
| 208 | ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | ||
| 209 | |||
| 210 | auto format = tic_entry.format.Value(); | ||
| 211 | |||
| 212 | auto texture = Texture::UnswizzleTexture( | ||
| 213 | memory_manager.PhysicalToVirtualAddress(tic_entry.Address()), | ||
| 214 | tic_entry.format.Value(), tic_entry.Width(), tic_entry.Height()); | ||
| 215 | |||
| 216 | LOG_CRITICAL(HW_GPU, | ||
| 217 | "Fragment shader using texture TIC %08X TSC %08X at address %016" PRIX64, | ||
| 218 | tex_info.tic_id.Value(), tex_info.tsc_id.Value(), tic_entry.Address()); | ||
| 219 | } | ||
| 220 | } | 179 | } |
| 221 | 180 | ||
| 222 | if (Tegra::g_debug_context) { | 181 | if (Tegra::g_debug_context) { |
| 223 | Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); | 182 | Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, |
| 183 | nullptr); | ||
| 224 | } | 184 | } |
| 225 | } | 185 | } |
| 226 | 186 | ||
| @@ -332,5 +292,50 @@ void Maxwell3D::ProcessCBData(u32 value) { | |||
| 332 | regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; | 292 | regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; |
| 333 | } | 293 | } |
| 334 | 294 | ||
| 295 | std::vector<Texture::TICEntry> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) { | ||
| 296 | std::vector<Texture::TICEntry> textures; | ||
| 297 | |||
| 298 | auto& fragment_shader = state.shader_stages[static_cast<size_t>(stage)]; | ||
| 299 | auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; | ||
| 300 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | ||
| 301 | |||
| 302 | GPUVAddr tic_base_address = regs.tic.TICAddress(); | ||
| 303 | |||
| 304 | GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; | ||
| 305 | |||
| 306 | // Offset into the texture constbuffer where the texture info begins. | ||
| 307 | static constexpr size_t TextureInfoOffset = 0x20; | ||
| 308 | |||
| 309 | for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; | ||
| 310 | current_texture < tex_info_buffer_end; current_texture += 4) { | ||
| 311 | |||
| 312 | Texture::TextureHandle tex_info{ | ||
| 313 | Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; | ||
| 314 | |||
| 315 | if (tex_info.tic_id != 0 || tex_info.tsc_id != 0) { | ||
| 316 | GPUVAddr tic_address_gpu = | ||
| 317 | tic_base_address + tex_info.tic_id * sizeof(Texture::TICEntry); | ||
| 318 | VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); | ||
| 319 | |||
| 320 | Texture::TICEntry tic_entry; | ||
| 321 | Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); | ||
| 322 | |||
| 323 | auto r_type = tic_entry.r_type.Value(); | ||
| 324 | auto g_type = tic_entry.g_type.Value(); | ||
| 325 | auto b_type = tic_entry.b_type.Value(); | ||
| 326 | auto a_type = tic_entry.a_type.Value(); | ||
| 327 | |||
| 328 | // TODO(Subv): Different data types for separate components are not supported | ||
| 329 | ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | ||
| 330 | |||
| 331 | auto format = tic_entry.format.Value(); | ||
| 332 | |||
| 333 | textures.push_back(tic_entry); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | return textures; | ||
| 338 | } | ||
| 339 | |||
| 335 | } // namespace Engines | 340 | } // namespace Engines |
| 336 | } // namespace Tegra | 341 | } // 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 @@ | |||
| 12 | #include "common/common_funcs.h" | 12 | #include "common/common_funcs.h" |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "video_core/memory_manager.h" | 14 | #include "video_core/memory_manager.h" |
| 15 | #include "video_core/textures/texture.h" | ||
| 15 | 16 | ||
| 16 | namespace Tegra { | 17 | namespace Tegra { |
| 17 | namespace Engines { | 18 | namespace Engines { |
| @@ -21,12 +22,6 @@ public: | |||
| 21 | explicit Maxwell3D(MemoryManager& memory_manager); | 22 | explicit Maxwell3D(MemoryManager& memory_manager); |
| 22 | ~Maxwell3D() = default; | 23 | ~Maxwell3D() = default; |
| 23 | 24 | ||
| 24 | /// Write the value to the register identified by method. | ||
| 25 | void WriteReg(u32 method, u32 value, u32 remaining_params); | ||
| 26 | |||
| 27 | /// Uploads the code for a GPU macro program associated with the specified entry. | ||
| 28 | void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||
| 29 | |||
| 30 | /// Register structure of the Maxwell3D engine. | 25 | /// Register structure of the Maxwell3D engine. |
| 31 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | 26 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. |
| 32 | struct Regs { | 27 | struct Regs { |
| @@ -430,6 +425,15 @@ public: | |||
| 430 | 425 | ||
| 431 | State state{}; | 426 | State state{}; |
| 432 | 427 | ||
| 428 | /// Write the value to the register identified by method. | ||
| 429 | void WriteReg(u32 method, u32 value, u32 remaining_params); | ||
| 430 | |||
| 431 | /// Uploads the code for a GPU macro program associated with the specified entry. | ||
| 432 | void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||
| 433 | |||
| 434 | /// Returns a list of enabled textures for the specified shader stage. | ||
| 435 | std::vector<Texture::TICEntry> GetStageTextures(Regs::ShaderStage stage); | ||
| 436 | |||
| 433 | private: | 437 | private: |
| 434 | MemoryManager& memory_manager; | 438 | MemoryManager& memory_manager; |
| 435 | 439 | ||