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)
{
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
}
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++;
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;
}
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);
}
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);
/* 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,
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);
/* 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);
/* 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);