mirror of
https://github.com/stenzek/duckstation.git
synced 2026-07-08 17:46:19 +00:00
GPUDevice: Enumerate fullscreen modes if using SDL
This commit is contained in:
@@ -3816,6 +3816,9 @@ void FullscreenUI::DrawGraphicsSettingsPage()
|
||||
options.emplace_back(FSUI_STR("Default"), current_adapter.has_value() && current_adapter->empty());
|
||||
for (const GPUDevice::AdapterInfo& adapter : s_settings_locals.graphics_adapter_list_cache)
|
||||
{
|
||||
if (adapter.name.empty())
|
||||
continue;
|
||||
|
||||
const bool checked = (current_adapter.has_value() && current_adapter.value() == adapter.name);
|
||||
options.emplace_back(adapter.name, checked);
|
||||
}
|
||||
|
||||
@@ -683,6 +683,9 @@ void GraphicsSettingsWidget::populateGPUAdaptersAndResolutions(RenderAPI render_
|
||||
const std::string current_adapter_name = m_dialog->getEffectiveStringValue("GPU", "Adapter", "");
|
||||
for (const GPUDevice::AdapterInfo& adapter : m_adapters)
|
||||
{
|
||||
if (adapter.name.empty())
|
||||
continue;
|
||||
|
||||
const QString qadaptername = QString::fromStdString(adapter.name);
|
||||
m_ui.adapter->addItem(qadaptername, QVariant(qadaptername));
|
||||
if (adapter.name == current_adapter_name)
|
||||
|
||||
@@ -200,6 +200,7 @@ if(NOT ANDROID)
|
||||
sdl_audio_stream.cpp
|
||||
sdl_input_source.cpp
|
||||
sdl_input_source.h
|
||||
sdl_video_helpers.h
|
||||
)
|
||||
if(ENABLE_OPENGL)
|
||||
target_sources(util PRIVATE
|
||||
|
||||
@@ -37,6 +37,7 @@ LOG_CHANNEL(GPUDevice);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "opengl_context.h"
|
||||
#include "opengl_device.h"
|
||||
#endif
|
||||
|
||||
@@ -394,8 +395,7 @@ std::optional<GPUDevice::AdapterInfoList> GPUDevice::GetAdapterListForAPI(Render
|
||||
#ifdef ENABLE_OPENGL
|
||||
case RenderAPI::OpenGL:
|
||||
case RenderAPI::OpenGLES:
|
||||
// No way of querying.
|
||||
ret = AdapterInfoList();
|
||||
ret = OpenGLContext::GetAdapterList(window_type, error);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -210,3 +210,13 @@ std::unique_ptr<OpenGLContext> OpenGLContext::Create(WindowInfo& wi, SurfaceHand
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
GPUDevice::AdapterInfoList OpenGLContext::GetAdapterList(WindowInfoType window_type, Error* error)
|
||||
{
|
||||
#ifdef ENABLE_SDL
|
||||
if (window_type == WindowInfoType::SDL)
|
||||
return OpenGLContextSDL::GetAdapterList(window_type, error);
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_device.h"
|
||||
#include "window_info.h"
|
||||
|
||||
#include "common/types.h"
|
||||
@@ -52,6 +53,8 @@ public:
|
||||
static std::unique_ptr<OpenGLContext> Create(WindowInfo& wi, SurfaceHandle* surface, bool prefer_gles_context,
|
||||
Error* error);
|
||||
|
||||
static GPUDevice::AdapterInfoList GetAdapterList(WindowInfoType window_type, Error* error);
|
||||
|
||||
protected:
|
||||
Version m_version = {};
|
||||
};
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
|
||||
|
||||
#include "opengl_context_sdl.h"
|
||||
#include "gpu_texture.h"
|
||||
#include "opengl_loader.h"
|
||||
#include "sdl_video_helpers.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/error.h"
|
||||
#include "common/log.h"
|
||||
#include "common/scoped_guard.h"
|
||||
|
||||
#include "SDL3/SDL.h"
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
LOG_CHANNEL(GPUDevice);
|
||||
|
||||
@@ -35,6 +36,26 @@ std::unique_ptr<OpenGLContext> OpenGLContextSDL::Create(WindowInfo& wi, SurfaceH
|
||||
return context;
|
||||
}
|
||||
|
||||
GPUDevice::AdapterInfoList OpenGLContextSDL::GetAdapterList(WindowInfoType window_type, Error* error)
|
||||
{
|
||||
std::vector<GPUDevice::ExclusiveFullscreenMode> fullscreen_modes = SDLVideoHelpers::GetFullscreenModeList();
|
||||
if (fullscreen_modes.empty())
|
||||
{
|
||||
// no point adding anything if no modes
|
||||
return {};
|
||||
}
|
||||
|
||||
// Set some reasonable defaults, since we don't know this until we actually create the context.
|
||||
GPUDevice::AdapterInfoList ret;
|
||||
GPUDevice::AdapterInfo& ai = ret.emplace_back();
|
||||
ai.driver_type = GPUDriverType::Unknown;
|
||||
ai.max_multisamples = 8;
|
||||
ai.supports_sample_shading = true;
|
||||
ai.max_texture_size = 16384;
|
||||
ai.fullscreen_modes = std::move(fullscreen_modes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool OpenGLContextSDL::Initialize(WindowInfo& wi, SurfaceHandle* surface, std::span<const Version> versions_to_try,
|
||||
bool share_context, Error* error)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
|
||||
static std::unique_ptr<OpenGLContext> Create(WindowInfo& wi, SurfaceHandle* surface,
|
||||
std::span<const Version> versions_to_try, Error* error);
|
||||
static GPUDevice::AdapterInfoList GetAdapterList(WindowInfoType window_type, Error* error);
|
||||
|
||||
void* GetProcAddress(const char* name) override;
|
||||
SurfaceHandle CreateSurface(WindowInfo& wi, Error* error = nullptr) override;
|
||||
|
||||
54
src/util/sdl_video_helpers.h
Normal file
54
src/util/sdl_video_helpers.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_device.h"
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/log.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace SDLVideoHelpers {
|
||||
|
||||
inline std::vector<GPUDevice::ExclusiveFullscreenMode> GetFullscreenModeList()
|
||||
{
|
||||
int display_count = 0;
|
||||
const SDL_DisplayID* const displays = SDL_GetDisplays(&display_count);
|
||||
if (display_count <= 0)
|
||||
{
|
||||
GENERIC_LOG(Log::Channel::SDL, Log::Level::Error, Log::Color::Default, "SDL_GetDisplays() returned no displays: {}",
|
||||
SDL_GetError());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<GPUDevice::ExclusiveFullscreenMode> modes;
|
||||
for (int i = 0; i < display_count; i++)
|
||||
{
|
||||
int dm_count = 0;
|
||||
const SDL_DisplayMode* const* const dms = SDL_GetFullscreenDisplayModes(displays[i], &dm_count);
|
||||
if (dm_count <= 0)
|
||||
{
|
||||
GENERIC_LOG(Log::Channel::SDL, Log::Level::Error, Log::Color::Default,
|
||||
"SDL_GetFullscreenDisplayModes() returned no modes for display {}: {}", displays[i], SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
modes.reserve(modes.size() + static_cast<size_t>(dm_count));
|
||||
|
||||
for (int j = 0; j < dm_count; j++)
|
||||
{
|
||||
const SDL_DisplayMode* const dm = dms[j];
|
||||
const GPUDevice::ExclusiveFullscreenMode mode{static_cast<u32>(dm->w), static_cast<u32>(dm->h), dm->refresh_rate};
|
||||
if (std::ranges::find(modes, mode) == modes.end())
|
||||
modes.push_back(mode);
|
||||
}
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
} // namespace SDLVideoHelpers
|
||||
@@ -92,6 +92,7 @@
|
||||
<ClInclude Include="postprocessing_shader_fx.h" />
|
||||
<ClInclude Include="postprocessing_shader_glsl.h" />
|
||||
<ClInclude Include="postprocessing_shader_slang.h" />
|
||||
<ClInclude Include="sdl_video_helpers.h" />
|
||||
<ClInclude Include="sdl_input_source.h" />
|
||||
<ClInclude Include="shadergen.h" />
|
||||
<ClInclude Include="shiftjis.h" />
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
<ClInclude Include="core_audio_stream.h" />
|
||||
<ClInclude Include="vulkan_headers.h" />
|
||||
<ClInclude Include="gpu_types.h" />
|
||||
<ClInclude Include="sdl_video_helpers.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="state_wrapper.cpp" />
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "common/log.h"
|
||||
|
||||
#ifdef ENABLE_SDL
|
||||
#include "sdl_video_helpers.h"
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
#endif
|
||||
|
||||
@@ -58,6 +59,8 @@ static void LockedDestroyVulkanInstance();
|
||||
static bool SelectInstanceExtensions(VulkanDevice::ExtensionList* extension_list, WindowInfoType wtype,
|
||||
bool debug_instance, Error* error);
|
||||
|
||||
static std::vector<GPUDevice::ExclusiveFullscreenMode> EnumerateFullscreenModes(WindowInfoType wtype);
|
||||
|
||||
VKAPI_ATTR static VkBool32 VKAPI_CALL DebugMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
@@ -735,6 +738,16 @@ VulkanLoader::GPUList VulkanLoader::EnumerateGPUs(Error* error)
|
||||
return gpus;
|
||||
}
|
||||
|
||||
std::vector<GPUDevice::ExclusiveFullscreenMode> VulkanLoader::EnumerateFullscreenModes(WindowInfoType wtype)
|
||||
{
|
||||
#ifdef ENABLE_SDL
|
||||
if (wtype == WindowInfoType::SDL)
|
||||
return SDLVideoHelpers::GetFullscreenModeList();
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool VulkanLoader::IsSuitableDefaultRenderer(WindowInfoType window_type)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
@@ -834,6 +847,7 @@ GPUDriverType VulkanLoader::GuessDriverType(const VkPhysicalDeviceProperties& de
|
||||
std::optional<GPUDevice::AdapterInfoList> VulkanLoader::GetAdapterList(WindowInfoType window_type, Error* error)
|
||||
{
|
||||
std::optional<GPUDevice::AdapterInfoList> ret;
|
||||
std::vector<GPUDevice::ExclusiveFullscreenMode> fullscreen_modes;
|
||||
GPUList gpus;
|
||||
{
|
||||
const std::lock_guard lock(s_locals.mutex);
|
||||
@@ -842,6 +856,7 @@ std::optional<GPUDevice::AdapterInfoList> VulkanLoader::GetAdapterList(WindowInf
|
||||
if (s_locals.instance != VK_NULL_HANDLE)
|
||||
{
|
||||
gpus = EnumerateGPUs(error);
|
||||
fullscreen_modes = EnumerateFullscreenModes(window_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -851,6 +866,7 @@ std::optional<GPUDevice::AdapterInfoList> VulkanLoader::GetAdapterList(WindowInf
|
||||
return ret;
|
||||
|
||||
gpus = EnumerateGPUs(error);
|
||||
fullscreen_modes = EnumerateFullscreenModes(window_type);
|
||||
|
||||
LockedReleaseVulkanInstance();
|
||||
}
|
||||
@@ -858,8 +874,18 @@ std::optional<GPUDevice::AdapterInfoList> VulkanLoader::GetAdapterList(WindowInf
|
||||
|
||||
ret.emplace();
|
||||
ret->reserve(gpus.size());
|
||||
for (auto& [physical_device, adapter_info] : gpus)
|
||||
ret->push_back(std::move(adapter_info));
|
||||
for (size_t i = 0; i < gpus.size(); i++)
|
||||
{
|
||||
GPUDevice::AdapterInfo& ai = gpus[i].second;
|
||||
|
||||
// splat fullscreen modes across gpus
|
||||
if (i == (gpus.size() - 1))
|
||||
ai.fullscreen_modes = std::move(fullscreen_modes);
|
||||
else
|
||||
ai.fullscreen_modes = fullscreen_modes;
|
||||
|
||||
ret->push_back(std::move(ai));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user