Re: [Mesa-dev] [PATCH v3 4/8] anv: Implement support for exporting semaphores as FENCE_FD

2017-08-13 Thread Lionel Landwerlin

On 04/08/17 18:24, Jason Ekstrand wrote:

---
  src/intel/vulkan/anv_batch_chain.c | 57 +--
  src/intel/vulkan/anv_device.c  |  1 +
  src/intel/vulkan/anv_gem.c | 36 
  src/intel/vulkan/anv_private.h | 23 +
  src/intel/vulkan/anv_queue.c   | 69 --
  5 files changed, 175 insertions(+), 11 deletions(-)

diff --git a/src/intel/vulkan/anv_batch_chain.c 
b/src/intel/vulkan/anv_batch_chain.c
index 65fe366..7a84bbd 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -1416,11 +1416,13 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
 struct anv_execbuf execbuf;
 anv_execbuf_init(&execbuf);
  
+   int in_fence = -1;

 VkResult result = VK_SUCCESS;
 for (uint32_t i = 0; i < num_in_semaphores; i++) {
ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]);
-  assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE);
-  struct anv_semaphore_impl *impl = &semaphore->permanent;
+  struct anv_semaphore_impl *impl =
+ semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ?
+ &semaphore->temporary : &semaphore->permanent;


I know you're not enabling this until patch 8, but for consistency, 
shouldn't this be part of patch 1?


  
switch (impl->type) {

case ANV_SEMAPHORE_TYPE_BO:
@@ -1429,11 +1431,29 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
   if (result != VK_SUCCESS)
  return result;
   break;
+
+  case ANV_SEMAPHORE_TYPE_SYNC_FILE:
+ if (in_fence == -1) {
+in_fence = impl->fd;
+ } else {
+int merge = anv_gem_sync_file_merge(device, in_fence, impl->fd);
+if (merge == -1)
+   return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+
+close(impl->fd);
+close(in_fence);
+in_fence = merge;
+ }
+
+ impl->fd = -1;
+ break;
+
default:
   break;
}
 }
  
+   bool need_out_fence = false;

 for (uint32_t i = 0; i < num_out_semaphores; i++) {
ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]);
  
@@ -1459,6 +1479,11 @@ anv_cmd_buffer_execbuf(struct anv_device *device,

   if (result != VK_SUCCESS)
  return result;
   break;
+
+  case ANV_SEMAPHORE_TYPE_SYNC_FILE:
+ need_out_fence = true;
+ break;
+
default:
   break;
}
@@ -1472,9 +1497,19 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
setup_empty_execbuf(&execbuf, device);
 }
  
+   if (in_fence != -1) {

+  execbuf.execbuf.flags |= I915_EXEC_FENCE_IN;
+  execbuf.execbuf.rsvd2 |= (uint32_t)in_fence;
+   }
+
+   if (need_out_fence)
+  execbuf.execbuf.flags |= I915_EXEC_FENCE_OUT;
  
 result = anv_device_execbuf(device, &execbuf.execbuf, execbuf.bos);
  
+   /* Execbuf does not consume the in_fence.  It's our job to close it. */

+   close(in_fence);
+
 for (uint32_t i = 0; i < num_in_semaphores; i++) {
ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]);
/* From the Vulkan 1.0.53 spec:
@@ -1489,6 +1524,24 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
anv_semaphore_reset_temporary(device, semaphore);
 }
  
+   if (result == VK_SUCCESS && need_out_fence) {

+  int out_fence = execbuf.execbuf.rsvd2 >> 32;
+  for (uint32_t i = 0; i < num_out_semaphores; i++) {
+ ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]);
+ /* Out fences can't have temporary state because that would imply
+  * that we imported a sync file and are trying to signal it.
+  */
+ assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE);
+ struct anv_semaphore_impl *impl = &semaphore->permanent;
+
+ if (impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE) {
+assert(impl->fd == -1);
+impl->fd = dup(out_fence);
+ }
+  }
+  close(out_fence);
+   }
+
 anv_execbuf_finish(&execbuf, &device->alloc);
  
 return result;

diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index e82e1e9..3c5f78c 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -337,6 +337,7 @@ anv_physical_device_init(struct anv_physical_device *device,
goto fail;
  
 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);
  
 bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
  
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c

index 36692f5..5b68e9b 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -22,6 +22,7 @@
   */
  
  #include 

+#include 
  #include 
  #include 
  #include 
