vulkan/wsi/win32: Support tearing (immediate) and VSync (FIFO) present modes

Reviewed-by: Giancarlo Devich <gdevich@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20945>
This commit is contained in:
Jesse Natalie
2023-01-26 10:05:34 -08:00
committed by Marge Bot
parent 747604b17c
commit d7730fcf22

View File

@@ -319,8 +319,12 @@ wsi_win32_surface_get_formats2(VkIcdSurfaceBase *icd_surface,
return vk_outarray_status(&out);
}
static const VkPresentModeKHR present_modes[] = {
//VK_PRESENT_MODE_MAILBOX_KHR,
static const VkPresentModeKHR present_modes_gdi[] = {
VK_PRESENT_MODE_FIFO_KHR,
};
static const VkPresentModeKHR present_modes_dxgi[] = {
VK_PRESENT_MODE_IMMEDIATE_KHR,
VK_PRESENT_MODE_MAILBOX_KHR,
VK_PRESENT_MODE_FIFO_KHR,
};
@@ -330,15 +334,25 @@ wsi_win32_surface_get_present_modes(VkIcdSurfaceBase *surface,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes)
{
const VkPresentModeKHR *array;
size_t array_size;
if (wsi_device->sw || !wsi_device->win32.get_d3d12_command_queue) {
array = present_modes_gdi;
array_size = ARRAY_SIZE(present_modes_gdi);
} else {
array = present_modes_dxgi;
array_size = ARRAY_SIZE(present_modes_dxgi);
}
if (pPresentModes == NULL) {
*pPresentModeCount = ARRAY_SIZE(present_modes);
*pPresentModeCount = array_size;
return VK_SUCCESS;
}
*pPresentModeCount = MIN2(*pPresentModeCount, ARRAY_SIZE(present_modes));
typed_memcpy(pPresentModes, present_modes, *pPresentModeCount);
*pPresentModeCount = MIN2(*pPresentModeCount, array_size);
typed_memcpy(pPresentModes, array, *pPresentModeCount);
if (*pPresentModeCount < ARRAY_SIZE(present_modes))
if (*pPresentModeCount < array_size)
return VK_INCOMPLETE;
else
return VK_SUCCESS;
@@ -609,8 +623,11 @@ wsi_win32_queue_present_dxgi(struct wsi_win32_swapchain *chain,
};
image->state = WSI_IMAGE_QUEUED;
UINT sync_interval = chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ? 1 : 0;
UINT present_flags = chain->base.present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR ?
DXGI_PRESENT_ALLOW_TEARING : 0;
HRESULT hres = chain->dxgi->Present1(0, 0, &params);
HRESULT hres = chain->dxgi->Present1(sync_interval, present_flags, &params);
switch (hres) {
case DXGI_ERROR_DEVICE_REMOVED: return VK_ERROR_DEVICE_LOST;
case E_OUTOFMEMORY: return VK_ERROR_OUT_OF_DEVICE_MEMORY;
@@ -687,7 +704,8 @@ wsi_win32_surface_create_swapchain_dxgi(
DXGI_SCALING_STRETCH,
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
DXGI_ALPHA_MODE_UNSPECIFIED,
0, // Flags
chain->base.present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR ?
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0
};
if (create_info->imageUsage &