radeonsi: set threadgroup size to 0 for threadgroups with only 1 wave
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index 9abecdf1003e1bed06b73fd7fb01d96fd3d1da74..8d06859f1f2d262103ec7966e0fb6a51f4ad6f8d 100644 (file)
@@ -55,8 +55,7 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
                                 struct lp_build_tgsi_context *bld_base,
                                 struct lp_build_emit_data *emit_data);
 
-static void si_dump_shader_key(unsigned processor, const struct si_shader *shader,
-                              FILE *f);
+static void si_dump_shader_key(const struct si_shader *shader, FILE *f);
 
 static void si_build_vs_prolog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
@@ -189,35 +188,39 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index,
 
                assert(!"invalid generic index");
                return 0;
-       case TGSI_SEMANTIC_PSIZE:
-               return SI_MAX_IO_GENERIC + 1;
-       case TGSI_SEMANTIC_CLIPDIST:
-               assert(index <= 1);
-               return SI_MAX_IO_GENERIC + 2 + index;
        case TGSI_SEMANTIC_FOG:
-               return SI_MAX_IO_GENERIC + 4;
-       case TGSI_SEMANTIC_LAYER:
-               return SI_MAX_IO_GENERIC + 5;
-       case TGSI_SEMANTIC_VIEWPORT_INDEX:
-               return SI_MAX_IO_GENERIC + 6;
-       case TGSI_SEMANTIC_PRIMID:
-               return SI_MAX_IO_GENERIC + 7;
+               return SI_MAX_IO_GENERIC + 1;
        case TGSI_SEMANTIC_COLOR:
                assert(index < 2);
-               return SI_MAX_IO_GENERIC + 8 + index;
+               return SI_MAX_IO_GENERIC + 2 + index;
        case TGSI_SEMANTIC_BCOLOR:
                assert(index < 2);
                /* If it's a varying, COLOR and BCOLOR alias. */
                if (is_varying)
-                       return SI_MAX_IO_GENERIC + 8 + index;
+                       return SI_MAX_IO_GENERIC + 2 + index;
                else
-                       return SI_MAX_IO_GENERIC + 10 + index;
+                       return SI_MAX_IO_GENERIC + 4 + index;
        case TGSI_SEMANTIC_TEXCOORD:
                assert(index < 8);
-               STATIC_ASSERT(SI_MAX_IO_GENERIC + 12 + 8 <= 63);
-               return SI_MAX_IO_GENERIC + 12 + index;
+               return SI_MAX_IO_GENERIC + 6 + index;
+
+       /* These are rarely used between LS and HS or ES and GS. */
+       case TGSI_SEMANTIC_CLIPDIST:
+               assert(index < 2);
+               return SI_MAX_IO_GENERIC + 6 + 8 + index;
        case TGSI_SEMANTIC_CLIPVERTEX:
-               return 63;
+               return SI_MAX_IO_GENERIC + 6 + 8 + 2;
+       case TGSI_SEMANTIC_PSIZE:
+               return SI_MAX_IO_GENERIC + 6 + 8 + 3;
+
+       /* These can't be written by LS, HS, and ES. */
+       case TGSI_SEMANTIC_LAYER:
+               return SI_MAX_IO_GENERIC + 6 + 8 + 4;
+       case TGSI_SEMANTIC_VIEWPORT_INDEX:
+               return SI_MAX_IO_GENERIC + 6 + 8 + 5;
+       case TGSI_SEMANTIC_PRIMID:
+               STATIC_ASSERT(SI_MAX_IO_GENERIC + 6 + 8 + 6 <= 63);
+               return SI_MAX_IO_GENERIC + 6 + 8 + 6;
        default:
                fprintf(stderr, "invalid semantic name = %u\n", semantic_name);
                assert(!"invalid semantic name");
@@ -541,8 +544,7 @@ void si_llvm_load_input_vs(
                tmp = ac_build_opencoded_load_format(
                                &ctx->ac, fix_fetch.u.log_size, fix_fetch.u.num_channels_m1 + 1,
                                fix_fetch.u.format, fix_fetch.u.reverse, !opencode,
-                               t_list, vertex_index, ctx->ac.i32_0, ctx->ac.i32_0,
-                               false, false, true);
+                               t_list, vertex_index, ctx->ac.i32_0, ctx->ac.i32_0, 0, true);
                for (unsigned i = 0; i < 4; ++i)
                        out[i] = LLVMBuildExtractElement(ctx->ac.builder, tmp, LLVMConstInt(ctx->i32, i, false), "");
                return;