@@ -400,3 +401,38 @@ anv_gem_fd_to_handle(struc

[Mesa-dev] [PATCH v3 4/8] anv: Implement support for exporting semaphores as FENCE_FD

2017-08-04 Thread Jason Ekstrand
---
 src/intel/vulkan/anv_batch_chain.c | 57 +--
 src/intel/vulkan/anv_device.c  |  1 +
 src/intel/vulkan/anv_gem.c | 36 
 src/intel/vulkan/anv_private.h | 23 +
 src/intel/vulkan/anv_queue.c   | 69 --
 5 files changed, 175 insertions(+), 11 deletions(-)

diff --git a/src/intel/vulkan/anv_batch_chain.c 
b/src/intel/vulkan/anv_batch_chain.c
index 65fe366..7a84bbd 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -1416,11 +1416,13 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
struct anv_execbuf execbuf;
anv_execbuf_init(&execbuf);
 
+   int in_fence = -1;
VkResult result = VK_SUCCESS;
for (uint32_t i = 0; i < num_in_semaphores; i++) {
   ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]);
-  assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE);
-  struct anv_semaphore_impl *impl = &semaphore->permanent;
+  struct anv_semaphore_impl *impl =
+ semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ?
+ &semaphore->temporary : &semaphore->permanent;
 
   switch (impl->type) {
   case ANV_SEMAPHORE_TYPE_BO:
@@ -1429,11 +1431,29 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
  if (result != VK_SUCCESS)
 return result;
  break;
+
+  case ANV_SEMAPHORE_TYPE_SYNC_FILE:
+ if (in_fence == -1) {
+in_fence = impl->fd;
+ } else {
+int merge = anv_gem_sync_file_merge(device, in_fence, impl->fd);
+if (merge == -1)
+   return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+
+close(impl->fd);
+close(in_fence);
+in_fence = merge;
+ }
+
+ impl->fd = -1;
+ break;
+
   default:
  break;
   }
}
 
+   bool need_out_fence = false;
for (uint32_t i = 0; i < num_out_semaphores; i++) {
   ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]);
 
@@ -1459,6 +1479,11 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
  if (result != VK_SUCCESS)
 return result;
  break;
+
+  case ANV_SEMAPHORE_TYPE_SYNC_FILE:
+ need_out_fence = true;
+ break;
+
   default:
  break;
   }
@@ -1472,9 +1497,19 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
   setup_empty_execbuf(&execbuf, device);
}
 
+   if (in_fence != -1) {
+  execbuf.execbuf.flags |= I915_EXEC_FENCE_IN;
+  execbuf.execbuf.rsvd2 |= (uint32_t)in_fence;
+   }
+
+   if (need_out_fence)
+  execbuf.execbuf.flags |= I915_EXEC_FENCE_OUT;
 
result = anv_device_execbuf(device, &execbuf.execbuf, execbuf.bos);
 
+   /* Execbuf does not consume the in_fence.  It's our job to close it. */
+   close(in_fence);
+
for (uint32_t i = 0; i < num_in_semaphores; i++) {
   ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]);
   /* From the Vulkan 1.0.53 spec:
@@ -1489,6 +1524,24 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
   anv_semaphore_reset_temporary(device, semaphore);
}
 
+   if (result == VK_SUCCESS && need_out_fence) {
+  int out_fence = execbuf.execbuf.rsvd2 >> 32;
+  for (uint32_t i = 0; i < num_out_semaphores; i++) {
+ ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]);
+ /* Out fences can't have temporary state because that would imply
+  * that we imported a sync file and are trying to signal it.
+  */
+ assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE);
+ struct anv_semaphore_impl *impl = &semaphore->permanent;
+
+ if (impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE) {
+assert(impl->fd == -1);
+impl->fd = dup(out_fence);
+ }
+  }
+  close(out_fence);
+   }
+
anv_execbuf_finish(&execbuf, &device->alloc);
 
return result;
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index e82e1e9..3c5f78c 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -337,6 +337,7 @@ anv_physical_device_init(struct anv_physical_device *device,
   goto fail;
 
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);
 
bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
 
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index 36692f5..5b68e9b 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -22,6 +22,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -400,3 +401,38 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
 
return args.handle;
 }
+
+#ifndef SYNC_IOC_MAGIC
+/* duplicated from linux/sync_file.h to avoid build-time depnedency
+ * on new (v4.7) kernel headers.  Once distro's are mostly using
+