From 67ed4fa92d342da62274f578a2f4886d94165bb4 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 26 Sep 2022 15:04:15 -0700 Subject: [PATCH 1/4] Common/Image: Add unit to log message --- Source/Core/Common/Image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Common/Image.cpp b/Source/Core/Common/Image.cpp index 94e65b9619..bdb8dcb4a8 100644 --- a/Source/Core/Common/Image.cpp +++ b/Source/Core/Common/Image.cpp @@ -115,8 +115,8 @@ bool SavePNG(const std::string& path, const u8* input, ImageByteFormat format, u size_t image_len = 0; spng_decoded_image_size(ctx.get(), SPNG_FMT_PNG, &image_len); - INFO_LOG_FMT(FRAMEDUMP, "{} byte {} by {} image saved to {} at level {} in {}", image_len, width, - height, path, level, timer.ElapsedMs()); + INFO_LOG_FMT(FRAMEDUMP, "{} byte {} by {} image saved to {} at level {} in {} ms", image_len, + width, height, path, level, timer.ElapsedMs()); return true; } From 56fce3ba8a8a3645da0250fbac91b9940e45cf8c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 26 Sep 2022 15:30:56 -0700 Subject: [PATCH 2/4] Software: Remove dedicated texture/frame dumping infrastructure Texture dumping can already be done using VideoCommon's system (and in fact the same setting already enabled *both* of these). Dumping objects/TEV stages/texture fetches doesn't currently have an equivalent, but could be added to the FIFO player instead. --- Source/Core/Core/Config/GraphicsSettings.cpp | 2 - Source/Core/Core/Config/GraphicsSettings.h | 2 - Source/Core/DolphinLib.props | 2 - .../Graphics/SoftwareRendererWidget.cpp | 81 ------- .../Config/Graphics/SoftwareRendererWidget.h | 8 - .../VideoBackends/Software/CMakeLists.txt | 2 - .../Core/VideoBackends/Software/DebugUtil.cpp | 219 ------------------ .../Core/VideoBackends/Software/DebugUtil.h | 25 -- .../VideoBackends/Software/SWVertexLoader.cpp | 7 +- Source/Core/VideoBackends/Software/SWmain.cpp | 3 - Source/Core/VideoBackends/Software/Tev.cpp | 45 ---- Source/Core/VideoCommon/VideoConfig.cpp | 6 - Source/Core/VideoCommon/VideoConfig.h | 7 - 13 files changed, 2 insertions(+), 407 deletions(-) delete mode 100644 Source/Core/VideoBackends/Software/DebugUtil.cpp delete mode 100644 Source/Core/VideoBackends/Software/DebugUtil.h diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index 4bbcf99413..e5056678bd 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -96,8 +96,6 @@ const Info GFX_SW_DUMP_OBJECTS{{System::GFX, "Settings", "SWDumpObjects"}, const Info GFX_SW_DUMP_TEV_STAGES{{System::GFX, "Settings", "SWDumpTevStages"}, false}; const Info GFX_SW_DUMP_TEV_TEX_FETCHES{{System::GFX, "Settings", "SWDumpTevTexFetches"}, false}; -const Info GFX_SW_DRAW_START{{System::GFX, "Settings", "SWDrawStart"}, 0}; -const Info GFX_SW_DRAW_END{{System::GFX, "Settings", "SWDrawEnd"}, 100000}; const Info GFX_PREFER_GLES{{System::GFX, "Settings", "PreferGLES"}, false}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index cdac08a77b..398a3dd5a0 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -77,8 +77,6 @@ extern const Info GFX_SAVE_TEXTURE_CACHE_TO_STATE; extern const Info GFX_SW_DUMP_OBJECTS; extern const Info GFX_SW_DUMP_TEV_STAGES; extern const Info GFX_SW_DUMP_TEV_TEX_FETCHES; -extern const Info GFX_SW_DRAW_START; -extern const Info GFX_SW_DRAW_END; extern const Info GFX_PREFER_GLES; diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 4c08f0a6d8..17a0e4c5f7 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -575,7 +575,6 @@ - @@ -1183,7 +1182,6 @@ - diff --git a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp index 432f09ab3b..6500a90027 100644 --- a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp @@ -55,57 +55,7 @@ void SoftwareRendererWidget::CreateWidgets() for (const auto& backend : VideoBackendBase::GetAvailableBackends()) m_backend_combo->addItem(tr(backend->GetDisplayName().c_str())); - auto* overlay_box = new QGroupBox(tr("Overlay Information")); - auto* overlay_layout = new QGridLayout(); - overlay_box->setLayout(overlay_layout); - m_show_statistics = new GraphicsBool(tr("Show Statistics"), Config::GFX_OVERLAY_STATS); - - overlay_layout->addWidget(m_show_statistics); - - auto* utility_box = new QGroupBox(tr("Utility")); - auto* utility_layout = new QGridLayout(); - m_dump_textures = new GraphicsBool(tr("Dump Textures"), Config::GFX_DUMP_TEXTURES); - m_dump_objects = new GraphicsBool(tr("Dump Objects"), Config::GFX_SW_DUMP_OBJECTS); - utility_box->setLayout(utility_layout); - - utility_layout->addWidget(m_dump_textures, 1, 1); - utility_layout->addWidget(m_dump_objects, 1, 2); - - auto* debug_box = new QGroupBox(tr("Debug Only")); - auto* debug_layout = new QGridLayout(); - m_dump_tev_stages = new GraphicsBool(tr("Dump TEV Stages"), Config::GFX_SW_DUMP_TEV_STAGES); - m_dump_tev_fetches = - new GraphicsBool(tr("Dump Texture Fetches"), Config::GFX_SW_DUMP_TEV_TEX_FETCHES); - - debug_layout->addWidget(m_dump_tev_stages, 1, 1); - debug_layout->addWidget(m_dump_tev_fetches, 1, 2); - - debug_box->setLayout(debug_layout); - -#ifdef _DEBUG - utility_layout->addWidget(debug_box, 2, 1, 1, 2); -#endif - - auto* object_range_box = new QGroupBox(tr("Drawn Object Range")); - auto* object_range_layout = new QGridLayout(); - m_object_range_min = new QSpinBox(); - m_object_range_max = new QSpinBox(); - - for (auto* spin : {m_object_range_min, m_object_range_max}) - { - spin->setMinimum(0); - spin->setMaximum(100000); - } - - object_range_box->setLayout(object_range_layout); - - object_range_layout->addWidget(m_object_range_min, 1, 1); - object_range_layout->addWidget(m_object_range_max, 1, 2); - main_layout->addWidget(rendering_box); - main_layout->addWidget(overlay_box); - main_layout->addWidget(utility_box); - main_layout->addWidget(object_range_box); main_layout->addStretch(); setLayout(main_layout); @@ -115,10 +65,6 @@ void SoftwareRendererWidget::ConnectWidgets() { connect(m_backend_combo, qOverload(&QComboBox::currentIndexChanged), [this](int) { SaveSettings(); }); - connect(m_object_range_min, qOverload(&QSpinBox::valueChanged), - [this](int) { SaveSettings(); }); - connect(m_object_range_max, qOverload(&QSpinBox::valueChanged), - [this](int) { SaveSettings(); }); } void SoftwareRendererWidget::LoadSettings() @@ -131,9 +77,6 @@ void SoftwareRendererWidget::LoadSettings() m_backend_combo->findText(tr(backend->GetDisplayName().c_str()))); } } - - m_object_range_min->setValue(Config::Get(Config::GFX_SW_DRAW_START)); - m_object_range_max->setValue(Config::Get(Config::GFX_SW_DRAW_END)); } void SoftwareRendererWidget::SaveSettings() @@ -148,9 +91,6 @@ void SoftwareRendererWidget::SaveSettings() break; } } - - Config::SetBaseOrCurrent(Config::GFX_SW_DRAW_START, m_object_range_min->value()); - Config::SetBaseOrCurrent(Config::GFX_SW_DRAW_END, m_object_range_max->value()); } void SoftwareRendererWidget::AddDescriptions() @@ -162,30 +102,9 @@ void SoftwareRendererWidget::AddDescriptions() "backend, so for the best emulation experience it's recommended to try both and " "choose the one that's less problematic.

If unsure, select " "OpenGL."); - static const char TR_SHOW_STATISTICS_DESCRIPTION[] = - QT_TR_NOOP("Show various rendering statistics.

If unsure, leave " - "this unchecked."); - static const char TR_DUMP_TEXTURES_DESCRIPTION[] = - QT_TR_NOOP("Dump decoded game textures to " - "User/Dump/Textures/<game_id>/.

If unsure, leave " - "this unchecked."); - static const char TR_DUMP_OBJECTS_DESCRIPTION[] = - QT_TR_NOOP("Dump objects to User/Dump/Objects/.

If unsure, leave " - "this unchecked."); - static const char TR_DUMP_TEV_STAGES_DESCRIPTION[] = - QT_TR_NOOP("Dump TEV Stages to User/Dump/Objects/.

If unsure, leave " - "this unchecked."); - static const char TR_DUMP_TEV_FETCHES_DESCRIPTION[] = QT_TR_NOOP( - "Dump Texture Fetches to User/Dump/Objects/.

If unsure, leave " - "this unchecked."); m_backend_combo->SetTitle(tr("Backend")); m_backend_combo->SetDescription(tr(TR_BACKEND_DESCRIPTION)); - m_show_statistics->SetDescription(tr(TR_SHOW_STATISTICS_DESCRIPTION)); - m_dump_textures->SetDescription(tr(TR_DUMP_TEXTURES_DESCRIPTION)); - m_dump_objects->SetDescription(tr(TR_DUMP_OBJECTS_DESCRIPTION)); - m_dump_tev_stages->SetDescription(tr(TR_DUMP_TEV_STAGES_DESCRIPTION)); - m_dump_tev_fetches->SetDescription(tr(TR_DUMP_TEV_FETCHES_DESCRIPTION)); } void SoftwareRendererWidget::OnEmulationStateChanged(bool running) diff --git a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h b/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h index 082002fa60..492a499287 100644 --- a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h +++ b/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h @@ -30,12 +30,4 @@ private: void OnEmulationStateChanged(bool running); ToolTipComboBox* m_backend_combo; - GraphicsBool* m_show_statistics; - GraphicsBool* m_dump_textures; - GraphicsBool* m_dump_objects; - GraphicsBool* m_dump_tev_stages; - GraphicsBool* m_dump_tev_fetches; - - QSpinBox* m_object_range_min; - QSpinBox* m_object_range_max; }; diff --git a/Source/Core/VideoBackends/Software/CMakeLists.txt b/Source/Core/VideoBackends/Software/CMakeLists.txt index 752fac48cc..f71421cb57 100644 --- a/Source/Core/VideoBackends/Software/CMakeLists.txt +++ b/Source/Core/VideoBackends/Software/CMakeLists.txt @@ -2,8 +2,6 @@ add_library(videosoftware Clipper.cpp Clipper.h CopyRegion.h - DebugUtil.cpp - DebugUtil.h EfbCopy.cpp EfbCopy.h EfbInterface.cpp diff --git a/Source/Core/VideoBackends/Software/DebugUtil.cpp b/Source/Core/VideoBackends/Software/DebugUtil.cpp deleted file mode 100644 index c580461172..0000000000 --- a/Source/Core/VideoBackends/Software/DebugUtil.cpp +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "VideoBackends/Software/DebugUtil.h" - -#include -#include - -#include "Common/CommonTypes.h" -#include "Common/FileUtil.h" -#include "Common/Image.h" -#include "Common/StringUtil.h" -#include "Common/Swap.h" - -#include "VideoBackends/Software/EfbInterface.h" -#include "VideoBackends/Software/TextureSampler.h" - -#include "VideoCommon/BPMemory.h" -#include "VideoCommon/Statistics.h" -#include "VideoCommon/VideoCommon.h" -#include "VideoCommon/VideoConfig.h" - -namespace DebugUtil -{ -static const int NUM_OBJECT_BUFFERS = 40; - -static u32* ObjectBuffer[NUM_OBJECT_BUFFERS]; -static u32 TempBuffer[NUM_OBJECT_BUFFERS]; - -static bool DrawnToBuffer[NUM_OBJECT_BUFFERS]; -static const char* ObjectBufferName[NUM_OBJECT_BUFFERS]; -static int BufferBase[NUM_OBJECT_BUFFERS]; - -void Init() -{ - for (int i = 0; i < NUM_OBJECT_BUFFERS; i++) - { - ObjectBuffer[i] = new u32[EFB_WIDTH * EFB_HEIGHT](); - DrawnToBuffer[i] = false; - ObjectBufferName[i] = nullptr; - BufferBase[i] = 0; - } -} - -void Shutdown() -{ - for (auto& slot : ObjectBuffer) - { - delete[] slot; - } -} - -static void SaveTexture(const std::string& filename, u32 texmap, s32 mip) -{ - u32 width = bpmem.tex.GetUnit(texmap).texImage0.width + 1; - u32 height = bpmem.tex.GetUnit(texmap).texImage0.height + 1; - - auto data = std::make_unique(width * height * 4); - - GetTextureRGBA(data.get(), texmap, mip, width, height); - Common::SavePNG(filename, data.get(), Common::ImageByteFormat::RGBA, width, height, width * 4); -} - -void GetTextureRGBA(u8* dst, u32 texmap, s32 mip, u32 width, u32 height) -{ - for (u32 y = 0; y < height; y++) - { - for (u32 x = 0; x < width; x++) - { - TextureSampler::SampleMip(x << 7, y << 7, mip, false, texmap, dst); - dst += 4; - } - } -} - -static s32 GetMaxTextureLod(u32 texmap) -{ - u8 maxLod = bpmem.tex.GetUnit(texmap).texMode1.max_lod; - u8 mip = maxLod >> 4; - u8 fract = maxLod & 0xf; - - if (fract) - ++mip; - - return (s32)mip; -} - -void DumpActiveTextures() -{ - for (unsigned int stageNum = 0; stageNum < bpmem.genMode.numindstages; stageNum++) - { - u32 texmap = bpmem.tevindref.getTexMap(stageNum); - - s32 maxLod = GetMaxTextureLod(texmap); - for (s32 mip = 0; mip <= maxLod; ++mip) - { - SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.png", - File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), - g_stats.this_frame.num_drawn_objects, stageNum, texmap, mip), - texmap, mip); - } - } - - for (unsigned int stageNum = 0; stageNum <= bpmem.genMode.numtevstages; stageNum++) - { - int stageNum2 = stageNum >> 1; - int stageOdd = stageNum & 1; - TwoTevStageOrders& order = bpmem.tevorders[stageNum2]; - - int texmap = order.getTexMap(stageOdd); - - s32 maxLod = GetMaxTextureLod(texmap); - for (s32 mip = 0; mip <= maxLod; ++mip) - { - SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.png", - File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), - g_stats.this_frame.num_drawn_objects, stageNum, texmap, mip), - texmap, mip); - } - } -} - -static void DumpEfb(const std::string& filename) -{ - auto data = std::make_unique(EFB_WIDTH * EFB_HEIGHT * 4); - u8* writePtr = data.get(); - - for (u32 y = 0; y < EFB_HEIGHT; y++) - { - for (u32 x = 0; x < EFB_WIDTH; x++) - { - // ABGR to RGBA - const u32 sample = Common::swap32(EfbInterface::GetColor(x, y)); - - std::memcpy(writePtr, &sample, sizeof(u32)); - writePtr += sizeof(u32); - } - } - - Common::SavePNG(filename, data.get(), Common::ImageByteFormat::RGBA, EFB_WIDTH, EFB_HEIGHT, - EFB_WIDTH * 4); -} - -void DrawObjectBuffer(s16 x, s16 y, const u8* color, int bufferBase, int subBuffer, - const char* name) -{ - int buffer = bufferBase + subBuffer; - - u32 offset = (x + y * EFB_WIDTH) * 4; - u8* dst = (u8*)&ObjectBuffer[buffer][offset]; - *(dst++) = color[2]; - *(dst++) = color[1]; - *(dst++) = color[0]; - *(dst++) = color[3]; - - DrawnToBuffer[buffer] = true; - ObjectBufferName[buffer] = name; - BufferBase[buffer] = bufferBase; -} - -void DrawTempBuffer(const u8* color, int buffer) -{ - u8* dst = (u8*)&TempBuffer[buffer]; - *(dst++) = color[2]; - *(dst++) = color[1]; - *(dst++) = color[0]; - *(dst++) = color[3]; -} - -void CopyTempBuffer(s16 x, s16 y, int bufferBase, int subBuffer, const char* name) -{ - int buffer = bufferBase + subBuffer; - - u32 offset = (x + y * EFB_WIDTH); - ObjectBuffer[buffer][offset] = TempBuffer[buffer]; - - DrawnToBuffer[buffer] = true; - ObjectBufferName[buffer] = name; - BufferBase[buffer] = bufferBase; -} - -void OnObjectBegin() -{ - if (g_ActiveConfig.bDumpTextures && - g_stats.this_frame.num_drawn_objects >= g_ActiveConfig.drawStart && - g_stats.this_frame.num_drawn_objects < g_ActiveConfig.drawEnd) - { - DumpActiveTextures(); - } -} - -void OnObjectEnd() -{ - if (g_ActiveConfig.bDumpObjects && - g_stats.this_frame.num_drawn_objects >= g_ActiveConfig.drawStart && - g_stats.this_frame.num_drawn_objects < g_ActiveConfig.drawEnd) - { - DumpEfb(StringFromFormat("%sobject%i.png", File::GetUserPath(D_DUMPOBJECTS_IDX).c_str(), - g_stats.this_frame.num_drawn_objects)); - } - - for (int i = 0; i < NUM_OBJECT_BUFFERS; i++) - { - if (DrawnToBuffer[i]) - { - DrawnToBuffer[i] = false; - std::string filename = StringFromFormat( - "%sobject%i_%s(%i).png", File::GetUserPath(D_DUMPOBJECTS_IDX).c_str(), - g_stats.this_frame.num_drawn_objects, ObjectBufferName[i], i - BufferBase[i]); - - Common::SavePNG(filename, reinterpret_cast(ObjectBuffer[i]), - Common::ImageByteFormat::RGBA, EFB_WIDTH, EFB_HEIGHT, EFB_WIDTH * 4); - memset(ObjectBuffer[i], 0, EFB_WIDTH * EFB_HEIGHT * sizeof(u32)); - } - } - - g_stats.this_frame.num_drawn_objects++; -} -} // namespace DebugUtil diff --git a/Source/Core/VideoBackends/Software/DebugUtil.h b/Source/Core/VideoBackends/Software/DebugUtil.h deleted file mode 100644 index 20209577a9..0000000000 --- a/Source/Core/VideoBackends/Software/DebugUtil.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "Common/CommonTypes.h" - -namespace DebugUtil -{ -void Init(); -void Shutdown(); - -void GetTextureRGBA(u8* dst, u32 texmap, s32 mip, u32 width, u32 height); - -void DumpActiveTextures(); - -void OnObjectBegin(); -void OnObjectEnd(); - -void DrawObjectBuffer(s16 x, s16 y, const u8* color, int bufferBase, int subBuffer, - const char* name); - -void DrawTempBuffer(const u8* color, int buffer); -void CopyTempBuffer(s16 x, s16 y, int bufferBase, int subBuffer, const char* name); -} // namespace DebugUtil diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index 00357b12d7..a38fd163ec 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -10,7 +10,6 @@ #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/NativeVertexFormat.h" #include "VideoBackends/Software/Rasterizer.h" #include "VideoBackends/Software/SWRenderer.h" @@ -42,8 +41,6 @@ DataReader SWVertexLoader::PrepareForAdditionalData(OpcodeDecoder::Primitive pri void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex) { - DebugUtil::OnObjectBegin(); - using OpcodeDecoder::Primitive; Primitive primitive_type = Primitive::GX_DRAW_QUADS; switch (m_current_primitive_type) @@ -90,10 +87,10 @@ void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_ // assemble and rasterize the primitive m_setup_unit.SetupVertex(); - INCSTAT(g_stats.this_frame.num_vertices_loaded) + INCSTAT(g_stats.this_frame.num_vertices_loaded); } - DebugUtil::OnObjectEnd(); + INCSTAT(g_stats.this_frame.num_drawn_objects); } void SWVertexLoader::SetFormat() diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 5076106089..b6d2005c26 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -14,7 +14,6 @@ #include "Common/MsgHandler.h" #include "VideoBackends/Software/Clipper.h" -#include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/EfbInterface.h" #include "VideoBackends/Software/Rasterizer.h" #include "VideoBackends/Software/SWOGLWindow.h" @@ -105,7 +104,6 @@ bool VideoSoftware::Initialize(const WindowSystemInfo& wsi) Clipper::Init(); Rasterizer::Init(); - DebugUtil::Init(); g_renderer = std::make_unique(std::move(window)); g_vertex_manager = std::make_unique(); @@ -135,7 +133,6 @@ void VideoSoftware::Shutdown() if (g_renderer) g_renderer->Shutdown(); - DebugUtil::Shutdown(); g_texture_cache.reset(); g_perf_query.reset(); g_framebuffer_manager.reset(); diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index e788d55d92..f2f903ccfc 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -9,7 +9,6 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" -#include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/EfbInterface.h" #include "VideoBackends/Software/SWBoundingBox.h" #include "VideoBackends/Software/TextureSampler.h" @@ -428,16 +427,6 @@ void Tev::Draw() TextureSampler::Sample(Uv[texcoordSel].s >> scaleS, Uv[texcoordSel].t >> scaleT, IndirectLod[stageNum], IndirectLinear[stageNum], texmap, IndirectTex[stageNum]); - -#if ALLOW_TEV_DUMPS - if (g_ActiveConfig.bDumpTevStages) - { - u8 stage[4] = {IndirectTex[stageNum][TextureSampler::ALP_SMP], - IndirectTex[stageNum][TextureSampler::BLU_SMP], - IndirectTex[stageNum][TextureSampler::GRN_SMP], 255}; - DebugUtil::DrawTempBuffer(stage, INDIRECT + stageNum); - } -#endif } for (unsigned int stageNum = 0; stageNum <= bpmem.genMode.numtevstages; stageNum++) @@ -478,11 +467,6 @@ void Tev::Draw() std::memset(texel, 0, 4); } -#if ALLOW_TEV_DUMPS - if (g_ActiveConfig.bDumpTevTextureFetches) - DebugUtil::DrawTempBuffer(texel, DIRECT_TFETCH + stageNum); -#endif - const auto& swap = bpmem.tevksel.GetSwapTable(ac.tswap); TexColor.r = texel[u32(swap[ColorChannel::Red])]; TexColor.g = texel[u32(swap[ColorChannel::Green])]; @@ -547,15 +531,6 @@ void Tev::Draw() Reg[ac.dest].a = Clamp255(Reg[ac.dest].a); else Reg[ac.dest].a = Clamp1024(Reg[ac.dest].a); - -#if ALLOW_TEV_DUMPS - if (g_ActiveConfig.bDumpTevStages) - { - u8 stage[4] = {(u8)Reg[cc.dest].r, (u8)Reg[cc.dest].g, (u8)Reg[cc.dest].b, - (u8)Reg[ac.dest].a}; - DebugUtil::DrawTempBuffer(stage, DIRECT + stageNum); - } -#endif } // convert to 8 bits per component @@ -711,26 +686,6 @@ void Tev::Draw() BBoxManager::Update(static_cast(Position[0] & ~1), static_cast(Position[0] | 1), static_cast(Position[1] & ~1), static_cast(Position[1] | 1)); -#if ALLOW_TEV_DUMPS - if (g_ActiveConfig.bDumpTevStages) - { - for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) - DebugUtil::CopyTempBuffer(Position[0], Position[1], INDIRECT, i, "Indirect"); - for (u32 i = 0; i <= bpmem.genMode.numtevstages; ++i) - DebugUtil::CopyTempBuffer(Position[0], Position[1], DIRECT, i, "Stage"); - } - - if (g_ActiveConfig.bDumpTevTextureFetches) - { - for (u32 i = 0; i <= bpmem.genMode.numtevstages; ++i) - { - TwoTevStageOrders& order = bpmem.tevorders[i >> 1]; - if (order.getEnable(i & 1)) - DebugUtil::CopyTempBuffer(Position[0], Position[1], DIRECT_TFETCH, i, "TFetch"); - } - } -#endif - INCSTAT(g_stats.this_frame.tev_pixels_out); EfbInterface::IncPerfCounterQuadCount(PQ_BLEND_INPUT); diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index e13e8d96ac..91e0550715 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -104,12 +104,6 @@ void VideoConfig::Refresh() iShaderCompilerThreads = Config::Get(Config::GFX_SHADER_COMPILER_THREADS); iShaderPrecompilerThreads = Config::Get(Config::GFX_SHADER_PRECOMPILER_THREADS); - bDumpObjects = Config::Get(Config::GFX_SW_DUMP_OBJECTS); - bDumpTevStages = Config::Get(Config::GFX_SW_DUMP_TEV_STAGES); - bDumpTevTextureFetches = Config::Get(Config::GFX_SW_DUMP_TEV_TEX_FETCHES); - drawStart = Config::Get(Config::GFX_SW_DRAW_START); - drawEnd = Config::Get(Config::GFX_SW_DRAW_END); - bForceFiltering = Config::Get(Config::GFX_ENHANCE_FORCE_FILTERING); iMaxAnisotropy = Config::Get(Config::GFX_ENHANCE_MAX_ANISOTROPY); sPostProcessingShader = Config::Get(Config::GFX_ENHANCE_POST_SHADER); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 105840bafa..ff52e96bde 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -148,13 +148,6 @@ struct VideoConfig final // D3D only config, mostly to be merged into the above int iAdapter = 0; - // VideoSW Debugging - int drawStart = 0; - int drawEnd = 0; - bool bDumpObjects = false; - bool bDumpTevStages = false; - bool bDumpTevTextureFetches = false; - // Enable API validation layers, currently only supported with Vulkan. bool bEnableValidationLayer = false; From b90d23158f26814fe6dc2c90acdaa3361a4ebf4b Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 26 Sep 2022 17:49:49 -0700 Subject: [PATCH 3/4] Software: Fix mipmaps and uneven strides in SWTexture I think this is only used for texture dumping, but this resolves some failed assertions and glitchy results. --- .../VideoBackends/Software/SWOGLWindow.cpp | 2 +- .../Core/VideoBackends/Software/SWTexture.cpp | 71 ++++++++++++------- .../Core/VideoBackends/Software/SWTexture.h | 6 +- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp index 387375cc85..a002e3e519 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp @@ -105,7 +105,7 @@ void SWOGLWindow::ShowImage(const AbstractTexture* image, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(sw_image->GetConfig().width), static_cast(sw_image->GetConfig().height), 0, GL_RGBA, GL_UNSIGNED_BYTE, - sw_image->GetData()); + sw_image->GetData(0, 0)); glUseProgram(m_image_program); diff --git a/Source/Core/VideoBackends/Software/SWTexture.cpp b/Source/Core/VideoBackends/Software/SWTexture.cpp index 082c26371e..6805ff0eb8 100644 --- a/Source/Core/VideoBackends/Software/SWTexture.cpp +++ b/Source/Core/VideoBackends/Software/SWTexture.cpp @@ -25,17 +25,17 @@ struct Pixel #pragma pack(pop) void CopyTextureData(const TextureConfig& src_config, const u8* src_ptr, u32 src_x, u32 src_y, - u32 width, u32 height, const TextureConfig& dst_config, u8* dst_ptr, u32 dst_x, - u32 dst_y) + u32 width, u32 height, u32 src_level, const TextureConfig& dst_config, + u8* dst_ptr, u32 dst_x, u32 dst_y, u32 dst_level) { - size_t texel_size = AbstractTexture::GetTexelSizeForFormat(src_config.format); - size_t src_stride = src_config.GetStride(); - size_t src_offset = + const size_t texel_size = AbstractTexture::GetTexelSizeForFormat(src_config.format); + const size_t src_stride = src_config.GetMipStride(src_level); + const size_t src_offset = static_cast(src_y) * src_stride + static_cast(src_x) * texel_size; - size_t dst_stride = dst_config.GetStride(); - size_t dst_offset = + const size_t dst_stride = dst_config.GetMipStride(dst_level); + const size_t dst_offset = static_cast(dst_y) * dst_stride + static_cast(dst_x) * texel_size; - size_t copy_len = static_cast(width) * texel_size; + const size_t copy_len = static_cast(width) * texel_size; src_ptr += src_offset; dst_ptr += dst_offset; @@ -56,15 +56,24 @@ void SWRenderer::ScaleTexture(AbstractFramebuffer* dst_framebuffer, const SWTexture* software_source_texture = static_cast(src_texture); SWTexture* software_dest_texture = static_cast(dst_framebuffer->GetColorAttachment()); - CopyRegion(reinterpret_cast(software_source_texture->GetData()), src_rect, + CopyRegion(reinterpret_cast(software_source_texture->GetData(0, 0)), src_rect, src_texture->GetWidth(), src_texture->GetHeight(), - reinterpret_cast(software_dest_texture->GetData()), dst_rect, + reinterpret_cast(software_dest_texture->GetData(0, 0)), dst_rect, dst_framebuffer->GetWidth(), dst_framebuffer->GetHeight()); } SWTexture::SWTexture(const TextureConfig& tex_config) : AbstractTexture(tex_config) { - m_data.resize(tex_config.width * tex_config.height * 4); + m_data.resize(tex_config.layers); + for (u32 layer = 0; layer < tex_config.layers; layer++) + { + m_data[layer].resize(tex_config.levels); + for (u32 level = 0; level < tex_config.levels; level++) + { + m_data[layer][level].resize(std::max(tex_config.width >> level, 1u) * + std::max(tex_config.height >> level, 1u) * sizeof(Pixel)); + } + } } void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src, @@ -72,10 +81,10 @@ void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src, u32 src_level, const MathUtil::Rectangle& dst_rect, u32 dst_layer, u32 dst_level) { - ASSERT(src_level == 0 && src_layer == 0 && dst_layer == 0 && dst_level == 0); - CopyTextureData(src->GetConfig(), static_cast(src)->m_data.data(), - src_rect.left, src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), m_config, - m_data.data(), dst_rect.left, dst_rect.top); + CopyTextureData(src->GetConfig(), + static_cast(src)->GetData(src_layer, src_level), src_rect.left, + src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), src_level, m_config, + GetData(dst_layer, dst_level), dst_rect.left, dst_rect.top, dst_level); } void SWTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle& rect, u32 layer, u32 level) @@ -85,17 +94,25 @@ void SWTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::R void SWTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, size_t buffer_size) { - m_data.assign(buffer, buffer + buffer_size); + for (u32 layer = 0; layer < m_config.layers; layer++) + { + u8* data = GetData(layer, level); + for (u32 y = 0; y < height; y++) + { + memcpy(&data[width * y * sizeof(Pixel)], &buffer[y * row_length * sizeof(Pixel)], + width * sizeof(Pixel)); + } + } } -const u8* SWTexture::GetData() const +const u8* SWTexture::GetData(u32 layer, u32 level) const { - return m_data.data(); + return m_data[layer][level].data(); } -u8* SWTexture::GetData() +u8* SWTexture::GetData(u32 layer, u32 level) { - return m_data.data(); + return m_data[layer][level].data(); } SWStagingTexture::SWStagingTexture(StagingTextureType type, const TextureConfig& config) @@ -112,10 +129,10 @@ void SWStagingTexture::CopyFromTexture(const AbstractTexture* src, const MathUtil::Rectangle& src_rect, u32 src_layer, u32 src_level, const MathUtil::Rectangle& dst_rect) { - ASSERT(src_level == 0 && src_layer == 0); - CopyTextureData(src->GetConfig(), static_cast(src)->GetData(), src_rect.left, - src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), m_config, m_data.data(), - dst_rect.left, dst_rect.top); + CopyTextureData(src->GetConfig(), + static_cast(src)->GetData(src_layer, src_level), src_rect.left, + src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), src_level, m_config, + m_data.data(), dst_rect.left, dst_rect.top, 0); m_needs_flush = true; } @@ -123,10 +140,10 @@ void SWStagingTexture::CopyToTexture(const MathUtil::Rectangle& src_rect, A const MathUtil::Rectangle& dst_rect, u32 dst_layer, u32 dst_level) { - ASSERT(dst_level == 0 && dst_layer == 0); CopyTextureData(m_config, m_data.data(), src_rect.left, src_rect.top, src_rect.GetWidth(), - src_rect.GetHeight(), dst->GetConfig(), static_cast(dst)->GetData(), - dst_rect.left, dst_rect.top); + src_rect.GetHeight(), 0, dst->GetConfig(), + static_cast(dst)->GetData(dst_layer, dst_level), dst_rect.left, + dst_rect.top, dst_level); m_needs_flush = true; } diff --git a/Source/Core/VideoBackends/Software/SWTexture.h b/Source/Core/VideoBackends/Software/SWTexture.h index bc3fcfbbf7..e3b90eb978 100644 --- a/Source/Core/VideoBackends/Software/SWTexture.h +++ b/Source/Core/VideoBackends/Software/SWTexture.h @@ -29,11 +29,11 @@ public: void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, size_t buffer_size) override; - const u8* GetData() const; - u8* GetData(); + const u8* GetData(u32 layer, u32 level) const; + u8* GetData(u32 layer, u32 level); private: - std::vector m_data; + std::vector>> m_data; }; class SWStagingTexture final : public AbstractStagingTexture From 3d0cd8b076a4a8ff4f6741769781305cd571b5b7 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 26 Sep 2022 15:39:52 -0700 Subject: [PATCH 4/4] DolphinQt: Remove software renderer settings widget Thus, the software renderer uses the same settings as everything else, fixing https://bugs.dolphin-emu.org/issues/13051. --- Source/Core/DolphinQt/CMakeLists.txt | 2 - .../Config/Graphics/GraphicsWindow.cpp | 34 +----- .../Graphics/SoftwareRendererWidget.cpp | 113 ------------------ .../Config/Graphics/SoftwareRendererWidget.h | 33 ----- Source/Core/DolphinQt/DolphinQt.vcxproj | 2 - 5 files changed, 4 insertions(+), 180 deletions(-) delete mode 100644 Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp delete mode 100644 Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index cd7e9def60..2455b6a03e 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -92,8 +92,6 @@ add_executable(dolphin-emu Config/Graphics/HacksWidget.h Config/Graphics/PostProcessingConfigWindow.cpp Config/Graphics/PostProcessingConfigWindow.h - Config/Graphics/SoftwareRendererWidget.cpp - Config/Graphics/SoftwareRendererWidget.h Config/GraphicsModListWidget.cpp Config/GraphicsModListWidget.h Config/GraphicsModWarningWidget.cpp diff --git a/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp b/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp index ab649f2a5f..e4e1978c8a 100644 --- a/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp @@ -18,7 +18,6 @@ #include "DolphinQt/Config/Graphics/EnhancementsWidget.h" #include "DolphinQt/Config/Graphics/GeneralWidget.h" #include "DolphinQt/Config/Graphics/HacksWidget.h" -#include "DolphinQt/Config/Graphics/SoftwareRendererWidget.h" #include "DolphinQt/MainWindow.h" #include "DolphinQt/QtUtils/WrapInScrollArea.h" @@ -51,30 +50,19 @@ void GraphicsWindow::CreateMainLayout() m_enhancements_widget = new EnhancementsWidget(this); m_hacks_widget = new HacksWidget(this); m_advanced_widget = new AdvancedWidget(this); - m_software_renderer = new SoftwareRendererWidget(this); connect(m_general_widget, &GeneralWidget::BackendChanged, this, &GraphicsWindow::OnBackendChanged); - connect(m_software_renderer, &SoftwareRendererWidget::BackendChanged, this, - &GraphicsWindow::OnBackendChanged); m_wrapped_general = GetWrappedWidget(m_general_widget, this, 50, 100); m_wrapped_enhancements = GetWrappedWidget(m_enhancements_widget, this, 50, 100); m_wrapped_hacks = GetWrappedWidget(m_hacks_widget, this, 50, 100); m_wrapped_advanced = GetWrappedWidget(m_advanced_widget, this, 50, 100); - m_wrapped_software = GetWrappedWidget(m_software_renderer, this, 50, 100); - if (Config::Get(Config::MAIN_GFX_BACKEND) != "Software Renderer") - { - m_tab_widget->addTab(m_wrapped_general, tr("General")); - m_tab_widget->addTab(m_wrapped_enhancements, tr("Enhancements")); - m_tab_widget->addTab(m_wrapped_hacks, tr("Hacks")); - m_tab_widget->addTab(m_wrapped_advanced, tr("Advanced")); - } - else - { - m_tab_widget->addTab(m_wrapped_software, tr("Software Renderer")); - } + m_tab_widget->addTab(m_wrapped_general, tr("General")); + m_tab_widget->addTab(m_wrapped_enhancements, tr("Enhancements")); + m_tab_widget->addTab(m_wrapped_hacks, tr("Hacks")); + m_tab_widget->addTab(m_wrapped_advanced, tr("Advanced")); setLayout(main_layout); } @@ -86,20 +74,6 @@ void GraphicsWindow::OnBackendChanged(const QString& backend_name) setWindowTitle( tr("%1 Graphics Configuration").arg(tr(g_video_backend->GetDisplayName().c_str()))); - if (backend_name == QStringLiteral("Software Renderer") && m_tab_widget->count() > 1) - { - m_tab_widget->clear(); - m_tab_widget->addTab(m_wrapped_software, tr("Software Renderer")); - } - - if (backend_name != QStringLiteral("Software Renderer") && m_tab_widget->count() == 1) - { - m_tab_widget->clear(); - m_tab_widget->addTab(m_wrapped_general, tr("General")); - m_tab_widget->addTab(m_wrapped_enhancements, tr("Enhancements")); - m_tab_widget->addTab(m_wrapped_hacks, tr("Hacks")); - m_tab_widget->addTab(m_wrapped_advanced, tr("Advanced")); - } emit BackendChanged(backend_name); } diff --git a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp deleted file mode 100644 index 6500a90027..0000000000 --- a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "DolphinQt/Config/Graphics/SoftwareRendererWidget.h" - -#include -#include -#include -#include -#include -#include - -#include "Core/Config/GraphicsSettings.h" -#include "Core/Config/MainSettings.h" -#include "Core/ConfigManager.h" -#include "Core/Core.h" - -#include "DolphinQt/Config/Graphics/GraphicsBool.h" -#include "DolphinQt/Config/Graphics/GraphicsWindow.h" -#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h" -#include "DolphinQt/Settings.h" - -#include "UICommon/VideoUtils.h" - -#include "VideoCommon/VideoBackendBase.h" -#include "VideoCommon/VideoConfig.h" - -SoftwareRendererWidget::SoftwareRendererWidget(GraphicsWindow* parent) -{ - CreateWidgets(); - LoadSettings(); - ConnectWidgets(); - AddDescriptions(); - emit BackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND))); - - connect(parent, &GraphicsWindow::BackendChanged, [this] { LoadSettings(); }); - connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) { - OnEmulationStateChanged(state != Core::State::Uninitialized); - }); - OnEmulationStateChanged(Core::GetState() != Core::State::Uninitialized); -} - -void SoftwareRendererWidget::CreateWidgets() -{ - auto* main_layout = new QVBoxLayout; - - auto* rendering_box = new QGroupBox(tr("Rendering")); - auto* rendering_layout = new QGridLayout(); - m_backend_combo = new ToolTipComboBox(); - - rendering_box->setLayout(rendering_layout); - rendering_layout->addWidget(new QLabel(tr("Backend:")), 1, 1); - rendering_layout->addWidget(m_backend_combo, 1, 2); - - for (const auto& backend : VideoBackendBase::GetAvailableBackends()) - m_backend_combo->addItem(tr(backend->GetDisplayName().c_str())); - - main_layout->addWidget(rendering_box); - main_layout->addStretch(); - - setLayout(main_layout); -} - -void SoftwareRendererWidget::ConnectWidgets() -{ - connect(m_backend_combo, qOverload(&QComboBox::currentIndexChanged), - [this](int) { SaveSettings(); }); -} - -void SoftwareRendererWidget::LoadSettings() -{ - for (const auto& backend : VideoBackendBase::GetAvailableBackends()) - { - if (backend->GetName() == Config::Get(Config::MAIN_GFX_BACKEND)) - { - m_backend_combo->setCurrentIndex( - m_backend_combo->findText(tr(backend->GetDisplayName().c_str()))); - } - } -} - -void SoftwareRendererWidget::SaveSettings() -{ - for (const auto& backend : VideoBackendBase::GetAvailableBackends()) - { - if (tr(backend->GetDisplayName().c_str()) == m_backend_combo->currentText()) - { - const auto backend_name = backend->GetName(); - if (backend_name != Config::Get(Config::MAIN_GFX_BACKEND)) - emit BackendChanged(QString::fromStdString(backend_name)); - break; - } - } -} - -void SoftwareRendererWidget::AddDescriptions() -{ - static const char TR_BACKEND_DESCRIPTION[] = QT_TR_NOOP( - "Selects what graphics API to use internally.
The software renderer is extremely " - "slow and only useful for debugging, so you'll want to use either Direct3D or " - "OpenGL. Different games and different GPUs will behave differently on each " - "backend, so for the best emulation experience it's recommended to try both and " - "choose the one that's less problematic.

If unsure, select " - "OpenGL."); - - m_backend_combo->SetTitle(tr("Backend")); - m_backend_combo->SetDescription(tr(TR_BACKEND_DESCRIPTION)); -} - -void SoftwareRendererWidget::OnEmulationStateChanged(bool running) -{ - m_backend_combo->setEnabled(!running); -} diff --git a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h b/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h deleted file mode 100644 index 492a499287..0000000000 --- a/Source/Core/DolphinQt/Config/Graphics/SoftwareRendererWidget.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "DolphinQt/Config/Graphics/GraphicsWidget.h" - -class GraphicsBool; -class GraphicsWindow; -class QSpinBox; -class ToolTipComboBox; - -class SoftwareRendererWidget final : public GraphicsWidget -{ - Q_OBJECT -public: - explicit SoftwareRendererWidget(GraphicsWindow* parent); - -signals: - void BackendChanged(const QString& backend); - -private: - void LoadSettings() override; - void SaveSettings() override; - - void CreateWidgets(); - void ConnectWidgets(); - void AddDescriptions(); - - void OnEmulationStateChanged(bool running); - - ToolTipComboBox* m_backend_combo; -}; diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index fce9c11813..3c37f4ca1e 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -79,7 +79,6 @@ - @@ -276,7 +275,6 @@ -