@@ -568,7 +570,7 @@ void si_llvm_load_input_vs(
        for (unsigned i = 0; i < num_fetches; ++i) {
                LLVMValueRef voffset = LLVMConstInt(ctx->i32, fetch_stride * i, 0);
                fetches[i] = ac_build_buffer_load_format(&ctx->ac, t_list, vertex_index, voffset,
-                                                        channels_per_fetch, false, true);
+                                                        channels_per_fetch, 0, true);
        }
 
        if (num_fetches == 1 && channels_per_fetch > 1) {
@@ -967,14 +969,14 @@ static LLVMValueRef buffer_load(struct lp_build_tgsi_context *bld_base,
 
        if (swizzle == ~0) {
                value = ac_build_buffer_load(&ctx->ac, buffer, 4, NULL, base, offset,
-                                            0, 1, 0, can_speculate, false);
+                                            0, ac_glc, can_speculate, false);
 
                return LLVMBuildBitCast(ctx->ac.builder, value, vec_type, "");
        }
 
        if (!llvm_type_is_64bit(ctx, type)) {
                value = ac_build_buffer_load(&ctx->ac, buffer, 4, NULL, base, offset,
-                                            0, 1, 0, can_speculate, false);
+                                            0, ac_glc, can_speculate, false);
 
                value = LLVMBuildBitCast(ctx->ac.builder, value, vec_type, "");
                return LLVMBuildExtractElement(ctx->ac.builder, value,
@@ -982,10 +984,10 @@ static LLVMValueRef buffer_load(struct lp_build_tgsi_context *bld_base,
        }
 
        value = ac_build_buffer_load(&ctx->ac, buffer, 1, NULL, base, offset,
-                                 swizzle * 4, 1, 0, can_speculate, false);
+                                 swizzle * 4, ac_glc, can_speculate, false);
 
        value2 = ac_build_buffer_load(&ctx->ac, buffer, 1, NULL, base, offset,
-                                  swizzle * 4 + 4, 1, 0, can_speculate, false);
+                                  swizzle * 4 + 4, ac_glc, can_speculate, false);
 
        return si_llvm_emit_fetch_64bit(bld_base, type, value, value2);
 }
@@ -1358,7 +1360,7 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
                if (reg->Register.WriteMask != 0xF && !is_tess_factor) {
                        ac_build_buffer_store_dword(&ctx->ac, buffer, value, 1,
                                                    buf_addr, base,
-                                                   4 * chan_index, 1, 0, false);
+                                                   4 * chan_index, ac_glc, false);
                }
 
                /* Write tess factors into VGPRs for the epilog. */
@@ -1378,7 +1380,7 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
                LLVMValueRef value = ac_build_gather_values(&ctx->ac,
                                                            values, 4);
                ac_build_buffer_store_dword(&ctx->ac, buffer, value, 4, buf_addr,
-                                           base, 0, 1, 0, false);
+                                           base, 0, ac_glc, false);
        }
 }
 
@@ -1486,7 +1488,7 @@ static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
                        ac_build_buffer_store_dword(&ctx->ac, buffer, value, 1,
                                                    addr, base,
                                                    4 * buffer_store_offset,
-                                                    1, 0, false);
+                                                    ac_glc, false);
                }
 
                /* Write tess factors into VGPRs for the epilog. */
@@ -1506,7 +1508,7 @@ static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
                LLVMValueRef value = ac_build_gather_values(&ctx->ac,
                                                            values, 4);
                ac_build_buffer_store_dword(&ctx->ac, buffer, value, 4, addr,
-                                           base, 0, 1, 0, false);
+                                           base, 0, ac_glc, false);
        }
 }
 
@@ -1589,14 +1591,14 @@ LLVMValueRef si_llvm_load_input_gs(struct ac_shader_abi *abi,
        soffset = LLVMConstInt(ctx->i32, (param * 4 + swizzle) * 256, 0);
 
        value = ac_build_buffer_load(&ctx->ac, ctx->esgs_ring, 1, ctx->i32_0,
-                                    vtx_offset, soffset, 0, 1, 0, true, false);
+                                    vtx_offset, soffset, 0, ac_glc, true, false);
        if (llvm_type_is_64bit(ctx, type)) {
                LLVMValueRef value2;
                soffset = LLVMConstInt(ctx->i32, (param * 4 + swizzle + 1) * 256, 0);
 
                value2 = ac_build_buffer_load(&ctx->ac, ctx->esgs_ring, 1,
                                              ctx->i32_0, vtx_offset, soffset,
-                                             0, 1, 0, true, false);
+                                             0, ac_glc, true, false);
                return si_llvm_emit_fetch_64bit(bld_base, type, value, value2);
        }
        return LLVMBuildBitCast(ctx->ac.builder, value, type, "");
@@ -1908,7 +1910,7 @@ static LLVMValueRef buffer_load_const(struct si_shader_context *ctx,
                                      LLVMValueRef offset)
 {
        return ac_build_buffer_load(&ctx->ac, resource, 1, NULL, offset, NULL,
-                                   0, 0, 0, true, true);
+                                   0, 0, true, true);
 }
 
 static LLVMValueRef load_sample_position(struct ac_shader_abi *abi, LLVMValueRef sample_id)
