Frontend: Updated the surface view debug widget to work with Maxwell surfaces.

This commit is contained in:
Subv 2018-03-22 16:40:11 -05:00
parent 025d111308
commit 39e60cfeb1
3 changed files with 38 additions and 19 deletions

View File

@ -13,6 +13,10 @@
namespace Tegra { namespace Tegra {
enum class RenderTargetFormat {
RGBA8_UNORM = 0xD5,
};
class DebugContext; class DebugContext;
/** /**

View File

@ -48,6 +48,8 @@ u32 BytesPerPixel(TextureFormat format) {
case TextureFormat::DXT1: case TextureFormat::DXT1:
// In this case a 'pixel' actually refers to a 4x4 tile. // In this case a 'pixel' actually refers to a 4x4 tile.
return 8; return 8;
case TextureFormat::A8R8G8B8:
return 4;
default: default:
UNIMPLEMENTED_MSG("Format not implemented"); UNIMPLEMENTED_MSG("Format not implemented");
break; 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, CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, DefaultBlockHeight); unswizzled_data.data(), true, DefaultBlockHeight);
break; break;
case TextureFormat::A8R8G8B8:
CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, DefaultBlockHeight);
break;
default: default:
UNIMPLEMENTED_MSG("Format not implemented"); UNIMPLEMENTED_MSG("Format not implemented");
break; break;
@ -82,6 +88,11 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
// TODO(Subv): Implement. // TODO(Subv): Implement.
switch (format) { 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: default:
UNIMPLEMENTED_MSG("Format not implemented"); UNIMPLEMENTED_MSG("Format not implemented");
break; break;

View File

@ -13,12 +13,23 @@
#include <QSpinBox> #include <QSpinBox>
#include "core/core.h" #include "core/core.h"
#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h"
#include "video_core/gpu.h"
#include "video_core/textures/decoders.h" #include "video_core/textures/decoders.h"
#include "video_core/textures/texture.h" #include "video_core/textures/texture.h"
#include "video_core/utils.h" #include "video_core/utils.h"
#include "yuzu/debugger/graphics/graphics_surface.h" #include "yuzu/debugger/graphics/graphics_surface.h"
#include "yuzu/util/spinbox.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_) SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_)
: QLabel(parent), surface_widget(surface_widget_) {} : QLabel(parent), surface_widget(surface_widget_) {}
SurfacePicture::~SurfacePicture() {} SurfacePicture::~SurfacePicture() {}
@ -62,7 +73,7 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Tegra::DebugContext
surface_address_control = new CSpinBox; surface_address_control = new CSpinBox;
surface_address_control->SetBase(16); surface_address_control->SetBase(16);
surface_address_control->SetRange(0, 0xFFFFFFFF); surface_address_control->SetRange(0, 0x7FFFFFFFFFFFFFFF);
surface_address_control->SetPrefix("0x"); surface_address_control->SetPrefix("0x");
unsigned max_dimension = 16384; // TODO: Find actual maximum unsigned max_dimension = 16384; // TODO: Find actual maximum
@ -243,7 +254,7 @@ void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) {
void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) { void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) {
if (surface_address != 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)); surface_source_list->setCurrentIndex(static_cast<int>(Source::Custom));
emit Update(); emit Update();
@ -302,13 +313,6 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
return; 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->setText(QString("Raw: <Unimplemented>\n(%1)").arg("<Unimplemented>"));
surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
} }
@ -318,8 +322,6 @@ void GraphicsSurfaceWidget::OnUpdate() {
QPixmap pixmap; QPixmap pixmap;
Tegra::GPUVAddr surface_address = 0;
switch (surface_source) { switch (surface_source) {
case Source::RenderTarget0: case Source::RenderTarget0:
case Source::RenderTarget1: case Source::RenderTarget1:
@ -333,11 +335,13 @@ void GraphicsSurfaceWidget::OnUpdate() {
// directly... // directly...
auto& registers = gpu.Get3DEngine().regs; 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_address = rt.Address();
surface_width = 0; surface_width = rt.horiz;
surface_height = 0; surface_height = rt.vert;
surface_format = Tegra::Texture::TextureFormat::DXT1; surface_format = ConvertToTextureFormat(static_cast<Tegra::RenderTargetFormat>(rt.format));
break; break;
} }
@ -378,9 +382,6 @@ void GraphicsSurfaceWidget::OnUpdate() {
auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
surface_width, surface_height); surface_width, surface_height);
ASSERT(texture_data.size() ==
surface_width * surface_height *
Tegra::Texture::BytesPerPixel(Tegra::Texture::TextureFormat::A8R8G8B8));
surface_picture_label->show(); surface_picture_label->show();
for (unsigned int y = 0; y < surface_height; ++y) { for (unsigned int y = 0; y < surface_height; ++y) {
@ -431,7 +432,10 @@ void GraphicsSurfaceWidget::SaveSurface() {
if (pixmap) if (pixmap)
pixmap->save(&file, "PNG"); pixmap->save(&file, "PNG");
} else if (selectedFilter == bin_filter) { } 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"); ASSERT_MSG(buffer != nullptr, "Memory not accessible");
QFile file(filename); QFile file(filename);