mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 09:35:40 +00:00
SDL: Support Vulkan
This commit is contained in:
parent
6aacf0019a
commit
d168947ae4
|
@ -7,10 +7,14 @@ add_executable(duckstation-sdl
|
|||
sdl_host_interface.cpp
|
||||
sdl_host_interface.h
|
||||
sdl_key_names.h
|
||||
sdl_util.cpp
|
||||
sdl_util.h
|
||||
sdl_vulkan_host_display.cpp
|
||||
sdl_vulkan_host_display.h
|
||||
)
|
||||
|
||||
target_include_directories(duckstation-sdl PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||
target_link_libraries(duckstation-sdl PRIVATE core common imgui nativefiledialog glad frontend-common scmversion ${SDL2_LIBRARIES})
|
||||
target_link_libraries(duckstation-sdl PRIVATE core common imgui nativefiledialog glad frontend-common scmversion vulkan-loader ${SDL2_LIBRARIES})
|
||||
|
||||
if(WIN32)
|
||||
target_sources(duckstation-sdl PRIVATE
|
||||
|
|
|
@ -381,6 +381,7 @@ bool D3D11HostDisplay::CreateImGuiContext()
|
|||
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame(m_window);
|
||||
ImGui::NewFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
<ClCompile Include="opengl_host_display.cpp" />
|
||||
<ClCompile Include="sdl_host_interface.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="sdl_util.cpp" />
|
||||
<ClCompile Include="sdl_vulkan_host_display.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="d3d11_host_display.h" />
|
||||
|
@ -68,6 +70,8 @@
|
|||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="sdl_host_interface.h" />
|
||||
<ClInclude Include="sdl_key_names.h" />
|
||||
<ClInclude Include="sdl_util.h" />
|
||||
<ClInclude Include="sdl_vulkan_host_display.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="duckstation-sdl.manifest" />
|
||||
|
@ -227,7 +231,7 @@
|
|||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -248,7 +252,7 @@
|
|||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -269,7 +273,7 @@
|
|||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
|
@ -293,7 +297,7 @@
|
|||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
|
@ -316,7 +320,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -339,7 +343,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -363,7 +367,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -386,7 +390,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
<ClCompile Include="sdl_host_interface.cpp" />
|
||||
<ClCompile Include="d3d11_host_display.cpp" />
|
||||
<ClCompile Include="imgui_impl_sdl.cpp" />
|
||||
<ClCompile Include="sdl_util.cpp" />
|
||||
<ClCompile Include="sdl_vulkan_host_display.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="opengl_host_display.h" />
|
||||
|
@ -14,6 +16,8 @@
|
|||
<ClInclude Include="imgui_impl_sdl.h" />
|
||||
<ClInclude Include="sdl_key_names.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="sdl_util.h" />
|
||||
<ClInclude Include="sdl_vulkan_host_display.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="duckstation-sdl.manifest" />
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "common/assert.h"
|
||||
#include "common/log.h"
|
||||
#include "imgui_impl_sdl.h"
|
||||
#include "sdl_util.h"
|
||||
#include <SDL_syswm.h>
|
||||
#include <array>
|
||||
#include <imgui.h>
|
||||
|
@ -9,17 +10,6 @@
|
|||
#include <tuple>
|
||||
Log_SetChannel(OpenGLHostDisplay);
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <objc/message.h>
|
||||
struct NSView;
|
||||
|
||||
static NSView* GetContentViewFromWindow(NSWindow* window)
|
||||
{
|
||||
// window.contentView
|
||||
return reinterpret_cast<NSView* (*)(id, SEL)>(objc_msgSend)(reinterpret_cast<id>(window), sel_getUid("contentView"));
|
||||
}
|
||||
#endif
|
||||
|
||||
class OpenGLDisplayWidgetTexture : public HostDisplayTexture
|
||||
{
|
||||
public:
|
||||
|
@ -220,52 +210,11 @@ static void APIENTRY GLDebugCallback(GLenum source, GLenum type, GLuint id, GLen
|
|||
|
||||
bool OpenGLHostDisplay::CreateGLContext(bool debug_device)
|
||||
{
|
||||
SDL_SysWMinfo syswm = {};
|
||||
SDL_VERSION(&syswm.version);
|
||||
if (!SDL_GetWindowWMInfo(m_window, &syswm))
|
||||
{
|
||||
Log_ErrorPrintf("SDL_GetWindowWMInfo failed");
|
||||
std::optional<WindowInfo> wi = SDLUtil::GetWindowInfoForSDLWindow(m_window);
|
||||
if (!wi)
|
||||
return false;
|
||||
}
|
||||
|
||||
int window_width, window_height;
|
||||
SDL_GetWindowSize(m_window, &window_width, &window_height);
|
||||
|
||||
WindowInfo wi;
|
||||
wi.surface_width = static_cast<u32>(window_width);
|
||||
wi.surface_height = static_cast<u32>(window_height);
|
||||
wi.surface_format = WindowInfo::SurfaceFormat::RGB8;
|
||||
|
||||
switch (syswm.subsystem)
|
||||
{
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
case SDL_SYSWM_WINDOWS:
|
||||
wi.type = WindowInfo::Type::Win32;
|
||||
wi.window_handle = syswm.info.win.window;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_COCOA
|
||||
case SDL_SYSWM_COCOA:
|
||||
wi.type = WindowInfo::Type::MacOS;
|
||||
wi.window_handle = GetContentViewFromWindow(syswm.info.cocoa.window);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
case SDL_SYSWM_X11:
|
||||
wi.type = WindowInfo::Type::X11;
|
||||
wi.window_handle = reinterpret_cast<void*>(static_cast<uintptr_t>(syswm.info.x11.window));
|
||||
wi.display_connection = syswm.info.x11.display;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
Log_ErrorPrintf("Unhandled syswm subsystem %u", static_cast<u32>(syswm.subsystem));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gl_context = GL::Context::Create(wi);
|
||||
m_gl_context = GL::Context::Create(wi.value());
|
||||
if (!m_gl_context)
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create a GL context of any kind.");
|
||||
|
@ -298,6 +247,7 @@ bool OpenGLHostDisplay::CreateImGuiContext()
|
|||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame(m_window);
|
||||
ImGui::NewFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "opengl_host_display.h"
|
||||
#include "scmversion/scmversion.h"
|
||||
#include "sdl_key_names.h"
|
||||
#include "sdl_vulkan_host_display.h"
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <imgui.h>
|
||||
|
@ -129,13 +130,29 @@ void SDLHostInterface::DestroySDLWindow()
|
|||
bool SDLHostInterface::CreateDisplay()
|
||||
{
|
||||
const bool debug_device = m_settings.gpu_use_debug_device;
|
||||
const std::string shader_cache_directory(GetShaderCacheDirectory());
|
||||
std::unique_ptr<HostDisplay> display;
|
||||
#ifdef WIN32
|
||||
display = UseOpenGLRenderer() ? OpenGLHostDisplay::Create(m_window, debug_device) :
|
||||
D3D11HostDisplay::Create(m_window, debug_device);
|
||||
#else
|
||||
display = OpenGLHostDisplay::Create(m_window, debug_device);
|
||||
|
||||
switch (m_settings.gpu_renderer)
|
||||
{
|
||||
case GPURenderer::HardwareVulkan:
|
||||
display = SDLVulkanHostDisplay::Create(m_window, shader_cache_directory, debug_device);
|
||||
break;
|
||||
|
||||
case GPURenderer::HardwareOpenGL:
|
||||
#ifndef WIN32
|
||||
default:
|
||||
#endif
|
||||
display = OpenGLHostDisplay::Create(m_window, debug_device);
|
||||
break;
|
||||
|
||||
#ifdef WIN32
|
||||
case GPURenderer::HardwareD3D11:
|
||||
default:
|
||||
display = D3D11HostDisplay::Create(m_window, debug_device);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!display)
|
||||
return false;
|
||||
|
@ -181,13 +198,32 @@ void SDLHostInterface::UpdateFramebufferScale()
|
|||
|
||||
bool SDLHostInterface::AcquireHostDisplay()
|
||||
{
|
||||
// Handle renderer switch if required on Windows.
|
||||
#ifdef WIN32
|
||||
// Handle renderer switch if required.
|
||||
const HostDisplay::RenderAPI render_api = m_display->GetRenderAPI();
|
||||
const bool render_api_is_gl =
|
||||
render_api == HostDisplay::RenderAPI::OpenGL || render_api == HostDisplay::RenderAPI::OpenGLES;
|
||||
const bool render_api_wants_gl = UseOpenGLRenderer();
|
||||
if (render_api_is_gl != render_api_wants_gl)
|
||||
bool needs_switch = false;
|
||||
switch (m_settings.gpu_renderer)
|
||||
{
|
||||
#ifdef WIN32
|
||||
case GPURenderer::HardwareD3D11:
|
||||
needs_switch = (render_api != HostDisplay::RenderAPI::D3D11);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GPURenderer::HardwareVulkan:
|
||||
needs_switch = (render_api != HostDisplay::RenderAPI::Vulkan);
|
||||
break;
|
||||
|
||||
case GPURenderer::HardwareOpenGL:
|
||||
needs_switch = (render_api != HostDisplay::RenderAPI::OpenGL && render_api != HostDisplay::RenderAPI::OpenGLES);
|
||||
break;
|
||||
|
||||
case GPURenderer::Software:
|
||||
default:
|
||||
needs_switch = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (needs_switch)
|
||||
{
|
||||
ImGui::EndFrame();
|
||||
DestroyDisplay();
|
||||
|
@ -198,10 +234,7 @@ bool SDLHostInterface::AcquireHostDisplay()
|
|||
|
||||
if (!CreateDisplay())
|
||||
Panic("Failed to recreate display on GPU renderer switch");
|
||||
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -358,8 +391,6 @@ bool SDLHostInterface::Initialize()
|
|||
|
||||
RegisterHotkeys();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
// process events to pick up controllers before updating input map
|
||||
ProcessEvents();
|
||||
UpdateInputMap();
|
||||
|
|
|
@ -58,12 +58,6 @@ protected:
|
|||
private:
|
||||
bool HasSystem() const { return static_cast<bool>(m_system); }
|
||||
|
||||
#ifdef WIN32
|
||||
bool UseOpenGLRenderer() const { return m_settings.gpu_renderer == GPURenderer::HardwareOpenGL; }
|
||||
#else
|
||||
bool UseOpenGLRenderer() const { return true; }
|
||||
#endif
|
||||
|
||||
static float GetDPIScaleFactor(SDL_Window* window);
|
||||
|
||||
bool CreateSDLWindow();
|
||||
|
|
68
src/duckstation-sdl/sdl_util.cpp
Normal file
68
src/duckstation-sdl/sdl_util.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "sdl_util.h"
|
||||
#include "common/log.h"
|
||||
#include <SDL_syswm.h>
|
||||
Log_SetChannel(SDLUtil);
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <objc/message.h>
|
||||
struct NSView;
|
||||
|
||||
static NSView* GetContentViewFromWindow(NSWindow* window)
|
||||
{
|
||||
// window.contentView
|
||||
return reinterpret_cast<NSView* (*)(id, SEL)>(objc_msgSend)(reinterpret_cast<id>(window), sel_getUid("contentView"));
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace SDLUtil {
|
||||
|
||||
std::optional<WindowInfo> GetWindowInfoForSDLWindow(SDL_Window* window)
|
||||
{
|
||||
SDL_SysWMinfo syswm = {};
|
||||
SDL_VERSION(&syswm.version);
|
||||
if (!SDL_GetWindowWMInfo(window, &syswm))
|
||||
{
|
||||
Log_ErrorPrintf("SDL_GetWindowWMInfo failed");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
int window_width, window_height;
|
||||
SDL_GetWindowSize(window, &window_width, &window_height);
|
||||
|
||||
WindowInfo wi;
|
||||
wi.surface_width = static_cast<u32>(window_width);
|
||||
wi.surface_height = static_cast<u32>(window_height);
|
||||
wi.surface_format = WindowInfo::SurfaceFormat::RGB8;
|
||||
|
||||
switch (syswm.subsystem)
|
||||
{
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
case SDL_SYSWM_WINDOWS:
|
||||
wi.type = WindowInfo::Type::Win32;
|
||||
wi.window_handle = syswm.info.win.window;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_COCOA
|
||||
case SDL_SYSWM_COCOA:
|
||||
wi.type = WindowInfo::Type::MacOS;
|
||||
wi.window_handle = GetContentViewFromWindow(syswm.info.cocoa.window);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
case SDL_SYSWM_X11:
|
||||
wi.type = WindowInfo::Type::X11;
|
||||
wi.window_handle = reinterpret_cast<void*>(static_cast<uintptr_t>(syswm.info.x11.window));
|
||||
wi.display_connection = syswm.info.x11.display;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
Log_ErrorPrintf("Unhandled syswm subsystem %u", static_cast<u32>(syswm.subsystem));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return wi;
|
||||
}
|
||||
} // namespace SDLUtil
|
10
src/duckstation-sdl/sdl_util.h
Normal file
10
src/duckstation-sdl/sdl_util.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
#include "common/types.h"
|
||||
#include "common/window_info.h"
|
||||
#include <optional>
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
namespace SDLUtil {
|
||||
std::optional<WindowInfo> GetWindowInfoForSDLWindow(SDL_Window* window);
|
||||
}
|
134
src/duckstation-sdl/sdl_vulkan_host_display.cpp
Normal file
134
src/duckstation-sdl/sdl_vulkan_host_display.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include "sdl_vulkan_host_display.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/log.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl.h"
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include "sdl_util.h"
|
||||
#include <SDL_syswm.h>
|
||||
#include <array>
|
||||
Log_SetChannel(VulkanHostDisplay);
|
||||
|
||||
SDLVulkanHostDisplay::SDLVulkanHostDisplay(SDL_Window* window) : m_window(window)
|
||||
{
|
||||
SDL_GetWindowSize(window, &m_window_width, &m_window_height);
|
||||
}
|
||||
|
||||
SDLVulkanHostDisplay::~SDLVulkanHostDisplay()
|
||||
{
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
m_display.DestroyImGuiContext();
|
||||
m_display.DestroyResources();
|
||||
m_display.DestroyShaderCache();
|
||||
m_display.DestroySwapChain();
|
||||
m_display.DestroyContext();
|
||||
|
||||
if (m_window)
|
||||
SDL_DestroyWindow(m_window);
|
||||
}
|
||||
|
||||
std::unique_ptr<HostDisplay> SDLVulkanHostDisplay::Create(SDL_Window* window, std::string_view shader_cache_directory,
|
||||
bool debug_device)
|
||||
{
|
||||
std::unique_ptr<SDLVulkanHostDisplay> display = std::make_unique<SDLVulkanHostDisplay>(window);
|
||||
if (!display->Initialize(shader_cache_directory, debug_device))
|
||||
return nullptr;
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
HostDisplay::RenderAPI SDLVulkanHostDisplay::GetRenderAPI() const
|
||||
{
|
||||
return m_display.GetRenderAPI();
|
||||
}
|
||||
|
||||
void* SDLVulkanHostDisplay::GetRenderDevice() const
|
||||
{
|
||||
return m_display.GetRenderDevice();
|
||||
}
|
||||
|
||||
void* SDLVulkanHostDisplay::GetRenderContext() const
|
||||
{
|
||||
return m_display.GetRenderContext();
|
||||
}
|
||||
|
||||
void SDLVulkanHostDisplay::WindowResized(s32 new_window_width, s32 new_window_height)
|
||||
{
|
||||
m_display.ResizeSwapChain(static_cast<u32>(new_window_width), static_cast<u32>(new_window_height));
|
||||
m_window_width = static_cast<s32>(m_display.GetSwapChainWidth());
|
||||
m_window_height = static_cast<s32>(m_display.GetSwapChainHeight());
|
||||
}
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> SDLVulkanHostDisplay::CreateTexture(u32 width, u32 height, const void* data,
|
||||
u32 data_stride, bool dynamic /*= false*/)
|
||||
{
|
||||
return m_display.CreateTexture(width, height, data, data_stride, dynamic);
|
||||
}
|
||||
|
||||
void SDLVulkanHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height,
|
||||
const void* data, u32 data_stride)
|
||||
{
|
||||
m_display.UpdateTexture(texture, x, y, width, height, data, data_stride);
|
||||
}
|
||||
|
||||
bool SDLVulkanHostDisplay::DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height,
|
||||
void* out_data, u32 out_data_stride)
|
||||
{
|
||||
return m_display.DownloadTexture(texture_handle, x, y, width, height, out_data, out_data_stride);
|
||||
}
|
||||
|
||||
void SDLVulkanHostDisplay::SetVSync(bool enabled)
|
||||
{
|
||||
m_display.SetVSync(enabled);
|
||||
}
|
||||
|
||||
bool SDLVulkanHostDisplay::Initialize(std::string_view shader_cache_directory, bool debug_device)
|
||||
{
|
||||
std::optional<WindowInfo> wi = SDLUtil::GetWindowInfoForSDLWindow(m_window);
|
||||
if (!wi.has_value())
|
||||
{
|
||||
Log_ErrorPrintf("Failed to get window info for SDL window");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_display.CreateContextAndSwapChain(wi.value(), debug_device))
|
||||
return false;
|
||||
|
||||
m_display.CreateShaderCache(shader_cache_directory, debug_device);
|
||||
|
||||
if (!m_display.CreateResources())
|
||||
return false;
|
||||
|
||||
if (!m_display.CreateImGuiContext() || !ImGui_ImplSDL2_InitForVulkan(m_window))
|
||||
return false;
|
||||
|
||||
ImGui_ImplSDL2_NewFrame(m_window);
|
||||
ImGui::NewFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDLVulkanHostDisplay::Render()
|
||||
{
|
||||
if (!m_display.BeginRender())
|
||||
return;
|
||||
|
||||
if (HasDisplayTexture())
|
||||
{
|
||||
const auto [left, top, width, height] = CalculateDrawRect(m_window_width, m_window_height, m_display_top_margin);
|
||||
m_display.RenderDisplay(left, top, width, height, m_display_texture_handle, m_display_texture_width,
|
||||
m_display_texture_height, m_display_texture_view_x, m_display_texture_view_y,
|
||||
m_display_texture_view_width, m_display_texture_view_height, m_display_linear_filtering);
|
||||
}
|
||||
|
||||
m_display.RenderImGui();
|
||||
|
||||
if (HasSoftwareCursor())
|
||||
{
|
||||
const auto [left, top, width, height] = CalculateSoftwareCursorDrawRect();
|
||||
m_display.RenderSoftwareCursor(left, top, width, height, m_cursor_texture.get());
|
||||
}
|
||||
|
||||
m_display.EndRenderAndPresent();
|
||||
|
||||
ImGui_ImplSDL2_NewFrame(m_window);
|
||||
}
|
40
src/duckstation-sdl/sdl_vulkan_host_display.h
Normal file
40
src/duckstation-sdl/sdl_vulkan_host_display.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include "core/host_display.h"
|
||||
#include "frontend-common/vulkan_host_display.h"
|
||||
#include <SDL.h>
|
||||
#include <string_view>
|
||||
|
||||
class SDLVulkanHostDisplay final : public HostDisplay
|
||||
{
|
||||
public:
|
||||
SDLVulkanHostDisplay(SDL_Window* window);
|
||||
~SDLVulkanHostDisplay();
|
||||
|
||||
static std::unique_ptr<HostDisplay> Create(SDL_Window* window, std::string_view shader_cache_directory,
|
||||
bool debug_device);
|
||||
|
||||
RenderAPI GetRenderAPI() const override;
|
||||
void* GetRenderDevice() const override;
|
||||
void* GetRenderContext() const override;
|
||||
|
||||
void WindowResized(s32 new_window_width, s32 new_window_height) override;
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride,
|
||||
bool dynamic = false) override;
|
||||
|
||||
void UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data,
|
||||
u32 data_stride) override;
|
||||
|
||||
bool DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||
u32 out_data_stride) override;
|
||||
|
||||
void SetVSync(bool enabled) override;
|
||||
|
||||
void Render() override;
|
||||
|
||||
private:
|
||||
bool Initialize(std::string_view shader_cache_directory, bool debug_device);
|
||||
|
||||
SDL_Window* m_window = nullptr;
|
||||
FrontendCommon::VulkanHostDisplay m_display;
|
||||
};
|
Loading…
Reference in a new issue