mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-27 08:05:41 +00:00
Vulkan: Support fullscreen resolution enumeration
This commit is contained in:
parent
e84a39245f
commit
65daf1d6a0
|
@ -132,7 +132,7 @@ static VkSurfaceKHR CreateDisplaySurface(VkInstance instance, VkPhysicalDevice p
|
||||||
const VkDisplayModePropertiesKHR* matched_mode = nullptr;
|
const VkDisplayModePropertiesKHR* matched_mode = nullptr;
|
||||||
for (const VkDisplayModePropertiesKHR& mode : modes)
|
for (const VkDisplayModePropertiesKHR& mode : modes)
|
||||||
{
|
{
|
||||||
const float refresh_rate = static_cast<float>(mode.parameters.refreshRate) * 1000.0f;
|
const float refresh_rate = static_cast<float>(mode.parameters.refreshRate) / 1000.0f;
|
||||||
Log_DevPrintf(" Mode %ux%u @ %f", mode.parameters.visibleRegion.width, mode.parameters.visibleRegion.height,
|
Log_DevPrintf(" Mode %ux%u @ %f", mode.parameters.visibleRegion.width, mode.parameters.visibleRegion.height,
|
||||||
refresh_rate);
|
refresh_rate);
|
||||||
|
|
||||||
|
@ -225,6 +225,67 @@ static VkSurfaceKHR CreateDisplaySurface(VkInstance instance, VkPhysicalDevice p
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<SwapChain::FullscreenModeInfo> GetDisplayModes(VkInstance instance, VkPhysicalDevice physical_device,
|
||||||
|
const WindowInfo& wi)
|
||||||
|
{
|
||||||
|
|
||||||
|
u32 num_displays;
|
||||||
|
VkResult res = vkGetPhysicalDeviceDisplayPropertiesKHR(physical_device, &num_displays, nullptr);
|
||||||
|
if (res != VK_SUCCESS || num_displays == 0)
|
||||||
|
{
|
||||||
|
LOG_VULKAN_ERROR(res, "vkGetPhysicalDeviceDisplayPropertiesKHR() failed:");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VkDisplayPropertiesKHR> displays(num_displays);
|
||||||
|
res = vkGetPhysicalDeviceDisplayPropertiesKHR(physical_device, &num_displays, displays.data());
|
||||||
|
if (res != VK_SUCCESS || num_displays != displays.size())
|
||||||
|
{
|
||||||
|
LOG_VULKAN_ERROR(res, "vkGetPhysicalDeviceDisplayPropertiesKHR() failed:");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SwapChain::FullscreenModeInfo> result;
|
||||||
|
for (u32 display_index = 0; display_index < num_displays; display_index++)
|
||||||
|
{
|
||||||
|
const VkDisplayPropertiesKHR& props = displays[display_index];
|
||||||
|
|
||||||
|
u32 num_modes;
|
||||||
|
res = vkGetDisplayModePropertiesKHR(physical_device, props.display, &num_modes, nullptr);
|
||||||
|
if (res != VK_SUCCESS || num_modes == 0)
|
||||||
|
{
|
||||||
|
LOG_VULKAN_ERROR(res, "vkGetDisplayModePropertiesKHR() failed:");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VkDisplayModePropertiesKHR> modes(num_modes);
|
||||||
|
res = vkGetDisplayModePropertiesKHR(physical_device, props.display, &num_modes, modes.data());
|
||||||
|
if (res != VK_SUCCESS || num_modes != modes.size())
|
||||||
|
{
|
||||||
|
LOG_VULKAN_ERROR(res, "vkGetDisplayModePropertiesKHR() failed:");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const VkDisplayModePropertiesKHR& mode : modes)
|
||||||
|
{
|
||||||
|
const float refresh_rate = static_cast<float>(mode.parameters.refreshRate) / 1000.0f;
|
||||||
|
if (std::find_if(result.begin(), result.end(), [&mode, refresh_rate](const SwapChain::FullscreenModeInfo& mi) {
|
||||||
|
return (mi.width == mode.parameters.visibleRegion.width &&
|
||||||
|
mi.height == mode.parameters.visibleRegion.height && mode.parameters.refreshRate == refresh_rate);
|
||||||
|
}) != result.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(SwapChain::FullscreenModeInfo{static_cast<u32>(mode.parameters.visibleRegion.width),
|
||||||
|
static_cast<u32>(mode.parameters.visibleRegion.height),
|
||||||
|
refresh_rate});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, VkPhysicalDevice physical_device, WindowInfo& wi)
|
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, VkPhysicalDevice physical_device, WindowInfo& wi)
|
||||||
{
|
{
|
||||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||||
|
@ -367,6 +428,15 @@ void SwapChain::DestroyVulkanSurface(VkInstance instance, WindowInfo& wi, VkSurf
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<SwapChain::FullscreenModeInfo>
|
||||||
|
SwapChain::GetSurfaceFullscreenModes(VkInstance instance, VkPhysicalDevice physical_device, const WindowInfo& wi)
|
||||||
|
{
|
||||||
|
if (wi.type == WindowInfo::Type::Display)
|
||||||
|
return GetDisplayModes(instance, physical_device, wi);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<SwapChain> SwapChain::Create(const WindowInfo& wi, VkSurfaceKHR surface, bool vsync)
|
std::unique_ptr<SwapChain> SwapChain::Create(const WindowInfo& wi, VkSurfaceKHR surface, bool vsync)
|
||||||
{
|
{
|
||||||
std::unique_ptr<SwapChain> swap_chain = std::make_unique<SwapChain>(wi, surface, vsync);
|
std::unique_ptr<SwapChain> swap_chain = std::make_unique<SwapChain>(wi, surface, vsync);
|
||||||
|
|
|
@ -26,6 +26,16 @@ public:
|
||||||
// Destroys a previously-created surface.
|
// Destroys a previously-created surface.
|
||||||
static void DestroyVulkanSurface(VkInstance instance, WindowInfo& wi, VkSurfaceKHR surface);
|
static void DestroyVulkanSurface(VkInstance instance, WindowInfo& wi, VkSurfaceKHR surface);
|
||||||
|
|
||||||
|
// Enumerates fullscreen modes for window info.
|
||||||
|
struct FullscreenModeInfo
|
||||||
|
{
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
float refresh_rate;
|
||||||
|
};
|
||||||
|
static std::vector<FullscreenModeInfo>
|
||||||
|
GetSurfaceFullscreenModes(VkInstance instance, VkPhysicalDevice physical_device, const WindowInfo& wi);
|
||||||
|
|
||||||
// Create a new swap chain from a pre-existing surface.
|
// Create a new swap chain from a pre-existing surface.
|
||||||
static std::unique_ptr<SwapChain> Create(const WindowInfo& wi, VkSurfaceKHR surface, bool vsync);
|
static std::unique_ptr<SwapChain> Create(const WindowInfo& wi, VkSurfaceKHR surface, bool vsync);
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ void DisplaySettingsWidget::populateGPUAdaptersAndResolutions()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case GPURenderer::HardwareVulkan:
|
case GPURenderer::HardwareVulkan:
|
||||||
aml = FrontendCommon::VulkanHostDisplay::StaticGetAdapterAndModeList();
|
aml = FrontendCommon::VulkanHostDisplay::StaticGetAdapterAndModeList(nullptr);
|
||||||
threaded_presentation_supported = true;
|
threaded_presentation_supported = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "common/vulkan/stream_buffer.h"
|
#include "common/vulkan/stream_buffer.h"
|
||||||
#include "common/vulkan/swap_chain.h"
|
#include "common/vulkan/swap_chain.h"
|
||||||
#include "common/vulkan/util.h"
|
#include "common/vulkan/util.h"
|
||||||
|
#include "common_host_interface.h"
|
||||||
#include "core/shader_cache_version.h"
|
#include "core/shader_cache_version.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_impl_vulkan.h"
|
#include "imgui_impl_vulkan.h"
|
||||||
|
@ -141,7 +142,7 @@ bool VulkanHostDisplay::SetFullscreen(bool fullscreen, u32 width, u32 height, fl
|
||||||
|
|
||||||
HostDisplay::AdapterAndModeList VulkanHostDisplay::GetAdapterAndModeList()
|
HostDisplay::AdapterAndModeList VulkanHostDisplay::GetAdapterAndModeList()
|
||||||
{
|
{
|
||||||
return StaticGetAdapterAndModeList();
|
return StaticGetAdapterAndModeList(m_window_info.type != WindowInfo::Type::Surfaceless ? &m_window_info : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHostDisplay::DestroyRenderSurface()
|
void VulkanHostDisplay::DestroyRenderSurface()
|
||||||
|
@ -752,13 +753,19 @@ void VulkanHostDisplay::RenderSoftwareCursor(s32 left, s32 top, s32 width, s32 h
|
||||||
vkCmdDraw(cmdbuffer, 3, 1, 0, 0);
|
vkCmdDraw(cmdbuffer, 3, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
HostDisplay::AdapterAndModeList VulkanHostDisplay::StaticGetAdapterAndModeList()
|
HostDisplay::AdapterAndModeList VulkanHostDisplay::StaticGetAdapterAndModeList(const WindowInfo* wi)
|
||||||
{
|
{
|
||||||
AdapterAndModeList ret;
|
AdapterAndModeList ret;
|
||||||
|
std::vector<Vulkan::SwapChain::FullscreenModeInfo> fsmodes;
|
||||||
|
|
||||||
if (g_vulkan_context)
|
if (g_vulkan_context)
|
||||||
{
|
{
|
||||||
ret.adapter_names = Vulkan::Context::EnumerateGPUNames(g_vulkan_context->GetVulkanInstance());
|
ret.adapter_names = Vulkan::Context::EnumerateGPUNames(g_vulkan_context->GetVulkanInstance());
|
||||||
|
if (wi)
|
||||||
|
{
|
||||||
|
fsmodes = Vulkan::SwapChain::GetSurfaceFullscreenModes(g_vulkan_context->GetVulkanInstance(),
|
||||||
|
g_vulkan_context->GetPhysicalDevice(), *wi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (Vulkan::LoadVulkanLibrary())
|
else if (Vulkan::LoadVulkanLibrary())
|
||||||
{
|
{
|
||||||
|
@ -774,7 +781,17 @@ HostDisplay::AdapterAndModeList VulkanHostDisplay::StaticGetAdapterAndModeList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
if (!fsmodes.empty())
|
||||||
|
{
|
||||||
|
ret.fullscreen_modes.reserve(fsmodes.size());
|
||||||
|
for (const Vulkan::SwapChain::FullscreenModeInfo& fmi : fsmodes)
|
||||||
|
{
|
||||||
|
ret.fullscreen_modes.push_back(
|
||||||
|
CommonHostInterface::GetFullscreenModeString(fmi.width, fmi.height, fmi.refresh_rate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanHostDisplay::PostProcessingStage::PostProcessingStage(PostProcessingStage&& move)
|
VulkanHostDisplay::PostProcessingStage::PostProcessingStage(PostProcessingStage&& move)
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
|
|
||||||
virtual bool Render() override;
|
virtual bool Render() override;
|
||||||
|
|
||||||
static AdapterAndModeList StaticGetAdapterAndModeList();
|
static AdapterAndModeList StaticGetAdapterAndModeList(const WindowInfo* wi);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct PushConstants
|
struct PushConstants
|
||||||
|
|
Loading…
Reference in a new issue