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 <jason.ekstrand@intel.com>

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 <jason.ekstrand@intel.com>

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
This commit is contained in:
Keith Packard
2017-06-15 21:00:56 -07:00
parent 86c8d93e5a
commit 16eb390834
4 changed files with 108 additions and 0 deletions

View File

@@ -113,6 +113,7 @@ EXTENSIONS = [
Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'), Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
Extension('VK_EXT_debug_report', 8, True), Extension('VK_EXT_debug_report', 8, True),
Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), 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_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_EXT_external_memory_dma_buf', 1, True), Extension('VK_EXT_external_memory_dma_buf', 1, True),
Extension('VK_EXT_global_priority', 1, Extension('VK_EXT_global_priority', 1,

View File

@@ -2134,6 +2134,7 @@ enum anv_fence_type {
ANV_FENCE_TYPE_NONE = 0, ANV_FENCE_TYPE_NONE = 0,
ANV_FENCE_TYPE_BO, ANV_FENCE_TYPE_BO,
ANV_FENCE_TYPE_SYNCOBJ, ANV_FENCE_TYPE_SYNCOBJ,
ANV_FENCE_TYPE_WSI,
}; };
enum anv_bo_fence_state { enum anv_bo_fence_state {
@@ -2168,6 +2169,9 @@ struct anv_fence_impl {
/** DRM syncobj handle for syncobj-based fences */ /** DRM syncobj handle for syncobj-based fences */
uint32_t syncobj; uint32_t syncobj;
/** WSI fence */
struct wsi_fence *fence_wsi;
}; };
}; };

View File

@@ -324,6 +324,10 @@ anv_fence_impl_cleanup(struct anv_device *device,
anv_gem_syncobj_destroy(device, impl->syncobj); anv_gem_syncobj_destroy(device, impl->syncobj);
break; break;
case ANV_FENCE_TYPE_WSI:
impl->fence_wsi->destroy(impl->fence_wsi);
break;
default: default:
unreachable("Invalid fence type"); unreachable("Invalid fence type");
} }
@@ -673,6 +677,17 @@ done:
return result; 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 static VkResult
anv_wait_for_fences(struct anv_device *device, anv_wait_for_fences(struct anv_device *device,
uint32_t fenceCount, 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], result = anv_wait_for_syncobj_fences(device, 1, &pFences[i],
true, abs_timeout); true, abs_timeout);
break; break;
case ANV_FENCE_TYPE_WSI:
result = anv_wait_for_wsi_fence(device, pFences[i], abs_timeout);
break;
case ANV_FENCE_TYPE_NONE: case ANV_FENCE_TYPE_NONE:
result = VK_SUCCESS; result = VK_SUCCESS;
break; break;

View File

@@ -174,3 +174,88 @@ anv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,
display); display);
} }
#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */ #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);
}