mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 12:34:39 +08:00 
			
		
		
		
	Frontend: Updated the surface view debug widget to work with Maxwell surfaces.
This commit is contained in:
		
							parent
							
								
									025d111308
								
							
						
					
					
						commit
						39e60cfeb1
					
				@ -13,6 +13,10 @@
 | 
			
		||||
 | 
			
		||||
namespace Tegra {
 | 
			
		||||
 | 
			
		||||
enum class RenderTargetFormat {
 | 
			
		||||
    RGBA8_UNORM = 0xD5,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DebugContext;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -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<u8> 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<u8> DecodeTexture(const std::vector<u8>& 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;
 | 
			
		||||
 | 
			
		||||
@ -13,12 +13,23 @@
 | 
			
		||||
#include <QSpinBox>
 | 
			
		||||
#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_ptr<Tegra::DebugContext
 | 
			
		||||
 | 
			
		||||
    surface_address_control = new CSpinBox;
 | 
			
		||||
    surface_address_control->SetBase(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<unsigned>(new_value);
 | 
			
		||||
        surface_address = static_cast<Tegra::GPUVAddr>(new_value);
 | 
			
		||||
 | 
			
		||||
        surface_source_list->setCurrentIndex(static_cast<int>(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: <Unimplemented>\n(%1)").arg("<Unimplemented>"));
 | 
			
		||||
    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<size_t>(surface_source) -
 | 
			
		||||
                                static_cast<size_t>(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<Tegra::RenderTargetFormat>(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);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user