diff --git a/src/core/settings.cpp b/src/core/settings.cpp index b088c7aac..37ba8cad2 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -17,6 +17,7 @@ void Settings::SetDefaults() gpu_true_color = true; gpu_texture_filtering = false; gpu_force_progressive_scan = true; + gpu_use_debug_device = false; display_linear_filtering = true; display_fullscreen = false; video_sync_enabled = true; @@ -51,6 +52,7 @@ void Settings::Load(SettingsInterface& si) gpu_resolution_scale = static_cast(si.GetIntValue("GPU", "ResolutionScale", 1)); gpu_true_color = si.GetBoolValue("GPU", "TrueColor", false); gpu_texture_filtering = si.GetBoolValue("GPU", "TextureFiltering", false); + gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false); display_linear_filtering = si.GetBoolValue("Display", "LinearFiltering", true); display_fullscreen = si.GetBoolValue("Display", "Fullscreen", false); @@ -86,6 +88,7 @@ void Settings::Save(SettingsInterface& si) const si.SetIntValue("GPU", "ResolutionScale", static_cast(gpu_resolution_scale)); si.SetBoolValue("GPU", "TrueColor", gpu_true_color); si.SetBoolValue("GPU", "TextureFiltering", gpu_texture_filtering); + si.SetBoolValue("GPU", "UseDebugDevice", gpu_use_debug_device); si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering); si.SetBoolValue("Display", "Fullscreen", display_fullscreen); diff --git a/src/core/settings.h b/src/core/settings.h index f8b110c94..6b2cd1e01 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -44,6 +44,7 @@ struct Settings bool gpu_true_color = false; bool gpu_texture_filtering = false; bool gpu_force_progressive_scan = false; + bool gpu_use_debug_device = false; bool display_linear_filtering = true; bool display_fullscreen = false; bool video_sync_enabled = true; diff --git a/src/duckstation-qt/d3d11displaywindow.cpp b/src/duckstation-qt/d3d11displaywindow.cpp index f311d3bc1..f66419db9 100644 --- a/src/duckstation-qt/d3d11displaywindow.cpp +++ b/src/duckstation-qt/d3d11displaywindow.cpp @@ -192,10 +192,8 @@ void D3D11DisplayWindow::onWindowResized(int width, int height) Panic("Failed to recreate swap chain RTV after resize"); } -bool D3D11DisplayWindow::createDeviceContext(QThread* worker_thread) +bool D3D11DisplayWindow::createDeviceContext(QThread* worker_thread, bool debug_device) { - const bool debug = false; - ComPtr dxgi_factory; HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(dxgi_factory.GetAddressOf())); if (FAILED(hr)) @@ -217,7 +215,7 @@ bool D3D11DisplayWindow::createDeviceContext(QThread* worker_thread) } UINT create_flags = 0; - if (debug) + if (debug_device) create_flags |= D3D11_CREATE_DEVICE_DEBUG; hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, create_flags, nullptr, 0, D3D11_SDK_VERSION, @@ -259,7 +257,7 @@ bool D3D11DisplayWindow::createDeviceContext(QThread* worker_thread) } } - if (debug) + if (debug_device) { ComPtr info; hr = m_device.As(&info); @@ -270,7 +268,7 @@ bool D3D11DisplayWindow::createDeviceContext(QThread* worker_thread) } } - if (!QtDisplayWindow::createDeviceContext(worker_thread)) + if (!QtDisplayWindow::createDeviceContext(worker_thread, debug_device)) { m_swap_chain.Reset(); m_context.Reset(); @@ -280,12 +278,12 @@ bool D3D11DisplayWindow::createDeviceContext(QThread* worker_thread) return true; } -bool D3D11DisplayWindow::initializeDeviceContext() +bool D3D11DisplayWindow::initializeDeviceContext(bool debug_device) { if (!createSwapChainRTV()) return false; - if (!QtDisplayWindow::initializeDeviceContext()) + if (!QtDisplayWindow::initializeDeviceContext(debug_device)) return false; return true; diff --git a/src/duckstation-qt/d3d11displaywindow.h b/src/duckstation-qt/d3d11displaywindow.h index 88e948a3b..0342ac89c 100644 --- a/src/duckstation-qt/d3d11displaywindow.h +++ b/src/duckstation-qt/d3d11displaywindow.h @@ -21,8 +21,8 @@ public: HostDisplay* getHostDisplayInterface() override; - bool createDeviceContext(QThread* worker_thread) override; - bool initializeDeviceContext() override; + bool createDeviceContext(QThread* worker_thread, bool debug_device) override; + bool initializeDeviceContext(bool debug_device) override; void destroyDeviceContext() override; RenderAPI GetRenderAPI() const override; diff --git a/src/duckstation-qt/opengldisplaywindow.cpp b/src/duckstation-qt/opengldisplaywindow.cpp index ebd7cdd03..f5f690045 100644 --- a/src/duckstation-qt/opengldisplaywindow.cpp +++ b/src/duckstation-qt/opengldisplaywindow.cpp @@ -234,7 +234,7 @@ static void APIENTRY GLDebugCallback(GLenum source, GLenum type, GLuint id, GLen } } -bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread) +bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread, bool debug_device) { m_gl_context = std::make_unique(); @@ -249,9 +249,8 @@ bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread) surface_format.setRenderableType(QSurfaceFormat::OpenGL); surface_format.setProfile(QSurfaceFormat::CoreProfile); -#ifdef _DEBUG - surface_format.setOption(QSurfaceFormat::DebugContext); -#endif + if (debug_device) + surface_format.setOption(QSurfaceFormat::DebugContext); for (const auto [major, minor] : desktop_versions_to_try) { @@ -269,9 +268,8 @@ bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread) // try es surface_format.setRenderableType(QSurfaceFormat::OpenGLES); surface_format.setProfile(QSurfaceFormat::NoProfile); -#ifdef _DEBUG - surface_format.setOption(QSurfaceFormat::DebugContext, false); -#endif + if (debug_device) + surface_format.setOption(QSurfaceFormat::DebugContext, false); for (const auto [major, minor] : es_versions_to_try) { @@ -300,7 +298,7 @@ bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread) return false; } - if (!QtDisplayWindow::createDeviceContext(worker_thread)) + if (!QtDisplayWindow::createDeviceContext(worker_thread, debug_device)) { m_gl_context->doneCurrent(); m_gl_context.reset(); @@ -312,7 +310,7 @@ bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread) return true; } -bool OpenGLDisplayWindow::initializeDeviceContext() +bool OpenGLDisplayWindow::initializeDeviceContext(bool debug_device) { if (!m_gl_context->makeCurrent(this)) return false; @@ -330,16 +328,14 @@ bool OpenGLDisplayWindow::initializeDeviceContext() return false; } -#if 0 - if (GLAD_GL_KHR_debug) + if (debug_device && GLAD_GL_KHR_debug) { glad_glDebugMessageCallbackKHR(GLDebugCallback, nullptr); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } -#endif - if (!QtDisplayWindow::initializeDeviceContext()) + if (!QtDisplayWindow::initializeDeviceContext(debug_device)) { s_thread_gl_context = nullptr; m_gl_context->doneCurrent(); diff --git a/src/duckstation-qt/opengldisplaywindow.h b/src/duckstation-qt/opengldisplaywindow.h index 100dc04a4..e50748588 100644 --- a/src/duckstation-qt/opengldisplaywindow.h +++ b/src/duckstation-qt/opengldisplaywindow.h @@ -20,8 +20,8 @@ public: HostDisplay* getHostDisplayInterface() override; - bool createDeviceContext(QThread* worker_thread) override; - bool initializeDeviceContext() override; + bool createDeviceContext(QThread* worker_thread, bool debug_device) override; + bool initializeDeviceContext(bool debug_device) override; void destroyDeviceContext() override; RenderAPI GetRenderAPI() const override; diff --git a/src/duckstation-qt/qtdisplaywindow.cpp b/src/duckstation-qt/qtdisplaywindow.cpp index 4d14c67a2..75d88afdc 100644 --- a/src/duckstation-qt/qtdisplaywindow.cpp +++ b/src/duckstation-qt/qtdisplaywindow.cpp @@ -18,12 +18,12 @@ HostDisplay* QtDisplayWindow::getHostDisplayInterface() return nullptr; } -bool QtDisplayWindow::createDeviceContext(QThread* worker_thread) +bool QtDisplayWindow::createDeviceContext(QThread* worker_thread, bool debug_device) { return true; } -bool QtDisplayWindow::initializeDeviceContext() +bool QtDisplayWindow::initializeDeviceContext(bool debug_device) { if (!createImGuiContext() || !createDeviceResources()) return false; diff --git a/src/duckstation-qt/qtdisplaywindow.h b/src/duckstation-qt/qtdisplaywindow.h index 6252aed09..f8a9fb551 100644 --- a/src/duckstation-qt/qtdisplaywindow.h +++ b/src/duckstation-qt/qtdisplaywindow.h @@ -18,8 +18,8 @@ public: virtual HostDisplay* getHostDisplayInterface(); - virtual bool createDeviceContext(QThread* worker_thread); - virtual bool initializeDeviceContext(); + virtual bool createDeviceContext(QThread* worker_thread, bool debug_device); + virtual bool initializeDeviceContext(bool debug_device); virtual void destroyDeviceContext(); virtual void Render(); diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index 9ce6e65ba..b4a74c1fc 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -150,7 +150,7 @@ void QtHostInterface::bootSystem(QString initial_filename, QString initial_save_ Assert(!isOnWorkerThread()); emit emulationStarting(); - if (!m_display_window->createDeviceContext(m_worker_thread)) + if (!m_display_window->createDeviceContext(m_worker_thread, m_settings.gpu_use_debug_device)) { emit emulationStopped(); return; @@ -420,7 +420,7 @@ QByteArray QtHostInterface::saveStateToMemory() void QtHostInterface::doBootSystem(QString initial_filename, QString initial_save_state_filename) { - if (!m_display_window->initializeDeviceContext()) + if (!m_display_window->initializeDeviceContext(m_settings.gpu_use_debug_device)) { emit emulationStopped(); return; diff --git a/src/duckstation/d3d11_host_display.cpp b/src/duckstation/d3d11_host_display.cpp index 8d0c8f26a..1ff4ccb30 100644 --- a/src/duckstation/d3d11_host_display.cpp +++ b/src/duckstation/d3d11_host_display.cpp @@ -190,10 +190,8 @@ void D3D11HostDisplay::WindowResized() Panic("Failed to recreate swap chain RTV after resize"); } -bool D3D11HostDisplay::CreateD3DDevice() +bool D3D11HostDisplay::CreateD3DDevice(bool debug_device) { - const bool debug = false; - SDL_SysWMinfo syswm = {}; if (!SDL_GetWindowWMInfo(m_window, &syswm)) { @@ -222,7 +220,7 @@ bool D3D11HostDisplay::CreateD3DDevice() } UINT create_flags = 0; - if (debug) + if (debug_device) create_flags |= D3D11_CREATE_DEVICE_DEBUG; hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, create_flags, nullptr, 0, D3D11_SDK_VERSION, @@ -264,7 +262,7 @@ bool D3D11HostDisplay::CreateD3DDevice() } } - if (debug) + if (debug_device) { ComPtr info; hr = m_device.As(&info); @@ -386,10 +384,10 @@ bool D3D11HostDisplay::CreateImGuiContext() return true; } -std::unique_ptr D3D11HostDisplay::Create(SDL_Window* window) +std::unique_ptr D3D11HostDisplay::Create(SDL_Window* window, bool debug_device) { std::unique_ptr display = std::make_unique(window); - if (!display->CreateD3DDevice() || !display->CreateSwapChainRTV() || !display->CreateD3DResources() || + if (!display->CreateD3DDevice(debug_device) || !display->CreateSwapChainRTV() || !display->CreateD3DResources() || !display->CreateImGuiContext()) { return nullptr; diff --git a/src/duckstation/d3d11_host_display.h b/src/duckstation/d3d11_host_display.h index c127397ad..c56177bdb 100644 --- a/src/duckstation/d3d11_host_display.h +++ b/src/duckstation/d3d11_host_display.h @@ -17,7 +17,7 @@ public: D3D11HostDisplay(SDL_Window* window); ~D3D11HostDisplay(); - static std::unique_ptr Create(SDL_Window* window); + static std::unique_ptr Create(SDL_Window* window, bool debug_device); RenderAPI GetRenderAPI() const override; void* GetRenderDevice() const override; @@ -44,7 +44,7 @@ public: private: static constexpr u32 DISPLAY_UNIFORM_BUFFER_SIZE = 16; - bool CreateD3DDevice(); + bool CreateD3DDevice(bool debug_device); bool CreateD3DResources(); bool CreateSwapChainRTV(); bool CreateImGuiContext(); diff --git a/src/duckstation/opengl_host_display.cpp b/src/duckstation/opengl_host_display.cpp index 57ca189da..ff33e571a 100644 --- a/src/duckstation/opengl_host_display.cpp +++ b/src/duckstation/opengl_host_display.cpp @@ -203,7 +203,7 @@ static void APIENTRY GLDebugCallback(GLenum source, GLenum type, GLuint id, GLen } } -bool OpenGLHostDisplay::CreateGLContext() +bool OpenGLHostDisplay::CreateGLContext(bool debug_device) { // Prefer a desktop OpenGL context where possible. If we can't get this, try OpenGL ES. static constexpr std::array, 11> desktop_versions_to_try = { @@ -212,9 +212,8 @@ bool OpenGLHostDisplay::CreateGLContext() SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); -#ifdef _DEBUG - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); -#endif + if (debug_device) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); for (const auto [major, minor] : desktop_versions_to_try) { @@ -267,16 +266,13 @@ bool OpenGLHostDisplay::CreateGLContext() return false; } -#if 0 - if (GLAD_GL_KHR_debug) + if (debug_device && GLAD_GL_KHR_debug) { glad_glDebugMessageCallbackKHR(GLDebugCallback, nullptr); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } -#endif - SDL_GL_SetSwapInterval(0); return true; } @@ -350,10 +346,10 @@ void main() return true; } -std::unique_ptr OpenGLHostDisplay::Create(SDL_Window* window) +std::unique_ptr OpenGLHostDisplay::Create(SDL_Window* window, bool debug_device) { std::unique_ptr display = std::make_unique(window); - if (!display->CreateGLContext() || !display->CreateImGuiContext() || !display->CreateGLResources()) + if (!display->CreateGLContext(debug_device) || !display->CreateImGuiContext() || !display->CreateGLResources()) return nullptr; return display; diff --git a/src/duckstation/opengl_host_display.h b/src/duckstation/opengl_host_display.h index 12536cbd5..77538db7d 100644 --- a/src/duckstation/opengl_host_display.h +++ b/src/duckstation/opengl_host_display.h @@ -12,7 +12,7 @@ public: OpenGLHostDisplay(SDL_Window* window); ~OpenGLHostDisplay(); - static std::unique_ptr Create(SDL_Window* window); + static std::unique_ptr Create(SDL_Window* window, bool debug_device); RenderAPI GetRenderAPI() const override; void* GetRenderDevice() const override; @@ -40,7 +40,7 @@ private: const char* GetGLSLVersionString() const; std::string GetGLSLVersionHeader() const; - bool CreateGLContext(); + bool CreateGLContext(bool debug_device); bool CreateImGuiContext(); bool CreateGLResources(); diff --git a/src/duckstation/sdl_host_interface.cpp b/src/duckstation/sdl_host_interface.cpp index 59137e6f5..1451fa4d5 100644 --- a/src/duckstation/sdl_host_interface.cpp +++ b/src/duckstation/sdl_host_interface.cpp @@ -85,10 +85,12 @@ void SDLHostInterface::DestroySDLWindow() bool SDLHostInterface::CreateDisplay() { + const bool debug_device = m_settings.gpu_use_debug_device; #ifdef WIN32 - m_display = UseOpenGLRenderer() ? OpenGLHostDisplay::Create(m_window) : D3D11HostDisplay::Create(m_window); + m_display = UseOpenGLRenderer() ? OpenGLHostDisplay::Create(m_window, debug_device) : + D3D11HostDisplay::Create(m_window, debug_device); #else - m_display = OpenGLHostDisplay::Create(m_window); + m_display = OpenGLHostDisplay::Create(m_window, debug_device); #endif if (!m_display) @@ -296,8 +298,7 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event) switch (event->type) { - case SDL_WINDOWEVENT: - { + case SDL_WINDOWEVENT: { if (event->window.event == SDL_WINDOWEVENT_RESIZED) m_display->WindowResized(); } @@ -308,22 +309,19 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event) break; case SDL_KEYDOWN: - case SDL_KEYUP: - { + case SDL_KEYUP: { if (!ImGui::GetIO().WantCaptureKeyboard) HandleSDLKeyEvent(event); } break; - case SDL_CONTROLLERDEVICEADDED: - { + case SDL_CONTROLLERDEVICEADDED: { Log_InfoPrintf("Controller %d inserted", event->cdevice.which); OpenGameController(event->cdevice.which); } break; - case SDL_CONTROLLERDEVICEREMOVED: - { + case SDL_CONTROLLERDEVICEREMOVED: { Log_InfoPrintf("Controller %d removed", event->cdevice.which); CloseGameController(event->cdevice.which); } @@ -334,8 +332,7 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event) break; case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: - { + case SDL_CONTROLLERBUTTONUP: { if (event->type == SDL_CONTROLLERBUTTONDOWN && event->cbutton.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK) { // focus the menu bar @@ -346,8 +343,7 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event) } break; - case SDL_USEREVENT: - { + case SDL_USEREVENT: { if (static_cast(event->user.code) == m_switch_gpu_renderer_event_id) SwitchGPURenderer(); } @@ -371,8 +367,7 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event) case SDL_SCANCODE_F5: case SDL_SCANCODE_F6: case SDL_SCANCODE_F7: - case SDL_SCANCODE_F8: - { + case SDL_SCANCODE_F8: { if (!pressed) { const u32 index = event->key.keysym.scancode - SDL_SCANCODE_F1 + 1; @@ -384,15 +379,13 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event) } break; - case SDL_SCANCODE_F11: - { + case SDL_SCANCODE_F11: { if (!pressed) DoToggleFullscreen(); } break; - case SDL_SCANCODE_TAB: - { + case SDL_SCANCODE_TAB: { if (!repeat) { m_speed_limiter_temp_disabled = pressed; @@ -401,22 +394,19 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event) } break; - case SDL_SCANCODE_PAUSE: - { + case SDL_SCANCODE_PAUSE: { if (pressed) DoTogglePause(); } break; - case SDL_SCANCODE_SPACE: - { + case SDL_SCANCODE_SPACE: { if (pressed) DoFrameStep(); } break; - case SDL_SCANCODE_HOME: - { + case SDL_SCANCODE_HOME: { if (pressed && !repeat && m_system) { m_settings.speed_limiter_enabled = !m_settings.speed_limiter_enabled; @@ -427,16 +417,14 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event) } break; - case SDL_SCANCODE_END: - { + case SDL_SCANCODE_END: { if (pressed) DoToggleSoftwareRendering(); } break; case SDL_SCANCODE_PAGEUP: - case SDL_SCANCODE_PAGEDOWN: - { + case SDL_SCANCODE_PAGEDOWN: { if (pressed) { DoModifyInternalResolution(event->key.keysym.scancode == SDL_SCANCODE_PAGEUP ? 1 : -1);