From: Scott D Phillips Date: Wed, 14 Mar 2018 17:31:16 +0000 (-0700) Subject: anv: Use a separate pool for binding tables when soft pinning X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c7db0ed4e94dce563d722e1b098684fbd7315d51;p=mesa.git anv: Use a separate pool for binding tables when soft pinning Soft pinning lets us satisfy the binding table address requirements without using both sides of a growing state_pool. If you do use both sides of a state pool, then you need to read the state pool's center_bo_offset (with the device mutex held) to know the final offset of relocations that target the state pool bo. By having a separate pool for binding tables that only grows in the forward direction, the center_bo_offset is always 0 and relocations don't need an update pass to adjust relocations with the mutex held. v2: - don't introduce a separate state flag for separate binding tables (Jason) - replace bo and map accessors with a single binding_table_pool accessor (Jason) v3: - assert bt_block->offset >= 0 for the separate binding table (Jason) Reviewed-by: Jason Ekstrand Reviewed-by: Jordan Justen --- diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index ec8815a3c44..9e01a275a1f 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -452,7 +452,7 @@ anv_cmd_buffer_surface_base_address(struct anv_cmd_buffer *cmd_buffer) { struct anv_state *bt_block = u_vector_head(&cmd_buffer->bt_block_states); return (struct anv_address) { - .bo = &cmd_buffer->device->surface_state_pool.block_pool.bo, + .bo = &anv_binding_table_pool(cmd_buffer->device)->block_pool.bo, .offset = bt_block->offset, }; } @@ -619,7 +619,8 @@ struct anv_state anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer, uint32_t entries, uint32_t *state_offset) { - struct anv_state_pool *state_pool = &cmd_buffer->device->surface_state_pool; + struct anv_device *device = cmd_buffer->device; + struct anv_state_pool *state_pool = &device->surface_state_pool; struct anv_state *bt_block = u_vector_head(&cmd_buffer->bt_block_states); struct anv_state state; @@ -629,12 +630,19 @@ anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer, return (struct anv_state) { 0 }; state.offset = cmd_buffer->bt_next; - state.map = state_pool->block_pool.map + bt_block->offset + state.offset; + state.map = anv_binding_table_pool(device)->block_pool.map + + bt_block->offset + state.offset; cmd_buffer->bt_next += state.alloc_size; - assert(bt_block->offset < 0); - *state_offset = -bt_block->offset; + if (device->instance->physicalDevice.use_softpin) { + assert(bt_block->offset >= 0); + *state_offset = device->surface_state_pool.block_pool.start_address - + device->binding_table_pool.block_pool.start_address - bt_block->offset; + } else { + assert(bt_block->offset < 0); + *state_offset = -bt_block->offset; + } return state; } @@ -658,15 +666,13 @@ anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer, VkResult anv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer) { - struct anv_state_pool *state_pool = &cmd_buffer->device->surface_state_pool; - struct anv_state *bt_block = u_vector_add(&cmd_buffer->bt_block_states); if (bt_block == NULL) { anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); } - *bt_block = anv_state_pool_alloc_back(state_pool); + *bt_block = anv_binding_table_pool_alloc(cmd_buffer->device); cmd_buffer->bt_next = 0; return VK_SUCCESS; @@ -740,7 +746,7 @@ anv_cmd_buffer_fini_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer) { struct anv_state *bt_block; u_vector_foreach(bt_block, &cmd_buffer->bt_block_states) - anv_state_pool_free(&cmd_buffer->device->surface_state_pool, *bt_block); + anv_binding_table_pool_free(cmd_buffer->device, *bt_block); u_vector_finish(&cmd_buffer->bt_block_states); anv_reloc_list_finish(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc); @@ -772,7 +778,7 @@ anv_cmd_buffer_reset_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer) while (u_vector_length(&cmd_buffer->bt_block_states) > 1) { struct anv_state *bt_block = u_vector_remove(&cmd_buffer->bt_block_states); - anv_state_pool_free(&cmd_buffer->device->surface_state_pool, *bt_block); + anv_binding_table_pool_free(cmd_buffer->device, *bt_block); } assert(u_vector_length(&cmd_buffer->bt_block_states) == 1); cmd_buffer->bt_next = 0; diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index e7201ec6721..067f4369b76 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -1641,9 +1641,18 @@ VkResult anv_CreateDevice( if (result != VK_SUCCESS) goto fail_instruction_state_pool; + if (physical_device->use_softpin) { + result = anv_state_pool_init(&device->binding_table_pool, device, + BINDING_TABLE_POOL_MIN_ADDRESS, + 4096, + bo_flags); + if (result != VK_SUCCESS) + goto fail_surface_state_pool; + } + result = anv_bo_init_new(&device->workaround_bo, device, 1024); if (result != VK_SUCCESS) - goto fail_surface_state_pool; + goto fail_binding_table_pool; anv_device_init_trivial_batch(device); @@ -1694,6 +1703,9 @@ VkResult anv_CreateDevice( anv_scratch_pool_finish(device, &device->scratch_pool); anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size); anv_gem_close(device, device->workaround_bo.gem_handle); + fail_binding_table_pool: + if (physical_device->use_softpin) + anv_state_pool_finish(&device->binding_table_pool); fail_surface_state_pool: anv_state_pool_finish(&device->surface_state_pool); fail_instruction_state_pool: diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 1641aaf7a69..bbbf7ecd4cf 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -955,6 +955,7 @@ struct anv_device { struct anv_state_pool dynamic_state_pool; struct anv_state_pool instruction_state_pool; + struct anv_state_pool binding_table_pool; struct anv_state_pool surface_state_pool; struct anv_bo workaround_bo; @@ -977,6 +978,29 @@ struct anv_device { bool lost; }; +static inline struct anv_state_pool * +anv_binding_table_pool(struct anv_device *device) +{ + if (device->instance->physicalDevice.use_softpin) + return &device->binding_table_pool; + else + return &device->surface_state_pool; +} + +static inline struct anv_state +anv_binding_table_pool_alloc(struct anv_device *device) { + if (device->instance->physicalDevice.use_softpin) + return anv_state_pool_alloc(&device->binding_table_pool, + device->binding_table_pool.block_size, 0); + else + return anv_state_pool_alloc_back(&device->surface_state_pool); +} + +static inline void +anv_binding_table_pool_free(struct anv_device *device, struct anv_state state) { + anv_state_pool_free(anv_binding_table_pool(device), state); +} + static void inline anv_state_flush(struct anv_device *device, struct anv_state state) {