[Mesa-dev] [counter-PATCH 2/2] Vulkan/wsi: Implement VK_EXT_display_surface_counter

Jason Ekstrand jason at jlekstrand.net
Sat Jun 16 17:58:42 UTC 2018


This extension is required to support EXT_display_control as it offers a
way to query whether the vblank counter is supported.  Internally, it is
implemented using a fake MESA extension which provides a chain-in to
GetSurfaceCapabilities2KHR which contains the one added field.  This has
the advantage of reducing number of callbacks needed in the back-ends.
It also means that anything chained into GetSurfaceCapabilities2EXT
through VkSurfaceCapabilities2KHR::pNext so we only need to handle
crawling the pNext chain once per back-end.

Cc: Keith Packard <kethp at keithp.com>

---

Sometimes the best way to review a patch is with another patch. :-)  I'm
not sure what you think of this approach but I didn't really relish the
idea of having 3 get_capabilities entrypoints.  With these two patches,
we're now down to one.  In order to implement VK_EXT_display_control, all
you have to do is add support in wsi_display_surface_get_capabilities2 for
the little chain-in struct and off we go.

If you like this plan, I'm more than happy to do the rebasing so you don't
have to.


 src/vulkan/wsi/wsi_common.c         | 44 +++++++++++++++++++++++++++++
 src/vulkan/wsi/wsi_common.h         |  6 ++++
 src/vulkan/wsi/wsi_common_private.h | 14 +++++++++
 3 files changed, 64 insertions(+)

diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index ab5b2dba0da..e3186d18156 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -719,6 +719,50 @@ wsi_common_get_surface_capabilities2(struct wsi_device *wsi_device,
                                    pSurfaceCapabilities);
 }
 
+VkResult
+wsi_common_get_surface_capabilities2ext(
+   struct wsi_device *wsi_device,
+   VkSurfaceKHR _surface,
+   VkSurfaceCapabilities2EXT *pSurfaceCapabilities)
+{
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+   struct wsi_interface *iface = wsi_device->wsi[surface->platform];
+
+   assert(pSurfaceCapabilities->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT);
+
+   struct wsi_surface_supported_counters counters = {
+      .sType = VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA,
+      .pNext = pSurfaceCapabilities->pNext,
+   };
+
+   VkSurfaceCapabilities2KHR caps2 = {
+      .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
+      .pNext = &counters,
+   };
+
+   VkResult result = iface->get_capabilities2(surface, NULL, &caps2);
+
+   if (result == VK_SUCCESS) {
+      VkSurfaceCapabilities2EXT *ext_caps = pSurfaceCapabilities;
+      VkSurfaceCapabilitiesKHR khr_caps = caps2.surfaceCapabilities;
+
+      ext_caps->minImageCount = khr_caps.minImageCount;
+      ext_caps->maxImageCount = khr_caps.maxImageCount;
+      ext_caps->currentExtent = khr_caps.currentExtent;
+      ext_caps->minImageExtent = khr_caps.minImageExtent;
+      ext_caps->maxImageExtent = khr_caps.maxImageExtent;
+      ext_caps->maxImageArrayLayers = khr_caps.maxImageArrayLayers;
+      ext_caps->supportedTransforms = khr_caps.supportedTransforms;
+      ext_caps->currentTransform = khr_caps.currentTransform;
+      ext_caps->supportedCompositeAlpha = khr_caps.supportedCompositeAlpha;
+      ext_caps->supportedUsageFlags = khr_caps.supportedUsageFlags;
+      ext_caps->supportedSurfaceCounters = counters.supported_surface_counters;
+   }
+
+   return result;
+}
+
 VkResult
 wsi_common_get_surface_formats(struct wsi_device *wsi_device,
                                VkSurfaceKHR _surface,
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 61b1de59d7f..054aad23c1c 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -178,6 +178,12 @@ wsi_common_get_surface_present_modes(struct wsi_device *wsi_device,
                                      uint32_t *pPresentModeCount,
                                      VkPresentModeKHR *pPresentModes);
 
+VkResult
+wsi_common_get_surface_capabilities2ext(
+   struct wsi_device *wsi_device,
+   VkSurfaceKHR surface,
+   VkSurfaceCapabilities2EXT *pSurfaceCapabilities);
+
 VkResult
 wsi_common_get_images(VkSwapchainKHR _swapchain,
                       uint32_t *pSwapchainImageCount,
diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h
index 9f2aacd6560..3b5811673a0 100644
--- a/src/vulkan/wsi/wsi_common_private.h
+++ b/src/vulkan/wsi/wsi_common_private.h
@@ -128,6 +128,20 @@ struct wsi_interface {
                                 struct wsi_swapchain **swapchain);
 };
 
+/* This is guaranteed to not collide with anything because it's in the
+ * VK_KHR_swapchain namespace but not actually used by the extension.
+ */
+#define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA \
+   (VkStructureType)1000001005
+
+/* To be chained into VkSurfaceCapabilities2KHR */
+struct wsi_surface_supported_counters {
+   VkStructureType sType;
+   const void *pNext;
+
+   VkSurfaceCounterFlagsEXT supported_surface_counters;
+};
+
 VkResult wsi_x11_init_wsi(struct wsi_device *wsi_device,
                           const VkAllocationCallbacks *alloc);
 void wsi_x11_finish_wsi(struct wsi_device *wsi_device,
-- 
2.17.1



More information about the mesa-dev mailing list