Re: [Mesa-dev] [PATCH v2 08/10] anv: Use DRM sync objects to back fences whenever possible
A v3 of this will be coming tomorrow. Dave asked me to rework some kernel apis. On August 24, 2017 4:49:53 PM Jason Ekstrandwrote: In order to implement VK_KHR_external_fence, we need to back our fences with something that's shareable. Since the kernel wait interface for sync objects already supports waiting for multiple fences in one go, it makes anv_WaitForFences much simpler if we only have one type of fence. --- src/intel/vulkan/anv_batch_chain.c | 8 +++ src/intel/vulkan/anv_device.c | 2 + src/intel/vulkan/anv_private.h | 4 ++ src/intel/vulkan/anv_queue.c | 133 ++--- 4 files changed, 138 insertions(+), 9 deletions(-) diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index 0a0be8d..52c4510 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -1560,6 +1560,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device, return result; break; + case ANV_FENCE_TYPE_SYNCOBJ: + result = anv_execbuf_add_syncobj(, impl->syncobj, + I915_EXEC_FENCE_SIGNAL, + >alloc); + if (result != VK_SUCCESS) +return result; + break; + default: unreachable("Invalid fence type"); } diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index a6d5215..2e0fa19 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -339,6 +339,8 @@ anv_physical_device_init(struct anv_physical_device *device, device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC); device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE); device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY); + device->has_syncobj_wait = device->has_syncobj && + anv_gem_supports_syncobj_wait(fd); bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 66a85db..4d83767 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -646,6 +646,7 @@ struct anv_physical_device { boolhas_exec_async; boolhas_exec_fence; boolhas_syncobj; +boolhas_syncobj_wait; uint32_teu_total; uint32_tsubslice_total; @@ -1748,6 +1749,9 @@ struct anv_fence_impl { struct anv_bo bo; enum anv_bo_fence_state state; } bo; + + /** DRM syncobj handle for syncobj-based fences */ + uint32_t syncobj; }; }; diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index 7348e15..5e84566 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -271,17 +271,28 @@ VkResult anv_CreateFence( if (fence == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - fence->permanent.type = ANV_FENCE_TYPE_BO; + if (device->instance->physicalDevice.has_syncobj_wait) { + fence->permanent.type = ANV_FENCE_TYPE_SYNCOBJ; - VkResult result = anv_bo_pool_alloc(>batch_bo_pool, - >permanent.bo.bo, 4096); - if (result != VK_SUCCESS) - return result; + fence->permanent.syncobj = anv_gem_syncobj_create(device); + if (!fence->permanent.syncobj) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) { - fence->permanent.bo.state = ANV_BO_FENCE_STATE_SIGNALED; + if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) + anv_gem_syncobj_signal(device, fence->permanent.syncobj); } else { - fence->permanent.bo.state = ANV_BO_FENCE_STATE_RESET; + fence->permanent.type = ANV_FENCE_TYPE_BO; + + VkResult result = anv_bo_pool_alloc(>batch_bo_pool, + >permanent.bo.bo, 4096); + if (result != VK_SUCCESS) + return result; + + if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) { + fence->permanent.bo.state = ANV_BO_FENCE_STATE_SIGNALED; + } else { + fence->permanent.bo.state = ANV_BO_FENCE_STATE_RESET; + } } *pFence = anv_fence_to_handle(fence); @@ -301,6 +312,10 @@ anv_fence_impl_cleanup(struct anv_device *device, case ANV_FENCE_TYPE_BO: anv_bo_pool_free(>batch_bo_pool, >bo.bo); return; + + case ANV_FENCE_TYPE_SYNCOBJ: + anv_gem_syncobj_destroy(device, impl->syncobj); + return; } unreachable("Invalid fence type"); @@ -328,6 +343,8 @@ VkResult anv_ResetFences( uint32_tfenceCount, const
[Mesa-dev] [PATCH v2 08/10] anv: Use DRM sync objects to back fences whenever possible
In order to implement VK_KHR_external_fence, we need to back our fences with something that's shareable. Since the kernel wait interface for sync objects already supports waiting for multiple fences in one go, it makes anv_WaitForFences much simpler if we only have one type of fence. --- src/intel/vulkan/anv_batch_chain.c | 8 +++ src/intel/vulkan/anv_device.c | 2 + src/intel/vulkan/anv_private.h | 4 ++ src/intel/vulkan/anv_queue.c | 133 ++--- 4 files changed, 138 insertions(+), 9 deletions(-) diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index 0a0be8d..52c4510 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -1560,6 +1560,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device, return result; break; + case ANV_FENCE_TYPE_SYNCOBJ: + result = anv_execbuf_add_syncobj(, impl->syncobj, + I915_EXEC_FENCE_SIGNAL, + >alloc); + if (result != VK_SUCCESS) +return result; + break; + default: unreachable("Invalid fence type"); } diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index a6d5215..2e0fa19 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -339,6 +339,8 @@ anv_physical_device_init(struct anv_physical_device *device, device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC); device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE); device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY); + device->has_syncobj_wait = device->has_syncobj && + anv_gem_supports_syncobj_wait(fd); bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 66a85db..4d83767 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -646,6 +646,7 @@ struct anv_physical_device { boolhas_exec_async; boolhas_exec_fence; boolhas_syncobj; +boolhas_syncobj_wait; uint32_teu_total; uint32_tsubslice_total; @@ -1748,6 +1749,9 @@ struct anv_fence_impl { struct anv_bo bo; enum anv_bo_fence_state state; } bo; + + /** DRM syncobj handle for syncobj-based fences */ + uint32_t syncobj; }; }; diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index 7348e15..5e84566 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -271,17 +271,28 @@ VkResult anv_CreateFence( if (fence == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - fence->permanent.type = ANV_FENCE_TYPE_BO; + if (device->instance->physicalDevice.has_syncobj_wait) { + fence->permanent.type = ANV_FENCE_TYPE_SYNCOBJ; - VkResult result = anv_bo_pool_alloc(>batch_bo_pool, - >permanent.bo.bo, 4096); - if (result != VK_SUCCESS) - return result; + fence->permanent.syncobj = anv_gem_syncobj_create(device); + if (!fence->permanent.syncobj) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) { - fence->permanent.bo.state = ANV_BO_FENCE_STATE_SIGNALED; + if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) + anv_gem_syncobj_signal(device, fence->permanent.syncobj); } else { - fence->permanent.bo.state = ANV_BO_FENCE_STATE_RESET; + fence->permanent.type = ANV_FENCE_TYPE_BO; + + VkResult result = anv_bo_pool_alloc(>batch_bo_pool, + >permanent.bo.bo, 4096); + if (result != VK_SUCCESS) + return result; + + if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) { + fence->permanent.bo.state = ANV_BO_FENCE_STATE_SIGNALED; + } else { + fence->permanent.bo.state = ANV_BO_FENCE_STATE_RESET; + } } *pFence = anv_fence_to_handle(fence); @@ -301,6 +312,10 @@ anv_fence_impl_cleanup(struct anv_device *device, case ANV_FENCE_TYPE_BO: anv_bo_pool_free(>batch_bo_pool, >bo.bo); return; + + case ANV_FENCE_TYPE_SYNCOBJ: + anv_gem_syncobj_destroy(device, impl->syncobj); + return; } unreachable("Invalid fence type"); @@ -328,6 +343,8 @@ VkResult anv_ResetFences( uint32_tfenceCount, const VkFence* pFences) { + ANV_FROM_HANDLE(anv_device, device, _device); + for (uint32_t i = 0; i < fenceCount; i++) {