@@ -85,6 +85,7 @@ EXTENSIONS = [
Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
+ Extension('VK_EXT_display_control', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_KHX_multiview', 1, '!ANDROID'),
Extension('VK_EXT_debug_report', 9, True),
Extension('VK_EXT_discard_rectangles', 1, True),
@@ -1647,8 +1647,17 @@ void radv_initialise_cmask(struct radv_cmd_buffer *cmd_buffer,
void radv_initialize_dcc(struct radv_cmd_buffer *cmd_buffer,
struct radv_image *image, uint32_t value);
+enum radv_fence_type {
+ RADV_FENCE_TYPE_WINSYS = 0,
+ RADV_FENCE_TYPE_WSI = 1
+};
+
struct radv_fence {
- struct radeon_winsys_fence *fence;
+ enum radv_fence_type type;
+ union {
+ struct radeon_winsys_fence *fence;
+ struct wsi_fence *fence_wsi;
+ };
bool submitted;
bool signalled;
@@ -182,3 +182,112 @@ radv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,
display);
}
#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
+
+/* VK_EXT_display_control */
+
+VkResult
+radv_DisplayPowerControlEXT(VkDevice _device,
+ VkDisplayKHR display,
+ const VkDisplayPowerInfoEXT *display_power_info)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+
+ return wsi_display_power_control(_device,
+ &device->physical_device->wsi_device,
+ display,
+ display_power_info);
+}
+
+VkResult
+radv_RegisterDeviceEventEXT(VkDevice _device,
+ const VkDeviceEventInfoEXT *device_event_info,
+ const VkAllocationCallbacks *allocator,
+ VkFence *_fence)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+ const VkAllocationCallbacks *alloc;
+ struct radv_fence *fence;
+ VkResult ret;
+
+ if (allocator)
+ alloc = allocator;
+ else
+ alloc = &device->instance->alloc;
+
+ fence = vk_alloc(alloc, sizeof (*fence), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!fence)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ fence->type = RADV_FENCE_TYPE_WSI;
+ fence->submitted = true;
+ fence->signalled = false;
+
+ ret = wsi_register_device_event(_device,
+ &device->physical_device->wsi_device,
+ device_event_info,
+ alloc,
+ &fence->fence_wsi);
+ if (ret == VK_SUCCESS)
+ *_fence = radv_fence_to_handle(fence);
+ else
+ vk_free(alloc, fence);
+ return ret;
+}
+
+VkResult
+radv_RegisterDisplayEventEXT(VkDevice _device,
+ VkDisplayKHR display,
+ const VkDisplayEventInfoEXT *display_event_info,
+ const VkAllocationCallbacks *allocator,
+ VkFence *_fence)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+
+ const VkAllocationCallbacks *alloc;
+ struct radv_fence *fence;
+ VkResult ret;
+
+ if (allocator)
+ alloc = allocator;
+ else
+ alloc = &device->instance->alloc;
+
+ fence = vk_alloc(alloc, sizeof (*fence), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!fence)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ fence->type = RADV_FENCE_TYPE_WSI;
+ fence->submitted = true;
+ fence->signalled = false;
+
+ ret = wsi_register_display_event(_device,
+ &device->physical_device->wsi_device,
+ display,
+ display_event_info,
+ alloc,
+ &(fence->fence_wsi));
+
+ if (ret == VK_SUCCESS)
+ *_fence = radv_fence_to_handle(fence);
+ else
+ vk_free(alloc, fence);
+ return ret;
+}
+
+VkResult
+radv_GetSwapchainCounterEXT(VkDevice _device,
+ VkSwapchainKHR swapchain,
+ VkSurfaceCounterFlagBitsEXT flag_bits,
+ uint64_t *value)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+
+ return wsi_get_swapchain_counter(_device,
+ &device->physical_device->wsi_device,
+ swapchain,
+ flag_bits,
+ value);
+}
+
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. Signed-off-by: Keith Packard <keithp@keithp.com> --- src/amd/vulkan/radv_extensions.py | 1 + src/amd/vulkan/radv_private.h | 11 +++- src/amd/vulkan/radv_wsi_display.c | 109 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-)