diff options
Diffstat (limited to 'src/citra_qt/debugger')
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_cmdlists.cpp | 36 | ||||
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_surface.cpp | 54 | ||||
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_tracing.cpp | 5 | ||||
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_tracing.h | 6 | ||||
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp | 9 | ||||
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_vertex_shader.h | 2 | ||||
-rw-r--r-- | src/citra_qt/debugger/profiler.cpp | 111 | ||||
-rw-r--r-- | src/citra_qt/debugger/profiler.h | 40 | ||||
-rw-r--r-- | src/citra_qt/debugger/profiler.ui | 33 |
9 files changed, 60 insertions, 236 deletions
diff --git a/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp index f5a2ec761..c68fe753b 100644 --- a/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp @@ -18,15 +18,16 @@ #include "citra_qt/util/util.h" #include "common/vector_math.h" #include "video_core/debug_utils/debug_utils.h" -#include "video_core/pica.h" #include "video_core/pica_state.h" +#include "video_core/regs.h" +#include "video_core/texture/texture_decode.h" namespace { -QImage LoadTexture(const u8* src, const Pica::DebugUtils::TextureInfo& info) { +QImage LoadTexture(const u8* src, const Pica::Texture::TextureInfo& info) { QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { - Math::Vec4<u8> color = Pica::DebugUtils::LookupTexture(src, x, y, info, true); + Math::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true); decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); } } @@ -36,9 +37,10 @@ QImage LoadTexture(const u8* src, const Pica::DebugUtils::TextureInfo& info) { class TextureInfoWidget : public QWidget { public: - TextureInfoWidget(const u8* src, const Pica::DebugUtils::TextureInfo& info, + TextureInfoWidget(const u8* src, const Pica::Texture::TextureInfo& info, QWidget* parent = nullptr) : QWidget(parent) { + QLabel* image_widget = new QLabel; QPixmap image_pixmap = QPixmap::fromImage(LoadTexture(src, info)); image_pixmap = image_pixmap.scaled(200, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation); @@ -70,7 +72,7 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const { if (role == Qt::DisplayRole) { switch (index.column()) { case 0: - return QString::fromLatin1(Pica::Regs::GetCommandName(write.cmd_id).c_str()); + return QString::fromLatin1(Pica::Regs::GetRegisterName(write.cmd_id)); case 1: return QString("%1").arg(write.cmd_id, 3, 16, QLatin1Char('0')); case 2: @@ -121,15 +123,16 @@ void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace& void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); - if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || - COMMAND_IN_RANGE(command_id, texture2)) { + if (COMMAND_IN_RANGE(command_id, texturing.texture0) || + COMMAND_IN_RANGE(command_id, texturing.texture1) || + COMMAND_IN_RANGE(command_id, texturing.texture2)) { unsigned texture_index; - if (COMMAND_IN_RANGE(command_id, texture0)) { + if (COMMAND_IN_RANGE(command_id, texturing.texture0)) { texture_index = 0; - } else if (COMMAND_IN_RANGE(command_id, texture1)) { + } else if (COMMAND_IN_RANGE(command_id, texturing.texture1)) { texture_index = 1; - } else if (COMMAND_IN_RANGE(command_id, texture2)) { + } else if (COMMAND_IN_RANGE(command_id, texturing.texture2)) { texture_index = 2; } else { UNREACHABLE_MSG("Unknown texture command"); @@ -144,23 +147,24 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); - if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || - COMMAND_IN_RANGE(command_id, texture2)) { + if (COMMAND_IN_RANGE(command_id, texturing.texture0) || + COMMAND_IN_RANGE(command_id, texturing.texture1) || + COMMAND_IN_RANGE(command_id, texturing.texture2)) { unsigned texture_index; - if (COMMAND_IN_RANGE(command_id, texture0)) { + if (COMMAND_IN_RANGE(command_id, texturing.texture0)) { texture_index = 0; - } else if (COMMAND_IN_RANGE(command_id, texture1)) { + } else if (COMMAND_IN_RANGE(command_id, texturing.texture1)) { texture_index = 1; } else { texture_index = 2; } - const auto texture = Pica::g_state.regs.GetTextures()[texture_index]; + const auto texture = Pica::g_state.regs.texturing.GetTextures()[texture_index]; const auto config = texture.config; const auto format = texture.format; - const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); + const auto info = Pica::Texture::TextureInfo::FromPicaRegister(config, format); const u8* src = Memory::GetPhysicalPointer(config.GetPhysicalAddress()); new_info_widget = new TextureInfoWidget(src, info); } diff --git a/src/citra_qt/debugger/graphics/graphics_surface.cpp b/src/citra_qt/debugger/graphics/graphics_surface.cpp index 4efd95d3c..47d9924e1 100644 --- a/src/citra_qt/debugger/graphics/graphics_surface.cpp +++ b/src/citra_qt/debugger/graphics/graphics_surface.cpp @@ -16,8 +16,10 @@ #include "common/color.h" #include "core/hw/gpu.h" #include "core/memory.h" -#include "video_core/pica.h" #include "video_core/pica_state.h" +#include "video_core/regs_framebuffer.h" +#include "video_core/regs_texturing.h" +#include "video_core/texture/texture_decode.h" #include "video_core/utils.h" SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) @@ -413,30 +415,30 @@ void GraphicsSurfaceWidget::OnUpdate() { // TODO: Store a reference to the registers in the debug context instead of accessing them // directly... - const auto& framebuffer = Pica::g_state.regs.framebuffer; + const auto& framebuffer = Pica::g_state.regs.framebuffer.framebuffer; surface_address = framebuffer.GetColorBufferPhysicalAddress(); surface_width = framebuffer.GetWidth(); surface_height = framebuffer.GetHeight(); switch (framebuffer.color_format) { - case Pica::Regs::ColorFormat::RGBA8: + case Pica::FramebufferRegs::ColorFormat::RGBA8: surface_format = Format::RGBA8; break; - case Pica::Regs::ColorFormat::RGB8: + case Pica::FramebufferRegs::ColorFormat::RGB8: surface_format = Format::RGB8; break; - case Pica::Regs::ColorFormat::RGB5A1: + case Pica::FramebufferRegs::ColorFormat::RGB5A1: surface_format = Format::RGB5A1; break; - case Pica::Regs::ColorFormat::RGB565: + case Pica::FramebufferRegs::ColorFormat::RGB565: surface_format = Format::RGB565; break; - case Pica::Regs::ColorFormat::RGBA4: + case Pica::FramebufferRegs::ColorFormat::RGBA4: surface_format = Format::RGBA4; break; @@ -449,22 +451,22 @@ void GraphicsSurfaceWidget::OnUpdate() { } case Source::DepthBuffer: { - const auto& framebuffer = Pica::g_state.regs.framebuffer; + const auto& framebuffer = Pica::g_state.regs.framebuffer.framebuffer; surface_address = framebuffer.GetDepthBufferPhysicalAddress(); surface_width = framebuffer.GetWidth(); surface_height = framebuffer.GetHeight(); switch (framebuffer.depth_format) { - case Pica::Regs::DepthFormat::D16: + case Pica::FramebufferRegs::DepthFormat::D16: surface_format = Format::D16; break; - case Pica::Regs::DepthFormat::D24: + case Pica::FramebufferRegs::DepthFormat::D24: surface_format = Format::D24; break; - case Pica::Regs::DepthFormat::D24S8: + case Pica::FramebufferRegs::DepthFormat::D24S8: surface_format = Format::D24X8; break; @@ -477,14 +479,14 @@ void GraphicsSurfaceWidget::OnUpdate() { } case Source::StencilBuffer: { - const auto& framebuffer = Pica::g_state.regs.framebuffer; + const auto& framebuffer = Pica::g_state.regs.framebuffer.framebuffer; surface_address = framebuffer.GetDepthBufferPhysicalAddress(); surface_width = framebuffer.GetWidth(); surface_height = framebuffer.GetHeight(); switch (framebuffer.depth_format) { - case Pica::Regs::DepthFormat::D24S8: + case Pica::FramebufferRegs::DepthFormat::D24S8: surface_format = Format::X24S8; break; @@ -511,8 +513,8 @@ void GraphicsSurfaceWidget::OnUpdate() { break; } - const auto texture = Pica::g_state.regs.GetTextures()[texture_index]; - auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format); + const auto texture = Pica::g_state.regs.texturing.GetTextures()[texture_index]; + auto info = Pica::Texture::TextureInfo::FromPicaRegister(texture.config, texture.format); surface_address = info.physical_address; surface_width = info.width; @@ -567,28 +569,27 @@ void GraphicsSurfaceWidget::OnUpdate() { surface_picture_label->show(); - unsigned nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format); - unsigned stride = nibbles_per_pixel * surface_width / 2; - - // We handle depth formats here because DebugUtils only supports TextureFormats if (surface_format <= Format::MaxTextureFormat) { - // Generate a virtual texture - Pica::DebugUtils::TextureInfo info; + Pica::Texture::TextureInfo info; info.physical_address = surface_address; info.width = surface_width; info.height = surface_height; - info.format = static_cast<Pica::Regs::TextureFormat>(surface_format); - info.stride = stride; + info.format = static_cast<Pica::TexturingRegs::TextureFormat>(surface_format); + info.SetDefaultStride(); for (unsigned int y = 0; y < surface_height; ++y) { for (unsigned int x = 0; x < surface_width; ++x) { - Math::Vec4<u8> color = Pica::DebugUtils::LookupTexture(buffer, x, y, info, true); + Math::Vec4<u8> color = Pica::Texture::LookupTexture(buffer, x, y, info, true); decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); } } - } else { + // We handle depth formats here because DebugUtils only supports TextureFormats + + // TODO(yuriks): Convert to newer tile-based addressing + unsigned nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format); + unsigned stride = nibbles_per_pixel * surface_width / 2; ASSERT_MSG(nibbles_per_pixel >= 2, "Depth decoder only supports formats with at least one byte per pixel"); @@ -689,7 +690,8 @@ void GraphicsSurfaceWidget::SaveSurface() { unsigned int GraphicsSurfaceWidget::NibblesPerPixel(GraphicsSurfaceWidget::Format format) { if (format <= Format::MaxTextureFormat) { - return Pica::Regs::NibblesPerPixel(static_cast<Pica::Regs::TextureFormat>(format)); + return Pica::TexturingRegs::NibblesPerPixel( + static_cast<Pica::TexturingRegs::TextureFormat>(format)); } switch (format) { diff --git a/src/citra_qt/debugger/graphics/graphics_tracing.cpp b/src/citra_qt/debugger/graphics/graphics_tracing.cpp index 716ed50b8..40d5bed51 100644 --- a/src/citra_qt/debugger/graphics/graphics_tracing.cpp +++ b/src/citra_qt/debugger/graphics/graphics_tracing.cpp @@ -18,7 +18,6 @@ #include "core/hw/lcd.h" #include "core/tracer/recorder.h" #include "nihstro/float24.h" -#include "video_core/pica.h" #include "video_core/pica_state.h" GraphicsTracingWidget::GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, @@ -71,8 +70,8 @@ void GraphicsTracingWidget::StartRecording() { std::array<u32, 4 * 16> default_attributes; for (unsigned i = 0; i < 16; ++i) { for (unsigned comp = 0; comp < 3; ++comp) { - default_attributes[4 * i + comp] = - nihstro::to_float24(Pica::g_state.vs_default_attributes[i][comp].ToFloat32()); + default_attributes[4 * i + comp] = nihstro::to_float24( + Pica::g_state.input_default_attributes.attr[i][comp].ToFloat32()); } } diff --git a/src/citra_qt/debugger/graphics/graphics_tracing.h b/src/citra_qt/debugger/graphics/graphics_tracing.h index 3f73bcd2e..eb1292c29 100644 --- a/src/citra_qt/debugger/graphics/graphics_tracing.h +++ b/src/citra_qt/debugger/graphics/graphics_tracing.h @@ -15,6 +15,9 @@ public: explicit GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent = nullptr); + void OnEmulationStarting(EmuThread* emu_thread); + void OnEmulationStopping(); + private slots: void StartRecording(); void StopRecording(); @@ -23,9 +26,6 @@ private slots: void OnBreakPointHit(Pica::DebugContext::Event event, void* data) override; void OnResumed() override; - void OnEmulationStarting(EmuThread* emu_thread); - void OnEmulationStopping(); - signals: void SetStartTracingButtonEnabled(bool enable); void SetStopTracingButtonEnabled(bool enable); diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp index f37524190..e3f3194db 100644 --- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp @@ -16,7 +16,6 @@ #include <QTreeView> #include "citra_qt/debugger/graphics/graphics_vertex_shader.h" #include "citra_qt/util/util.h" -#include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/shader/debug_data.h" #include "video_core/shader/shader.h" @@ -359,7 +358,7 @@ void GraphicsVertexShaderWidget::DumpShader() { auto& config = Pica::g_state.regs.vs; Pica::DebugUtils::DumpShader(filename.toStdString(), config, setup, - Pica::g_state.regs.vs_output_attributes); + Pica::g_state.regs.rasterizer.vs_output_attributes); } GraphicsVertexShaderWidget::GraphicsVertexShaderWidget( @@ -511,7 +510,7 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d auto& shader_config = Pica::g_state.regs.vs; for (auto instr : shader_setup.program_code) info.code.push_back({instr}); - int num_attributes = Pica::g_state.regs.vertex_attributes.GetNumTotalAttributes(); + int num_attributes = shader_config.max_input_attribute_index + 1; for (auto pattern : shader_setup.swizzle_data) info.swizzle_info.push_back({pattern}); @@ -522,11 +521,11 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d // Generate debug information Pica::Shader::InterpreterEngine shader_engine; shader_engine.SetupBatch(shader_setup, entry_point); - debug_data = shader_engine.ProduceDebugInfo(shader_setup, input_vertex, num_attributes); + debug_data = shader_engine.ProduceDebugInfo(shader_setup, input_vertex, shader_config); // Reload widget state for (int attr = 0; attr < num_attributes; ++attr) { - unsigned source_attr = shader_config.input_register_map.GetRegisterForAttribute(attr); + unsigned source_attr = shader_config.GetRegisterForAttribute(attr); input_data_mapping[attr]->setText(QString("-> v%1").arg(source_attr)); input_data_container[attr]->setVisible(true); } diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.h b/src/citra_qt/debugger/graphics/graphics_vertex_shader.h index 3292573f3..c249a2ff8 100644 --- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.h +++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.h @@ -82,7 +82,7 @@ private: nihstro::ShaderInfo info; Pica::Shader::DebugData<true> debug_data; - Pica::Shader::InputVertex input_vertex; + Pica::Shader::AttributeBuffer input_vertex; friend class GraphicsVertexShaderModel; }; diff --git a/src/citra_qt/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp index cee10403d..f060bbe08 100644 --- a/src/citra_qt/debugger/profiler.cpp +++ b/src/citra_qt/debugger/profiler.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <QAction> +#include <QLayout> #include <QMouseEvent> #include <QPainter> #include <QString> @@ -9,121 +11,12 @@ #include "citra_qt/util/util.h" #include "common/common_types.h" #include "common/microprofile.h" -#include "common/profiler_reporting.h" // Include the implementation of the UI in this file. This isn't in microprofile.cpp because the // non-Qt frontends don't need it (and don't implement the UI drawing hooks either). #if MICROPROFILE_ENABLED #define MICROPROFILEUI_IMPL 1 #include "common/microprofileui.h" -#endif - -using namespace Common::Profiling; - -static QVariant GetDataForColumn(int col, const AggregatedDuration& duration) { - static auto duration_to_float = [](Duration dur) -> float { - using FloatMs = std::chrono::duration<float, std::chrono::milliseconds::period>; - return std::chrono::duration_cast<FloatMs>(dur).count(); - }; - - switch (col) { - case 1: - return duration_to_float(duration.avg); - case 2: - return duration_to_float(duration.min); - case 3: - return duration_to_float(duration.max); - default: - return QVariant(); - } -} - -ProfilerModel::ProfilerModel(QObject* parent) : QAbstractItemModel(parent) { - updateProfilingInfo(); -} - -QVariant ProfilerModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) { - case 0: - return tr("Category"); - case 1: - return tr("Avg"); - case 2: - return tr("Min"); - case 3: - return tr("Max"); - } - } - - return QVariant(); -} - -QModelIndex ProfilerModel::index(int row, int column, const QModelIndex& parent) const { - return createIndex(row, column); -} - -QModelIndex ProfilerModel::parent(const QModelIndex& child) const { - return QModelIndex(); -} - -int ProfilerModel::columnCount(const QModelIndex& parent) const { - return 4; -} - -int ProfilerModel::rowCount(const QModelIndex& parent) const { - if (parent.isValid()) { - return 0; - } else { - return 2; - } -} - -QVariant ProfilerModel::data(const QModelIndex& index, int role) const { - if (role == Qt::DisplayRole) { - if (index.row() == 0) { - if (index.column() == 0) { - return tr("Frame"); - } else { - return GetDataForColumn(index.column(), results.frame_time); - } - } else if (index.row() == 1) { - if (index.column() == 0) { - return tr("Frame (with swapping)"); - } else { - return GetDataForColumn(index.column(), results.interframe_time); - } - } - } - - return QVariant(); -} - -void ProfilerModel::updateProfilingInfo() { - results = GetTimingResultsAggregator()->GetAggregatedResults(); - emit dataChanged(createIndex(0, 1), createIndex(rowCount() - 1, 3)); -} - -ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent) { - ui.setupUi(this); - - model = new ProfilerModel(this); - ui.treeView->setModel(model); - - connect(this, SIGNAL(visibilityChanged(bool)), SLOT(setProfilingInfoUpdateEnabled(bool))); - connect(&update_timer, SIGNAL(timeout()), model, SLOT(updateProfilingInfo())); -} - -void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable) { - if (enable) { - update_timer.start(100); - model->updateProfilingInfo(); - } else { - update_timer.stop(); - } -} - -#if MICROPROFILE_ENABLED class MicroProfileWidget : public QWidget { public: diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h index c8912fd5a..eae1e9e3c 100644 --- a/src/citra_qt/debugger/profiler.h +++ b/src/citra_qt/debugger/profiler.h @@ -8,46 +8,6 @@ #include <QDockWidget> #include <QTimer> #include "common/microprofile.h" -#include "common/profiler_reporting.h" -#include "ui_profiler.h" - -class ProfilerModel : public QAbstractItemModel { - Q_OBJECT - -public: - explicit ProfilerModel(QObject* parent); - - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; - QModelIndex index(int row, int column, - const QModelIndex& parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex& child) const override; - int columnCount(const QModelIndex& parent = QModelIndex()) const override; - int rowCount(const QModelIndex& parent = QModelIndex()) const override; - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - -public slots: - void updateProfilingInfo(); - -private: - Common::Profiling::AggregatedFrameResult results; -}; - -class ProfilerWidget : public QDockWidget { - Q_OBJECT - -public: - explicit ProfilerWidget(QWidget* parent = nullptr); - -private slots: - void setProfilingInfoUpdateEnabled(bool enable); - -private: - Ui::Profiler ui; - ProfilerModel* model; - - QTimer update_timer; -}; class MicroProfileDialog : public QWidget { Q_OBJECT diff --git a/src/citra_qt/debugger/profiler.ui b/src/citra_qt/debugger/profiler.ui deleted file mode 100644 index d3c9a9a1f..000000000 --- a/src/citra_qt/debugger/profiler.ui +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Profiler</class> - <widget class="QDockWidget" name="Profiler"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <property name="windowTitle"> - <string>Profiler</string> - </property> - <widget class="QWidget" name="dockWidgetContents"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QTreeView" name="treeView"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="uniformRowHeights"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - <resources/> - <connections/> -</ui> |