summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEduardo Lima Mitev <elima@igalia.com>2016-10-28 14:34:39 +0200
committerEmil Velikov <emil.l.velikov@gmail.com>2016-11-24 16:34:42 +0000
commitf7b58a378ca94cf1c2637d640ce5b9fb8f8519a6 (patch)
tree6b39ae495cba7dcadeb89dee64fd18f0712c7cf4
parent28c6c8d09e6bb468bfc53a57e12e579411c30941 (diff)
downloadexternal_mesa3d-f7b58a378ca94cf1c2637d640ce5b9fb8f8519a6.zip
external_mesa3d-f7b58a378ca94cf1c2637d640ce5b9fb8f8519a6.tar.gz
external_mesa3d-f7b58a378ca94cf1c2637d640ce5b9fb8f8519a6.tar.bz2
vulkan/wsi/x11: Fix behavior of vkGetPhysicalDeviceSurfacePresentModesKHR
x11_surface_get_present_modes() is currently asserting that the number of elements in pPresentModeCount must be greater than or equal to the number of present modes available. This is buggy because pPresentModeCount elements are later copied from the internal modes' array, so if pPresentModeCount is greater, it will overflow it. On top of that, this assertion violates the spec. From the Vulkan 1.0 (revision 32, with KHR extensions), page 581 of the PDF: "If the value of pPresentModeCount is less than the number of presentation modes supported, at most pPresentModeCount values will be written. If pPresentModeCount is smaller than the number of presentation modes supported for the given surface, VK_INCOMPLETE will be returned instead of VK_SUCCESS to indicate that not all the available values were returned." So, the correct behavior is: if pPresentModeCount is greater than the internal number of formats, it is clamped to that many present modes. But if it is lesser than that, then pPresentModeCount elements are copied, and the call returns VK_INCOMPLETE. This fix is similar (but simpler and more readable) than the one I provided in 750d8cad72a for vkGetPhysicalDeviceSurfaceFormatsKHR, which was suffering from the same problem. Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> (cherry picked from commit b677b99db5c48ffd1eeef538b962080ac5fd65d9) Nominated-by: Emil Velikov <emil.velikov@collabora.com>
-rw-r--r--src/vulkan/wsi/wsi_common_x11.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 6b7e133..09718eb 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -421,11 +421,11 @@ x11_surface_get_present_modes(VkIcdSurfaceBase *surface,
return VK_SUCCESS;
}
- assert(*pPresentModeCount >= ARRAY_SIZE(present_modes));
+ *pPresentModeCount = MIN2(*pPresentModeCount, ARRAY_SIZE(present_modes));
typed_memcpy(pPresentModes, present_modes, *pPresentModeCount);
- *pPresentModeCount = ARRAY_SIZE(present_modes);
- return VK_SUCCESS;
+ return *pPresentModeCount < ARRAY_SIZE(present_modes) ?
+ VK_INCOMPLETE : VK_SUCCESS;
}
VkResult wsi_create_xcb_surface(const VkAllocationCallbacks *pAllocator,