1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[vulkan] Support exclusive fullscreen control in presenter

This commit is contained in:
Philip Rebohle 2019-12-03 01:54:32 +01:00
parent 9c26fad40e
commit 575a267f07
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 83 additions and 16 deletions

View File

@ -389,6 +389,7 @@ namespace dxvk {
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1); presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats); presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes); presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes);
presenterDesc.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT;
if (m_presenter->recreateSwapChain(presenterDesc) != VK_SUCCESS) if (m_presenter->recreateSwapChain(presenterDesc) != VK_SUCCESS)
throw DxvkError("D3D11SwapChain: Failed to recreate swap chain"); throw DxvkError("D3D11SwapChain: Failed to recreate swap chain");
@ -419,6 +420,7 @@ namespace dxvk {
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1); presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats); presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes); presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes);
presenterDesc.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT;
m_presenter = new vk::Presenter(m_window, m_presenter = new vk::Presenter(m_window,
m_device->adapter()->vki(), m_device->adapter()->vki(),

View File

@ -119,10 +119,10 @@ namespace dxvk::vk {
return status; return status;
} }
if ((status = getSupportedFormats(formats)) != VK_SUCCESS) if ((status = getSupportedFormats(formats, desc)) != VK_SUCCESS)
return status; return status;
if ((status = getSupportedPresentModes(modes)) != VK_SUCCESS) if ((status = getSupportedPresentModes(modes, desc)) != VK_SUCCESS)
return status; return status;
// Select actual swap chain properties and create swap chain // Select actual swap chain properties and create swap chain
@ -131,6 +131,11 @@ namespace dxvk::vk {
m_info.imageExtent = pickImageExtent(caps, desc.imageExtent); m_info.imageExtent = pickImageExtent(caps, desc.imageExtent);
m_info.imageCount = pickImageCount(caps, m_info.presentMode, desc.imageCount); m_info.imageCount = pickImageCount(caps, m_info.presentMode, desc.imageCount);
VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo;
fullScreenInfo.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT;
fullScreenInfo.pNext = nullptr;
fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive;
VkSwapchainCreateInfoKHR swapInfo; VkSwapchainCreateInfoKHR swapInfo;
swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapInfo.pNext = nullptr; swapInfo.pNext = nullptr;
@ -152,12 +157,16 @@ namespace dxvk::vk {
swapInfo.clipped = VK_TRUE; swapInfo.clipped = VK_TRUE;
swapInfo.oldSwapchain = VK_NULL_HANDLE; swapInfo.oldSwapchain = VK_NULL_HANDLE;
if (m_device.features.fullScreenExclusive)
swapInfo.pNext = &fullScreenInfo;
Logger::info(str::format( Logger::info(str::format(
"Presenter: Actual swap chain properties:" "Presenter: Actual swap chain properties:"
"\n Format: ", m_info.format.format, "\n Format: ", m_info.format.format,
"\n Present mode: ", m_info.presentMode, "\n Present mode: ", m_info.presentMode,
"\n Buffer size: ", m_info.imageExtent.width, "x", m_info.imageExtent.height, "\n Buffer size: ", m_info.imageExtent.width, "x", m_info.imageExtent.height,
"\n Image count: ", m_info.imageCount)); "\n Image count: ", m_info.imageCount,
"\n Exclusive FS: ", desc.fullScreenExclusive));
if ((status = m_vkd->vkCreateSwapchainKHR(m_vkd->device(), if ((status = m_vkd->vkCreateSwapchainKHR(m_vkd->device(),
&swapInfo, nullptr, &m_swapchain)) != VK_SUCCESS) &swapInfo, nullptr, &m_swapchain)) != VK_SUCCESS)
@ -229,35 +238,89 @@ namespace dxvk::vk {
} }
VkResult Presenter::getSupportedFormats(std::vector<VkSurfaceFormatKHR>& formats) { VkResult Presenter::getSupportedFormats(std::vector<VkSurfaceFormatKHR>& formats, const PresenterDesc& desc) {
uint32_t numFormats = 0; uint32_t numFormats = 0;
VkResult status = m_vki->vkGetPhysicalDeviceSurfaceFormatsKHR( VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo;
m_device.adapter, m_surface, &numFormats, nullptr); fullScreenInfo.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT;
fullScreenInfo.pNext = nullptr;
fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive;
VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo;
surfaceInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
surfaceInfo.pNext = &fullScreenInfo;
surfaceInfo.surface = m_surface;
VkResult status;
if (m_device.features.fullScreenExclusive) {
status = m_vki->vkGetPhysicalDeviceSurfaceFormats2KHR(
m_device.adapter, &surfaceInfo, &numFormats, nullptr);
} else {
status = m_vki->vkGetPhysicalDeviceSurfaceFormatsKHR(
m_device.adapter, m_surface, &numFormats, nullptr);
}
if (status != VK_SUCCESS) if (status != VK_SUCCESS)
return status; return status;
formats.resize(numFormats); formats.resize(numFormats);
return m_vki->vkGetPhysicalDeviceSurfaceFormatsKHR( if (m_device.features.fullScreenExclusive) {
m_device.adapter, m_surface, &numFormats, formats.data()); std::vector<VkSurfaceFormat2KHR> tmpFormats(numFormats,
{ VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR, nullptr, VkSurfaceFormatKHR() });
status = m_vki->vkGetPhysicalDeviceSurfaceFormats2KHR(
m_device.adapter, &surfaceInfo, &numFormats, tmpFormats.data());
for (uint32_t i = 0; i < numFormats; i++)
formats[i] = tmpFormats[i].surfaceFormat;
} else {
status = m_vki->vkGetPhysicalDeviceSurfaceFormatsKHR(
m_device.adapter, m_surface, &numFormats, formats.data());
}
return status;
} }
VkResult Presenter::getSupportedPresentModes(std::vector<VkPresentModeKHR>& modes) { VkResult Presenter::getSupportedPresentModes(std::vector<VkPresentModeKHR>& modes, const PresenterDesc& desc) {
uint32_t numModes = 0; uint32_t numModes = 0;
VkResult status = m_vki->vkGetPhysicalDeviceSurfacePresentModesKHR( VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo;
m_device.adapter, m_surface, &numModes, nullptr); fullScreenInfo.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT;
fullScreenInfo.pNext = nullptr;
fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive;
VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo;
surfaceInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
surfaceInfo.pNext = &fullScreenInfo;
surfaceInfo.surface = m_surface;
VkResult status;
if (m_device.features.fullScreenExclusive) {
status = m_vki->vkGetPhysicalDeviceSurfacePresentModes2EXT(
m_device.adapter, &surfaceInfo, &numModes, nullptr);
} else {
status = m_vki->vkGetPhysicalDeviceSurfacePresentModesKHR(
m_device.adapter, m_surface, &numModes, nullptr);
}
if (status != VK_SUCCESS) if (status != VK_SUCCESS)
return status; return status;
modes.resize(numModes); modes.resize(numModes);
return m_vki->vkGetPhysicalDeviceSurfacePresentModesKHR( if (m_device.features.fullScreenExclusive) {
m_device.adapter, m_surface, &numModes, modes.data()); status = m_vki->vkGetPhysicalDeviceSurfacePresentModes2EXT(
m_device.adapter, &surfaceInfo, &numModes, modes.data());
} else {
status = m_vki->vkGetPhysicalDeviceSurfacePresentModesKHR(
m_device.adapter, m_surface, &numModes, modes.data());
}
return status;
} }

View File

@ -26,7 +26,7 @@ namespace dxvk::vk {
VkSurfaceFormatKHR formats[4]; VkSurfaceFormatKHR formats[4];
uint32_t numPresentModes; uint32_t numPresentModes;
VkPresentModeKHR presentModes[4]; VkPresentModeKHR presentModes[4];
VkFullScreenExclusiveEXT fullscreenExclusive; VkFullScreenExclusiveEXT fullScreenExclusive;
}; };
/** /**
@ -196,10 +196,12 @@ namespace dxvk::vk {
uint32_t m_frameIndex = 0; uint32_t m_frameIndex = 0;
VkResult getSupportedFormats( VkResult getSupportedFormats(
std::vector<VkSurfaceFormatKHR>& formats); std::vector<VkSurfaceFormatKHR>& formats,
const PresenterDesc& desc);
VkResult getSupportedPresentModes( VkResult getSupportedPresentModes(
std::vector<VkPresentModeKHR>& modes); std::vector<VkPresentModeKHR>& modes,
const PresenterDesc& desc);
VkResult getSwapImages( VkResult getSwapImages(
std::vector<VkImage>& images); std::vector<VkImage>& images);