radeonsi: add code for combining and uploading shaders from 3 shader parts
authorMarek Olšák <marek.olsak@amd.com>
Tue, 26 Jan 2016 21:12:26 +0000 (22:12 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 21 Feb 2016 20:08:57 +0000 (21:08 +0100)
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h

index 50154c210be860df90b1f7626493cde48e0ddcf2..fb8f511fa6aa57f5ca4198901922c10e8993159f 100644 (file)
@@ -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;
 }
index 9331156b0025a7ede0a9c5e5bdc8e77c9cd0dac4..4c3c14ae169717afd807f27a85da8c59c40307e7 100644 (file)
@@ -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)