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