From: Jason Ekstrand Date: Tue, 26 May 2015 00:38:15 +0000 (-0700) Subject: vk/device: Make reloc lists growable X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=403266be05bbe36e9376f0a747dd454bf0da0958;p=mesa.git vk/device: Make reloc lists growable --- diff --git a/src/vulkan/device.c b/src/vulkan/device.c index 5c2e276210d..4cbf409b216 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -501,6 +501,75 @@ VkResult anv_GetDeviceQueue( return VK_SUCCESS; } +static VkResult +anv_reloc_list_init(struct anv_reloc_list *list, struct anv_device *device) +{ + list->num_relocs = 0; + list->array_length = 256; + list->relocs = + anv_device_alloc(device, list->array_length * sizeof(*list->relocs), 8, + VK_SYSTEM_ALLOC_TYPE_INTERNAL); + + if (list->relocs == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + list->reloc_bos = + anv_device_alloc(device, list->array_length * sizeof(*list->reloc_bos), 8, + VK_SYSTEM_ALLOC_TYPE_INTERNAL); + + if (list->relocs == NULL) { + anv_device_free(device, list->relocs); + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + } + + return VK_SUCCESS; +} + +static void +anv_reloc_list_finish(struct anv_reloc_list *list, struct anv_device *device) +{ + anv_device_free(device, list->relocs); + anv_device_free(device, list->reloc_bos); +} + +static VkResult +anv_reloc_list_grow(struct anv_reloc_list *list, struct anv_device *device, + size_t num_additional_relocs) +{ + if (list->num_relocs + num_additional_relocs <= list->array_length) + return VK_SUCCESS; + + size_t new_length = list->array_length * 2; + while (new_length < list->num_relocs + num_additional_relocs) + new_length *= 2; + + struct drm_i915_gem_relocation_entry *new_relocs = + anv_device_alloc(device, new_length * sizeof(*list->relocs), 8, + VK_SYSTEM_ALLOC_TYPE_INTERNAL); + if (new_relocs == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + struct anv_bo **new_reloc_bos = + anv_device_alloc(device, new_length * sizeof(*list->reloc_bos), 8, + VK_SYSTEM_ALLOC_TYPE_INTERNAL); + if (new_relocs == NULL) { + anv_device_free(device, new_relocs); + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + } + + memcpy(new_relocs, list->relocs, list->num_relocs * sizeof(*list->relocs)); + memcpy(new_reloc_bos, list->reloc_bos, + list->num_relocs * sizeof(*list->reloc_bos)); + + anv_device_free(device, list->relocs); + anv_device_free(device, list->reloc_bos); + + list->relocs = new_relocs; + list->reloc_bos = new_reloc_bos; + + return VK_SUCCESS; +} + VkResult anv_batch_init(struct anv_batch *batch, struct anv_device *device) { @@ -510,16 +579,23 @@ anv_batch_init(struct anv_batch *batch, struct anv_device *device) if (result != VK_SUCCESS) return result; - batch->cmd_relocs.num_relocs = 0; + result = anv_reloc_list_init(&batch->cmd_relocs, device); + if (result != VK_SUCCESS) { + anv_bo_pool_free(&device->batch_bo_pool, &batch->bo); + return result; + } + + batch->device = device; batch->next = batch->bo.map; return VK_SUCCESS; } void -anv_batch_finish(struct anv_batch *batch, struct anv_device *device) +anv_batch_finish(struct anv_batch *batch) { - anv_bo_pool_free(&device->batch_bo_pool, &batch->bo); + anv_bo_pool_free(&batch->device->batch_bo_pool, &batch->bo); + anv_reloc_list_finish(&batch->cmd_relocs, batch->device); } void @@ -540,31 +616,32 @@ anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords) } static void -anv_reloc_list_append(struct anv_reloc_list *list, +anv_reloc_list_append(struct anv_reloc_list *list, struct anv_device *device, struct anv_reloc_list *other, uint32_t offset) { - uint32_t i, count; + anv_reloc_list_grow(list, device, other->num_relocs); + /* TODO: Handle failure */ - count = list->num_relocs; - memcpy(&list->relocs[count], &other->relocs[0], + memcpy(&list->relocs[list->num_relocs], &other->relocs[0], other->num_relocs * sizeof(other->relocs[0])); - memcpy(&list->reloc_bos[count], &other->reloc_bos[0], + memcpy(&list->reloc_bos[list->num_relocs], &other->reloc_bos[0], other->num_relocs * sizeof(other->reloc_bos[0])); - for (i = 0; i < other->num_relocs; i++) - list->relocs[i + count].offset += offset; - count += other->num_relocs; + for (uint32_t i = 0; i < other->num_relocs; i++) + list->relocs[i + list->num_relocs].offset += offset; + + list->num_relocs += other->num_relocs; } static uint64_t -anv_reloc_list_add(struct anv_reloc_list *list, - uint32_t offset, - struct anv_bo *target_bo, uint32_t delta) +anv_reloc_list_add(struct anv_reloc_list *list, struct anv_device *device, + uint32_t offset, struct anv_bo *target_bo, uint32_t delta) { struct drm_i915_gem_relocation_entry *entry; int index; - assert(list->num_relocs < ANV_BATCH_MAX_RELOCS); + anv_reloc_list_grow(list, device, 1); + /* TODO: Handle failure */ /* XXX: Can we use I915_EXEC_HANDLE_LUT? */ index = list->num_relocs++; @@ -589,7 +666,8 @@ anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other) memcpy(batch->next, other->bo.map, size); offset = batch->next - batch->bo.map; - anv_reloc_list_append(&batch->cmd_relocs, &other->cmd_relocs, offset); + anv_reloc_list_append(&batch->cmd_relocs, batch->device, + &other->cmd_relocs, offset); batch->next += size; } @@ -598,7 +676,7 @@ uint64_t anv_batch_emit_reloc(struct anv_batch *batch, void *location, struct anv_bo *bo, uint32_t delta) { - return anv_reloc_list_add(&batch->cmd_relocs, + return anv_reloc_list_add(&batch->cmd_relocs, batch->device, location - batch->bo.map, bo, delta); } @@ -2147,10 +2225,11 @@ anv_cmd_buffer_destroy(struct anv_device *device, anv_gem_munmap(cmd_buffer->surface_bo.map, BATCH_SIZE); anv_gem_close(device, cmd_buffer->surface_bo.gem_handle); + anv_reloc_list_finish(&cmd_buffer->surface_relocs, device); anv_state_stream_finish(&cmd_buffer->surface_state_stream); anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); anv_state_stream_finish(&cmd_buffer->binding_table_state_stream); - anv_batch_finish(&cmd_buffer->batch, device); + anv_batch_finish(&cmd_buffer->batch); anv_device_free(device, cmd_buffer->exec2_objects); anv_device_free(device, cmd_buffer->exec2_bos); anv_device_free(device, cmd_buffer); @@ -2195,7 +2274,7 @@ VkResult anv_CreateCommandBuffer( /* Start surface_next at 1 so surface offset 0 is invalid. */ cmd_buffer->surface_next = 1; - cmd_buffer->surface_relocs.num_relocs = 0; + anv_reloc_list_init(&cmd_buffer->surface_relocs, device); cmd_buffer->exec2_objects = anv_device_alloc(device, 8192 * sizeof(cmd_buffer->exec2_objects[0]), 8, @@ -2235,7 +2314,7 @@ VkResult anv_CreateCommandBuffer( fail_surface_bo: anv_gem_close(device, cmd_buffer->surface_bo.gem_handle); fail_batch: - anv_batch_finish(&cmd_buffer->batch, device); + anv_batch_finish(&cmd_buffer->batch); fail: anv_device_free(device, cmd_buffer); @@ -2546,6 +2625,7 @@ void anv_CmdBindDescriptorSets( /* The address goes in dwords 8 and 9 of the SURFACE_STATE */ *(uint64_t *)(state.map + 8 * 4) = anv_reloc_list_add(&cmd_buffer->surface_relocs, + cmd_buffer->device, state.offset + 8 * 4, view->bo, view->offset); @@ -3321,6 +3401,7 @@ anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer) /* The address goes in dwords 8 and 9 of the SURFACE_STATE */ *(uint64_t *)(state.map + 8 * 4) = anv_reloc_list_add(&cmd_buffer->surface_relocs, + cmd_buffer->device, state.offset + 8 * 4, view->bo, view->offset); diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c index e33b7e6c376..c0606dabba7 100644 --- a/src/vulkan/pipeline.c +++ b/src/vulkan/pipeline.c @@ -378,7 +378,7 @@ anv_pipeline_destroy(struct anv_device *device, assert(obj_type == VK_OBJECT_TYPE_PIPELINE); anv_compiler_free(pipeline); - anv_batch_finish(&pipeline->batch, pipeline->device); + anv_batch_finish(&pipeline->batch); anv_device_free(pipeline->device, pipeline); } diff --git a/src/vulkan/private.h b/src/vulkan/private.h index 6e43258c903..a77fb28449b 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -389,23 +389,24 @@ int anv_gem_userptr(struct anv_device *device, void *mem, size_t size); VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size); -/* TODO: Remove hardcoded reloc limit. */ -#define ANV_BATCH_MAX_RELOCS 256 - struct anv_reloc_list { size_t num_relocs; - struct drm_i915_gem_relocation_entry relocs[ANV_BATCH_MAX_RELOCS]; - struct anv_bo * reloc_bos[ANV_BATCH_MAX_RELOCS]; + size_t array_length; + struct drm_i915_gem_relocation_entry * relocs; + struct anv_bo ** reloc_bos; }; struct anv_batch { + struct anv_device * device; + struct anv_bo bo; void * next; + struct anv_reloc_list cmd_relocs; }; VkResult anv_batch_init(struct anv_batch *batch, struct anv_device *device); -void anv_batch_finish(struct anv_batch *batch, struct anv_device *device); +void anv_batch_finish(struct anv_batch *batch); void anv_batch_reset(struct anv_batch *batch); void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords); void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other);