From 39e60cfeb10ef317521ff1685df3d265d2c9d5ef Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 22 Mar 2018 16:40:11 -0500 Subject: [PATCH] Frontend: Updated the surface view debug widget to work with Maxwell surfaces. --- src/video_core/gpu.h | 4 ++ src/video_core/textures/decoders.cpp | 11 +++++ .../debugger/graphics/graphics_surface.cpp | 42 ++++++++++--------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 778b63218..8183b12e9 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -13,6 +13,10 @@ namespace Tegra { +enum class RenderTargetFormat { + RGBA8_UNORM = 0xD5, +}; + class DebugContext; /** diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 300267209..2e87281eb 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -48,6 +48,8 @@ u32 BytesPerPixel(TextureFormat format) { case TextureFormat::DXT1: // In this case a 'pixel' actually refers to a 4x4 tile. return 8; + case TextureFormat::A8R8G8B8: + return 4; default: UNIMPLEMENTED_MSG("Format not implemented"); break; @@ -68,6 +70,10 @@ std::vector UnswizzleTexture(VAddr address, TextureFormat format, u32 width, CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, unswizzled_data.data(), true, DefaultBlockHeight); break; + case TextureFormat::A8R8G8B8: + CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, + unswizzled_data.data(), true, DefaultBlockHeight); + break; default: UNIMPLEMENTED_MSG("Format not implemented"); break; @@ -82,6 +88,11 @@ std::vector DecodeTexture(const std::vector& texture_data, TextureFormat // TODO(Subv): Implement. switch (format) { + case TextureFormat::DXT1: + case TextureFormat::A8R8G8B8: + // TODO(Subv): For the time being just forward the same data without any decoding. + rgba_data = texture_data; + break; default: UNIMPLEMENTED_MSG("Format not implemented"); break; diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 54b816054..d061013da 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -13,12 +13,23 @@ #include #include "core/core.h" #include "video_core/engines/maxwell_3d.h" +#include "video_core/gpu.h" #include "video_core/textures/decoders.h" #include "video_core/textures/texture.h" #include "video_core/utils.h" #include "yuzu/debugger/graphics/graphics_surface.h" #include "yuzu/util/spinbox.h" +static Tegra::Texture::TextureFormat ConvertToTextureFormat( + Tegra::RenderTargetFormat render_target_format) { + switch (render_target_format) { + case Tegra::RenderTargetFormat::RGBA8_UNORM: + return Tegra::Texture::TextureFormat::A8R8G8B8; + default: + UNIMPLEMENTED_MSG("Unimplemented RT format"); + } +} + SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) : QLabel(parent), surface_widget(surface_widget_) {} SurfacePicture::~SurfacePicture() {} @@ -62,7 +73,7 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptrSetBase(16); - surface_address_control->SetRange(0, 0xFFFFFFFF); + surface_address_control->SetRange(0, 0x7FFFFFFFFFFFFFFF); surface_address_control->SetPrefix("0x"); unsigned max_dimension = 16384; // TODO: Find actual maximum @@ -243,7 +254,7 @@ void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) { void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) { if (surface_address != new_value) { - surface_address = static_cast(new_value); + surface_address = static_cast(new_value); surface_source_list->setCurrentIndex(static_cast(Source::Custom)); emit Update(); @@ -302,13 +313,6 @@ void GraphicsSurfaceWidget::Pick(int x, int y) { return; } - u8* buffer = Memory::GetPhysicalPointer(surface_address); - if (buffer == nullptr) { - surface_info_label->setText(tr("(unable to access pixel data)")); - surface_info_label->setAlignment(Qt::AlignCenter); - return; - } - surface_info_label->setText(QString("Raw: \n(%1)").arg("")); surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); } @@ -318,8 +322,6 @@ void GraphicsSurfaceWidget::OnUpdate() { QPixmap pixmap; - Tegra::GPUVAddr surface_address = 0; - switch (surface_source) { case Source::RenderTarget0: case Source::RenderTarget1: @@ -333,11 +335,13 @@ void GraphicsSurfaceWidget::OnUpdate() { // directly... auto& registers = gpu.Get3DEngine().regs; + auto& rt = registers.rt[static_cast(surface_source) - + static_cast(Source::RenderTarget0)]; - surface_address = 0; - surface_width = 0; - surface_height = 0; - surface_format = Tegra::Texture::TextureFormat::DXT1; + surface_address = rt.Address(); + surface_width = rt.horiz; + surface_height = rt.vert; + surface_format = ConvertToTextureFormat(static_cast(rt.format)); break; } @@ -378,9 +382,6 @@ void GraphicsSurfaceWidget::OnUpdate() { auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, surface_width, surface_height); - ASSERT(texture_data.size() == - surface_width * surface_height * - Tegra::Texture::BytesPerPixel(Tegra::Texture::TextureFormat::A8R8G8B8)); surface_picture_label->show(); for (unsigned int y = 0; y < surface_height; ++y) { @@ -431,7 +432,10 @@ void GraphicsSurfaceWidget::SaveSurface() { if (pixmap) pixmap->save(&file, "PNG"); } else if (selectedFilter == bin_filter) { - const u8* buffer = Memory::GetPhysicalPointer(surface_address); + auto& gpu = Core::System::GetInstance().GPU(); + VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); + + const u8* buffer = Memory::GetPointer(address); ASSERT_MSG(buffer != nullptr, "Memory not accessible"); QFile file(filename);