Frontend/Qt: Allow the framebuffer widget to inspect the depth buffer
This commit is contained in:
		| @@ -27,6 +27,7 @@ GraphicsFramebufferWidget::GraphicsFramebufferWidget(std::shared_ptr<Pica::Debug | |||||||
|  |  | ||||||
|     framebuffer_source_list = new QComboBox; |     framebuffer_source_list = new QComboBox; | ||||||
|     framebuffer_source_list->addItem(tr("Active Render Target")); |     framebuffer_source_list->addItem(tr("Active Render Target")); | ||||||
|  |     framebuffer_source_list->addItem(tr("Active Depth Buffer")); | ||||||
|     framebuffer_source_list->addItem(tr("Custom")); |     framebuffer_source_list->addItem(tr("Custom")); | ||||||
|     framebuffer_source_list->setCurrentIndex(static_cast<int>(framebuffer_source)); |     framebuffer_source_list->setCurrentIndex(static_cast<int>(framebuffer_source)); | ||||||
|  |  | ||||||
| @@ -49,6 +50,9 @@ GraphicsFramebufferWidget::GraphicsFramebufferWidget(std::shared_ptr<Pica::Debug | |||||||
|     framebuffer_format_control->addItem(tr("RGB5A1")); |     framebuffer_format_control->addItem(tr("RGB5A1")); | ||||||
|     framebuffer_format_control->addItem(tr("RGB565")); |     framebuffer_format_control->addItem(tr("RGB565")); | ||||||
|     framebuffer_format_control->addItem(tr("RGBA4")); |     framebuffer_format_control->addItem(tr("RGBA4")); | ||||||
|  |     framebuffer_format_control->addItem(tr("D16")); | ||||||
|  |     framebuffer_format_control->addItem(tr("D24")); | ||||||
|  |     framebuffer_format_control->addItem(tr("D24S8")); | ||||||
|  |  | ||||||
|     // TODO: This QLabel should shrink the image to the available space rather than just expanding... |     // TODO: This QLabel should shrink the image to the available space rather than just expanding... | ||||||
|     framebuffer_picture_label = new QLabel; |     framebuffer_picture_label = new QLabel; | ||||||
| @@ -173,7 +177,6 @@ void GraphicsFramebufferWidget::OnUpdate() | |||||||
|         // TODO: Store a reference to the registers in the debug context instead of accessing them directly... |         // TODO: Store a reference to the registers in the debug context instead of accessing them directly... | ||||||
|  |  | ||||||
|         auto framebuffer = Pica::registers.framebuffer; |         auto framebuffer = Pica::registers.framebuffer; | ||||||
|         using Framebuffer = decltype(framebuffer); |  | ||||||
|  |  | ||||||
|         framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); |         framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); | ||||||
|         framebuffer_width = framebuffer.GetWidth(); |         framebuffer_width = framebuffer.GetWidth(); | ||||||
| @@ -184,6 +187,18 @@ void GraphicsFramebufferWidget::OnUpdate() | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     case Source::DepthBuffer: | ||||||
|  |     { | ||||||
|  |         auto framebuffer = Pica::registers.framebuffer; | ||||||
|  |  | ||||||
|  |         framebuffer_address = framebuffer.GetDepthBufferPhysicalAddress(); | ||||||
|  |         framebuffer_width = framebuffer.GetWidth(); | ||||||
|  |         framebuffer_height = framebuffer.GetHeight(); | ||||||
|  |         framebuffer_format = Format::D16; | ||||||
|  |  | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     case Source::Custom: |     case Source::Custom: | ||||||
|     { |     { | ||||||
|         // Keep user-specified values |         // Keep user-specified values | ||||||
| @@ -197,15 +212,16 @@ void GraphicsFramebufferWidget::OnUpdate() | |||||||
|  |  | ||||||
|     // TODO: Implement a good way to visualize alpha components! |     // TODO: Implement a good way to visualize alpha components! | ||||||
|     // TODO: Unify this decoding code with the texture decoder |     // TODO: Unify this decoding code with the texture decoder | ||||||
|     u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer_format)); |     u32 bytes_per_pixel = GraphicsFramebufferWidget::BytesPerPixel(framebuffer_format); | ||||||
|  |  | ||||||
|     QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); |     QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); | ||||||
|     u8* color_buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); |     u8* buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); | ||||||
|  |  | ||||||
|     for (unsigned int y = 0; y < framebuffer_height; ++y) { |     for (unsigned int y = 0; y < framebuffer_height; ++y) { | ||||||
|         for (unsigned int x = 0; x < framebuffer_width; ++x) { |         for (unsigned int x = 0; x < framebuffer_width; ++x) { | ||||||
|             const u32 coarse_y = y & ~7; |             const u32 coarse_y = y & ~7; | ||||||
|             u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * framebuffer_width * bytes_per_pixel; |             u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * framebuffer_width * bytes_per_pixel; | ||||||
|             const u8* pixel = color_buffer + offset; |             const u8* pixel = buffer + offset; | ||||||
|             Math::Vec4<u8> color = { 0, 0, 0, 0 }; |             Math::Vec4<u8> color = { 0, 0, 0, 0 }; | ||||||
|  |  | ||||||
|             switch (framebuffer_format) { |             switch (framebuffer_format) { | ||||||
| @@ -224,6 +240,29 @@ void GraphicsFramebufferWidget::OnUpdate() | |||||||
|             case Format::RGBA4: |             case Format::RGBA4: | ||||||
|                 color = Color::DecodeRGBA4(pixel); |                 color = Color::DecodeRGBA4(pixel); | ||||||
|                 break; |                 break; | ||||||
|  |             case Format::D16: | ||||||
|  |             { | ||||||
|  |                 u32 data = Color::DecodeD16(pixel); | ||||||
|  |                 color.r() = data & 0xFF; | ||||||
|  |                 color.g() = (data >> 8) & 0xFF; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case Format::D24: | ||||||
|  |             { | ||||||
|  |                 u32 data = Color::DecodeD24(pixel); | ||||||
|  |                 color.r() = data & 0xFF; | ||||||
|  |                 color.g() = (data >> 8) & 0xFF; | ||||||
|  |                 color.b() = (data >> 16) & 0xFF; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case Format::D24S8: | ||||||
|  |             { | ||||||
|  |                 Math::Vec2<u32> data = Color::DecodeD24S8(pixel); | ||||||
|  |                 color.r() = data.x & 0xFF; | ||||||
|  |                 color.g() = (data.x >> 8) & 0xFF; | ||||||
|  |                 color.b() = (data.x >> 16) & 0xFF; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|             default: |             default: | ||||||
|                 qDebug() << "Unknown fb color format " << static_cast<int>(framebuffer_format); |                 qDebug() << "Unknown fb color format " << static_cast<int>(framebuffer_format); | ||||||
|                 break; |                 break; | ||||||
| @@ -240,3 +279,19 @@ void GraphicsFramebufferWidget::OnUpdate() | |||||||
|     framebuffer_format_control->setCurrentIndex(static_cast<int>(framebuffer_format)); |     framebuffer_format_control->setCurrentIndex(static_cast<int>(framebuffer_format)); | ||||||
|     framebuffer_picture_label->setPixmap(pixmap); |     framebuffer_picture_label->setPixmap(pixmap); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | u32 GraphicsFramebufferWidget::BytesPerPixel(GraphicsFramebufferWidget::Format format) { | ||||||
|  |     switch (format) { | ||||||
|  |         case Format::RGBA8: | ||||||
|  |         case Format::D24S8: | ||||||
|  |             return 4; | ||||||
|  |         case Format::RGB8: | ||||||
|  |         case Format::D24: | ||||||
|  |             return 3; | ||||||
|  |         case Format::RGB5A1: | ||||||
|  |         case Format::RGB565: | ||||||
|  |         case Format::RGBA4: | ||||||
|  |         case Format::D16: | ||||||
|  |             return 2; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -21,7 +21,8 @@ class GraphicsFramebufferWidget : public BreakPointObserverDock { | |||||||
|  |  | ||||||
|     enum class Source { |     enum class Source { | ||||||
|         PicaTarget = 0, |         PicaTarget = 0, | ||||||
|         Custom = 1, |         DepthBuffer = 1, | ||||||
|  |         Custom = 2, | ||||||
|  |  | ||||||
|         // TODO: Add GPU framebuffer sources! |         // TODO: Add GPU framebuffer sources! | ||||||
|     }; |     }; | ||||||
| @@ -32,8 +33,13 @@ class GraphicsFramebufferWidget : public BreakPointObserverDock { | |||||||
|         RGB5A1   = 2, |         RGB5A1   = 2, | ||||||
|         RGB565   = 3, |         RGB565   = 3, | ||||||
|         RGBA4    = 4, |         RGBA4    = 4, | ||||||
|  |         D16      = 5, | ||||||
|  |         D24      = 6, | ||||||
|  |         D24S8    = 7 | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     static u32 BytesPerPixel(Format format); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     GraphicsFramebufferWidget(std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent = nullptr); |     GraphicsFramebufferWidget(std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent = nullptr); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Subv
					Subv