[Mesa-dev] [PATCH v3 2/8] anv: Submit a dummy batch when only semaphores are provided.

Lionel Landwerlin lionel.g.landwerlin at intel.com
Sun Aug 13 11:37:36 UTC 2017


On 04/08/17 18:24, Jason Ekstrand wrote:
> Vulkan allows you to do a submit whose only job is to wait on and
> trigger semaphores.  The easiest way for us to support that right
> now is to insert a dummy execbuf.
> ---
>   src/intel/vulkan/anv_batch_chain.c | 28 +++++++++++++++++++++++++---
>   src/intel/vulkan/anv_device.c      | 30 ++++++++++++++++++++++++++++++
>   src/intel/vulkan/anv_private.h     |  1 +
>   src/intel/vulkan/anv_queue.c       | 17 +++++++++++++++++
>   4 files changed, 73 insertions(+), 3 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
> index 94e7a7d..65fe366 100644
> --- a/src/intel/vulkan/anv_batch_chain.c
> +++ b/src/intel/vulkan/anv_batch_chain.c
> @@ -1388,6 +1388,23 @@ setup_execbuf_for_cmd_buffer(struct anv_execbuf *execbuf,
>      return VK_SUCCESS;
>   }
>   
> +static void
> +setup_empty_execbuf(struct anv_execbuf *execbuf, struct anv_device *device)
> +{
> +   anv_execbuf_add_bo(execbuf, &device->trivial_batch_bo, NULL, 0,
> +                      &device->alloc);
> +
> +   execbuf->execbuf = (struct drm_i915_gem_execbuffer2) {
> +      .buffers_ptr = (uintptr_t) execbuf->objects,
> +      .buffer_count = execbuf->bo_count,
> +      .batch_start_offset = 0,
> +      .batch_len = 8, /* GEN8_MI_BATCH_BUFFER_END and NOOP */

nit: since you're using GEN7_MI_BATCH_BUFFER_END below, you could use it 
here too.

> +      .flags = I915_EXEC_HANDLE_LUT | I915_EXEC_RENDER,
> +      .rsvd1 = device->context_id,
> +      .rsvd2 = 0,
> +   };
> +}
> +
>   VkResult
>   anv_cmd_buffer_execbuf(struct anv_device *device,
>                          struct anv_cmd_buffer *cmd_buffer,
> @@ -1447,9 +1464,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
>         }
>      }
>   
> -   result = setup_execbuf_for_cmd_buffer(&execbuf, cmd_buffer);
> -   if (result != VK_SUCCESS)
> -      return result;
> +   if (cmd_buffer) {
> +      result = setup_execbuf_for_cmd_buffer(&execbuf, cmd_buffer);
> +      if (result != VK_SUCCESS)
> +         return result;
> +   } else {
> +      setup_empty_execbuf(&execbuf, device);
> +   }
> +
>   
>      result = anv_device_execbuf(device, &execbuf.execbuf, execbuf.bos);
>   
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index 793e519..e82e1e9 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -1014,6 +1014,32 @@ anv_device_init_border_colors(struct anv_device *device)
>                                                       border_colors);
>   }
>   
> +static void
> +anv_device_init_trivial_batch(struct anv_device *device)
> +{
> +   anv_bo_init_new(&device->trivial_batch_bo, device, 4096);
> +
> +   if (device->instance->physicalDevice.has_exec_async)
> +      device->trivial_batch_bo.flags |= EXEC_OBJECT_ASYNC;
> +
> +   void *map = anv_gem_mmap(device, device->trivial_batch_bo.gem_handle,
> +                            0, 4096, 0);
> +
> +   struct anv_batch batch = {
> +      .start = map,
> +      .next = map,
> +      .end = map + 4096,
> +   };
> +
> +   anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END, bbe);
> +   anv_batch_emit(&batch, GEN7_MI_NOOP, noop);
> +
> +   if (!device->info.has_llc)
> +      gen_clflush_range(map, batch.next - map);
> +
> +   anv_gem_munmap(map, device->trivial_batch_bo.size);
> +}
> +
>   VkResult anv_CreateDevice(
>       VkPhysicalDevice                            physicalDevice,
>       const VkDeviceCreateInfo*                   pCreateInfo,
> @@ -1131,6 +1157,8 @@ VkResult anv_CreateDevice(
>      if (result != VK_SUCCESS)
>         goto fail_surface_state_pool;
>   
> +   anv_device_init_trivial_batch(device);
> +
>      anv_scratch_pool_init(device, &device->scratch_pool);
>   
>      anv_queue_init(device, &device->queue);
> @@ -1220,6 +1248,8 @@ void anv_DestroyDevice(
>      anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size);
>      anv_gem_close(device, device->workaround_bo.gem_handle);
>   
> +   anv_gem_close(device, device->trivial_batch_bo.gem_handle);
> +
>      anv_state_pool_finish(&device->surface_state_pool);
>      anv_state_pool_finish(&device->instruction_state_pool);
>      anv_state_pool_finish(&device->dynamic_state_pool);
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index b599db3..bc67bb6 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -745,6 +745,7 @@ struct anv_device {
>       struct anv_state_pool                       surface_state_pool;
>   
>       struct anv_bo                               workaround_bo;
> +    struct anv_bo                               trivial_batch_bo;
>   
>       struct anv_pipeline_cache                   blorp_shader_cache;
>       struct blorp_context                        blorp;
> diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c
> index 9a0789c..039dfd7 100644
> --- a/src/intel/vulkan/anv_queue.c
> +++ b/src/intel/vulkan/anv_queue.c
> @@ -159,6 +159,23 @@ VkResult anv_QueueSubmit(
>      pthread_mutex_lock(&device->mutex);
>   
>      for (uint32_t i = 0; i < submitCount; i++) {
> +      if (pSubmits[i].commandBufferCount == 0) {
> +         /* If we don't have any command buffers, we need to submit a dummy
> +          * batch to give GEM something to wait on.  We could, potentially,
> +          * come up with something more efficient but this shouldn't be a
> +          * common case.
> +          */
> +         result = anv_cmd_buffer_execbuf(device, NULL,
> +                                         pSubmits[i].pWaitSemaphores,
> +                                         pSubmits[i].waitSemaphoreCount,
> +                                         pSubmits[i].pSignalSemaphores,
> +                                         pSubmits[i].signalSemaphoreCount);
> +         if (result != VK_SUCCESS)
> +            goto out;
> +
> +         continue;
> +      }
> +
>         for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) {
>            ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer,
>                            pSubmits[i].pCommandBuffers[j]);




More information about the mesa-dev mailing list