diff options
Diffstat (limited to 'src/citra_qt/debugger/graphics_surface.cpp')
| -rw-r--r-- | src/citra_qt/debugger/graphics_surface.cpp | 240 |
1 files changed, 107 insertions, 133 deletions
diff --git a/src/citra_qt/debugger/graphics_surface.cpp b/src/citra_qt/debugger/graphics_surface.cpp index ac2d6f89b..906daaa50 100644 --- a/src/citra_qt/debugger/graphics_surface.cpp +++ b/src/citra_qt/debugger/graphics_surface.cpp | |||
| @@ -11,24 +11,20 @@ | |||
| 11 | #include <QPushButton> | 11 | #include <QPushButton> |
| 12 | #include <QScrollArea> | 12 | #include <QScrollArea> |
| 13 | #include <QSpinBox> | 13 | #include <QSpinBox> |
| 14 | |||
| 15 | #include "citra_qt/debugger/graphics_surface.h" | 14 | #include "citra_qt/debugger/graphics_surface.h" |
| 16 | #include "citra_qt/util/spinbox.h" | 15 | #include "citra_qt/util/spinbox.h" |
| 17 | |||
| 18 | #include "common/color.h" | 16 | #include "common/color.h" |
| 19 | |||
| 20 | #include "core/memory.h" | ||
| 21 | #include "core/hw/gpu.h" | 17 | #include "core/hw/gpu.h" |
| 22 | 18 | #include "core/memory.h" | |
| 23 | #include "video_core/pica.h" | 19 | #include "video_core/pica.h" |
| 24 | #include "video_core/pica_state.h" | 20 | #include "video_core/pica_state.h" |
| 25 | #include "video_core/utils.h" | 21 | #include "video_core/utils.h" |
| 26 | 22 | ||
| 27 | SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) : QLabel(parent), surface_widget(surface_widget_) {} | 23 | SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) |
| 24 | : QLabel(parent), surface_widget(surface_widget_) {} | ||
| 28 | SurfacePicture::~SurfacePicture() {} | 25 | SurfacePicture::~SurfacePicture() {} |
| 29 | 26 | ||
| 30 | void SurfacePicture::mousePressEvent(QMouseEvent* event) | 27 | void SurfacePicture::mousePressEvent(QMouseEvent* event) { |
| 31 | { | ||
| 32 | // Only do something while the left mouse button is held down | 28 | // Only do something while the left mouse button is held down |
| 33 | if (!(event->buttons() & Qt::LeftButton)) | 29 | if (!(event->buttons() & Qt::LeftButton)) |
| 34 | return; | 30 | return; |
| @@ -41,18 +37,15 @@ void SurfacePicture::mousePressEvent(QMouseEvent* event) | |||
| 41 | event->y() * pixmap()->height() / height()); | 37 | event->y() * pixmap()->height() / height()); |
| 42 | } | 38 | } |
| 43 | 39 | ||
| 44 | void SurfacePicture::mouseMoveEvent(QMouseEvent* event) | 40 | void SurfacePicture::mouseMoveEvent(QMouseEvent* event) { |
| 45 | { | ||
| 46 | // We also want to handle the event if the user moves the mouse while holding down the LMB | 41 | // We also want to handle the event if the user moves the mouse while holding down the LMB |
| 47 | mousePressEvent(event); | 42 | mousePressEvent(event); |
| 48 | } | 43 | } |
| 49 | 44 | ||
| 50 | |||
| 51 | GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, | 45 | GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, |
| 52 | QWidget* parent) | 46 | QWidget* parent) |
| 53 | : BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent), | 47 | : BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent), |
| 54 | surface_source(Source::ColorBuffer) | 48 | surface_source(Source::ColorBuffer) { |
| 55 | { | ||
| 56 | setObjectName("PicaSurface"); | 49 | setObjectName("PicaSurface"); |
| 57 | 50 | ||
| 58 | surface_source_list = new QComboBox; | 51 | surface_source_list = new QComboBox; |
| @@ -124,13 +117,20 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> | |||
| 124 | 117 | ||
| 125 | // Connections | 118 | // Connections |
| 126 | connect(this, SIGNAL(Update()), this, SLOT(OnUpdate())); | 119 | connect(this, SIGNAL(Update()), this, SLOT(OnUpdate())); |
| 127 | connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSurfaceSourceChanged(int))); | 120 | connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, |
| 128 | connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, SLOT(OnSurfaceAddressChanged(qint64))); | 121 | SLOT(OnSurfaceSourceChanged(int))); |
| 129 | connect(surface_width_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfaceWidthChanged(int))); | 122 | connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, |
| 130 | connect(surface_height_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfaceHeightChanged(int))); | 123 | SLOT(OnSurfaceAddressChanged(qint64))); |
| 131 | connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSurfaceFormatChanged(int))); | 124 | connect(surface_width_control, SIGNAL(valueChanged(int)), this, |
| 132 | connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfacePickerXChanged(int))); | 125 | SLOT(OnSurfaceWidthChanged(int))); |
| 133 | connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfacePickerYChanged(int))); | 126 | connect(surface_height_control, SIGNAL(valueChanged(int)), this, |
| 127 | SLOT(OnSurfaceHeightChanged(int))); | ||
| 128 | connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, | ||
| 129 | SLOT(OnSurfaceFormatChanged(int))); | ||
| 130 | connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, | ||
| 131 | SLOT(OnSurfacePickerXChanged(int))); | ||
| 132 | connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, | ||
| 133 | SLOT(OnSurfacePickerYChanged(int))); | ||
| 134 | connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface())); | 134 | connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface())); |
| 135 | 135 | ||
| 136 | auto main_widget = new QWidget; | 136 | auto main_widget = new QWidget; |
| @@ -203,25 +203,21 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> | |||
| 203 | } | 203 | } |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | void GraphicsSurfaceWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data) | 206 | void GraphicsSurfaceWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data) { |
| 207 | { | ||
| 208 | emit Update(); | 207 | emit Update(); |
| 209 | widget()->setEnabled(true); | 208 | widget()->setEnabled(true); |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | void GraphicsSurfaceWidget::OnResumed() | 211 | void GraphicsSurfaceWidget::OnResumed() { |
| 213 | { | ||
| 214 | widget()->setEnabled(false); | 212 | widget()->setEnabled(false); |
| 215 | } | 213 | } |
| 216 | 214 | ||
| 217 | void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) | 215 | void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) { |
| 218 | { | ||
| 219 | surface_source = static_cast<Source>(new_value); | 216 | surface_source = static_cast<Source>(new_value); |
| 220 | emit Update(); | 217 | emit Update(); |
| 221 | } | 218 | } |
| 222 | 219 | ||
| 223 | void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) | 220 | void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) { |
| 224 | { | ||
| 225 | if (surface_address != new_value) { | 221 | if (surface_address != new_value) { |
| 226 | surface_address = static_cast<unsigned>(new_value); | 222 | surface_address = static_cast<unsigned>(new_value); |
| 227 | 223 | ||
| @@ -230,8 +226,7 @@ void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) | |||
| 230 | } | 226 | } |
| 231 | } | 227 | } |
| 232 | 228 | ||
| 233 | void GraphicsSurfaceWidget::OnSurfaceWidthChanged(int new_value) | 229 | void GraphicsSurfaceWidget::OnSurfaceWidthChanged(int new_value) { |
| 234 | { | ||
| 235 | if (surface_width != static_cast<unsigned>(new_value)) { | 230 | if (surface_width != static_cast<unsigned>(new_value)) { |
| 236 | surface_width = static_cast<unsigned>(new_value); | 231 | surface_width = static_cast<unsigned>(new_value); |
| 237 | 232 | ||
| @@ -240,8 +235,7 @@ void GraphicsSurfaceWidget::OnSurfaceWidthChanged(int new_value) | |||
| 240 | } | 235 | } |
| 241 | } | 236 | } |
| 242 | 237 | ||
| 243 | void GraphicsSurfaceWidget::OnSurfaceHeightChanged(int new_value) | 238 | void GraphicsSurfaceWidget::OnSurfaceHeightChanged(int new_value) { |
| 244 | { | ||
| 245 | if (surface_height != static_cast<unsigned>(new_value)) { | 239 | if (surface_height != static_cast<unsigned>(new_value)) { |
| 246 | surface_height = static_cast<unsigned>(new_value); | 240 | surface_height = static_cast<unsigned>(new_value); |
| 247 | 241 | ||
| @@ -250,8 +244,7 @@ void GraphicsSurfaceWidget::OnSurfaceHeightChanged(int new_value) | |||
| 250 | } | 244 | } |
| 251 | } | 245 | } |
| 252 | 246 | ||
| 253 | void GraphicsSurfaceWidget::OnSurfaceFormatChanged(int new_value) | 247 | void GraphicsSurfaceWidget::OnSurfaceFormatChanged(int new_value) { |
| 254 | { | ||
| 255 | if (surface_format != static_cast<Format>(new_value)) { | 248 | if (surface_format != static_cast<Format>(new_value)) { |
| 256 | surface_format = static_cast<Format>(new_value); | 249 | surface_format = static_cast<Format>(new_value); |
| 257 | 250 | ||
| @@ -260,24 +253,21 @@ void GraphicsSurfaceWidget::OnSurfaceFormatChanged(int new_value) | |||
| 260 | } | 253 | } |
| 261 | } | 254 | } |
| 262 | 255 | ||
| 263 | void GraphicsSurfaceWidget::OnSurfacePickerXChanged(int new_value) | 256 | void GraphicsSurfaceWidget::OnSurfacePickerXChanged(int new_value) { |
| 264 | { | ||
| 265 | if (surface_picker_x != new_value) { | 257 | if (surface_picker_x != new_value) { |
| 266 | surface_picker_x = new_value; | 258 | surface_picker_x = new_value; |
| 267 | Pick(surface_picker_x, surface_picker_y); | 259 | Pick(surface_picker_x, surface_picker_y); |
| 268 | } | 260 | } |
| 269 | } | 261 | } |
| 270 | 262 | ||
| 271 | void GraphicsSurfaceWidget::OnSurfacePickerYChanged(int new_value) | 263 | void GraphicsSurfaceWidget::OnSurfacePickerYChanged(int new_value) { |
| 272 | { | ||
| 273 | if (surface_picker_y != new_value) { | 264 | if (surface_picker_y != new_value) { |
| 274 | surface_picker_y = new_value; | 265 | surface_picker_y = new_value; |
| 275 | Pick(surface_picker_x, surface_picker_y); | 266 | Pick(surface_picker_x, surface_picker_y); |
| 276 | } | 267 | } |
| 277 | } | 268 | } |
| 278 | 269 | ||
| 279 | void GraphicsSurfaceWidget::Pick(int x, int y) | 270 | void GraphicsSurfaceWidget::Pick(int x, int y) { |
| 280 | { | ||
| 281 | surface_picker_x_control->setValue(x); | 271 | surface_picker_x_control->setValue(x); |
| 282 | surface_picker_y_control->setValue(y); | 272 | surface_picker_y_control->setValue(y); |
| 283 | 273 | ||
| @@ -312,74 +302,63 @@ void GraphicsSurfaceWidget::Pick(int x, int y) | |||
| 312 | 302 | ||
| 313 | auto GetText = [offset](Format format, const u8* pixel) { | 303 | auto GetText = [offset](Format format, const u8* pixel) { |
| 314 | switch (format) { | 304 | switch (format) { |
| 315 | case Format::RGBA8: | 305 | case Format::RGBA8: { |
| 316 | { | ||
| 317 | auto value = Color::DecodeRGBA8(pixel) / 255.0f; | 306 | auto value = Color::DecodeRGBA8(pixel) / 255.0f; |
| 318 | return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") | 307 | return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") |
| 319 | .arg(QString::number(value.r(), 'f', 2)) | 308 | .arg(QString::number(value.r(), 'f', 2)) |
| 320 | .arg(QString::number(value.g(), 'f', 2)) | 309 | .arg(QString::number(value.g(), 'f', 2)) |
| 321 | .arg(QString::number(value.b(), 'f', 2)) | 310 | .arg(QString::number(value.b(), 'f', 2)) |
| 322 | .arg(QString::number(value.a(), 'f', 2)); | 311 | .arg(QString::number(value.a(), 'f', 2)); |
| 323 | } | 312 | } |
| 324 | case Format::RGB8: | 313 | case Format::RGB8: { |
| 325 | { | ||
| 326 | auto value = Color::DecodeRGB8(pixel) / 255.0f; | 314 | auto value = Color::DecodeRGB8(pixel) / 255.0f; |
| 327 | return QString("Red: %1, Green: %2, Blue: %3") | 315 | return QString("Red: %1, Green: %2, Blue: %3") |
| 328 | .arg(QString::number(value.r(), 'f', 2)) | 316 | .arg(QString::number(value.r(), 'f', 2)) |
| 329 | .arg(QString::number(value.g(), 'f', 2)) | 317 | .arg(QString::number(value.g(), 'f', 2)) |
| 330 | .arg(QString::number(value.b(), 'f', 2)); | 318 | .arg(QString::number(value.b(), 'f', 2)); |
| 331 | } | 319 | } |
| 332 | case Format::RGB5A1: | 320 | case Format::RGB5A1: { |
| 333 | { | ||
| 334 | auto value = Color::DecodeRGB5A1(pixel) / 255.0f; | 321 | auto value = Color::DecodeRGB5A1(pixel) / 255.0f; |
| 335 | return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") | 322 | return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") |
| 336 | .arg(QString::number(value.r(), 'f', 2)) | 323 | .arg(QString::number(value.r(), 'f', 2)) |
| 337 | .arg(QString::number(value.g(), 'f', 2)) | 324 | .arg(QString::number(value.g(), 'f', 2)) |
| 338 | .arg(QString::number(value.b(), 'f', 2)) | 325 | .arg(QString::number(value.b(), 'f', 2)) |
| 339 | .arg(QString::number(value.a(), 'f', 2)); | 326 | .arg(QString::number(value.a(), 'f', 2)); |
| 340 | } | 327 | } |
| 341 | case Format::RGB565: | 328 | case Format::RGB565: { |
| 342 | { | ||
| 343 | auto value = Color::DecodeRGB565(pixel) / 255.0f; | 329 | auto value = Color::DecodeRGB565(pixel) / 255.0f; |
| 344 | return QString("Red: %1, Green: %2, Blue: %3") | 330 | return QString("Red: %1, Green: %2, Blue: %3") |
| 345 | .arg(QString::number(value.r(), 'f', 2)) | 331 | .arg(QString::number(value.r(), 'f', 2)) |
| 346 | .arg(QString::number(value.g(), 'f', 2)) | 332 | .arg(QString::number(value.g(), 'f', 2)) |
| 347 | .arg(QString::number(value.b(), 'f', 2)); | 333 | .arg(QString::number(value.b(), 'f', 2)); |
| 348 | } | 334 | } |
| 349 | case Format::RGBA4: | 335 | case Format::RGBA4: { |
| 350 | { | ||
| 351 | auto value = Color::DecodeRGBA4(pixel) / 255.0f; | 336 | auto value = Color::DecodeRGBA4(pixel) / 255.0f; |
| 352 | return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") | 337 | return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") |
| 353 | .arg(QString::number(value.r(), 'f', 2)) | 338 | .arg(QString::number(value.r(), 'f', 2)) |
| 354 | .arg(QString::number(value.g(), 'f', 2)) | 339 | .arg(QString::number(value.g(), 'f', 2)) |
| 355 | .arg(QString::number(value.b(), 'f', 2)) | 340 | .arg(QString::number(value.b(), 'f', 2)) |
| 356 | .arg(QString::number(value.a(), 'f', 2)); | 341 | .arg(QString::number(value.a(), 'f', 2)); |
| 357 | } | 342 | } |
| 358 | case Format::IA8: | 343 | case Format::IA8: |
| 359 | return QString("Index: %1, Alpha: %2") | 344 | return QString("Index: %1, Alpha: %2").arg(pixel[0]).arg(pixel[1]); |
| 360 | .arg(pixel[0]) | ||
| 361 | .arg(pixel[1]); | ||
| 362 | case Format::RG8: { | 345 | case Format::RG8: { |
| 363 | auto value = Color::DecodeRG8(pixel) / 255.0f; | 346 | auto value = Color::DecodeRG8(pixel) / 255.0f; |
| 364 | return QString("Red: %1, Green: %2") | 347 | return QString("Red: %1, Green: %2") |
| 365 | .arg(QString::number(value.r(), 'f', 2)) | 348 | .arg(QString::number(value.r(), 'f', 2)) |
| 366 | .arg(QString::number(value.g(), 'f', 2)); | 349 | .arg(QString::number(value.g(), 'f', 2)); |
| 367 | } | 350 | } |
| 368 | case Format::I8: | 351 | case Format::I8: |
| 369 | return QString("Index: %1").arg(*pixel); | 352 | return QString("Index: %1").arg(*pixel); |
| 370 | case Format::A8: | 353 | case Format::A8: |
| 371 | return QString("Alpha: %1").arg(QString::number(*pixel / 255.0f, 'f', 2)); | 354 | return QString("Alpha: %1").arg(QString::number(*pixel / 255.0f, 'f', 2)); |
| 372 | case Format::IA4: | 355 | case Format::IA4: |
| 373 | return QString("Index: %1, Alpha: %2") | 356 | return QString("Index: %1, Alpha: %2").arg(*pixel & 0xF).arg((*pixel & 0xF0) >> 4); |
| 374 | .arg(*pixel & 0xF) | 357 | case Format::I4: { |
| 375 | .arg((*pixel & 0xF0) >> 4); | ||
| 376 | case Format::I4: | ||
| 377 | { | ||
| 378 | u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; | 358 | u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; |
| 379 | return QString("Index: %1").arg(i); | 359 | return QString("Index: %1").arg(i); |
| 380 | } | 360 | } |
| 381 | case Format::A4: | 361 | case Format::A4: { |
| 382 | { | ||
| 383 | u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; | 362 | u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; |
| 384 | return QString("Alpha: %1").arg(QString::number(a / 15.0f, 'f', 2)); | 363 | return QString("Alpha: %1").arg(QString::number(a / 15.0f, 'f', 2)); |
| 385 | } | 364 | } |
| @@ -387,21 +366,20 @@ void GraphicsSurfaceWidget::Pick(int x, int y) | |||
| 387 | case Format::ETC1A4: | 366 | case Format::ETC1A4: |
| 388 | // TODO: Display block information or channel values? | 367 | // TODO: Display block information or channel values? |
| 389 | return QString("Compressed data"); | 368 | return QString("Compressed data"); |
| 390 | case Format::D16: | 369 | case Format::D16: { |
| 391 | { | ||
| 392 | auto value = Color::DecodeD16(pixel); | 370 | auto value = Color::DecodeD16(pixel); |
| 393 | return QString("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4)); | 371 | return QString("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4)); |
| 394 | } | 372 | } |
| 395 | case Format::D24: | 373 | case Format::D24: { |
| 396 | { | ||
| 397 | auto value = Color::DecodeD24(pixel); | 374 | auto value = Color::DecodeD24(pixel); |
| 398 | return QString("Depth: %1").arg(QString::number(value / (float)0xFFFFFF, 'f', 4)); | 375 | return QString("Depth: %1").arg(QString::number(value / (float)0xFFFFFF, 'f', 4)); |
| 399 | } | 376 | } |
| 400 | case Format::D24X8: | 377 | case Format::D24X8: |
| 401 | case Format::X24S8: | 378 | case Format::X24S8: { |
| 402 | { | ||
| 403 | auto values = Color::DecodeD24S8(pixel); | 379 | auto values = Color::DecodeD24S8(pixel); |
| 404 | return QString("Depth: %1, Stencil: %2").arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4)).arg(values[1]); | 380 | return QString("Depth: %1, Stencil: %2") |
| 381 | .arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4)) | ||
| 382 | .arg(values[1]); | ||
| 405 | } | 383 | } |
| 406 | case Format::Unknown: | 384 | case Format::Unknown: |
| 407 | return QString("Unknown format"); | 385 | return QString("Unknown format"); |
| @@ -422,18 +400,18 @@ void GraphicsSurfaceWidget::Pick(int x, int y) | |||
| 422 | nibbles.append(QString::number(nibble, 16).toUpper()); | 400 | nibbles.append(QString::number(nibble, 16).toUpper()); |
| 423 | } | 401 | } |
| 424 | 402 | ||
| 425 | surface_info_label->setText(QString("Raw: 0x%3\n(%4)").arg(nibbles).arg(GetText(surface_format, pixel))); | 403 | surface_info_label->setText( |
| 404 | QString("Raw: 0x%3\n(%4)").arg(nibbles).arg(GetText(surface_format, pixel))); | ||
| 426 | surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); | 405 | surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); |
| 427 | } | 406 | } |
| 428 | 407 | ||
| 429 | void GraphicsSurfaceWidget::OnUpdate() | 408 | void GraphicsSurfaceWidget::OnUpdate() { |
| 430 | { | ||
| 431 | QPixmap pixmap; | 409 | QPixmap pixmap; |
| 432 | 410 | ||
| 433 | switch (surface_source) { | 411 | switch (surface_source) { |
| 434 | case Source::ColorBuffer: | 412 | case Source::ColorBuffer: { |
| 435 | { | 413 | // TODO: Store a reference to the registers in the debug context instead of accessing them |
| 436 | // TODO: Store a reference to the registers in the debug context instead of accessing them directly... | 414 | // directly... |
| 437 | 415 | ||
| 438 | const auto& framebuffer = Pica::g_state.regs.framebuffer; | 416 | const auto& framebuffer = Pica::g_state.regs.framebuffer; |
| 439 | 417 | ||
| @@ -470,8 +448,7 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 470 | break; | 448 | break; |
| 471 | } | 449 | } |
| 472 | 450 | ||
| 473 | case Source::DepthBuffer: | 451 | case Source::DepthBuffer: { |
| 474 | { | ||
| 475 | const auto& framebuffer = Pica::g_state.regs.framebuffer; | 452 | const auto& framebuffer = Pica::g_state.regs.framebuffer; |
| 476 | 453 | ||
| 477 | surface_address = framebuffer.GetDepthBufferPhysicalAddress(); | 454 | surface_address = framebuffer.GetDepthBufferPhysicalAddress(); |
| @@ -499,8 +476,7 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 499 | break; | 476 | break; |
| 500 | } | 477 | } |
| 501 | 478 | ||
| 502 | case Source::StencilBuffer: | 479 | case Source::StencilBuffer: { |
| 503 | { | ||
| 504 | const auto& framebuffer = Pica::g_state.regs.framebuffer; | 480 | const auto& framebuffer = Pica::g_state.regs.framebuffer; |
| 505 | 481 | ||
| 506 | surface_address = framebuffer.GetDepthBufferPhysicalAddress(); | 482 | surface_address = framebuffer.GetDepthBufferPhysicalAddress(); |
| @@ -522,12 +498,14 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 522 | 498 | ||
| 523 | case Source::Texture0: | 499 | case Source::Texture0: |
| 524 | case Source::Texture1: | 500 | case Source::Texture1: |
| 525 | case Source::Texture2: | 501 | case Source::Texture2: { |
| 526 | { | ||
| 527 | unsigned texture_index; | 502 | unsigned texture_index; |
| 528 | if (surface_source == Source::Texture0) texture_index = 0; | 503 | if (surface_source == Source::Texture0) |
| 529 | else if (surface_source == Source::Texture1) texture_index = 1; | 504 | texture_index = 0; |
| 530 | else if (surface_source == Source::Texture2) texture_index = 2; | 505 | else if (surface_source == Source::Texture1) |
| 506 | texture_index = 1; | ||
| 507 | else if (surface_source == Source::Texture2) | ||
| 508 | texture_index = 2; | ||
| 531 | else { | 509 | else { |
| 532 | qDebug() << "Unknown texture source " << static_cast<int>(surface_source); | 510 | qDebug() << "Unknown texture source " << static_cast<int>(surface_source); |
| 533 | break; | 511 | break; |
| @@ -547,8 +525,7 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 547 | break; | 525 | break; |
| 548 | } | 526 | } |
| 549 | 527 | ||
| 550 | case Source::Custom: | 528 | case Source::Custom: { |
| 551 | { | ||
| 552 | // Keep user-specified values | 529 | // Keep user-specified values |
| 553 | break; | 530 | break; |
| 554 | } | 531 | } |
| @@ -613,7 +590,8 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 613 | 590 | ||
| 614 | } else { | 591 | } else { |
| 615 | 592 | ||
| 616 | ASSERT_MSG(nibbles_per_pixel >= 2, "Depth decoder only supports formats with at least one byte per pixel"); | 593 | ASSERT_MSG(nibbles_per_pixel >= 2, |
| 594 | "Depth decoder only supports formats with at least one byte per pixel"); | ||
| 617 | unsigned bytes_per_pixel = nibbles_per_pixel / 2; | 595 | unsigned bytes_per_pixel = nibbles_per_pixel / 2; |
| 618 | 596 | ||
| 619 | for (unsigned int y = 0; y < surface_height; ++y) { | 597 | for (unsigned int y = 0; y < surface_height; ++y) { |
| @@ -621,34 +599,30 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 621 | const u32 coarse_y = y & ~7; | 599 | const u32 coarse_y = y & ~7; |
| 622 | u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride; | 600 | u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride; |
| 623 | const u8* pixel = buffer + offset; | 601 | const u8* pixel = buffer + offset; |
| 624 | Math::Vec4<u8> color = { 0, 0, 0, 0 }; | 602 | Math::Vec4<u8> color = {0, 0, 0, 0}; |
| 625 | 603 | ||
| 626 | switch(surface_format) { | 604 | switch (surface_format) { |
| 627 | case Format::D16: | 605 | case Format::D16: { |
| 628 | { | ||
| 629 | u32 data = Color::DecodeD16(pixel); | 606 | u32 data = Color::DecodeD16(pixel); |
| 630 | color.r() = data & 0xFF; | 607 | color.r() = data & 0xFF; |
| 631 | color.g() = (data >> 8) & 0xFF; | 608 | color.g() = (data >> 8) & 0xFF; |
| 632 | break; | 609 | break; |
| 633 | } | 610 | } |
| 634 | case Format::D24: | 611 | case Format::D24: { |
| 635 | { | ||
| 636 | u32 data = Color::DecodeD24(pixel); | 612 | u32 data = Color::DecodeD24(pixel); |
| 637 | color.r() = data & 0xFF; | 613 | color.r() = data & 0xFF; |
| 638 | color.g() = (data >> 8) & 0xFF; | 614 | color.g() = (data >> 8) & 0xFF; |
| 639 | color.b() = (data >> 16) & 0xFF; | 615 | color.b() = (data >> 16) & 0xFF; |
| 640 | break; | 616 | break; |
| 641 | } | 617 | } |
| 642 | case Format::D24X8: | 618 | case Format::D24X8: { |
| 643 | { | ||
| 644 | Math::Vec2<u32> data = Color::DecodeD24S8(pixel); | 619 | Math::Vec2<u32> data = Color::DecodeD24S8(pixel); |
| 645 | color.r() = data.x & 0xFF; | 620 | color.r() = data.x & 0xFF; |
| 646 | color.g() = (data.x >> 8) & 0xFF; | 621 | color.g() = (data.x >> 8) & 0xFF; |
| 647 | color.b() = (data.x >> 16) & 0xFF; | 622 | color.b() = (data.x >> 16) & 0xFF; |
| 648 | break; | 623 | break; |
| 649 | } | 624 | } |
| 650 | case Format::X24S8: | 625 | case Format::X24S8: { |
| 651 | { | ||
| 652 | Math::Vec2<u32> data = Color::DecodeD24S8(pixel); | 626 | Math::Vec2<u32> data = Color::DecodeD24S8(pixel); |
| 653 | color.r() = color.g() = color.b() = data.y; | 627 | color.r() = color.g() = color.b() = data.y; |
| 654 | break; | 628 | break; |
| @@ -661,7 +635,6 @@ void GraphicsSurfaceWidget::OnUpdate() | |||
| 661 | decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), 255)); | 635 | decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), 255)); |
| 662 | } | 636 | } |
| 663 | } | 637 | } |
| 664 | |||
| 665 | } | 638 | } |
| 666 | 639 | ||
| 667 | pixmap = QPixmap::fromImage(decoded_image); | 640 | pixmap = QPixmap::fromImage(decoded_image); |
| @@ -682,8 +655,10 @@ void GraphicsSurfaceWidget::SaveSurface() { | |||
| 682 | QString bin_filter = tr("Binary data (*.bin)"); | 655 | QString bin_filter = tr("Binary data (*.bin)"); |
| 683 | 656 | ||
| 684 | QString selectedFilter; | 657 | QString selectedFilter; |
| 685 | QString filename = QFileDialog::getSaveFileName(this, tr("Save Surface"), QString("texture-0x%1.png").arg(QString::number(surface_address, 16)), | 658 | QString filename = QFileDialog::getSaveFileName( |
| 686 | QString("%1;;%2").arg(png_filter, bin_filter), &selectedFilter); | 659 | this, tr("Save Surface"), |
| 660 | QString("texture-0x%1.png").arg(QString::number(surface_address, 16)), | ||
| 661 | QString("%1;;%2").arg(png_filter, bin_filter), &selectedFilter); | ||
| 687 | 662 | ||
| 688 | if (filename.isEmpty()) { | 663 | if (filename.isEmpty()) { |
| 689 | // If the user canceled the dialog, don't save anything. | 664 | // If the user canceled the dialog, don't save anything. |
| @@ -718,19 +693,18 @@ unsigned int GraphicsSurfaceWidget::NibblesPerPixel(GraphicsSurfaceWidget::Forma | |||
| 718 | } | 693 | } |
| 719 | 694 | ||
| 720 | switch (format) { | 695 | switch (format) { |
| 721 | case Format::D24X8: | 696 | case Format::D24X8: |
| 722 | case Format::X24S8: | 697 | case Format::X24S8: |
| 723 | return 4 * 2; | 698 | return 4 * 2; |
| 724 | case Format::D24: | 699 | case Format::D24: |
| 725 | return 3 * 2; | 700 | return 3 * 2; |
| 726 | case Format::D16: | 701 | case Format::D16: |
| 727 | return 2 * 2; | 702 | return 2 * 2; |
| 728 | default: | 703 | default: |
| 729 | UNREACHABLE_MSG("GraphicsSurfaceWidget::BytesPerPixel: this " | 704 | UNREACHABLE_MSG("GraphicsSurfaceWidget::BytesPerPixel: this should not be reached as this " |
| 730 | "should not be reached as this function should " | 705 | "function should be given a format which is in " |
| 731 | "be given a format which is in " | 706 | "GraphicsSurfaceWidget::Format. Instead got %i", |
| 732 | "GraphicsSurfaceWidget::Format. Instead got %i", | 707 | static_cast<int>(format)); |
| 733 | static_cast<int>(format)); | 708 | return 0; |
| 734 | return 0; | ||
| 735 | } | 709 | } |
| 736 | } | 710 | } |