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:
@@ -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,
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user