summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c35
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h9
2 files changed, 36 insertions, 8 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 50154c210be..fb8f511fa6a 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -4036,26 +4036,45 @@ void si_shader_apply_scratch_relocs(struct si_context *sctx,
int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader)
{
- const struct radeon_shader_binary *binary = &shader->binary;
- unsigned code_size = binary->code_size + binary->rodata_size;
+ const struct radeon_shader_binary *prolog =
+ shader->prolog ? &shader->prolog->binary : NULL;
+ const struct radeon_shader_binary *epilog =
+ shader->epilog ? &shader->epilog->binary : NULL;
+ const struct radeon_shader_binary *mainb = &shader->binary;
+ unsigned bo_size =
+ (prolog ? prolog->code_size : 0) +
+ mainb->code_size +
+ (epilog ? epilog->code_size : mainb->rodata_size);
unsigned char *ptr;
+ assert(!prolog || !prolog->rodata_size);
+ assert((!prolog && !epilog) || !mainb->rodata_size);
+ assert(!epilog || !epilog->rodata_size);
+
r600_resource_reference(&shader->bo, NULL);
shader->bo = si_resource_create_custom(&sscreen->b.b,
PIPE_USAGE_IMMUTABLE,
- code_size);
+ bo_size);
if (!shader->bo)
return -ENOMEM;
+ /* Upload. */
ptr = sscreen->b.ws->buffer_map(shader->bo->buf, NULL,
PIPE_TRANSFER_READ_WRITE);
- util_memcpy_cpu_to_le32(ptr, binary->code, binary->code_size);
- if (binary->rodata_size > 0) {
- ptr += binary->code_size;
- util_memcpy_cpu_to_le32(ptr, binary->rodata,
- binary->rodata_size);
+
+ if (prolog) {
+ util_memcpy_cpu_to_le32(ptr, prolog->code, prolog->code_size);
+ ptr += prolog->code_size;
}
+ util_memcpy_cpu_to_le32(ptr, mainb->code, mainb->code_size);
+ ptr += mainb->code_size;
+
+ if (epilog)
+ util_memcpy_cpu_to_le32(ptr, epilog->code, epilog->code_size);
+ else if (mainb->rodata_size > 0)
+ util_memcpy_cpu_to_le32(ptr, mainb->rodata, mainb->rodata_size);
+
sscreen->b.ws->buffer_unmap(shader->bo->buf);
return 0;
}
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 9331156b002..4c3c14ae169 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -304,6 +304,9 @@ struct si_shader {
struct si_shader_selector *selector;
struct si_shader *next_variant;
+ struct si_shader_part *prolog;
+ struct si_shader_part *epilog;
+
struct si_shader *gs_copy_shader;
struct si_pm4_state *pm4;
struct r600_resource *bo;
@@ -322,6 +325,12 @@ struct si_shader {
unsigned nr_param_exports;
};
+struct si_shader_part {
+ struct si_shader_part *next;
+ struct radeon_shader_binary binary;
+ struct si_shader_config config;
+};
+
static inline struct tgsi_shader_info *si_get_vs_info(struct si_context *sctx)
{
if (sctx->gs_shader.cso)