@@ -2044,12 +2046,19 @@ void si_load_system_value(struct si_shader_context *ctx,
                break;
 
        case TGSI_SEMANTIC_INVOCATIONID:
-               if (ctx->type == PIPE_SHADER_TESS_CTRL)
+               if (ctx->type == PIPE_SHADER_TESS_CTRL) {
                        value = unpack_llvm_param(ctx, ctx->abi.tcs_rel_ids, 8, 5);
-               else if (ctx->type == PIPE_SHADER_GEOMETRY)
-                       value = ctx->abi.gs_invocation_id;
-               else
+               } else if (ctx->type == PIPE_SHADER_GEOMETRY) {
+                       if (ctx->screen->info.chip_class >= GFX10) {
+                               value = LLVMBuildAnd(ctx->ac.builder,
+                                                    ctx->abi.gs_invocation_id,
+                                                    LLVMConstInt(ctx->i32, 127, 0), "");
+                       } else {
+                               value = ctx->abi.gs_invocation_id;
+                       }
+               } else {
                        assert(!"INVOCATIONID not implemented");
+               }
                break;
 
        case TGSI_SEMANTIC_POSITION:
@@ -2450,9 +2459,15 @@ static void si_llvm_init_export_args(struct si_shader_context *ctx,
                break;
 
        case V_028714_SPI_SHADER_32_AR:
-               args->enabled_channels = 0x9; /* writemask */
-               args->out[0] = values[0];
-               args->out[3] = values[3];
+               if (ctx->screen->info.chip_class >= GFX10) {
+                       args->enabled_channels = 0x3; /* writemask */
+                       args->out[0] = values[0];
+                       args->out[1] = values[3];
+               } else {
+                       args->enabled_channels = 0x9; /* writemask */
+                       args->out[0] = values[0];
+                       args->out[3] = values[3];
+               }
                break;
 
        case V_028714_SPI_SHADER_FP16_ABGR:
@@ -2674,7 +2689,7 @@ void si_emit_streamout_output(struct si_shader_context *ctx,
                                    vdata, num_comps,
                                    so_write_offsets[buf_idx],
                                    ctx->i32_0,
-                                   stream_out->dst_offset * 4, 1, 1, false);
+                                   stream_out->dst_offset * 4, ac_glc | ac_slc, false);
 }
 
 /**
@@ -2949,11 +2964,11 @@ void si_llvm_export_vs(struct si_shader_context *ctx,
 
        /* Write the misc vector (point size, edgeflag, layer, viewport). */
        if (shader->selector->info.writes_psize ||
-           shader->selector->info.writes_edgeflag ||
+           shader->selector->pos_writes_edgeflag ||
            shader->selector->info.writes_viewport_index ||
            shader->selector->info.writes_layer) {
                pos_args[1].enabled_channels = shader->selector->info.writes_psize |
-                                              (shader->selector->info.writes_edgeflag << 1) |
+                                              (shader->selector->pos_writes_edgeflag << 1) |
                                               (shader->selector->info.writes_layer << 2);
 
                pos_args[1].valid_mask = 0; /* EXEC mask */
@@ -2968,7 +2983,7 @@ void si_llvm_export_vs(struct si_shader_context *ctx,
                if (shader->selector->info.writes_psize)
                        pos_args[1].out[0] = psize_value;
 
-               if (shader->selector->info.writes_edgeflag) {
+               if (shader->selector->pos_writes_edgeflag) {
                        /* The output is a float, but the hw expects an integer
                         * with the first bit containing the edge flag. */
                        edgeflag_value = LLVMBuildFPToUI(ctx->ac.builder,
@@ -3015,6 +3030,14 @@ void si_llvm_export_vs(struct si_shader_context *ctx,
                if (pos_args[i].out[0])
                        shader->info.nr_pos_exports++;
 
+       /* Navi10-14 skip POS0 exports if EXEC=0 and DONE=0, causing a hang.
+        * Setting valid_mask=1 prevents it and has no other effect.
+        */
+       if (ctx->screen->info.family == CHIP_NAVI10 ||
+           ctx->screen->info.family == CHIP_NAVI12 ||
+           ctx->screen->info.family == CHIP_NAVI14)
+               pos_args[0].valid_mask = 1;
+
        pos_idx = 0;
        for (i = 0; i < 4; i++) {
                if (!pos_args[i].out[0])
@@ -3070,7 +3093,7 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
                LLVMValueRef value = lshs_lds_load(bld_base, ctx->ac.i32, ~0, lds_ptr);
 
                ac_build_buffer_store_dword(&ctx->ac, buffer, value, 4, buffer_addr,
-                                           buffer_offset, 0, 1, 0, false);
+                                           buffer_offset, 0, ac_glc, false);
        }
 }
 
@@ -3196,7 +3219,7 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                ac_build_buffer_store_dword(&ctx->ac, buffer,
                                            LLVMConstInt(ctx->i32, 0x80000000, 0),
                                            1, ctx->i32_0, tf_base,
-                                           offset, 1, 0, false);
+                                           offset, ac_glc, false);
                offset += 4;
        }
 
@@ -3205,12 +3228,12 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
        /* Store the tessellation factors. */
        ac_build_buffer_store_dword(&ctx->ac, buffer, vec0,
                                    MIN2(stride, 4), byteoffset, tf_base,
-                                   offset, 1, 0, false);
+                                   offset, ac_glc, false);
        offset += 16;
        if (vec1)
                ac_build_buffer_store_dword(&ctx->ac, buffer, vec1,
                                            stride - 4, byteoffset, tf_base,
-                                           offset, 1, 0, false);
+                                           offset, ac_glc, false);
 
        /* Store the tess factors into the offchip buffer if TES reads them. */
        if (shader->key.part.tcs.epilog.tes_reads_tess_factors) {
@@ -3233,7 +3256,7 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
 
                ac_build_buffer_store_dword(&ctx->ac, buf, outer_vec,
                                            outer_comps, tf_outer_offset,
-                                           base, 0, 1, 0, false);
+                                           base, 0, ac_glc, false);
                if (inner_comps) {
                        param_inner = si_shader_io_get_unique_index_patch(
                                              TGSI_SEMANTIC_TESSINNER, 0);
@@ -3244,7 +3267,7 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                                    ac_build_gather_values(&ctx->ac, inner, inner_comps);
                        ac_build_buffer_store_dword(&ctx->ac, buf, inner_vec,
                                                    inner_comps, tf_inner_offset,
-                                                   base, 0, 1, 0, false);
+                                                   base, 0, ac_glc, false);
                }
        }
 
