summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600/r600_asm.c
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2012-12-09 18:51:31 +0100
committerMarek Olšák <maraeo@gmail.com>2012-12-12 13:12:31 +0100
commitd225d076a9807083ea065462390981b9514b6cfc (patch)
treeae80bb230a75ded9f9cb731718c3bea2319f52c6 /src/gallium/drivers/r600/r600_asm.c
parent8df3855eed67302e83e4b181c4fa02183ccc185a (diff)
r600g: suballocate memory for fetch shaders from a large buffer
Fetch shaders are usually destroyed at the context destruction by the state tracker, so we can put them all in a large buffer without wasting memory. This reduces the number of relocations sent to the kernel a little bit. Tested-by: Aaron Watry <awatry@gmail.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src/gallium/drivers/r600/r600_asm.c')
-rw-r--r--src/gallium/drivers/r600/r600_asm.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index f06af444473..268137ff2e7 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -2766,7 +2766,7 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
unsigned format, num_format, format_comp, endian;
uint32_t *bytecode;
int i, j, r, fs_size;
- struct r600_resource *fetch_shader;
+ struct r600_fetch_shader *shader;
assert(count < 32);
@@ -2873,22 +2873,25 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
fs_size = bc.ndw*4;
- fetch_shader = (struct r600_resource*)
- pipe_buffer_create(rctx->context.screen,
- PIPE_BIND_CUSTOM,
- PIPE_USAGE_IMMUTABLE, fs_size);
- if (fetch_shader == NULL) {
+ /* Allocate the CSO. */
+ shader = CALLOC_STRUCT(r600_fetch_shader);
+ if (!shader) {
r600_bytecode_clear(&bc);
return NULL;
}
- bytecode = rctx->ws->buffer_map(fetch_shader->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE);
- if (bytecode == NULL) {
+ u_suballocator_alloc(rctx->allocator_fetch_shader, fs_size, &shader->offset,
+ (struct pipe_resource**)&shader->buffer);
+ if (!shader->buffer) {
r600_bytecode_clear(&bc);
- pipe_resource_reference((struct pipe_resource**)&fetch_shader, NULL);
+ FREE(shader);
return NULL;
}
+ bytecode = rctx->ws->buffer_map(shader->buffer->cs_buf, rctx->cs,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED);
+ bytecode += shader->offset / 4;
+
if (R600_BIG_ENDIAN) {
for (i = 0; i < fs_size / 4; ++i) {
bytecode[i] = bswap_32(bc.bytecode[i]);
@@ -2896,11 +2899,10 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
} else {
memcpy(bytecode, bc.bytecode, fs_size);
}
+ rctx->ws->buffer_unmap(shader->buffer->cs_buf);
- rctx->ws->buffer_unmap(fetch_shader->cs_buf);
r600_bytecode_clear(&bc);
-
- return fetch_shader;
+ return shader;
}
void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)