+ 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]);
+ struct anv_semaphore_impl *impl =
+ semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ?
+ &semaphore->temporary : &semaphore->permanent;
+
+ switch (impl->type) {
+ case ANV_SEMAPHORE_TYPE_BO:
+ assert(!pdevice->has_syncobj);
+ result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL,
+ 0, &device->alloc);
+ if (result != VK_SUCCESS)
+ return result;
+ break;
+
+ case ANV_SEMAPHORE_TYPE_SYNC_FILE:
+ assert(!pdevice->has_syncobj);
+ 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);
+
+ close(impl->fd);
+ close(in_fence);
+ in_fence = merge;
+ }
+
+ impl->fd = -1;
+ break;
+
+ case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
+ result = anv_execbuf_add_syncobj(&execbuf, impl->syncobj,
+ I915_EXEC_FENCE_WAIT,
+ &device->alloc);
+ if (result != VK_SUCCESS)
+ return result;
+ 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]);
+
+ /* Under most circumstances, out fences won't be temporary. However,
+ * the spec does allow it for opaque_fd. From the Vulkan 1.0.53 spec:
+ *
+ * "If the import is temporary, the implementation must restore the
+ * semaphore to its prior permanent state after submitting the next
+ * semaphore wait operation."
+ *
+ * The spec says nothing whatsoever about signal operations on
+ * temporarily imported semaphores so it appears they are allowed.
+ * There are also CTS tests that require this to work.
+ */
+ struct anv_semaphore_impl *impl =
+ semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ?
+ &semaphore->temporary : &semaphore->permanent;
+
+ switch (impl->type) {
+ case ANV_SEMAPHORE_TYPE_BO:
+ assert(!pdevice->has_syncobj);
+ result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL,
+ EXEC_OBJECT_WRITE, &device->alloc);
+ if (result != VK_SUCCESS)
+ return result;
+ break;
+
+ case ANV_SEMAPHORE_TYPE_SYNC_FILE:
+ assert(!pdevice->has_syncobj);
+ need_out_fence = true;
+ break;
+
+ case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
+ result = anv_execbuf_add_syncobj(&execbuf, impl->syncobj,
+ I915_EXEC_FENCE_SIGNAL,
+ &device->alloc);
+ if (result != VK_SUCCESS)
+ return result;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (fence) {
+ /* Under most circumstances, out fences won't be temporary. However,
+ * the spec does allow it for opaque_fd. From the Vulkan 1.0.53 spec:
+ *
+ * "If the import is temporary, the implementation must restore the
+ * semaphore to its prior permanent state after submitting the next
+ * semaphore wait operation."
+ *
+ * The spec says nothing whatsoever about signal operations on
+ * temporarily imported semaphores so it appears they are allowed.
+ * There are also CTS tests that require this to work.
+ */
+ struct anv_fence_impl *impl =
+ fence->temporary.type != ANV_FENCE_TYPE_NONE ?
+ &fence->temporary : &fence->permanent;
+
+ switch (impl->type) {
+ case ANV_FENCE_TYPE_BO:
+ assert(!pdevice->has_syncobj_wait);
+ result = anv_execbuf_add_bo(&execbuf, &impl->bo.bo, NULL,
+ EXEC_OBJECT_WRITE, &device->alloc);
+ if (result != VK_SUCCESS)
+ return result;
+ break;
+
+ case ANV_FENCE_TYPE_SYNCOBJ:
+ result = anv_execbuf_add_syncobj(&execbuf, impl->syncobj,
+ I915_EXEC_FENCE_SIGNAL,
+ &device->alloc);
+ if (result != VK_SUCCESS)
+ return result;
+ break;
+
+ default:
+ unreachable("Invalid fence type");
+ }
+ }
+
+ if (cmd_buffer) {
+ if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) {
+ struct anv_batch_bo **bo = u_vector_head(&cmd_buffer->seen_bbos);
+
+ device->cmd_buffer_being_decoded = cmd_buffer;
+ gen_print_batch(&device->decoder_ctx, (*bo)->bo.map,
+ (*bo)->bo.size, (*bo)->bo.offset, false);
+ device->cmd_buffer_being_decoded = NULL;
+ }
+
+ result = setup_execbuf_for_cmd_buffer(&execbuf, cmd_buffer);
+ } else {
+ result = setup_empty_execbuf(&execbuf, device);
+ }
+