@@ -3432,6 +3455,10 @@ static void si_set_es_return_value_for_gs(struct si_shader_context *ctx)
        ret = si_insert_input_ptr(ctx, ret,
                                  ctx->param_bindless_samplers_and_images,
                                  8 + SI_SGPR_BINDLESS_SAMPLERS_AND_IMAGES);
+       if (ctx->screen->info.chip_class >= GFX10) {
+               ret = si_insert_input_ptr(ctx, ret, ctx->param_vs_state_bits,
+                                         8 + SI_SGPR_VS_STATE_BITS);
+       }
 
        unsigned vgpr;
        if (ctx->type == PIPE_SHADER_VERTEX)
@@ -3555,7 +3582,7 @@ static void si_llvm_emit_es_epilogue(struct ac_shader_abi *abi,
                                                    ctx->esgs_ring,
                                                    out_val, 1, NULL, soffset,
                                                    (4 * param + chan) * 4,
-                                                   1, 1, true);
+                                                   ac_glc | ac_slc, true);
                }
        }
 
@@ -3578,6 +3605,9 @@ static void emit_gs_epilogue(struct si_shader_context *ctx)
                return;
        }
 
+       if (ctx->screen->info.chip_class >= GFX10)
+               LLVMBuildFence(ctx->ac.builder, LLVMAtomicOrderingRelease, false, "");
+
        ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_NOP | AC_SENDMSG_GS_DONE,
                         si_get_gs_wave_id(ctx));
 
@@ -3631,7 +3661,8 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
                }
        }
 
-       if (ctx->shader->selector->so.num_outputs)
+       if (ctx->ac.chip_class <= GFX9 &&
+           ctx->shader->selector->so.num_outputs)
                si_llvm_emit_streamout(ctx, outputs, i, 0);
 
        /* Export PrimitiveID. */
@@ -3882,21 +3913,20 @@ static void membar_emit(
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef src0 = lp_build_emit_fetch(bld_base, emit_data->inst, 0, 0);
        unsigned flags = LLVMConstIntGetZExtValue(src0);
-       unsigned waitcnt = NOOP_WAITCNT;
+       unsigned wait_flags = 0;
 
        if (flags & TGSI_MEMBAR_THREAD_GROUP)
-               waitcnt &= VM_CNT & LGKM_CNT;
+               wait_flags |= AC_WAIT_LGKM | AC_WAIT_VLOAD | AC_WAIT_VSTORE;
 
        if (flags & (TGSI_MEMBAR_ATOMIC_BUFFER |
                     TGSI_MEMBAR_SHADER_BUFFER |
                     TGSI_MEMBAR_SHADER_IMAGE))
-               waitcnt &= VM_CNT;
+               wait_flags |= AC_WAIT_VLOAD | AC_WAIT_VSTORE;
 
        if (flags & TGSI_MEMBAR_SHARED)
-               waitcnt &= LGKM_CNT;
+               wait_flags |= AC_WAIT_LGKM;
 
-       if (waitcnt != NOOP_WAITCNT)
-               ac_build_waitcnt(&ctx->ac, waitcnt);
+       ac_build_waitcnt(&ctx->ac, wait_flags);
 }
 
 static void clock_emit(
@@ -4278,7 +4308,7 @@ static void si_llvm_emit_vertex(struct ac_shader_abi *abi,
                                                    ctx->gsvs_ring[stream],
                                                    out_val, 1,
                                                    voffset, soffset, 0,
-                                                   1, 1, true);
+                                                   ac_glc | ac_slc, true);
                }
        }
 
@@ -4346,7 +4376,7 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
         */
        if (ctx->screen->info.chip_class == GFX6 &&
            ctx->type == PIPE_SHADER_TESS_CTRL) {
-               ac_build_waitcnt(&ctx->ac, LGKM_CNT & VM_CNT);
+               ac_build_waitcnt(&ctx->ac, AC_WAIT_LGKM | AC_WAIT_VLOAD | AC_WAIT_VSTORE);
                return;
        }
 
