From 16eb390834daaa153522e63bb17df9526eb9123c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 15 Jun 2017 21:00:56 -0700 Subject: [PATCH] anv: add VK_EXT_display_control to anv driver [v5] This extension provides fences and frame count information to direct display contexts. It uses new kernel ioctls to provide 64-bits of vblank sequence and nanosecond resolution. v2: Adopt Jason Ekstrand's coding conventions Declare variables at first use, eliminate extra whitespace between types and names. Wrap lines to 80 columns. Add extension to list in alphabetical order Suggested-by: Jason Ekstrand v3: Adapt to WSI fence API change. It now returns VkResult and no longer has an option for relative timeouts. v4: wsi_register_display_event and wsi_register_device_event now use the default allocator when NULL is provided, so remove the computation of 'alloc' here. v5: use zalloc2 instead of alloc2 for the WSI fence. Suggested-by: Jason Ekstrand Signed-off-by: Keith Packard Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_private.h | 4 ++ src/intel/vulkan/anv_queue.c | 18 +++++++ src/intel/vulkan/anv_wsi_display.c | 85 ++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index ecef1b254bf..0f99f58ecb1 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -113,6 +113,7 @@ EXTENSIONS = [ Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'), Extension('VK_EXT_debug_report', 8, True), Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), + Extension('VK_EXT_display_control', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_external_memory_dma_buf', 1, True), Extension('VK_EXT_global_priority', 1, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index edc5317bac4..510471da602 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2134,6 +2134,7 @@ enum anv_fence_type { ANV_FENCE_TYPE_NONE = 0, ANV_FENCE_TYPE_BO, ANV_FENCE_TYPE_SYNCOBJ, + ANV_FENCE_TYPE_WSI, }; enum anv_bo_fence_state { @@ -2168,6 +2169,9 @@ struct anv_fence_impl { /** DRM syncobj handle for syncobj-based fences */ uint32_t syncobj; + + /** WSI fence */ + struct wsi_fence *fence_wsi; }; }; diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index 6e275629e14..e0c0a42069f 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -324,6 +324,10 @@ anv_fence_impl_cleanup(struct anv_device *device, anv_gem_syncobj_destroy(device, impl->syncobj); break; + case ANV_FENCE_TYPE_WSI: + impl->fence_wsi->destroy(impl->fence_wsi); + break; + default: unreachable("Invalid fence type"); } @@ -673,6 +677,17 @@ done: return result; } +static VkResult +anv_wait_for_wsi_fence(struct anv_device *device, + const VkFence _fence, + uint64_t abs_timeout) +{ + ANV_FROM_HANDLE(anv_fence, fence, _fence); + struct anv_fence_impl *impl = &fence->permanent; + + return impl->fence_wsi->wait(impl->fence_wsi, abs_timeout); +} + static VkResult anv_wait_for_fences(struct anv_device *device, uint32_t fenceCount, @@ -695,6 +710,9 @@ anv_wait_for_fences(struct anv_device *device, result = anv_wait_for_syncobj_fences(device, 1, &pFences[i], true, abs_timeout); break; + case ANV_FENCE_TYPE_WSI: + result = anv_wait_for_wsi_fence(device, pFences[i], abs_timeout); + break; case ANV_FENCE_TYPE_NONE: result = VK_SUCCESS; break; diff --git a/src/intel/vulkan/anv_wsi_display.c b/src/intel/vulkan/anv_wsi_display.c index ed679e85e13..94e16010463 100644 --- a/src/intel/vulkan/anv_wsi_display.c +++ b/src/intel/vulkan/anv_wsi_display.c @@ -174,3 +174,88 @@ anv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device, display); } #endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */ + +/* VK_EXT_display_control */ + +VkResult +anv_DisplayPowerControlEXT(VkDevice _device, + VkDisplayKHR display, + const VkDisplayPowerInfoEXT *display_power_info) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + + return wsi_display_power_control( + _device, &device->instance->physicalDevice.wsi_device, + display, display_power_info); +} + +VkResult +anv_RegisterDeviceEventEXT(VkDevice _device, + const VkDeviceEventInfoEXT *device_event_info, + const VkAllocationCallbacks *allocator, + VkFence *_fence) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_fence *fence; + VkResult ret; + + fence = vk_zalloc2(&device->instance->alloc, allocator, sizeof (*fence), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!fence) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + fence->permanent.type = ANV_FENCE_TYPE_WSI; + + ret = wsi_register_device_event(_device, + &device->instance->physicalDevice.wsi_device, + device_event_info, + allocator, + &fence->permanent.fence_wsi); + if (ret == VK_SUCCESS) + *_fence = anv_fence_to_handle(fence); + else + vk_free2(&device->instance->alloc, allocator, fence); + return ret; +} + +VkResult +anv_RegisterDisplayEventEXT(VkDevice _device, + VkDisplayKHR display, + const VkDisplayEventInfoEXT *display_event_info, + const VkAllocationCallbacks *allocator, + VkFence *_fence) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_fence *fence; + VkResult ret; + + fence = vk_zalloc2(&device->alloc, allocator, sizeof (*fence), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!fence) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + fence->permanent.type = ANV_FENCE_TYPE_WSI; + + ret = wsi_register_display_event( + _device, &device->instance->physicalDevice.wsi_device, + display, display_event_info, allocator, &(fence->permanent.fence_wsi)); + + if (ret == VK_SUCCESS) + *_fence = anv_fence_to_handle(fence); + else + vk_free2(&device->alloc, allocator, fence); + return ret; +} + +VkResult +anv_GetSwapchainCounterEXT(VkDevice _device, + VkSwapchainKHR swapchain, + VkSurfaceCounterFlagBitsEXT flag_bits, + uint64_t *value) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + + return wsi_get_swapchain_counter( + _device, &device->instance->physicalDevice.wsi_device, + swapchain, flag_bits, value); +} -- 2.30.2