amd/rtld: layout and relocate LDS symbols
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index 8c4f4e756535086b99d40450a3a0dbb217632b91..ab97cd872738f59d71c8b3237345ec88642641d2 100644 (file)
 #include "tgsi/tgsi_util.h"
 #include "tgsi/tgsi_dump.h"
 
+#include "ac_binary.h"
 #include "ac_exp_param.h"
 #include "ac_shader_util.h"
+#include "ac_rtld.h"
 #include "ac_llvm_util.h"
 #include "si_shader_internal.h"
 #include "si_pipe.h"
 
 #include "compiler/nir/nir.h"
 
-static const char *scratch_rsrc_dword0_symbol =
+static const char scratch_rsrc_dword0_symbol[] =
        "SCRATCH_RSRC_DWORD0";
 
-static const char *scratch_rsrc_dword1_symbol =
+static const char scratch_rsrc_dword1_symbol[] =
        "SCRATCH_RSRC_DWORD1";
 
 struct si_shader_output_values
@@ -5045,258 +5047,181 @@ static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
        ac_build_kill_if_false(&ctx->ac, bit);
 }
 
-void si_shader_binary_read_config(struct ac_shader_binary *binary,
-                                 struct si_shader_config *conf,
-                                 unsigned symbol_offset)
-{
-       unsigned i;
-       const unsigned char *config =
-               ac_shader_binary_config_start(binary, symbol_offset);
-       bool really_needs_scratch = false;
+/* For the UMR disassembler. */
+#define DEBUGGER_END_OF_CODE_MARKER    0xbf9f0000 /* invalid instruction */
+#define DEBUGGER_NUM_MARKERS           5
 
-       /* LLVM adds SGPR spills to the scratch size.
-        * Find out if we really need the scratch buffer.
-        */
-       for (i = 0; i < binary->reloc_count; i++) {
-               const struct ac_shader_reloc *reloc = &binary->relocs[i];
+static bool si_shader_binary_open(struct si_screen *screen,
+                                 struct si_shader *shader,
+                                 struct ac_rtld_binary *rtld)
+{
+       const char *part_elfs[5];
+       size_t part_sizes[5];
+       unsigned num_parts = 0;
 
-               if (!strcmp(scratch_rsrc_dword0_symbol, reloc->name) ||
-                   !strcmp(scratch_rsrc_dword1_symbol, reloc->name)) {
-                       really_needs_scratch = true;
-                       break;
-               }
+#define add_part(shader_or_part) \
+       if (shader_or_part) { \
+               part_elfs[num_parts] = (shader_or_part)->binary.elf_buffer; \
+               part_sizes[num_parts] = (shader_or_part)->binary.elf_size; \
+               num_parts++; \
        }
 
-       /* XXX: We may be able to emit some of these values directly rather than
-        * extracting fields to be emitted later.
-        */
+       add_part(shader->prolog);
+       add_part(shader->previous_stage);
+       add_part(shader->prolog2);
+       add_part(shader);
+       add_part(shader->epilog);
 
-       for (i = 0; i < binary->config_size_per_symbol; i+= 8) {
-               unsigned reg = util_le32_to_cpu(*(uint32_t*)(config + i));
-               unsigned value = util_le32_to_cpu(*(uint32_t*)(config + i + 4));
-               switch (reg) {
-               case R_00B028_SPI_SHADER_PGM_RSRC1_PS:
-               case R_00B128_SPI_SHADER_PGM_RSRC1_VS:
-               case R_00B228_SPI_SHADER_PGM_RSRC1_GS:
-               case R_00B428_SPI_SHADER_PGM_RSRC1_HS:
-               case R_00B848_COMPUTE_PGM_RSRC1:
-                       conf->num_sgprs = MAX2(conf->num_sgprs, (G_00B028_SGPRS(value) + 1) * 8);
-                       conf->num_vgprs = MAX2(conf->num_vgprs, (G_00B028_VGPRS(value) + 1) * 4);
-                       conf->float_mode =  G_00B028_FLOAT_MODE(value);
-                       conf->rsrc1 = value;
-                       break;
-               case R_00B02C_SPI_SHADER_PGM_RSRC2_PS:
-                       conf->lds_size = MAX2(conf->lds_size, G_00B02C_EXTRA_LDS_SIZE(value));
-                       break;
-               case R_00B84C_COMPUTE_PGM_RSRC2:
-                       conf->lds_size = MAX2(conf->lds_size, G_00B84C_LDS_SIZE(value));
-                       conf->rsrc2 = value;
-                       break;
-               case R_0286CC_SPI_PS_INPUT_ENA:
-                       conf->spi_ps_input_ena = value;
-                       break;
-               case R_0286D0_SPI_PS_INPUT_ADDR:
-                       conf->spi_ps_input_addr = value;
-                       break;
-               case R_0286E8_SPI_TMPRING_SIZE:
-               case R_00B860_COMPUTE_TMPRING_SIZE:
-                       /* WAVESIZE is in units of 256 dwords. */
-                       if (really_needs_scratch)
-                               conf->scratch_bytes_per_wave =
-                                       G_00B860_WAVESIZE(value) * 256 * 4;
-                       break;
-               case 0x4: /* SPILLED_SGPRS */
-                       conf->spilled_sgprs = value;
-                       break;
-               case 0x8: /* SPILLED_VGPRS */
-                       conf->spilled_vgprs = value;
-                       break;
-               default:
-                       {
-                               static bool printed;
+#undef add_part
 
-                               if (!printed) {
-                                       fprintf(stderr, "Warning: LLVM emitted unknown "
-                                               "config register: 0x%x\n", reg);
-                                       printed = true;
-                               }
-                       }
-                       break;
-               }
+       bool ok = ac_rtld_open(rtld, (struct ac_rtld_open_info){
+                       .info = &screen->info,
+                       .num_parts = num_parts,
+                       .elf_ptrs = part_elfs,
+                       .elf_sizes = part_sizes });
+
+       if (rtld->lds_size > 0) {
+               unsigned alloc_granularity = screen->info.chip_class >= GFX7 ? 512 : 256;
+               shader->config.lds_size =
+                       align(rtld->lds_size, alloc_granularity) / alloc_granularity;
        }
 
-       if (!conf->spi_ps_input_addr)
-               conf->spi_ps_input_addr = conf->spi_ps_input_ena;
+       return ok;
 }
 
-void si_shader_apply_scratch_relocs(struct si_shader *shader,
-                                   uint64_t scratch_va)
+static unsigned si_get_shader_binary_size(struct si_screen *screen, struct si_shader *shader)
 {
-       unsigned i;
-       uint32_t scratch_rsrc_dword0 = scratch_va;
-       uint32_t scratch_rsrc_dword1 =
-               S_008F04_BASE_ADDRESS_HI(scratch_va >> 32);
-
-       /* Enable scratch coalescing. */
-       scratch_rsrc_dword1 |= S_008F04_SWIZZLE_ENABLE(1);
-
-       for (i = 0 ; i < shader->binary.reloc_count; i++) {
-               const struct ac_shader_reloc *reloc =
-                                       &shader->binary.relocs[i];
-               if (!strcmp(scratch_rsrc_dword0_symbol, reloc->name)) {
-                       util_memcpy_cpu_to_le32(shader->binary.code + reloc->offset,
-                       &scratch_rsrc_dword0, 4);
-               } else if (!strcmp(scratch_rsrc_dword1_symbol, reloc->name)) {
-                       util_memcpy_cpu_to_le32(shader->binary.code + reloc->offset,
-                       &scratch_rsrc_dword1, 4);
+       struct ac_rtld_binary rtld;
+       si_shader_binary_open(screen, shader, &rtld);
+       return rtld.rx_size;
+}
+
+
+static bool si_get_external_symbol(void *data, const char *name, uint64_t *value)
+{
+       uint64_t *scratch_va = data;
+
+       if (!strcmp(scratch_rsrc_dword0_symbol, name)) {
+               *value = (uint32_t)*scratch_va;
+               return true;
+       }
+       if (!strcmp(scratch_rsrc_dword1_symbol, name)) {
+               /* Enable scratch coalescing. */
+               *value = S_008F04_BASE_ADDRESS_HI(*scratch_va >> 32) |
+                        S_008F04_SWIZZLE_ENABLE(1);
+               if (HAVE_LLVM < 0x0800) {
+                       /* Old LLVM created an R_ABS32_HI relocation for
+                        * this symbol. */
+                       *value <<= 32;
                }
+               return true;
        }
-}
 
-/* For the UMR disassembler. */
-#define DEBUGGER_END_OF_CODE_MARKER    0xbf9f0000 /* invalid instruction */
-#define DEBUGGER_NUM_MARKERS           5
+       return false;
+}
 
-static unsigned si_get_shader_binary_size(const struct si_shader *shader)
-{
-       unsigned size = shader->binary.code_size;
-
-       if (shader->prolog)
-               size += shader->prolog->binary.code_size;
-       if (shader->previous_stage)
-               size += shader->previous_stage->binary.code_size;
-       if (shader->prolog2)
-               size += shader->prolog2->binary.code_size;
-       if (shader->epilog)
-               size += shader->epilog->binary.code_size;
-       return size + DEBUGGER_NUM_MARKERS * 4;
-}
-
-int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader)
-{
-       const struct ac_shader_binary *prolog =
-               shader->prolog ? &shader->prolog->binary : NULL;
-       const struct ac_shader_binary *previous_stage =
-               shader->previous_stage ? &shader->previous_stage->binary : NULL;
-       const struct ac_shader_binary *prolog2 =
-               shader->prolog2 ? &shader->prolog2->binary : NULL;
-       const struct ac_shader_binary *epilog =
-               shader->epilog ? &shader->epilog->binary : NULL;
-       const struct ac_shader_binary *mainb = &shader->binary;
-       unsigned bo_size = si_get_shader_binary_size(shader) +
-                          (!epilog ? mainb->rodata_size : 0);
-       unsigned char *ptr;
-
-       assert(!prolog || !prolog->rodata_size);
-       assert(!previous_stage || !previous_stage->rodata_size);
-       assert(!prolog2 || !prolog2->rodata_size);
-       assert((!prolog && !previous_stage && !prolog2 && !epilog) ||
-              !mainb->rodata_size);
-       assert(!epilog || !epilog->rodata_size);
+bool si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader,
+                            uint64_t scratch_va)
+{
+       struct ac_rtld_binary binary;
+       if (!si_shader_binary_open(sscreen, shader, &binary))
+               return false;
 
        si_resource_reference(&shader->bo, NULL);
        shader->bo = si_aligned_buffer_create(&sscreen->b,
                                              sscreen->cpdma_prefetch_writes_memory ?
                                                0 : SI_RESOURCE_FLAG_READ_ONLY,
                                               PIPE_USAGE_IMMUTABLE,
-                                              align(bo_size, SI_CPDMA_ALIGNMENT),
+                                              align(binary.rx_size, SI_CPDMA_ALIGNMENT),
                                               256);
        if (!shader->bo)
-               return -ENOMEM;
+               return false;
 
        /* Upload. */
-       ptr = sscreen->ws->buffer_map(shader->bo->buf, NULL,
+       struct ac_rtld_upload_info u = {};
+       u.binary = &binary;
+       u.get_external_symbol = si_get_external_symbol;
+       u.cb_data = &scratch_va;
+       u.rx_va = shader->bo->gpu_address;
+       u.rx_ptr = sscreen->ws->buffer_map(shader->bo->buf, NULL,
                                        PIPE_TRANSFER_READ_WRITE |
                                        PIPE_TRANSFER_UNSYNCHRONIZED |
                                        RADEON_TRANSFER_TEMPORARY);
+       if (!u.rx_ptr)
+               return false;
 
-       /* Don't use util_memcpy_cpu_to_le32. LLVM binaries are
-        * endian-independent. */
-       if (prolog) {
-               memcpy(ptr, prolog->code, prolog->code_size);
-               ptr += prolog->code_size;
-       }
-       if (previous_stage) {
-               memcpy(ptr, previous_stage->code, previous_stage->code_size);
-               ptr += previous_stage->code_size;
-       }
-       if (prolog2) {
-               memcpy(ptr, prolog2->code, prolog2->code_size);
-               ptr += prolog2->code_size;
-       }
-
-       memcpy(ptr, mainb->code, mainb->code_size);
-       ptr += mainb->code_size;
-
-       if (epilog) {
-               memcpy(ptr, epilog->code, epilog->code_size);
-               ptr += epilog->code_size;
-       } else if (mainb->rodata_size > 0) {
-               memcpy(ptr, mainb->rodata, mainb->rodata_size);
-               ptr += mainb->rodata_size;
-       }
-
-       /* Add end-of-code markers for the UMR disassembler. */
-       uint32_t *ptr32 = (uint32_t*)ptr;
-       for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
-               ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
+       bool ok = ac_rtld_upload(&u);
 
        sscreen->ws->buffer_unmap(shader->bo->buf);
-       return 0;
+       ac_rtld_close(&binary);
+
+       return ok;
 }
 
-static void si_shader_dump_disassembly(const struct ac_shader_binary *binary,
+static void si_shader_dump_disassembly(struct si_screen *screen,
+                                      const struct si_shader_binary *binary,
                                       struct pipe_debug_callback *debug,
                                       const char *name, FILE *file)
 {
-       char *line, *p;
-       unsigned i, count;
+       struct ac_rtld_binary rtld_binary;
 
-       if (binary->disasm_string) {
-               fprintf(file, "Shader %s disassembly:\n", name);
-               fprintf(file, "%s", binary->disasm_string);
+       if (!ac_rtld_open(&rtld_binary, (struct ac_rtld_open_info){
+                       .info = &screen->info,
+                       .num_parts = 1,
+                       .elf_ptrs = &binary->elf_buffer,
+                       .elf_sizes = &binary->elf_size }))
+               return;
 
-               if (debug && debug->debug_message) {
-                       /* Very long debug messages are cut off, so send the
-                        * disassembly one line at a time. This causes more
-                        * overhead, but on the plus side it simplifies
-                        * parsing of resulting logs.
-                        */
-                       pipe_debug_message(debug, SHADER_INFO,
-                                          "Shader Disassembly Begin");
+       const char *disasm;
+       size_t nbytes;
 
-                       line = binary->disasm_string;
-                       while (*line) {
-                               p = util_strchrnul(line, '\n');
-                               count = p - line;
+       if (!ac_rtld_get_section_by_name(&rtld_binary, ".AMDGPU.disasm", &disasm, &nbytes))
+               goto out;
 
-                               if (count) {
-                                       pipe_debug_message(debug, SHADER_INFO,
-                                                          "%.*s", count, line);
-                               }
+       fprintf(file, "Shader %s disassembly:\n", name);
+       if (nbytes > INT_MAX) {
+               fprintf(file, "too long\n");
+               goto out;
+       }
 
-                               if (!*p)
-                                       break;
-                               line = p + 1;
+       fprintf(file, "%*s", (int)nbytes, disasm);
+
+       if (debug && debug->debug_message) {
+               /* Very long debug messages are cut off, so send the
+                * disassembly one line at a time. This causes more
+                * overhead, but on the plus side it simplifies
+                * parsing of resulting logs.
+                */
+               pipe_debug_message(debug, SHADER_INFO,
+                                  "Shader Disassembly Begin");
+
+               uint64_t line = 0;
+               while (line < nbytes) {
+                       int count = nbytes - line;
+                       const char *nl = memchr(disasm + line, '\n', nbytes - line);
+                       if (nl)
+                               count = nl - disasm;
+
+                       if (count) {
+                               pipe_debug_message(debug, SHADER_INFO,
+                                                  "%.*s", count, disasm + line);
                        }
 
-                       pipe_debug_message(debug, SHADER_INFO,
-                                          "Shader Disassembly End");
-               }
-       } else {
-               fprintf(file, "Shader %s binary:\n", name);
-               for (i = 0; i < binary->code_size; i += 4) {
-                       fprintf(file, "@0x%x: %02x%02x%02x%02x\n", i,
-                               binary->code[i + 3], binary->code[i + 2],
-                               binary->code[i + 1], binary->code[i]);
+                       line += count + 1;
                }
+
+               pipe_debug_message(debug, SHADER_INFO,
+                                  "Shader Disassembly End");
        }
+
+out:
+       ac_rtld_close(&rtld_binary);
 }
 
 static void si_calculate_max_simd_waves(struct si_shader *shader)
 {
        struct si_screen *sscreen = shader->selector->screen;
-       struct si_shader_config *conf = &shader->config;
+       struct ac_shader_config *conf = &shader->config;
        unsigned num_inputs = shader->selector->info.num_inputs;
        unsigned lds_increment = sscreen->info.chip_class >= GFX7 ? 512 : 256;
        unsigned lds_per_wave = 0;
@@ -5345,32 +5270,33 @@ static void si_calculate_max_simd_waves(struct si_shader *shader)
        if (lds_per_wave)
                max_simd_waves = MIN2(max_simd_waves, 16384 / lds_per_wave);
 
-       conf->max_simd_waves = max_simd_waves;
+       shader->info.max_simd_waves = max_simd_waves;
 }
 
-void si_shader_dump_stats_for_shader_db(const struct si_shader *shader,
+void si_shader_dump_stats_for_shader_db(struct si_screen *screen,
+                                       struct si_shader *shader,
                                        struct pipe_debug_callback *debug)
 {
-       const struct si_shader_config *conf = &shader->config;
+       const struct ac_shader_config *conf = &shader->config;
 
        pipe_debug_message(debug, SHADER_INFO,
                           "Shader Stats: SGPRS: %d VGPRS: %d Code Size: %d "
                           "LDS: %d Scratch: %d Max Waves: %d Spilled SGPRs: %d "
                           "Spilled VGPRs: %d PrivMem VGPRs: %d",
                           conf->num_sgprs, conf->num_vgprs,
-                          si_get_shader_binary_size(shader),
+                          si_get_shader_binary_size(screen, shader),
                           conf->lds_size, conf->scratch_bytes_per_wave,
-                          conf->max_simd_waves, conf->spilled_sgprs,
-                          conf->spilled_vgprs, conf->private_mem_vgprs);
+                          shader->info.max_simd_waves, conf->spilled_sgprs,
+                          conf->spilled_vgprs, shader->info.private_mem_vgprs);
 }
 
 static void si_shader_dump_stats(struct si_screen *sscreen,
-                                const struct si_shader *shader,
+                                struct si_shader *shader,
                                 unsigned processor,
                                 FILE *file,
                                 bool check_debug_option)
 {
-       const struct si_shader_config *conf = &shader->config;
+       const struct ac_shader_config *conf = &shader->config;
 
        if (!check_debug_option ||
            si_can_dump_shader(sscreen, processor)) {
@@ -5394,10 +5320,10 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
                        "********************\n\n\n",
                        conf->num_sgprs, conf->num_vgprs,
                        conf->spilled_sgprs, conf->spilled_vgprs,
-                       conf->private_mem_vgprs,
-                       si_get_shader_binary_size(shader),
+                       shader->info.private_mem_vgprs,
+                       si_get_shader_binary_size(sscreen, shader),
                        conf->lds_size, conf->scratch_bytes_per_wave,
-                       conf->max_simd_waves);
+                       shader->info.max_simd_waves);
        }
 }
 
@@ -5434,7 +5360,7 @@ const char *si_get_shader_name(const struct si_shader *shader, unsigned processo
        }
 }
 
-void si_shader_dump(struct si_screen *sscreen, const struct si_shader *shader,
+void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
                    struct pipe_debug_callback *debug, unsigned processor,
                    FILE *file, bool check_debug_option)
 {
@@ -5461,19 +5387,19 @@ void si_shader_dump(struct si_screen *sscreen, const struct si_shader *shader,
                fprintf(file, "\n%s:\n", si_get_shader_name(shader, processor));
 
                if (shader->prolog)
-                       si_shader_dump_disassembly(&shader->prolog->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->prolog->binary,
                                                   debug, "prolog", file);
                if (shader->previous_stage)
-                       si_shader_dump_disassembly(&shader->previous_stage->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->previous_stage->binary,
                                                   debug, "previous stage", file);
                if (shader->prolog2)
-                       si_shader_dump_disassembly(&shader->prolog2->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->prolog2->binary,
                                                   debug, "prolog2", file);
 
-               si_shader_dump_disassembly(&shader->binary, debug, "main", file);
+               si_shader_dump_disassembly(sscreen, &shader->binary, debug, "main", file);
 
                if (shader->epilog)
-                       si_shader_dump_disassembly(&shader->epilog->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->epilog->binary,
                                                   debug, "epilog", file);
                fprintf(file, "\n");
        }
@@ -5483,8 +5409,8 @@ void si_shader_dump(struct si_screen *sscreen, const struct si_shader *shader,
 }
 
 static int si_compile_llvm(struct si_screen *sscreen,
-                          struct ac_shader_binary *binary,
-                          struct si_shader_config *conf,
+                          struct si_shader_binary *binary,
+                          struct ac_shader_config *conf,
                           struct ac_llvm_compiler *compiler,
                           LLVMModuleRef mod,
                           struct pipe_debug_callback *debug,
@@ -5492,7 +5418,6 @@ static int si_compile_llvm(struct si_screen *sscreen,
                           const char *name,
                           bool less_optimized)
 {
-       int r = 0;
        unsigned count = p_atomic_inc_return(&sscreen->num_compilations);
 
        if (si_can_dump_shader(sscreen, processor)) {
@@ -5512,13 +5437,24 @@ static int si_compile_llvm(struct si_screen *sscreen,
        }
 
        if (!si_replace_shader(count, binary)) {
-               r = si_llvm_compile(mod, binary, compiler, debug,
-                                   less_optimized);
+               unsigned r = si_llvm_compile(mod, binary, compiler, debug,
+                                            less_optimized);
                if (r)
                        return r;
        }
 
-       si_shader_binary_read_config(binary, conf, 0);
+       struct ac_rtld_binary rtld;
+       if (!ac_rtld_open(&rtld, (struct ac_rtld_open_info){
+                       .info = &sscreen->info,
+                       .num_parts = 1,
+                       .elf_ptrs = &binary->elf_buffer,
+                       .elf_sizes = &binary->elf_size }))
+               return -1;
+
+       bool ok = ac_rtld_read_config(&rtld, conf);
+       ac_rtld_close(&rtld);
+       if (!ok)
+               return -1;
 
        /* Enable 64-bit and 16-bit denormals, because there is no performance
         * cost.
@@ -5534,24 +5470,7 @@ static int si_compile_llvm(struct si_screen *sscreen,
         */
        conf->float_mode |= V_00B028_FP_64_DENORMS;
 
-       FREE(binary->config);
-       FREE(binary->global_symbol_offsets);
-       binary->config = NULL;
-       binary->global_symbol_offsets = NULL;
-
-       /* Some shaders can't have rodata because their binaries can be
-        * concatenated.
-        */
-       if (binary->rodata_size &&
-           (processor == PIPE_SHADER_VERTEX ||
-            processor == PIPE_SHADER_TESS_CTRL ||
-            processor == PIPE_SHADER_TESS_EVAL ||
-            processor == PIPE_SHADER_FRAGMENT)) {
-               fprintf(stderr, "radeonsi: The shader can't have rodata.");
-               return -EINVAL;
-       }
-
-       return r;
+       return 0;
 }
 
 static void si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret)
@@ -5574,7 +5493,7 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
        LLVMBuilderRef builder;
        struct si_shader_output_values outputs[SI_MAX_VS_OUTPUTS];
        struct tgsi_shader_info *gsinfo = &gs_selector->info;
-       int i, r;
+       int i;
 
 
        shader = CALLOC_STRUCT(si_shader);
@@ -5683,22 +5602,26 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
        ctx.type = PIPE_SHADER_GEOMETRY; /* override for shader dumping */
        si_llvm_optimize_module(&ctx);
 
-       r = si_compile_llvm(sscreen, &ctx.shader->binary,
+       bool ok = false;
+       if (si_compile_llvm(sscreen, &ctx.shader->binary,
                            &ctx.shader->config, ctx.compiler,
                            ctx.ac.module,
                            debug, PIPE_SHADER_GEOMETRY,
-                           "GS Copy Shader", false);
-       if (!r) {
+                           "GS Copy Shader", false) == 0) {
                if (si_can_dump_shader(sscreen, PIPE_SHADER_GEOMETRY))
                        fprintf(stderr, "GS Copy Shader:\n");
                si_shader_dump(sscreen, ctx.shader, debug,
                               PIPE_SHADER_GEOMETRY, stderr, true);
-               r = si_shader_binary_upload(sscreen, ctx.shader);
+
+               if (!ctx.shader->config.scratch_bytes_per_wave)
+                       ok = si_shader_binary_upload(sscreen, ctx.shader, 0);
+               else
+                       ok = true;
        }
 
        si_llvm_dispose(&ctx);
 
-       if (r != 0) {
+       if (!ok) {
                FREE(shader);
                shader = NULL;
        } else {
@@ -6893,7 +6816,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 
        if ((debug && debug->debug_message) ||
            si_can_dump_shader(sscreen, ctx.type)) {
-               ctx.shader->config.private_mem_vgprs =
+               ctx.shader->info.private_mem_vgprs =
                        ac_count_scratch_private_memory(ctx.main_fn);
        }
 
@@ -6992,7 +6915,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
        }
 
        si_calculate_max_simd_waves(shader);
-       si_shader_dump_stats_for_shader_db(shader, debug);
+       si_shader_dump_stats_for_shader_db(sscreen, shader, debug);
        return 0;
 }
 
@@ -7965,7 +7888,7 @@ static void si_fix_resource_usage(struct si_screen *sscreen,
        }
 }
 
-int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compiler,
+bool si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compiler,
                     struct si_shader *shader,
                     struct pipe_debug_callback *debug)
 {
@@ -7985,7 +7908,7 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                 */
                r = si_compile_tgsi_shader(sscreen, compiler, shader, debug);
                if (r)
-                       return r;
+                       return false;
        } else {
                /* The shader consists of several parts:
                 *
@@ -8003,7 +7926,7 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                 */
 
                if (!mainp)
-                       return -1;
+                       return false;
 
                /* Copy the compiled TGSI shader data over. */
                shader->is_binary_shared = true;
@@ -8024,21 +7947,21 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                switch (sel->type) {
                case PIPE_SHADER_VERTEX:
                        if (!si_shader_select_vs_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
                        break;
                case PIPE_SHADER_TESS_CTRL:
                        if (!si_shader_select_tcs_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
                        break;
                case PIPE_SHADER_TESS_EVAL:
                        break;
                case PIPE_SHADER_GEOMETRY:
                        if (!si_shader_select_gs_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
                        break;
                case PIPE_SHADER_FRAGMENT:
                        if (!si_shader_select_ps_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
 
                        /* Make sure we have at least as many VGPRs as there
                         * are allocated inputs.
@@ -8066,9 +7989,9 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                        shader->config.spilled_vgprs =
                                MAX2(shader->config.spilled_vgprs,
                                     shader->previous_stage->config.spilled_vgprs);
-                       shader->config.private_mem_vgprs =
-                               MAX2(shader->config.private_mem_vgprs,
-                                    shader->previous_stage->config.private_mem_vgprs);
+                       shader->info.private_mem_vgprs =
+                               MAX2(shader->info.private_mem_vgprs,
+                                    shader->previous_stage->info.private_mem_vgprs);
                        shader->config.scratch_bytes_per_wave =
                                MAX2(shader->config.scratch_bytes_per_wave,
                                     shader->previous_stage->config.scratch_bytes_per_wave);
@@ -8095,13 +8018,12 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                       stderr, true);
 
        /* Upload. */
-       r = si_shader_binary_upload(sscreen, shader);
-       if (r) {
+       if (!si_shader_binary_upload(sscreen, shader, 0)) {
                fprintf(stderr, "LLVM failed to upload shader\n");
-               return r;
+               return false;
        }
 
-       return 0;
+       return true;
 }
 
 void si_shader_destroy(struct si_shader *shader)
@@ -8112,7 +8034,7 @@ void si_shader_destroy(struct si_shader *shader)
        si_resource_reference(&shader->bo, NULL);
 
        if (!shader->is_binary_shared)
-               ac_shader_binary_clean(&shader->binary);
+               si_shader_binary_clean(&shader->binary);
 
        free(shader->shader_log);
 }