diff options
Diffstat (limited to 'src/citra_qt/debugger')
| -rw-r--r-- | src/citra_qt/debugger/callstack.cpp | 4 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_breakpoints.cpp | 14 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_cmdlists.cpp | 56 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_framebuffer.cpp | 23 |
4 files changed, 66 insertions, 31 deletions
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp index 895851be3..a9ec2f7fe 100644 --- a/src/citra_qt/debugger/callstack.cpp +++ b/src/citra_qt/debugger/callstack.cpp | |||
| @@ -27,10 +27,10 @@ void CallstackWidget::OnCPUStepped() | |||
| 27 | ARM_Interface* app_core = Core::g_app_core; | 27 | ARM_Interface* app_core = Core::g_app_core; |
| 28 | 28 | ||
| 29 | u32 sp = app_core->GetReg(13); //stack pointer | 29 | u32 sp = app_core->GetReg(13); //stack pointer |
| 30 | u32 addr, ret_addr, call_addr, func_addr; | 30 | u32 ret_addr, call_addr, func_addr; |
| 31 | 31 | ||
| 32 | int counter = 0; | 32 | int counter = 0; |
| 33 | for (int addr = 0x10000000; addr >= sp; addr -= 4) | 33 | for (u32 addr = 0x10000000; addr >= sp; addr -= 4) |
| 34 | { | 34 | { |
| 35 | ret_addr = Memory::Read32(addr); | 35 | ret_addr = Memory::Read32(addr); |
| 36 | call_addr = ret_addr - 4; //get call address??? | 36 | call_addr = ret_addr - 4; //get call address??? |
diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics_breakpoints.cpp index e391f895b..9486f06cc 100644 --- a/src/citra_qt/debugger/graphics_breakpoints.cpp +++ b/src/citra_qt/debugger/graphics_breakpoints.cpp | |||
| @@ -39,15 +39,17 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const | |||
| 39 | switch (index.column()) { | 39 | switch (index.column()) { |
| 40 | case 0: | 40 | case 0: |
| 41 | { | 41 | { |
| 42 | std::map<Pica::DebugContext::Event, QString> map; | 42 | static const std::map<Pica::DebugContext::Event, QString> map = { |
| 43 | map.insert({Pica::DebugContext::Event::CommandLoaded, tr("Pica command loaded")}); | 43 | { Pica::DebugContext::Event::CommandLoaded, tr("Pica command loaded") }, |
| 44 | map.insert({Pica::DebugContext::Event::CommandProcessed, tr("Pica command processed")}); | 44 | { Pica::DebugContext::Event::CommandProcessed, tr("Pica command processed") }, |
| 45 | map.insert({Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch")}); | 45 | { Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch") }, |
| 46 | map.insert({Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch")}); | 46 | { Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch") }, |
| 47 | { Pica::DebugContext::Event::VertexLoaded, tr("Vertex Loaded") } | ||
| 48 | }; | ||
| 47 | 49 | ||
| 48 | _dbg_assert_(Debug_GPU, map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents)); | 50 | _dbg_assert_(Debug_GPU, map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents)); |
| 49 | 51 | ||
| 50 | return map[event]; | 52 | return (map.find(event) != map.end()) ? map.at(event) : QString(); |
| 51 | } | 53 | } |
| 52 | 54 | ||
| 53 | case 1: | 55 | case 1: |
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index 83102c647..753cc25da 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp | |||
| @@ -24,7 +24,7 @@ QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { | |||
| 24 | QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); | 24 | QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); |
| 25 | for (int y = 0; y < info.height; ++y) { | 25 | for (int y = 0; y < info.height; ++y) { |
| 26 | for (int x = 0; x < info.width; ++x) { | 26 | for (int x = 0; x < info.width; ++x) { |
| 27 | Math::Vec4<u8> color = Pica::DebugUtils::LookupTexture(src, x, y, info); | 27 | Math::Vec4<u8> color = Pica::DebugUtils::LookupTexture(src, x, y, info, true); |
| 28 | decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); | 28 | decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); |
| 29 | } | 29 | } |
| 30 | } | 30 | } |
| @@ -47,7 +47,7 @@ public: | |||
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo& info, QWidget* parent) | 49 | TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo& info, QWidget* parent) |
| 50 | : QDockWidget(tr("Texture 0x%1").arg(info.address, 8, 16, QLatin1Char('0'))), | 50 | : QDockWidget(tr("Texture 0x%1").arg(info.physical_address, 8, 16, QLatin1Char('0'))), |
| 51 | info(info) { | 51 | info(info) { |
| 52 | 52 | ||
| 53 | QWidget* main_widget = new QWidget; | 53 | QWidget* main_widget = new QWidget; |
| @@ -60,7 +60,7 @@ TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo | |||
| 60 | phys_address_spinbox->SetBase(16); | 60 | phys_address_spinbox->SetBase(16); |
| 61 | phys_address_spinbox->SetRange(0, 0xFFFFFFFF); | 61 | phys_address_spinbox->SetRange(0, 0xFFFFFFFF); |
| 62 | phys_address_spinbox->SetPrefix("0x"); | 62 | phys_address_spinbox->SetPrefix("0x"); |
| 63 | phys_address_spinbox->SetValue(info.address); | 63 | phys_address_spinbox->SetValue(info.physical_address); |
| 64 | connect(phys_address_spinbox, SIGNAL(ValueChanged(qint64)), this, SLOT(OnAddressChanged(qint64))); | 64 | connect(phys_address_spinbox, SIGNAL(ValueChanged(qint64)), this, SLOT(OnAddressChanged(qint64))); |
| 65 | 65 | ||
| 66 | QComboBox* format_choice = new QComboBox; | 66 | QComboBox* format_choice = new QComboBox; |
| @@ -69,6 +69,13 @@ TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo | |||
| 69 | format_choice->addItem(tr("RGBA5551")); | 69 | format_choice->addItem(tr("RGBA5551")); |
| 70 | format_choice->addItem(tr("RGB565")); | 70 | format_choice->addItem(tr("RGB565")); |
| 71 | format_choice->addItem(tr("RGBA4")); | 71 | format_choice->addItem(tr("RGBA4")); |
| 72 | format_choice->addItem(tr("IA8")); | ||
| 73 | format_choice->addItem(tr("UNK6")); | ||
| 74 | format_choice->addItem(tr("I8")); | ||
| 75 | format_choice->addItem(tr("A8")); | ||
| 76 | format_choice->addItem(tr("IA4")); | ||
| 77 | format_choice->addItem(tr("UNK10")); | ||
| 78 | format_choice->addItem(tr("A4")); | ||
| 72 | format_choice->setCurrentIndex(static_cast<int>(info.format)); | 79 | format_choice->setCurrentIndex(static_cast<int>(info.format)); |
| 73 | connect(format_choice, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormatChanged(int))); | 80 | connect(format_choice, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormatChanged(int))); |
| 74 | 81 | ||
| @@ -125,7 +132,7 @@ TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo | |||
| 125 | } | 132 | } |
| 126 | 133 | ||
| 127 | void TextureInfoDockWidget::OnAddressChanged(qint64 value) { | 134 | void TextureInfoDockWidget::OnAddressChanged(qint64 value) { |
| 128 | info.address = value; | 135 | info.physical_address = value; |
| 129 | emit UpdatePixmap(ReloadPixmap()); | 136 | emit UpdatePixmap(ReloadPixmap()); |
| 130 | } | 137 | } |
| 131 | 138 | ||
| @@ -150,7 +157,7 @@ void TextureInfoDockWidget::OnStrideChanged(int value) { | |||
| 150 | } | 157 | } |
| 151 | 158 | ||
| 152 | QPixmap TextureInfoDockWidget::ReloadPixmap() const { | 159 | QPixmap TextureInfoDockWidget::ReloadPixmap() const { |
| 153 | u8* src = Memory::GetPointer(info.address); | 160 | u8* src = Memory::GetPointer(Pica::PAddrToVAddr(info.physical_address)); |
| 154 | return QPixmap::fromImage(LoadTexture(src, info)); | 161 | return QPixmap::fromImage(LoadTexture(src, info)); |
| 155 | } | 162 | } |
| 156 | 163 | ||
| @@ -223,9 +230,21 @@ void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace& | |||
| 223 | 230 | ||
| 224 | void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { | 231 | void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { |
| 225 | const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); | 232 | const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); |
| 226 | if (COMMAND_IN_RANGE(command_id, texture0)) { | 233 | if (COMMAND_IN_RANGE(command_id, texture0) || |
| 227 | auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(Pica::registers.texture0, | 234 | COMMAND_IN_RANGE(command_id, texture1) || |
| 228 | Pica::registers.texture0_format); | 235 | COMMAND_IN_RANGE(command_id, texture2)) { |
| 236 | |||
| 237 | unsigned index; | ||
| 238 | if (COMMAND_IN_RANGE(command_id, texture0)) { | ||
| 239 | index = 0; | ||
| 240 | } else if (COMMAND_IN_RANGE(command_id, texture1)) { | ||
| 241 | index = 1; | ||
| 242 | } else { | ||
| 243 | index = 2; | ||
| 244 | } | ||
| 245 | auto config = Pica::registers.GetTextures()[index].config; | ||
| 246 | auto format = Pica::registers.GetTextures()[index].format; | ||
| 247 | auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); | ||
| 229 | 248 | ||
| 230 | // TODO: Instead, emit a signal here to be caught by the main window widget. | 249 | // TODO: Instead, emit a signal here to be caught by the main window widget. |
| 231 | auto main_window = static_cast<QMainWindow*>(parent()); | 250 | auto main_window = static_cast<QMainWindow*>(parent()); |
| @@ -237,10 +256,23 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { | |||
| 237 | QWidget* new_info_widget; | 256 | QWidget* new_info_widget; |
| 238 | 257 | ||
| 239 | const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); | 258 | const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); |
| 240 | if (COMMAND_IN_RANGE(command_id, texture0)) { | 259 | if (COMMAND_IN_RANGE(command_id, texture0) || |
| 241 | u8* src = Memory::GetPointer(Pica::registers.texture0.GetPhysicalAddress()); | 260 | COMMAND_IN_RANGE(command_id, texture1) || |
| 242 | auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(Pica::registers.texture0, | 261 | COMMAND_IN_RANGE(command_id, texture2)) { |
| 243 | Pica::registers.texture0_format); | 262 | |
| 263 | unsigned index; | ||
| 264 | if (COMMAND_IN_RANGE(command_id, texture0)) { | ||
| 265 | index = 0; | ||
| 266 | } else if (COMMAND_IN_RANGE(command_id, texture1)) { | ||
| 267 | index = 1; | ||
| 268 | } else { | ||
| 269 | index = 2; | ||
| 270 | } | ||
| 271 | auto config = Pica::registers.GetTextures()[index].config; | ||
| 272 | auto format = Pica::registers.GetTextures()[index].format; | ||
| 273 | |||
| 274 | auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); | ||
| 275 | u8* src = Memory::GetPointer(Pica::PAddrToVAddr(config.GetPhysicalAddress())); | ||
| 244 | new_info_widget = new TextureInfoWidget(src, info); | 276 | new_info_widget = new TextureInfoWidget(src, info); |
| 245 | } else { | 277 | } else { |
| 246 | new_info_widget = new QWidget; | 278 | new_info_widget = new QWidget; |
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp index fb62e8f17..dd41c3880 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.cpp +++ b/src/citra_qt/debugger/graphics_framebuffer.cpp | |||
| @@ -125,7 +125,8 @@ GraphicsFramebufferWidget::GraphicsFramebufferWidget(std::shared_ptr<Pica::Debug | |||
| 125 | setWidget(main_widget); | 125 | setWidget(main_widget); |
| 126 | 126 | ||
| 127 | // Load current data - TODO: Make sure this works when emulation is not running | 127 | // Load current data - TODO: Make sure this works when emulation is not running |
| 128 | emit Update(); | 128 | if (debug_context && debug_context->at_breakpoint) |
| 129 | emit Update(); | ||
| 129 | widget()->setEnabled(false); // TODO: Only enable if currently at breakpoint | 130 | widget()->setEnabled(false); // TODO: Only enable if currently at breakpoint |
| 130 | } | 131 | } |
| 131 | 132 | ||
| @@ -198,7 +199,7 @@ void GraphicsFramebufferWidget::OnUpdate() | |||
| 198 | auto framebuffer = Pica::registers.framebuffer; | 199 | auto framebuffer = Pica::registers.framebuffer; |
| 199 | using Framebuffer = decltype(framebuffer); | 200 | using Framebuffer = decltype(framebuffer); |
| 200 | 201 | ||
| 201 | framebuffer_address = framebuffer.GetColorBufferAddress(); | 202 | framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); |
| 202 | framebuffer_width = framebuffer.GetWidth(); | 203 | framebuffer_width = framebuffer.GetWidth(); |
| 203 | framebuffer_height = framebuffer.GetHeight(); | 204 | framebuffer_height = framebuffer.GetHeight(); |
| 204 | framebuffer_format = static_cast<Format>(framebuffer.color_format); | 205 | framebuffer_format = static_cast<Format>(framebuffer.color_format); |
| @@ -223,9 +224,9 @@ void GraphicsFramebufferWidget::OnUpdate() | |||
| 223 | case Format::RGBA8: | 224 | case Format::RGBA8: |
| 224 | { | 225 | { |
| 225 | QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); | 226 | QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); |
| 226 | u32* color_buffer = (u32*)Memory::GetPointer(framebuffer_address); | 227 | u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); |
| 227 | for (int y = 0; y < framebuffer_height; ++y) { | 228 | for (unsigned y = 0; y < framebuffer_height; ++y) { |
| 228 | for (int x = 0; x < framebuffer_width; ++x) { | 229 | for (unsigned x = 0; x < framebuffer_width; ++x) { |
| 229 | u32 value = *(color_buffer + x + y * framebuffer_width); | 230 | u32 value = *(color_buffer + x + y * framebuffer_width); |
| 230 | 231 | ||
| 231 | decoded_image.setPixel(x, y, qRgba((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, 255/*value >> 24*/)); | 232 | decoded_image.setPixel(x, y, qRgba((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, 255/*value >> 24*/)); |
| @@ -238,9 +239,9 @@ void GraphicsFramebufferWidget::OnUpdate() | |||
| 238 | case Format::RGB8: | 239 | case Format::RGB8: |
| 239 | { | 240 | { |
| 240 | QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); | 241 | QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); |
| 241 | u8* color_buffer = Memory::GetPointer(framebuffer_address); | 242 | u8* color_buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); |
| 242 | for (int y = 0; y < framebuffer_height; ++y) { | 243 | for (unsigned y = 0; y < framebuffer_height; ++y) { |
| 243 | for (int x = 0; x < framebuffer_width; ++x) { | 244 | for (unsigned x = 0; x < framebuffer_width; ++x) { |
| 244 | u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width; | 245 | u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width; |
| 245 | 246 | ||
| 246 | decoded_image.setPixel(x, y, qRgba(pixel_pointer[0], pixel_pointer[1], pixel_pointer[2], 255/*value >> 24*/)); | 247 | decoded_image.setPixel(x, y, qRgba(pixel_pointer[0], pixel_pointer[1], pixel_pointer[2], 255/*value >> 24*/)); |
| @@ -253,9 +254,9 @@ void GraphicsFramebufferWidget::OnUpdate() | |||
| 253 | case Format::RGBA5551: | 254 | case Format::RGBA5551: |
| 254 | { | 255 | { |
| 255 | QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); | 256 | QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); |
| 256 | u32* color_buffer = (u32*)Memory::GetPointer(framebuffer_address); | 257 | u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); |
| 257 | for (int y = 0; y < framebuffer_height; ++y) { | 258 | for (unsigned y = 0; y < framebuffer_height; ++y) { |
| 258 | for (int x = 0; x < framebuffer_width; ++x) { | 259 | for (unsigned x = 0; x < framebuffer_width; ++x) { |
| 259 | u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2); | 260 | u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2); |
| 260 | u8 r = (value >> 11) & 0x1F; | 261 | u8 r = (value >> 11) & 0x1F; |
| 261 | u8 g = (value >> 6) & 0x1F; | 262 | u8 g = (value >> 6) & 0x1F; |