diff mbox

[15/21] radv: add VK_EXT_display_control to radv driver

Message ID 20180214003134.1552-16-keithp@keithp.com
State New, archived
Headers show

Commit Message

Keith Packard Feb. 14, 2018, 12:31 a.m. UTC
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(-)
diff mbox

Patch

diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 048192b9e05..42b8d996b6a 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -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),
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 1e3719bcc4f..fc6a5781847 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -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;
 
diff --git a/src/amd/vulkan/radv_wsi_display.c b/src/amd/vulkan/radv_wsi_display.c
index d7a5956ad97..92d8936bba0 100644
--- a/src/amd/vulkan/radv_wsi_display.c
+++ b/src/amd/vulkan/radv_wsi_display.c
@@ -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);
+}
+