[Mesa-dev] [PATCH 2/8] anv: Submit a dummy batch when only semaphores are provided.
Jason Ekstrand
jason at jlekstrand.net
Thu Jul 13 22:55:47 UTC 2017
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 | 26 ++++++++++++++++++++++++++
src/intel/vulkan/anv_private.h | 1 +
src/intel/vulkan/anv_queue.c | 17 +++++++++++++++++
4 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
index ad76dc1..ec745a4 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 */
+ .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,
@@ -1434,9 +1451,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 6fc57cd..a98bd7c 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1101,6 +1101,28 @@ 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);
+ 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,
@@ -1225,6 +1247,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);
@@ -1314,6 +1338,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 4dce360..e95a640 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -740,6 +740,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 570efec..14bc50d 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]);
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list