Re: [Mesa-dev] [PATCH v2 08/10] anv: Use DRM sync objects to back fences whenever possible

2017-08-24 Thread Jason Ekstrand
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 Ekstrand  wrote:


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

2017-08-24 Thread Jason Ekstrand
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++) {