From 71ebc3e90da9882139d2a5695ca1ed59ea77e94f Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 19 Mar 2018 18:00:29 -0500 Subject: GPU: Preliminary work for texture decoding. --- src/video_core/engines/maxwell_3d.cpp | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 4d9745e48..ca1b150a7 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "common/assert.h" #include "video_core/engines/maxwell_3d.h" +#include "video_core/textures/decoders.h" +#include "video_core/textures/texture.h" namespace Tegra { namespace Engines { @@ -160,6 +163,48 @@ void Maxwell3D::ProcessQueryGet() { void Maxwell3D::DrawArrays() { LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring"); + + 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::DecodeTexture( + 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()); + } + } } void Maxwell3D::BindTextureInfoBuffer(const std::vector& parameters) { -- cgit v1.2.3 From 1b8d798835c2d39c2867f53d8dcacdc7d0ba0d15 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 22 Mar 2018 15:17:10 -0500 Subject: GPU: Added a method to unswizzle a texture without decoding it. Allow unswizzling of DXT1 textures. --- src/video_core/engines/maxwell_3d.cpp | 2 +- src/video_core/textures/decoders.cpp | 84 ++++++++++++++++++++++++++++++++++- src/video_core/textures/decoders.h | 10 ++++- src/video_core/textures/texture.h | 4 ++ 4 files changed, 95 insertions(+), 5 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index ca1b150a7..d1edfe09a 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -196,7 +196,7 @@ void Maxwell3D::DrawArrays() { auto format = tic_entry.format.Value(); - auto texture = Texture::DecodeTexture( + auto texture = Texture::UnswizzleTexture( memory_manager.PhysicalToVirtualAddress(tic_entry.Address()), tic_entry.format.Value(), tic_entry.Width(), tic_entry.Height()); diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 705e2e066..300267209 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -2,13 +2,93 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include "common/assert.h" #include "video_core/textures/decoders.h" +#include "video_core/textures/texture.h" namespace Tegra { namespace Texture { -std::vector DecodeTexture(VAddr address, TextureFormat format, u32 width, u32 height) { - return {}; +/** + * Calculates the offset of an (x, y) position within a swizzled texture. + * Taken from the Tegra X1 TRM. + */ +static u32 GetSwizzleOffset(u32 x, u32 y, u32 image_width, u32 bytes_per_pixel, u32 block_height) { + u32 image_width_in_gobs = image_width * bytes_per_pixel / 64; + u32 GOB_address = 0 + (y / (8 * block_height)) * 512 * block_height * image_width_in_gobs + + (x * bytes_per_pixel / 64) * 512 * block_height + + (y % (8 * block_height) / 8) * 512; + x *= bytes_per_pixel; + u32 address = GOB_address + ((x % 64) / 32) * 256 + ((y % 8) / 2) * 64 + ((x % 32) / 16) * 32 + + (y % 2) * 16 + (x % 16); + + return address; } + +static void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, + u8* swizzled_data, u8* unswizzled_data, bool unswizzle, + u32 block_height) { + u8* data_ptrs[2]; + for (unsigned y = 0; y < height; ++y) { + for (unsigned x = 0; x < width; ++x) { + u32 swizzle_offset = GetSwizzleOffset(x, y, width, bytes_per_pixel, block_height); + u32 pixel_index = (x + y * width) * out_bytes_per_pixel; + + data_ptrs[unswizzle] = swizzled_data + swizzle_offset; + data_ptrs[!unswizzle] = &unswizzled_data[pixel_index]; + + std::memcpy(data_ptrs[0], data_ptrs[1], bytes_per_pixel); + } + } } + +u32 BytesPerPixel(TextureFormat format) { + switch (format) { + case TextureFormat::DXT1: + // In this case a 'pixel' actually refers to a 4x4 tile. + return 8; + default: + UNIMPLEMENTED_MSG("Format not implemented"); + break; + } +} + +std::vector UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height) { + u8* data = Memory::GetPointer(address); + u32 bytes_per_pixel = BytesPerPixel(format); + + static constexpr u32 DefaultBlockHeight = 16; + + std::vector unswizzled_data(width * height * bytes_per_pixel); + + switch (format) { + case TextureFormat::DXT1: + // In the DXT1 format, each 4x4 tile is swizzled instead of just individual pixel values. + CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, + unswizzled_data.data(), true, DefaultBlockHeight); + break; + default: + UNIMPLEMENTED_MSG("Format not implemented"); + break; + } + + return unswizzled_data; +} + +std::vector DecodeTexture(const std::vector& texture_data, TextureFormat format, u32 width, + u32 height) { + std::vector rgba_data; + + // TODO(Subv): Implement. + switch (format) { + default: + UNIMPLEMENTED_MSG("Format not implemented"); + break; + } + + return rgba_data; +} + +} // namespace Texture } // namespace Tegra diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index e0d55600e..0c21694ff 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -12,9 +12,15 @@ namespace Tegra { namespace Texture { /** - * Decodes a swizzled texture into a RGBA8888 texture. + * Unswizzles a swizzled texture without changing its format. */ -std::vector DecodeTexture(VAddr address, TextureFormat format, u32 width, u32 height); +std::vector UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height); + +/** + * Decodes an unswizzled texture into a A8R8G8B8 texture. + */ +std::vector DecodeTexture(const std::vector& texture_data, TextureFormat format, u32 width, + u32 height); } // namespace Texture } // namespace Tegra diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 3306d2ab2..d969bcdd9 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -13,6 +13,7 @@ namespace Tegra { namespace Texture { enum class TextureFormat : u32 { + A8R8G8B8 = 8, DXT1 = 0x24, }; @@ -53,5 +54,8 @@ struct TICEntry { }; static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size"); +/// Returns the number of bytes per pixel of the input texture format. +u32 BytesPerPixel(TextureFormat format); + } // namespace Texture } // namespace Tegra -- cgit v1.2.3 From 1ad97c75a0fe94000b0f54ff43ca5d29d8a9edc6 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 22 Mar 2018 15:25:17 -0500 Subject: GPU: Implement the MaxwellCommandLoaded/Processed debug breakpoints. --- src/video_core/engines/maxwell_3d.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index d1edfe09a..ae6a4d5f1 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -4,6 +4,7 @@ #include #include "common/assert.h" +#include "video_core/debug_utils/debug_utils.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/textures/decoders.h" #include "video_core/textures/texture.h" @@ -75,6 +76,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { return; } + if (Tegra::g_debug_context) { + Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); + } + regs.reg_array[method] = value; #define MAXWELL3D_REG_INDEX(field_name) (offsetof(Regs, field_name) / sizeof(u32)) @@ -140,6 +145,11 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { } #undef MAXWELL3D_REG_INDEX + + if (Tegra::g_debug_context) { + Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, + nullptr); + } } void Maxwell3D::ProcessQueryGet() { -- cgit v1.2.3 From 1c31e2b3d2efb3a6425518df62cd1c277367f17a Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 22 Mar 2018 15:27:28 -0500 Subject: GPU: Implement the Incoming/FinishedPrimitiveBatch debug breakpoints. --- src/video_core/engines/maxwell_3d.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index ae6a4d5f1..aa375f51f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -173,6 +173,9 @@ 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]; @@ -215,6 +218,10 @@ void Maxwell3D::DrawArrays() { tex_info.tic_id.Value(), tex_info.tsc_id.Value(), tic_entry.Address()); } } + + if (Tegra::g_debug_context) { + Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); + } } void Maxwell3D::BindTextureInfoBuffer(const std::vector& parameters) { -- cgit v1.2.3 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(-) (limited to 'src/video_core/engines') 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 From 0ce52b1da2228f3325d94e52bead7335c8b07d1c Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 24 Mar 2018 23:35:06 -0500 Subject: GPU: Make the debug_context variable a member of the frontend instead of a global. --- src/core/core.h | 11 +++++++++++ src/video_core/debug_utils/debug_utils.cpp | 2 -- src/video_core/debug_utils/debug_utils.h | 2 -- src/video_core/engines/maxwell_3d.cpp | 24 +++++++++++++----------- src/yuzu/debugger/graphics/graphics_surface.cpp | 5 ++++- src/yuzu/main.cpp | 9 ++++++--- src/yuzu/main.h | 6 ++++++ 7 files changed, 40 insertions(+), 19 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/core/core.h b/src/core/core.h index 552c8f5ee..ade456cfc 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -13,6 +13,7 @@ #include "core/memory.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" +#include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu.h" class EmuWindow; @@ -135,6 +136,14 @@ public: return *app_loader; } + void SetGPUDebugContext(std::shared_ptr context) { + debug_context = std::move(context); + } + + std::shared_ptr GetGPUDebugContext() const { + return debug_context; + } + private: /** * Initialize the emulated system. @@ -154,6 +163,8 @@ private: std::unique_ptr scheduler; std::unique_ptr gpu_core; + std::shared_ptr debug_context; + Kernel::SharedPtr current_process; /// When true, signals that a reschedule should happen diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 73fd4d7a3..22d44aab2 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -23,8 +23,6 @@ namespace Tegra { -std::shared_ptr g_debug_context; - void DebugContext::DoOnEvent(Event event, void* data) { { std::unique_lock lock(breakpoint_mutex); diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 98461d6d9..bbba8e380 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -160,6 +160,4 @@ private: std::list breakpoint_observers; }; -extern std::shared_ptr g_debug_context; - } // namespace Tegra diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index c962887ca..986165c6d 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -4,6 +4,7 @@ #include #include "common/assert.h" +#include "core/core.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/textures/decoders.h" @@ -50,6 +51,8 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { ASSERT_MSG(method < Regs::NUM_REGS, "Invalid Maxwell3D register, increase the size of the Regs structure"); + auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); + // It is an error to write to a register other than the current macro's ARG register before it // has finished execution. if (executing_macro != 0) { @@ -76,8 +79,8 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { return; } - if (Tegra::g_debug_context) { - Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); + if (debug_context) { + debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); } regs.reg_array[method] = value; @@ -146,9 +149,8 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { #undef MAXWELL3D_REG_INDEX - if (Tegra::g_debug_context) { - Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, - nullptr); + if (debug_context) { + debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); } } @@ -173,14 +175,14 @@ 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 debug_context = Core::System::GetInstance().GetGPUDebugContext(); + + if (debug_context) { + debug_context->OnEvent(Tegra::DebugContext::Event::IncomingPrimitiveBatch, nullptr); } - if (Tegra::g_debug_context) { - Tegra::g_debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, - nullptr); + if (debug_context) { + debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); } } diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index d061013da..8e6509adc 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -341,7 +341,10 @@ void GraphicsSurfaceWidget::OnUpdate() { surface_address = rt.Address(); surface_width = rt.horiz; surface_height = rt.vert; - surface_format = ConvertToTextureFormat(static_cast(rt.format)); + if (rt.format != 0) { + surface_format = + ConvertToTextureFormat(static_cast(rt.format)); + } break; } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index b8c23ae15..bd323870b 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -25,6 +25,7 @@ #include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" #include "core/settings.h" +#include "video_core/debug_utils/debug_utils.h" #include "yuzu/about_dialog.h" #include "yuzu/bootmanager.h" #include "yuzu/configuration/config.h" @@ -71,7 +72,7 @@ void GMainWindow::ShowCallouts() {} GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { - Tegra::g_debug_context = Tegra::DebugContext::Construct(); + debug_context = Tegra::DebugContext::Construct(); setAcceptDrops(true); ui.setupUi(this); @@ -165,12 +166,12 @@ void GMainWindow::InitializeDebugWidgets() { connect(this, &GMainWindow::EmulationStopping, registersWidget, &RegistersWidget::OnEmulationStopping); - graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Tegra::g_debug_context, this); + graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(debug_context, this); addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget); graphicsBreakpointsWidget->hide(); debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction()); - graphicsSurfaceWidget = new GraphicsSurfaceWidget(Tegra::g_debug_context, this); + graphicsSurfaceWidget = new GraphicsSurfaceWidget(debug_context, this); addDockWidget(Qt::RightDockWidgetArea, graphicsSurfaceWidget); graphicsSurfaceWidget->hide(); debug_menu->addAction(graphicsSurfaceWidget->toggleViewAction()); @@ -339,6 +340,8 @@ bool GMainWindow::LoadROM(const QString& filename) { Core::System& system{Core::System::GetInstance()}; + system.SetGPUDebugContext(debug_context); + const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "Qt"); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 0f89607c8..2471caf83 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -23,6 +23,10 @@ class ProfilerWidget; class RegistersWidget; class WaitTreeWidget; +namespace Tegra { +class DebugContext; +} + class GMainWindow : public QMainWindow { Q_OBJECT @@ -135,6 +139,8 @@ private: Ui::MainWindow ui; + std::shared_ptr debug_context; + GRenderWindow* render_window; GameList* game_list; -- cgit v1.2.3