diff options
| author | 2018-03-22 16:40:11 -0500 | |
|---|---|---|
| committer | 2018-03-24 11:31:53 -0500 | |
| commit | 39e60cfeb10ef317521ff1685df3d265d2c9d5ef (patch) | |
| tree | f6fee21c4607642cabea7c809a10cca7aaa7c794 /src | |
| parent | Frontend: Allow opening the Surface View widget in the Qt frontend. (diff) | |
| download | yuzu-39e60cfeb10ef317521ff1685df3d265d2c9d5ef.tar.gz yuzu-39e60cfeb10ef317521ff1685df3d265d2c9d5ef.tar.xz yuzu-39e60cfeb10ef317521ff1685df3d265d2c9d5ef.zip | |
Frontend: Updated the surface view debug widget to work with Maxwell surfaces.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/gpu.h | 4 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 11 | ||||
| -rw-r--r-- | src/yuzu/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 @@ | |||
| 13 | 13 | ||
| 14 | namespace Tegra { | 14 | namespace Tegra { |
| 15 | 15 | ||
| 16 | enum class RenderTargetFormat { | ||
| 17 | RGBA8_UNORM = 0xD5, | ||
| 18 | }; | ||
| 19 | |||
| 16 | class DebugContext; | 20 | class DebugContext; |
| 17 | 21 | ||
| 18 | /** | 22 | /** |
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) { | |||
| 48 | case TextureFormat::DXT1: | 48 | case TextureFormat::DXT1: |
| 49 | // In this case a 'pixel' actually refers to a 4x4 tile. | 49 | // In this case a 'pixel' actually refers to a 4x4 tile. |
| 50 | return 8; | 50 | return 8; |
| 51 | case TextureFormat::A8R8G8B8: | ||
| 52 | return 4; | ||
| 51 | default: | 53 | default: |
| 52 | UNIMPLEMENTED_MSG("Format not implemented"); | 54 | UNIMPLEMENTED_MSG("Format not implemented"); |
| 53 | break; | 55 | break; |
| @@ -68,6 +70,10 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, | |||
| 68 | CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, | 70 | CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, |
| 69 | unswizzled_data.data(), true, DefaultBlockHeight); | 71 | unswizzled_data.data(), true, DefaultBlockHeight); |
| 70 | break; | 72 | break; |
| 73 | case TextureFormat::A8R8G8B8: | ||
| 74 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, | ||
| 75 | unswizzled_data.data(), true, DefaultBlockHeight); | ||
| 76 | break; | ||
| 71 | default: | 77 | default: |
| 72 | UNIMPLEMENTED_MSG("Format not implemented"); | 78 | UNIMPLEMENTED_MSG("Format not implemented"); |
| 73 | break; | 79 | break; |
| @@ -82,6 +88,11 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat | |||
| 82 | 88 | ||
| 83 | // TODO(Subv): Implement. | 89 | // TODO(Subv): Implement. |
| 84 | switch (format) { | 90 | switch (format) { |
| 91 | case TextureFormat::DXT1: | ||
| 92 | case TextureFormat::A8R8G8B8: | ||
| 93 | // TODO(Subv): For the time being just forward the same data without any decoding. | ||
| 94 | rgba_data = texture_data; | ||
| 95 | break; | ||
| 85 | default: | 96 | default: |
| 86 | UNIMPLEMENTED_MSG("Format not implemented"); | 97 | UNIMPLEMENTED_MSG("Format not implemented"); |
| 87 | break; | 98 | 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 @@ | |||
| 13 | #include <QSpinBox> | 13 | #include <QSpinBox> |
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "video_core/engines/maxwell_3d.h" | 15 | #include "video_core/engines/maxwell_3d.h" |
| 16 | #include "video_core/gpu.h" | ||
| 16 | #include "video_core/textures/decoders.h" | 17 | #include "video_core/textures/decoders.h" |
| 17 | #include "video_core/textures/texture.h" | 18 | #include "video_core/textures/texture.h" |
| 18 | #include "video_core/utils.h" | 19 | #include "video_core/utils.h" |
| 19 | #include "yuzu/debugger/graphics/graphics_surface.h" | 20 | #include "yuzu/debugger/graphics/graphics_surface.h" |
| 20 | #include "yuzu/util/spinbox.h" | 21 | #include "yuzu/util/spinbox.h" |
| 21 | 22 | ||
| 23 | static Tegra::Texture::TextureFormat ConvertToTextureFormat( | ||
| 24 | Tegra::RenderTargetFormat render_target_format) { | ||
| 25 | switch (render_target_format) { | ||
| 26 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | ||
| 27 | return Tegra::Texture::TextureFormat::A8R8G8B8; | ||
| 28 | default: | ||
| 29 | UNIMPLEMENTED_MSG("Unimplemented RT format"); | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 22 | SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) | 33 | SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) |
| 23 | : QLabel(parent), surface_widget(surface_widget_) {} | 34 | : QLabel(parent), surface_widget(surface_widget_) {} |
| 24 | SurfacePicture::~SurfacePicture() {} | 35 | SurfacePicture::~SurfacePicture() {} |
| @@ -62,7 +73,7 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Tegra::DebugContext | |||
| 62 | 73 | ||
| 63 | surface_address_control = new CSpinBox; | 74 | surface_address_control = new CSpinBox; |
| 64 | surface_address_control->SetBase(16); | 75 | surface_address_control->SetBase(16); |
| 65 | surface_address_control->SetRange(0, 0xFFFFFFFF); | 76 | surface_address_control->SetRange(0, 0x7FFFFFFFFFFFFFFF); |
| 66 | surface_address_control->SetPrefix("0x"); | 77 | surface_address_control->SetPrefix("0x"); |
| 67 | 78 | ||
| 68 | unsigned max_dimension = 16384; // TODO: Find actual maximum | 79 | unsigned max_dimension = 16384; // TODO: Find actual maximum |
| @@ -243,7 +254,7 @@ void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) { | |||
| 243 | 254 | ||
| 244 | void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) { | 255 | void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) { |
| 245 | if (surface_address != new_value) { | 256 | if (surface_address != new_value) { |
| 246 | surface_address = static_cast<unsigned>(new_value); | 257 | surface_address = static_cast<Tegra::GPUVAddr>(new_value); |
| 247 | 258 | ||
| 248 | surface_source_list->setCurrentIndex(static_cast<int>(Source::Custom)); | 259 | surface_source_list->setCurrentIndex(static_cast<int>(Source::Custom)); |
| 249 | emit Update(); | 260 | emit Update(); |
| @@ -302,13 +313,6 @@ void GraphicsSurfaceWidget::Pick(int x, int y) { | |||
| 302 | return; | 313 | return; |
| 303 | } | 314 | } |
| 304 | 315 | ||
| 305 | u8* buffer = Memory::GetPhysicalPointer(surface_address); | ||
| 306 | if (buffer == nullptr) { | ||
| 307 | surface_info_label->setText(tr("(unable to access pixel data)")); | ||
| 308 | surface_info_label->setAlignment(Qt::AlignCenter); | ||
| 309 | return; | ||
| 310 | } | ||
| 311 | |||
| 312 | surface_info_label->setText(QString("Raw: <Unimplemented>\n(%1)").arg("<Unimplemented>")); | 316 | surface_info_label->setText(QString("Raw: <Unimplemented>\n(%1)").arg("<Unimplemented>")); |
| 313 | surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); | 317 | surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); |
| 314 | } | 318 | } |
| @@ -318,8 +322,6 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 318 | 322 | ||
| 319 | QPixmap pixmap; | 323 | QPixmap pixmap; |
| 320 | 324 | ||
| 321 | Tegra::GPUVAddr surface_address = 0; | ||
| 322 | |||
| 323 | switch (surface_source) { | 325 | switch (surface_source) { |
| 324 | case Source::RenderTarget0: | 326 | case Source::RenderTarget0: |
| 325 | case Source::RenderTarget1: | 327 | case Source::RenderTarget1: |
| @@ -333,11 +335,13 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 333 | // directly... | 335 | // directly... |
| 334 | 336 | ||
| 335 | auto& registers = gpu.Get3DEngine().regs; | 337 | auto& registers = gpu.Get3DEngine().regs; |
| 338 | auto& rt = registers.rt[static_cast<size_t>(surface_source) - | ||
| 339 | static_cast<size_t>(Source::RenderTarget0)]; | ||
| 336 | 340 | ||
| 337 | surface_address = 0; | 341 | surface_address = rt.Address(); |
| 338 | surface_width = 0; | 342 | surface_width = rt.horiz; |
| 339 | surface_height = 0; | 343 | surface_height = rt.vert; |
| 340 | surface_format = Tegra::Texture::TextureFormat::DXT1; | 344 | surface_format = ConvertToTextureFormat(static_cast<Tegra::RenderTargetFormat>(rt.format)); |
| 341 | 345 | ||
| 342 | break; | 346 | break; |
| 343 | } | 347 | } |
| @@ -378,9 +382,6 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 378 | auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, | 382 | auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, |
| 379 | surface_width, surface_height); | 383 | surface_width, surface_height); |
| 380 | 384 | ||
| 381 | ASSERT(texture_data.size() == | ||
| 382 | surface_width * surface_height * | ||
| 383 | Tegra::Texture::BytesPerPixel(Tegra::Texture::TextureFormat::A8R8G8B8)); | ||
| 384 | surface_picture_label->show(); | 385 | surface_picture_label->show(); |
| 385 | 386 | ||
| 386 | for (unsigned int y = 0; y < surface_height; ++y) { | 387 | for (unsigned int y = 0; y < surface_height; ++y) { |
| @@ -431,7 +432,10 @@ void GraphicsSurfaceWidget::SaveSurface() { | |||
| 431 | if (pixmap) | 432 | if (pixmap) |
| 432 | pixmap->save(&file, "PNG"); | 433 | pixmap->save(&file, "PNG"); |
| 433 | } else if (selectedFilter == bin_filter) { | 434 | } else if (selectedFilter == bin_filter) { |
| 434 | const u8* buffer = Memory::GetPhysicalPointer(surface_address); | 435 | auto& gpu = Core::System::GetInstance().GPU(); |
| 436 | VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); | ||
| 437 | |||
| 438 | const u8* buffer = Memory::GetPointer(address); | ||
| 435 | ASSERT_MSG(buffer != nullptr, "Memory not accessible"); | 439 | ASSERT_MSG(buffer != nullptr, "Memory not accessible"); |
| 436 | 440 | ||
| 437 | QFile file(filename); | 441 | QFile file(filename); |