anv/allocator: Convert the state stream to pull from a state pool

Reviewed-by: Juan A. Suarez Romero <jasuarez@igalia.com>
This commit is contained in:
Jason Ekstrand
2017-04-23 17:22:26 -07:00
parent e049dea5b2
commit e86aeecb6a
4 changed files with 55 additions and 51 deletions

View File

@@ -741,14 +741,12 @@ anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state)
anv_state_pool_free_no_vg(pool, state); anv_state_pool_free_no_vg(pool, state);
} }
#define NULL_BLOCK 1
struct anv_state_stream_block { struct anv_state_stream_block {
struct anv_state block;
/* The next block */ /* The next block */
struct anv_state_stream_block *next; struct anv_state_stream_block *next;
/* The offset into the block pool at which this block starts */
uint32_t offset;
#ifdef HAVE_VALGRIND #ifdef HAVE_VALGRIND
/* A pointer to the first user-allocated thing in this block. This is /* A pointer to the first user-allocated thing in this block. This is
* what valgrind sees as the start of the block. * what valgrind sees as the start of the block.
@@ -762,16 +760,20 @@ struct anv_state_stream_block {
*/ */
void void
anv_state_stream_init(struct anv_state_stream *stream, anv_state_stream_init(struct anv_state_stream *stream,
struct anv_block_pool *block_pool) struct anv_state_pool *state_pool,
uint32_t block_size)
{ {
stream->block_pool = block_pool; stream->state_pool = state_pool;
stream->block = NULL; stream->block_size = block_size;
/* Ensure that next + whatever > end. This way the first call to stream->block = ANV_STATE_NULL;
stream->block_list = NULL;
/* Ensure that next + whatever > block_size. This way the first call to
* state_stream_alloc fetches a new block. * state_stream_alloc fetches a new block.
*/ */
stream->next = 1; stream->next = block_size;
stream->end = 0;
VG(VALGRIND_CREATE_MEMPOOL(stream, 0, false)); VG(VALGRIND_CREATE_MEMPOOL(stream, 0, false));
} }
@@ -779,14 +781,12 @@ anv_state_stream_init(struct anv_state_stream *stream,
void void
anv_state_stream_finish(struct anv_state_stream *stream) anv_state_stream_finish(struct anv_state_stream *stream)
{ {
VG(const uint32_t block_size = stream->block_pool->block_size); struct anv_state_stream_block *next = stream->block_list;
struct anv_state_stream_block *next = stream->block;
while (next != NULL) { while (next != NULL) {
struct anv_state_stream_block sb = VG_NOACCESS_READ(next); struct anv_state_stream_block sb = VG_NOACCESS_READ(next);
VG(VALGRIND_MEMPOOL_FREE(stream, sb._vg_ptr)); VG(VALGRIND_MEMPOOL_FREE(stream, sb._vg_ptr));
VG(VALGRIND_MAKE_MEM_UNDEFINED(next, block_size)); VG(VALGRIND_MAKE_MEM_UNDEFINED(next, stream->block_size));
anv_block_pool_free(stream->block_pool, sb.offset); anv_state_pool_free_no_vg(stream->state_pool, sb.block);
next = sb.next; next = sb.next;
} }
@@ -800,35 +800,38 @@ anv_state_stream_alloc(struct anv_state_stream *stream,
if (size == 0) if (size == 0)
return ANV_STATE_NULL; return ANV_STATE_NULL;
struct anv_state_stream_block *sb = stream->block; assert(alignment <= PAGE_SIZE);
struct anv_state state; uint32_t offset = align_u32(stream->next, alignment);
if (offset + size > stream->block_size) {
stream->block = anv_state_pool_alloc_no_vg(stream->state_pool,
stream->block_size,
PAGE_SIZE);
state.offset = align_u32(stream->next, alignment); struct anv_state_stream_block *sb = stream->block.map;
if (state.offset + size > stream->end) { VG_NOACCESS_WRITE(&sb->block, stream->block);
uint32_t block = anv_block_pool_alloc(stream->block_pool); VG_NOACCESS_WRITE(&sb->next, stream->block_list);
sb = stream->block_pool->map + block; stream->block_list = sb;
VG_NOACCESS_WRITE(&sb->_vg_ptr, NULL);
VG(VALGRIND_MAKE_MEM_UNDEFINED(sb, sizeof(*sb))); VG(VALGRIND_MAKE_MEM_NOACCESS(stream->block.map, stream->block_size));
sb->next = stream->block;
sb->offset = block;
VG(sb->_vg_ptr = NULL);
VG(VALGRIND_MAKE_MEM_NOACCESS(sb, stream->block_pool->block_size));
stream->block = sb; /* Reset back to the start plus space for the header */
stream->start = block; stream->next = sizeof(*sb);
stream->next = block + sizeof(*sb);
stream->end = block + stream->block_pool->block_size;
state.offset = align_u32(stream->next, alignment); offset = align_u32(stream->next, alignment);
assert(state.offset + size <= stream->end); assert(offset + size <= stream->block_size);
} }
assert(state.offset > stream->start); struct anv_state state = stream->block;
state.map = (void *)sb + (state.offset - stream->start); state.offset += offset;
state.alloc_size = size; state.alloc_size = size;
state.map += offset;
stream->next = offset + size;
#ifdef HAVE_VALGRIND #ifdef HAVE_VALGRIND
struct anv_state_stream_block *sb = stream->block_list;
void *vg_ptr = VG_NOACCESS_READ(&sb->_vg_ptr); void *vg_ptr = VG_NOACCESS_READ(&sb->_vg_ptr);
if (vg_ptr == NULL) { if (vg_ptr == NULL) {
vg_ptr = state.map; vg_ptr = state.map;
@@ -844,8 +847,6 @@ anv_state_stream_alloc(struct anv_state_stream *stream,
} }
#endif #endif
stream->next = state.offset + size;
return state; return state;
} }

View File

@@ -212,9 +212,9 @@ static VkResult anv_create_cmd_buffer(
goto fail; goto fail;
anv_state_stream_init(&cmd_buffer->surface_state_stream, anv_state_stream_init(&cmd_buffer->surface_state_stream,
&device->surface_state_block_pool); &device->surface_state_pool, 4096);
anv_state_stream_init(&cmd_buffer->dynamic_state_stream, anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
&device->dynamic_state_block_pool); &device->dynamic_state_pool, 16384);
memset(&cmd_buffer->state.push_descriptor, 0, memset(&cmd_buffer->state.push_descriptor, 0,
sizeof(cmd_buffer->state.push_descriptor)); sizeof(cmd_buffer->state.push_descriptor));
@@ -306,11 +306,11 @@ anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
anv_state_stream_finish(&cmd_buffer->surface_state_stream); anv_state_stream_finish(&cmd_buffer->surface_state_stream);
anv_state_stream_init(&cmd_buffer->surface_state_stream, anv_state_stream_init(&cmd_buffer->surface_state_stream,
&cmd_buffer->device->surface_state_block_pool); &cmd_buffer->device->surface_state_pool, 4096);
anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
anv_state_stream_init(&cmd_buffer->dynamic_state_stream, anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
&cmd_buffer->device->dynamic_state_block_pool); &cmd_buffer->device->dynamic_state_pool, 16384);
return VK_SUCCESS; return VK_SUCCESS;
} }

View File

@@ -345,7 +345,7 @@ VkResult anv_CreateDescriptorPool(
pool->free_list = EMPTY; pool->free_list = EMPTY;
anv_state_stream_init(&pool->surface_state_stream, anv_state_stream_init(&pool->surface_state_stream,
&device->surface_state_block_pool); &device->surface_state_pool, 4096);
pool->surface_state_free_list = NULL; pool->surface_state_free_list = NULL;
*pDescriptorPool = anv_descriptor_pool_to_handle(pool); *pDescriptorPool = anv_descriptor_pool_to_handle(pool);
@@ -380,7 +380,7 @@ VkResult anv_ResetDescriptorPool(
pool->free_list = EMPTY; pool->free_list = EMPTY;
anv_state_stream_finish(&pool->surface_state_stream); anv_state_stream_finish(&pool->surface_state_stream);
anv_state_stream_init(&pool->surface_state_stream, anv_state_stream_init(&pool->surface_state_stream,
&device->surface_state_block_pool); &device->surface_state_pool, 4096);
pool->surface_state_free_list = NULL; pool->surface_state_free_list = NULL;
return VK_SUCCESS; return VK_SUCCESS;

View File

@@ -511,17 +511,19 @@ struct anv_state_pool {
struct anv_state_stream_block; struct anv_state_stream_block;
struct anv_state_stream { struct anv_state_stream {
struct anv_block_pool *block_pool; struct anv_state_pool *state_pool;
/* The current working block */ /* The size of blocks to allocate from the state pool */
struct anv_state_stream_block *block; uint32_t block_size;
/* Offset at which the current block starts */ /* Current block we're allocating from */
uint32_t start; struct anv_state block;
/* Offset at which to allocate the next state */
/* Offset into the current block at which to allocate the next state */
uint32_t next; uint32_t next;
/* Offset at which the current block ends */
uint32_t end; /* List of all blocks allocated from this pool */
struct anv_state_stream_block *block_list;
}; };
#define CACHELINE_SIZE 64 #define CACHELINE_SIZE 64
@@ -566,7 +568,8 @@ struct anv_state anv_state_pool_alloc(struct anv_state_pool *pool,
size_t state_size, size_t alignment); size_t state_size, size_t alignment);
void anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state); void anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state);
void anv_state_stream_init(struct anv_state_stream *stream, void anv_state_stream_init(struct anv_state_stream *stream,
struct anv_block_pool *block_pool); struct anv_state_pool *state_pool,
uint32_t block_size);
void anv_state_stream_finish(struct anv_state_stream *stream); void anv_state_stream_finish(struct anv_state_stream *stream);
struct anv_state anv_state_stream_alloc(struct anv_state_stream *stream, struct anv_state anv_state_stream_alloc(struct anv_state_stream *stream,
uint32_t size, uint32_t alignment); uint32_t size, uint32_t alignment);