@@ -4423,7 +4453,8 @@ static void declare_streamout_params(struct si_shader_context *ctx,
                                     struct pipe_stream_output_info *so,
                                     struct si_function_info *fninfo)
 {
-       int i;
+       if (ctx->ac.chip_class >= GFX10)
+               return;
 
        /* Streamout SGPRs. */
        if (so->num_outputs) {
@@ -4435,7 +4466,7 @@ static void declare_streamout_params(struct si_shader_context *ctx,
                ctx->param_streamout_write_index = add_arg(fninfo, ARG_SGPR, ctx->ac.i32);
        }
        /* A streamout buffer offset is loaded if the stride is non-zero. */
-       for (i = 0; i < 4; i++) {
+       for (int i = 0; i < 4; i++) {
                if (!so->stride[i])
                        continue;
 
@@ -4453,10 +4484,10 @@ static unsigned si_get_max_workgroup_size(const struct si_shader *shader)
        case PIPE_SHADER_TESS_CTRL:
                /* Return this so that LLVM doesn't remove s_barrier
                 * instructions on chips where we use s_barrier. */
-               return shader->selector->screen->info.chip_class >= GFX7 ? 128 : 64;
+               return shader->selector->screen->info.chip_class >= GFX7 ? 128 : 0;
 
        case PIPE_SHADER_GEOMETRY:
-               return shader->selector->screen->info.chip_class >= GFX9 ? 128 : 64;
+               return shader->selector->screen->info.chip_class >= GFX9 ? 128 : 0;
 
        case PIPE_SHADER_COMPUTE:
                break; /* see below */
@@ -5005,6 +5036,26 @@ static void create_function(struct si_shader_context *ctx)
        }
 }
 
+/* Ensure that the esgs ring is declared.
+ *
+ * We declare it with 64KB alignment as a hint that the
+ * pointer value will always be 0.
+ */
+static void declare_esgs_ring(struct si_shader_context *ctx)
+{
+       if (ctx->esgs_ring)
+               return;
+
+       assert(!LLVMGetNamedGlobal(ctx->ac.module, "esgs_ring"));
+
+       ctx->esgs_ring = LLVMAddGlobalInAddressSpace(
+               ctx->ac.module, LLVMArrayType(ctx->i32, 0),
+               "esgs_ring",
+               AC_ADDR_SPACE_LDS);
+       LLVMSetLinkage(ctx->esgs_ring, LLVMExternalLinkage);
+       LLVMSetAlignment(ctx->esgs_ring, 64 * 1024);
+}
+
 /**
  * Load ESGS and GSVS ring buffer resource descriptors and save the variables
  * for later use.
@@ -5027,17 +5078,8 @@ static void preload_ring_buffers(struct si_shader_context *ctx)
                                ac_build_load_to_sgpr(&ctx->ac, buf_ptr, offset);
                } else {
                        if (USE_LDS_SYMBOLS && HAVE_LLVM >= 0x0900) {
-                               /* Declare the ESGS ring as an explicit LDS symbol.
-                                * For monolithic shaders, we declare the ring only once.
-                                *
-                                * We declare it with 64KB alignment as a hint that the
-                                * pointer value will always be 0.
-                                */
-                               ctx->esgs_ring = LLVMAddGlobalInAddressSpace(
-                                       ctx->ac.module, LLVMArrayType(ctx->i32, 0),
-                                       "esgs_ring",
-                                       AC_ADDR_SPACE_LDS);
-                               LLVMSetAlignment(ctx->esgs_ring, 64 * 1024);
+                               /* Declare the ESGS ring as an explicit LDS symbol. */
+                               declare_esgs_ring(ctx);
                        } else {
                                ac_declare_lds_as_pointer(&ctx->ac);
                                ctx->esgs_ring = ctx->ac.lds;
@@ -5193,8 +5235,8 @@ static bool si_shader_binary_open(struct si_screen *screen,
        struct ac_rtld_symbol lds_symbols[2];
        unsigned num_lds_symbols = 0;
 
-       if (sel && screen->info.chip_class >= GFX9 &&
-           sel->type == PIPE_SHADER_GEOMETRY && !shader->is_gs_copy_shader) {
+       if (sel && screen->info.chip_class >= GFX9 && !shader->is_gs_copy_shader &&
+           (sel->type == PIPE_SHADER_GEOMETRY || shader->key.as_ngg)) {
                /* We add this symbol even on LLVM <= 8 to ensure that
                 * shader->config.lds_size is set correctly below.
                 */
@@ -5302,6 +5344,7 @@ bool si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader
 
 static void si_shader_dump_disassembly(struct si_screen *screen,
                                       const struct si_shader_binary *binary,
+                                      enum pipe_shader_type shader_type,
                                       struct pipe_debug_callback *debug,
                                       const char *name, FILE *file)
 {
@@ -5309,6 +5352,7 @@ static void si_shader_dump_disassembly(struct si_screen *screen,
 
        if (!ac_rtld_open(&rtld_binary, (struct ac_rtld_open_info){
                        .info = &screen->info,
+                       .shader_type = tgsi_processor_to_shader_stage(shader_type),
                        .num_parts = 1,
                        .elf_ptrs = &binary->elf_buffer,
                        .elf_sizes = &binary->elf_size }))
@@ -5395,6 +5439,7 @@ static void si_calculate_max_simd_waves(struct si_shader *shader)
                                       DIV_ROUND_UP(max_workgroup_size, 64);
                }
                break;
+       default:;
        }
 
        /* Compute the per-SIMD wave counts. */
@@ -5422,7 +5467,9 @@ void si_shader_dump_stats_for_shader_db(struct si_screen *screen,
        const struct ac_shader_config *conf = &shader->config;
 
        if (screen->options.debug_disassembly)
-               si_shader_dump_disassembly(screen, &shader->binary, debug, "main", NULL);
+               si_shader_dump_disassembly(screen, &shader->binary,
+                                          shader->selector->type,
+                                          debug, "main", NULL);
 
        pipe_debug_message(debug, SHADER_INFO,
                           "Shader Stats: SGPRS: %d VGPRS: %d Code Size: %d "
@@ -5437,15 +5484,16 @@ void si_shader_dump_stats_for_shader_db(struct si_screen *screen,
 
 static void si_shader_dump_stats(struct si_screen *sscreen,
                                 struct si_shader *shader,
-                                unsigned processor,
                                 FILE *file,
                                 bool check_debug_option)
 {
        const struct ac_shader_config *conf = &shader->config;
+       enum pipe_shader_type shader_type =
+               shader->selector ? shader->selector->type : PIPE_SHADER_COMPUTE;
 
        if (!check_debug_option ||
-           si_can_dump_shader(sscreen, processor)) {
-               if (processor == PIPE_SHADER_FRAGMENT) {
+           si_can_dump_shader(sscreen, shader_type)) {
+               if (shader_type == PIPE_SHADER_FRAGMENT) {
                        fprintf(file, "*** SHADER CONFIG ***\n"
                                "SPI_PS_INPUT_ADDR = 0x%04x\n"
                                "SPI_PS_INPUT_ENA  = 0x%04x\n",
@@ -5472,9 +5520,12 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
        }
 }
 
-const char *si_get_shader_name(const struct si_shader *shader, unsigned processor)
+const char *si_get_shader_name(const struct si_shader *shader)
 {
-       switch (processor) {
+       enum pipe_shader_type shader_type =
+               shader->selector ? shader->selector->type : PIPE_SHADER_COMPUTE;
+
+       switch (shader_type) {
        case PIPE_SHADER_VERTEX:
                if (shader->key.as_es)
                        return "Vertex Shader as ES";
@@ -5510,51 +5561,53 @@ const char *si_get_shader_name(const struct si_shader *shader, unsigned processo
 }
 
 void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
-                   struct pipe_debug_callback *debug, unsigned processor,
+                   struct pipe_debug_callback *debug,
                    FILE *file, bool check_debug_option)
 {
+       enum pipe_shader_type shader_type =
+               shader->selector ? shader->selector->type : PIPE_SHADER_COMPUTE;
+
        if (!check_debug_option ||
-           si_can_dump_shader(sscreen, processor))
-               si_dump_shader_key(processor, shader, file);
+           si_can_dump_shader(sscreen, shader_type))
+               si_dump_shader_key(shader, file);
 
        if (!check_debug_option && shader->binary.llvm_ir_string) {
                if (shader->previous_stage &&
                    shader->previous_stage->binary.llvm_ir_string) {
                        fprintf(file, "\n%s - previous stage - LLVM IR:\n\n",
-                               si_get_shader_name(shader, processor));
+                               si_get_shader_name(shader));
                        fprintf(file, "%s\n", shader->previous_stage->binary.llvm_ir_string);
                }
 
                fprintf(file, "\n%s - main shader part - LLVM IR:\n\n",
-                       si_get_shader_name(shader, processor));
+                       si_get_shader_name(shader));
                fprintf(file, "%s\n", shader->binary.llvm_ir_string);
        }
 
        if (!check_debug_option ||
-           (si_can_dump_shader(sscreen, processor) &&
+           (si_can_dump_shader(sscreen, shader_type) &&
             !(sscreen->debug_flags & DBG(NO_ASM)))) {
-               fprintf(file, "\n%s:\n", si_get_shader_name(shader, processor));
+               fprintf(file, "\n%s:\n", si_get_shader_name(shader));
 
                if (shader->prolog)
                        si_shader_dump_disassembly(sscreen, &shader->prolog->binary,
-                                                  debug, "prolog", file);
+                                                  shader_type, debug, "prolog", file);
                if (shader->previous_stage)
                        si_shader_dump_disassembly(sscreen, &shader->previous_stage->binary,
-                                                  debug, "previous stage", file);
+                                                  shader_type, debug, "previous stage", file);
                if (shader->prolog2)
                        si_shader_dump_disassembly(sscreen, &shader->prolog2->binary,
-                                                  debug, "prolog2", file);
+                                                  shader_type, debug, "prolog2", file);
 
-               si_shader_dump_disassembly(sscreen, &shader->binary, debug, "main", file);
+               si_shader_dump_disassembly(sscreen, &shader->binary, shader_type, debug, "main", file);
 
                if (shader->epilog)
                        si_shader_dump_disassembly(sscreen, &shader->epilog->binary,
-                                                  debug, "epilog", file);
+                                                  shader_type, debug, "epilog", file);
                fprintf(file, "\n");
        }
 
-       si_shader_dump_stats(sscreen, shader, processor, file,
-                            check_debug_option);
+       si_shader_dump_stats(sscreen, shader, file, check_debug_option);
 }
 
 static int si_compile_llvm(struct si_screen *sscreen,
@@ -5563,13 +5616,13 @@ static int si_compile_llvm(struct si_screen *sscreen,
                           struct ac_llvm_compiler *compiler,
                           LLVMModuleRef mod,
                           struct pipe_debug_callback *debug,
-                          unsigned processor,
+                          enum pipe_shader_type shader_type,
                           const char *name,
                           bool less_optimized)
 {
        unsigned count = p_atomic_inc_return(&sscreen->num_compilations);
 
-       if (si_can_dump_shader(sscreen, processor)) {
+       if (si_can_dump_shader(sscreen, shader_type)) {
                fprintf(stderr, "radeonsi: Compiling shader %d\n", count);
 
                if (!(sscreen->debug_flags & (DBG(NO_IR) | DBG(PREOPT_IR)))) {
@@ -5595,6 +5648,7 @@ static int si_compile_llvm(struct si_screen *sscreen,
        struct ac_rtld_binary rtld;
        if (!ac_rtld_open(&rtld, (struct ac_rtld_open_info){
                        .info = &sscreen->info,
+                       .shader_type = tgsi_processor_to_shader_stage(shader_type),
                        .num_parts = 1,
                        .elf_ptrs = &binary->elf_buffer,
                        .elf_sizes = &binary->elf_size }))
@@ -5672,7 +5726,7 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
        /* Fetch the vertex stream ID.*/
        LLVMValueRef stream_id;
 
-       if (gs_selector->so.num_outputs)
+       if (ctx.ac.chip_class <= GFX9 && gs_selector->so.num_outputs)
                stream_id = si_unpack_param(&ctx, ctx.param_streamout_config, 24, 2);
        else
                stream_id = ctx.i32_0;
@@ -5726,13 +5780,13 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
                                        ac_build_buffer_load(&ctx.ac,
                                                             ctx.gsvs_ring[0], 1,
                                                             ctx.i32_0, voffset,
-                                                            soffset, 0, 1, 1,
+                                                            soffset, 0, ac_glc | ac_slc,
                                                             true, false);
                        }
                }
 
                /* Streamout and exports. */
-               if (gs_selector->so.num_outputs) {
+               if (ctx.ac.chip_class <= GFX9 && gs_selector->so.num_outputs) {
                        si_llvm_emit_streamout(&ctx, outputs,
                                               gsinfo->num_outputs,
                                               stream);
@@ -5759,8 +5813,7 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
                            "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);
+               si_shader_dump(sscreen, ctx.shader, debug, stderr, true);
 
                if (!ctx.shader->config.scratch_bytes_per_wave)
                        ok = si_shader_binary_upload(sscreen, ctx.shader, 0);
@@ -5807,14 +5860,15 @@ static void si_dump_shader_key_vs(const struct si_shader_key *key,
        fprintf(f, "}\n");
 }
 
-static void si_dump_shader_key(unsigned processor, const struct si_shader *shader,
-                              FILE *f)
+static void si_dump_shader_key(const struct si_shader *shader, FILE *f)
 {
        const struct si_shader_key *key = &shader->key;
+       enum pipe_shader_type shader_type =
+               shader->selector ? shader->selector->type : PIPE_SHADER_COMPUTE;
 
        fprintf(f, "SHADER KEY\n");
 
-       switch (processor) {
+       switch (shader_type) {
        case PIPE_SHADER_VERTEX:
                si_dump_shader_key_vs(key, &key->part.vs.prolog,
                                      "part.vs.prolog", f);
@@ -5900,9 +5954,9 @@ static void si_dump_shader_key(unsigned processor, const struct si_shader *shade
                assert(0);
        }
 
-       if ((processor == PIPE_SHADER_GEOMETRY ||
-            processor == PIPE_SHADER_TESS_EVAL ||
-            processor == PIPE_SHADER_VERTEX) &&
+       if ((shader_type == PIPE_SHADER_GEOMETRY ||
+            shader_type == PIPE_SHADER_TESS_EVAL ||
+            shader_type == PIPE_SHADER_VERTEX) &&
            !key->as_es && !key->as_ls) {
                fprintf(f, "  opt.kill_outputs = 0x%"PRIx64"\n", key->opt.kill_outputs);
                fprintf(f, "  opt.clip_disable = %u\n", key->opt.clip_disable);
@@ -6026,12 +6080,10 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
                ctx->abi.load_patch_vertices_in = si_load_patch_vertices_in;
                if (shader->key.as_es)
                        ctx->abi.emit_outputs = si_llvm_emit_es_epilogue;
-               else {
-                       if (shader->key.as_ngg)
-                               ctx->abi.emit_outputs = gfx10_emit_ngg_epilogue;
-                       else
-                               ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
-               }
+               else if (shader->key.as_ngg)
+                       ctx->abi.emit_outputs = gfx10_emit_ngg_epilogue;
+               else
+                       ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
                bld_base->emit_epilogue = si_tgsi_emit_epilogue;
                break;
        case PIPE_SHADER_GEOMETRY:
@@ -6082,12 +6134,18 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
                        for (unsigned i = 0; i < 4; ++i) {
                                ctx->gs_curprim_verts[i] =
                                        lp_build_alloca(&ctx->gallivm, ctx->ac.i32, "");
+                               ctx->gs_generated_prims[i] =
+                                       lp_build_alloca(&ctx->gallivm, ctx->ac.i32, "");
                        }
 
-                       LLVMTypeRef a8i32 = LLVMArrayType(ctx->i32, 8);
+                       unsigned scratch_size = 8;
+                       if (sel->so.num_outputs)
+                               scratch_size = 44;
+
+                       LLVMTypeRef ai32 = LLVMArrayType(ctx->i32, scratch_size);
                        ctx->gs_ngg_scratch = LLVMAddGlobalInAddressSpace(ctx->ac.module,
-                               a8i32, "ngg_scratch", AC_ADDR_SPACE_LDS);
-                       LLVMSetInitializer(ctx->gs_ngg_scratch, LLVMGetUndef(a8i32));
+                               ai32, "ngg_scratch", AC_ADDR_SPACE_LDS);
+                       LLVMSetInitializer(ctx->gs_ngg_scratch, LLVMGetUndef(ai32));
                        LLVMSetAlignment(ctx->gs_ngg_scratch, 4);
 
                        ctx->gs_ngg_emit = LLVMAddGlobalInAddressSpace(ctx->ac.module,
@@ -6097,6 +6155,26 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
                }
        }
 
+       if (shader->key.as_ngg && ctx->type != PIPE_SHADER_GEOMETRY) {
+               /* Unconditionally declare scratch space base for streamout and
+                * vertex compaction. Whether space is actually allocated is
+                * determined during linking / PM4 creation.
+                *
+                * Add an extra dword per vertex to ensure an odd stride, which
+                * avoids bank conflicts for SoA accesses.
+                */
+               declare_esgs_ring(ctx);
+
+               /* This is really only needed when streamout and / or vertex
+                * compaction is enabled.
+                */
+               LLVMTypeRef asi32 = LLVMArrayType(ctx->i32, 8);
+               ctx->gs_ngg_scratch = LLVMAddGlobalInAddressSpace(ctx->ac.module,
+                       asi32, "ngg_scratch", AC_ADDR_SPACE_LDS);
+               LLVMSetInitializer(ctx->gs_ngg_scratch, LLVMGetUndef(asi32));
+               LLVMSetAlignment(ctx->gs_ngg_scratch, 4);
+       }
+
        /* For GFX9 merged shaders:
         * - Set EXEC for the first shader. If the prolog is present, set
         *   EXEC there instead.
@@ -6135,9 +6213,15 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
 
                        if (ctx->type == PIPE_SHADER_TESS_CTRL ||
                            ctx->type == PIPE_SHADER_GEOMETRY) {
+                               if (ctx->type == PIPE_SHADER_GEOMETRY && shader->key.as_ngg) {
+                                       gfx10_ngg_gs_emit_prologue(ctx);
+                                       nested_barrier = false;
+                               } else {
+                                       nested_barrier = true;
+                               }
+
                                /* Number of patches / primitives */
                                num_threads = si_unpack_param(ctx, ctx->param_merged_wave_info, 8, 8);
-                               nested_barrier = true;
                        } else {
                                /* Number of vertices */
                                num_threads = si_unpack_param(ctx, ctx->param_merged_wave_info, 0, 8);
@@ -6817,7 +6901,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 
        /* Dump TGSI code before doing TGSI->LLVM conversion in case the
         * conversion fails. */
-       if (si_can_dump_shader(sscreen, sel->info.processor) &&
+       if (si_can_dump_shader(sscreen, sel->type) &&
            !(sscreen->debug_flags & DBG(NO_TGSI))) {
                if (sel->tokens)
                        tgsi_dump(sel->tokens, 0);
@@ -6939,6 +7023,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
                        memset(&gs_prolog_key, 0, sizeof(gs_prolog_key));
                        gs_prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
                        gs_prolog_key.gs_prolog.is_monolithic = true;
+                       gs_prolog_key.gs_prolog.as_ngg = shader->key.as_ngg;
                        si_build_gs_prolog_function(&ctx, &gs_prolog_key);
                        gs_prolog = ctx.main_fn;
 
@@ -7042,7 +7127,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
        /* Compile to bytecode. */
        r = si_compile_llvm(sscreen, &shader->binary, &shader->config, compiler,
                            ctx.ac.module, debug, ctx.type,
-                           si_get_shader_name(shader, ctx.type),
+                           si_get_shader_name(shader),
                            si_should_optimize_less(compiler, shader->selector));
        si_llvm_dispose(&ctx);
        if (r) {
@@ -7176,11 +7261,6 @@ si_get_shader_part(struct si_screen *sscreen,
        result->key = *key;
 
        struct si_shader shader = {};
-       struct si_shader_context ctx;
-
-       si_init_shader_ctx(&ctx, sscreen, compiler);
-       ctx.shader = &shader;
-       ctx.type = type;
 
        switch (type) {
        case PIPE_SHADER_VERTEX:
@@ -7194,6 +7274,7 @@ si_get_shader_part(struct si_screen *sscreen,
                break;
        case PIPE_SHADER_GEOMETRY:
                assert(prolog);
+               shader.key.as_ngg = key->gs_prolog.as_ngg;
                break;
        case PIPE_SHADER_FRAGMENT:
                if (prolog)
@@ -7205,6 +7286,11 @@ si_get_shader_part(struct si_screen *sscreen,
                unreachable("bad shader part");
        }
 
+       struct si_shader_context ctx;
+       si_init_shader_ctx(&ctx, sscreen, compiler);
+       ctx.shader = &shader;
+       ctx.type = type;
+
        build(&ctx, key);
 
        /* Compile. */
@@ -7540,7 +7626,7 @@ static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
 
        /* Create the function. */
        si_create_function(ctx, "tcs_epilog", NULL, 0, &fninfo,
-                          ctx->screen->info.chip_class >= GFX7 ? 128 : 64);
+                          ctx->screen->info.chip_class >= GFX7 ? 128 : 0);
        ac_declare_lds_as_pointer(&ctx->ac);
        func = ctx->main_fn;
 
@@ -7615,6 +7701,7 @@ static bool si_shader_select_gs_parts(struct si_screen *sscreen,
        union si_shader_part_key prolog_key;
        memset(&prolog_key, 0, sizeof(prolog_key));
        prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
+       prolog_key.gs_prolog.as_ngg = shader->key.as_ngg;
 
        shader->prolog2 = si_get_shader_part(sscreen, &sscreen->gs_prologs,
                                            PIPE_SHADER_GEOMETRY, true,
@@ -8220,6 +8307,7 @@ bool si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compil
                        shader->config.num_vgprs = MAX2(shader->config.num_vgprs,
                                                        shader->info.num_input_vgprs);
                        break;
+               default:;
                }
 
                /* Update SGPR and VGPR counts. */
@@ -8272,8 +8360,7 @@ bool si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compil
        }
 
        si_fix_resource_usage(sscreen, shader);
-       si_shader_dump(sscreen, shader, debug, sel->info.processor,
-                      stderr, true);
+       si_shader_dump(sscreen, shader, debug, stderr, true);
 
        /* Upload. */
        if (!si_shader_binary_upload(sscreen, shader, 0)) {