summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2014-07-14 16:49:08 -0400
committerTom Stellard <[email protected]>2014-07-21 10:00:09 -0400
commit9ba3105e0a4b186d6b1ee4c23886a3c4cd0a3543 (patch)
treed2bc36a2b8ed1d69765b4444dd439c1d15a70698 /src
parent01c21c459f02b7540ea4e32e03c1e7b1acbd3fe6 (diff)
radeonsi: Read rodata from ELF and append it to the end of shaders
The is used for programs that have arrays of constants that are accessed using dynamic indices. The shader will compute the base address of the constants and then access them using SMRD instructions.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h5
-rw-r--r--src/gallium/drivers/radeon/radeon_elf_util.c5
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c13
3 files changed, 22 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index d82adf5d387..8f1a0a5944c 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -108,6 +108,11 @@ struct radeon_shader_binary {
unsigned char *config;
unsigned config_size;
+ /** Constant data accessed by the shader. This will be uploaded
+ * into a constant buffer. */
+ unsigned char *rodata;
+ unsigned rodata_size;
+
/** Set to 1 if the disassembly for this binary has been dumped to
* stderr. */
int disassembled;
diff --git a/src/gallium/drivers/radeon/radeon_elf_util.c b/src/gallium/drivers/radeon/radeon_elf_util.c
index 7d929623937..7c5f93ef67a 100644
--- a/src/gallium/drivers/radeon/radeon_elf_util.c
+++ b/src/gallium/drivers/radeon/radeon_elf_util.c
@@ -80,6 +80,11 @@ void radeon_elf_read(const char *elf_data, unsigned elf_size,
fprintf(stderr, "\nShader Disassembly:\n\n");
fprintf(stderr, "%.*s\n", (int)section_data->d_size,
(char *)section_data->d_buf);
+ } else if (!strncmp(name, ".rodata", 7)) {
+ section_data = elf_getdata(section, section_data);
+ binary->rodata_size = section_data->d_size;
+ binary->rodata = MALLOC(binary->rodata_size * sizeof(unsigned char));
+ memcpy(binary->rodata, section_data->d_buf, binary->rodata_size);
}
}
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 4c3e83f9605..be18dfc88c7 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -2558,6 +2558,7 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
bool dump = r600_can_dump_shader(&sctx->screen->b,
shader->selector ? shader->selector->tokens : NULL);
const char * gpu_family = r600_get_llvm_processor_name(sctx->screen->b.family);
+ unsigned code_size;
/* Use LLVM to compile shader */
memset(&binary, 0, sizeof(binary));
@@ -2605,9 +2606,10 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
}
/* copy new shader */
+ code_size = binary.code_size + binary.rodata_size;
r600_resource_reference(&shader->bo, NULL);
shader->bo = si_resource_create_custom(sctx->b.b.screen, PIPE_USAGE_IMMUTABLE,
- binary.code_size);
+ code_size);
if (shader->bo == NULL) {
return -ENOMEM;
}
@@ -2617,13 +2619,22 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
for (i = 0; i < binary.code_size / 4; ++i) {
ptr[i] = util_cpu_to_le32((*(uint32_t*)(binary.code + i*4)));
}
+ ptr += (binary.code_size / 4);
+ for (i = 0; i < binary.rodata_size / 4; ++i) {
+ ptr[i] = util_cpu_to_le32((*(uint32_t*)(binary.rodata + i * 4)));
+ }
} else {
memcpy(ptr, binary.code, binary.code_size);
+ if (binary.rodata_size > 0) {
+ ptr += (binary.code_size / 4);
+ memcpy(ptr, binary.rodata, binary.rodata_size);
+ }
}
sctx->b.ws->buffer_unmap(shader->bo->cs_buf);
free(binary.code);
free(binary.config);
+ free(binary.rodata);
return r;
}