diff options
author | Jason Ekstrand <[email protected]> | 2017-02-27 16:34:13 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-08-15 19:08:26 -0700 |
commit | 017cdb10cf5001d018b65eeec4b06ebeacbb5593 (patch) | |
tree | 13eb65fc54732c45ad17bd5260fb39fc6bebf024 | |
parent | 031f57eba3719c8dd6462ebd2af696d2632d71b8 (diff) |
anv: Submit a dummy batch when only semaphores are provided.
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.
Reviewed-by: Lionel Landwerlin <[email protected]>
-rw-r--r-- | src/intel/vulkan/anv_batch_chain.c | 28 | ||||
-rw-r--r-- | src/intel/vulkan/anv_device.c | 30 | ||||
-rw-r--r-- | src/intel/vulkan/anv_private.h | 1 | ||||
-rw-r--r-- | 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 52ecfe89027..b55fc03b24b 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, /* GEN7_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, @@ -1448,9 +1465,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 793e519ad97..e82e1e97ca5 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 b599db3b801..bc67bb6013a 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 9a0789ca322..039dfd7e2dc 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]); |