radeonsi/gfx10: implement streamout-related queries
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index d532d6643070355dae4a2b146c77b516fec62c76..68506b7a92cb105e061a578224071af006ec6b4b 100644 (file)
 #include "tgsi/tgsi_strings.h"
 #include "tgsi/tgsi_util.h"
 #include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_from_mesa.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
-{
-       LLVMValueRef values[4];
-       unsigned semantic_name;
-       unsigned semantic_index;
-       ubyte vertex_stream[4];
-};
-
 static void si_init_shader_ctx(struct si_shader_context *ctx,
                               struct si_screen *sscreen,
                               struct ac_llvm_compiler *compiler);
@@ -88,7 +83,8 @@ static bool llvm_type_is_64bit(struct si_shader_context *ctx,
        return false;
 }
 
-static bool is_merged_shader(struct si_shader_context *ctx)
+/** Whether the shader runs as a combination of multiple API shaders */
+static bool is_multi_part_shader(struct si_shader_context *ctx)
 {
        if (ctx->screen->info.chip_class <= GFX8)
                return false;
@@ -99,6 +95,12 @@ static bool is_merged_shader(struct si_shader_context *ctx)
               ctx->type == PIPE_SHADER_GEOMETRY;
 }
 
+/** Whether the shader runs on a merged HW stage (LSHS or ESGS) */
+static bool is_merged_shader(struct si_shader_context *ctx)
+{
+       return ctx->shader->key.as_ngg || is_multi_part_shader(ctx);
+}
+
 void si_init_function_info(struct si_function_info *fninfo)
 {
        fninfo->num_params = 0;
@@ -644,8 +646,8 @@ static void declare_input_vs(
        si_llvm_load_input_vs(ctx, input_index, out);
 }
 
-static LLVMValueRef get_primitive_id(struct si_shader_context *ctx,
-                                    unsigned swizzle)
+LLVMValueRef si_get_primitive_id(struct si_shader_context *ctx,
+                                unsigned swizzle)
 {
        if (swizzle > 0)
                return ctx->i32_0;
@@ -989,13 +991,13 @@ static LLVMValueRef buffer_load(struct lp_build_tgsi_context *bld_base,
 }
 
 /**
- * Load from LDS.
+ * Load from LSHS LDS storage.
  *
  * \param type         output value type
  * \param swizzle      offset (typically 0..3); it can be ~0, which loads a vec4
  * \param dw_addr      address in dwords
  */
-static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
+static LLVMValueRef lshs_lds_load(struct lp_build_tgsi_context *bld_base,
                             LLVMTypeRef type, unsigned swizzle,
                             LLVMValueRef dw_addr)
 {
@@ -1006,7 +1008,7 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
                LLVMValueRef values[TGSI_NUM_CHANNELS];
 
                for (unsigned chan = 0; chan < TGSI_NUM_CHANNELS; chan++)
-                       values[chan] = lds_load(bld_base, type, chan, dw_addr);
+                       values[chan] = lshs_lds_load(bld_base, type, chan, dw_addr);
 
                return ac_build_gather_values(&ctx->ac, values,
                                              TGSI_NUM_CHANNELS);
@@ -1016,8 +1018,8 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
        if (llvm_type_is_64bit(ctx, type)) {
                LLVMValueRef lo, hi;
 
-               lo = lds_load(bld_base, ctx->i32, swizzle, dw_addr);
-               hi = lds_load(bld_base, ctx->i32, swizzle + 1, dw_addr);
+               lo = lshs_lds_load(bld_base, ctx->i32, swizzle, dw_addr);
+               hi = lshs_lds_load(bld_base, ctx->i32, swizzle + 1, dw_addr);
                return si_llvm_emit_fetch_64bit(bld_base, type, lo, hi);
        }
 
@@ -1030,13 +1032,13 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
 }
 
 /**
- * Store to LDS.
+ * Store to LSHS LDS storage.
  *
  * \param swizzle      offset (typically 0..3)
  * \param dw_addr      address in dwords
  * \param value                value to store
  */
-static void lds_store(struct si_shader_context *ctx,
+static void lshs_lds_store(struct si_shader_context *ctx,
                      unsigned dw_offset_imm, LLVMValueRef dw_addr,
                      LLVMValueRef value)
 {
@@ -1072,18 +1074,25 @@ static LLVMValueRef get_tess_ring_descriptor(struct si_shader_context *ctx,
                                    LLVMConstInt(ctx->i32, tf_offset, 0), "");
        }
 
+       uint32_t rsrc3 = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+                        S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+                        S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+                        S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
+
+       if (ctx->screen->info.chip_class >= GFX10)
+               rsrc3 |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
+                        S_008F0C_OOB_SELECT(3) |
+                        S_008F0C_RESOURCE_LEVEL(1);
+       else
+               rsrc3 |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+                        S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
+
        LLVMValueRef desc[4];
        desc[0] = addr;
        desc[1] = LLVMConstInt(ctx->i32,
                               S_008F04_BASE_ADDRESS_HI(ctx->screen->info.address32_hi), 0);
        desc[2] = LLVMConstInt(ctx->i32, 0xffffffff, 0);
-       desc[3] = LLVMConstInt(ctx->i32,
-                              S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
-                              S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
-                              S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
-                              S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
-                              S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
-                              S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32), 0);
+       desc[3] = LLVMConstInt(ctx->i32, rsrc3, false);
 
        return ac_build_gather_values(&ctx->ac, desc, 4);
 }
@@ -1100,7 +1109,7 @@ static LLVMValueRef fetch_input_tcs(
        dw_addr = get_tcs_in_current_patch_offset(ctx);
        dw_addr = get_dw_address(ctx, NULL, reg, stride, dw_addr);
 
-       return lds_load(bld_base, tgsi2llvmtype(bld_base, type), swizzle, dw_addr);
+       return lshs_lds_load(bld_base, tgsi2llvmtype(bld_base, type), swizzle, dw_addr);
 }
 
 static LLVMValueRef si_nir_load_tcs_varyings(struct ac_shader_abi *abi,
@@ -1167,7 +1176,7 @@ static LLVMValueRef si_nir_load_tcs_varyings(struct ac_shader_abi *abi,
                        offset *= 2;
 
                offset += component;
-               value[i + component] = lds_load(bld_base, type, offset, dw_addr);
+               value[i + component] = lshs_lds_load(bld_base, type, offset, dw_addr);
        }
 
        return ac_build_varying_gather_values(&ctx->ac, value, num_components, component);
@@ -1191,7 +1200,7 @@ static LLVMValueRef fetch_output_tcs(
                dw_addr = get_dw_address(ctx, NULL, reg, NULL, dw_addr);
        }
 
-       return lds_load(bld_base, tgsi2llvmtype(bld_base, type), swizzle, dw_addr);
+       return lshs_lds_load(bld_base, tgsi2llvmtype(bld_base, type), swizzle, dw_addr);
 }
 
 static LLVMValueRef fetch_input_tes(
@@ -1341,7 +1350,7 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
 
                /* Skip LDS stores if there is no LDS read of this output. */
                if (!skip_lds_store)
-                       lds_store(ctx, chan_index, dw_addr, value);
+                       lshs_lds_store(ctx, chan_index, dw_addr, value);
 
                value = ac_to_integer(&ctx->ac, value);
                values[chan_index] = value;
@@ -1349,7 +1358,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, true, false);
+                                                   4 * chan_index, 1, 0, false);
                }
 
                /* Write tess factors into VGPRs for the epilog. */
@@ -1369,7 +1378,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, true, false);
+                                           base, 0, 1, 0, false);
        }
 }
 
@@ -1468,7 +1477,7 @@ static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
 
                /* Skip LDS stores if there is no LDS read of this output. */
                if (!skip_lds_store)
-                       lds_store(ctx, chan, dw_addr, value);
+                       lshs_lds_store(ctx, chan, dw_addr, value);
 
                value = ac_to_integer(&ctx->ac, value);
                values[chan] = value;
@@ -1477,7 +1486,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, true, false);
+                                                    1, 0, false);
                }
 
                /* Write tess factors into VGPRs for the epilog. */
@@ -1497,7 +1506,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, true, false);
+                                           base, 0, 1, 0, false);
        }
 }
 
@@ -1541,9 +1550,22 @@ LLVMValueRef si_llvm_load_input_gs(struct ac_shader_abi *abi,
                        return NULL;
                }
 
+               unsigned offset = param * 4 + swizzle;
                vtx_offset = LLVMBuildAdd(ctx->ac.builder, vtx_offset,
-                                         LLVMConstInt(ctx->i32, param * 4, 0), "");
-               return lds_load(bld_base, type, swizzle, vtx_offset);
+                                         LLVMConstInt(ctx->i32, offset, false), "");
+
+               LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->esgs_ring, vtx_offset);
+               LLVMValueRef value = LLVMBuildLoad(ctx->ac.builder, ptr, "");
+               if (llvm_type_is_64bit(ctx, type)) {
+                       ptr = LLVMBuildGEP(ctx->ac.builder, ptr,
+                                          &ctx->ac.i32_1, 1, "");
+                       LLVMValueRef values[2] = {
+                               value,
+                               LLVMBuildLoad(ctx->ac.builder, ptr, "")
+                       };
+                       value = ac_build_gather_values(&ctx->ac, values, 2);
+               }
+               return LLVMBuildBitCast(ctx->ac.builder, value, type, "");
        }
 
        /* GFX6: input load from the ESGS ring in memory. */
@@ -1617,7 +1639,7 @@ static LLVMValueRef fetch_input_gs(
 
        unsigned semantic_name = info->input_semantic_name[reg->Register.Index];
        if (swizzle != ~0 && semantic_name == TGSI_SEMANTIC_PRIMID)
-               return get_primitive_id(ctx, swizzle);
+               return si_get_primitive_id(ctx, swizzle);
 
        if (!reg->Register.Dimension)
                return NULL;
@@ -2103,7 +2125,7 @@ void si_load_system_value(struct si_shader_context *ctx,
        }
 
        case TGSI_SEMANTIC_PRIMID:
-               value = get_primitive_id(ctx, 0);
+               value = si_get_primitive_id(ctx, 0);
                break;
 
        case TGSI_SEMANTIC_GRID_SIZE:
@@ -2202,7 +2224,7 @@ void si_declare_compute_memory(struct si_shader_context *ctx)
                                          LLVMArrayType(ctx->i8, lds_size),
                                          "compute_lds",
                                          AC_ADDR_SPACE_LDS);
-       LLVMSetAlignment(var, 4);
+       LLVMSetAlignment(var, 64 * 1024);
 
        ctx->ac.lds = LLVMBuildBitCast(ctx->ac.builder, var, i8p, "");
 }
@@ -2234,17 +2256,24 @@ static LLVMValueRef load_const_buffer_desc_fast_path(struct si_shader_context *c
        desc1 = LLVMConstInt(ctx->i32,
                             S_008F04_BASE_ADDRESS_HI(ctx->screen->info.address32_hi), 0);
 
+       uint32_t rsrc3 = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+                        S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+                        S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+                        S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
+
+       if (ctx->screen->info.chip_class >= GFX10)
+               rsrc3 |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
+                        S_008F0C_OOB_SELECT(3) |
+                        S_008F0C_RESOURCE_LEVEL(1);
+       else
+               rsrc3 |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+                        S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
+
        LLVMValueRef desc_elems[] = {
                desc0,
                desc1,
                LLVMConstInt(ctx->i32, (sel->info.const_file_max[0] + 1) * 16, 0),
-               LLVMConstInt(ctx->i32,
-                       S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
-                       S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
-                       S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
-                       S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
-                       S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
-                       S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32), 0)
+               LLVMConstInt(ctx->i32, rsrc3, false)
        };
 
        return ac_build_gather_values(&ctx->ac, desc_elems, 4);
@@ -2598,11 +2627,11 @@ static void si_dump_streamout(struct pipe_stream_output_info *so)
        }
 }
 
-static void emit_streamout_output(struct si_shader_context *ctx,
-                                 LLVMValueRef const *so_buffers,
-                                 LLVMValueRef const *so_write_offsets,
-                                 struct pipe_stream_output *stream_out,
-                                 struct si_shader_output_values *shader_out)
+void si_emit_streamout_output(struct si_shader_context *ctx,
+                             LLVMValueRef const *so_buffers,
+                             LLVMValueRef const *so_write_offsets,
+                             struct pipe_stream_output *stream_out,
+                             struct si_shader_output_values *shader_out)
 {
        unsigned buf_idx = stream_out->output_buffer;
        unsigned start = stream_out->start_component;
@@ -2645,7 +2674,7 @@ static void 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, true, false);
+                                   stream_out->dst_offset * 4, 1, 1, false);
 }
 
 /**
@@ -2725,8 +2754,8 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
                        if (stream != so->output[i].stream)
                                continue;
 
-                       emit_streamout_output(ctx, so_buffers, so_write_offset,
-                                             &so->output[i], &outputs[reg]);
+                       si_emit_streamout_output(ctx, so_buffers, so_write_offset,
+                                                &so->output[i], &outputs[reg]);
                }
        }
        lp_build_endif(&if_ctx);
@@ -2854,10 +2883,12 @@ static void si_vertex_color_clamping(struct si_shader_context *ctx,
        }
 }
 
-/* Generate export instructions for hardware VS shader stage */
-static void si_llvm_export_vs(struct si_shader_context *ctx,
-                             struct si_shader_output_values *outputs,
-                             unsigned noutput)
+/* Generate export instructions for hardware VS shader stage or NGG GS stage
+ * (position and parameter data only).
+ */
+void si_llvm_export_vs(struct si_shader_context *ctx,
+                      struct si_shader_output_values *outputs,
+                      unsigned noutput)
 {
        struct si_shader *shader = ctx->shader;
        struct ac_export_args pos_args[4] = {};
@@ -3036,11 +3067,10 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
                                              invocation_id,
                                              LLVMConstInt(ctx->i32, i, 0));
 
-               LLVMValueRef value = lds_load(bld_base, ctx->ac.i32, ~0,
-                                             lds_ptr);
+               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, true, false);
+                                           buffer_offset, 0, 1, 0, false);
        }
 }
 
@@ -3123,11 +3153,11 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
 
                for (i = 0; i < outer_comps; i++) {
                        outer[i] = out[i] =
-                               lds_load(bld_base, ctx->ac.i32, i, lds_outer);
+                               lshs_lds_load(bld_base, ctx->ac.i32, i, lds_outer);
                }
                for (i = 0; i < inner_comps; i++) {
                        inner[i] = out[outer_comps+i] =
-                               lds_load(bld_base, ctx->ac.i32, i, lds_inner);
+                               lshs_lds_load(bld_base, ctx->ac.i32, i, lds_inner);
                }
        }
 
@@ -3166,7 +3196,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, true, false);
+                                           offset, 1, 0, false);
                offset += 4;
        }
 
@@ -3175,12 +3205,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, true, false);
+                                   offset, 1, 0, false);
        offset += 16;
        if (vec1)
                ac_build_buffer_store_dword(&ctx->ac, buffer, vec1,
                                            stride - 4, byteoffset, tf_base,
-                                           offset, 1, 0, true, false);
+                                           offset, 1, 0, false);
 
        /* Store the tess factors into the offchip buffer if TES reads them. */
        if (shader->key.part.tcs.epilog.tes_reads_tess_factors) {
@@ -3203,7 +3233,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, true, false);
+                                           base, 0, 1, 0, false);
                if (inner_comps) {
                        param_inner = si_shader_io_get_unique_index_patch(
                                              TGSI_SEMANTIC_TESSINNER, 0);
@@ -3214,7 +3244,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, true, false);
+                                                   base, 0, 1, 0, false);
                }
        }
 
@@ -3385,11 +3415,15 @@ static void si_set_ls_return_value_for_tcs(struct si_shader_context *ctx)
 /* Pass GS inputs from ES to GS on GFX9. */
 static void si_set_es_return_value_for_gs(struct si_shader_context *ctx)
 {
+       LLVMBuilderRef builder = ctx->ac.builder;
        LLVMValueRef ret = ctx->return_value;
 
        ret = si_insert_input_ptr(ctx, ret, 0, 0);
        ret = si_insert_input_ptr(ctx, ret, 1, 1);
-       ret = si_insert_input_ret(ctx, ret, ctx->param_gs2vs_offset, 2);
+       if (ctx->shader->key.as_ngg)
+               ret = LLVMBuildInsertValue(builder, ret, ctx->gs_tg_info, 2, "");
+       else
+               ret = si_insert_input_ret(ctx, ret, ctx->param_gs2vs_offset, 2);
        ret = si_insert_input_ret(ctx, ret, ctx->param_merged_wave_info, 3);
        ret = si_insert_input_ret(ctx, ret, ctx->param_merged_scratch_offset, 5);
 
@@ -3459,7 +3493,7 @@ static void si_llvm_emit_ls_epilogue(struct ac_shader_abi *abi,
                        if (!(info->output_usagemask[i] & (1 << chan)))
                                continue;
 
-                       lds_store(ctx, chan, dw_addr,
+                       lshs_lds_store(ctx, chan, dw_addr,
                                  LLVMBuildLoad(ctx->ac.builder, addrs[4 * i + chan], ""));
                }
        }
@@ -3511,7 +3545,9 @@ static void si_llvm_emit_es_epilogue(struct ac_shader_abi *abi,
 
                        /* GFX9 has the ESGS ring in LDS. */
                        if (ctx->screen->info.chip_class >= GFX9) {
-                               lds_store(ctx, param * 4 + chan, lds_base, out_val);
+                               LLVMValueRef idx = LLVMConstInt(ctx->i32, param * 4 + chan, false);
+                               idx = LLVMBuildAdd(ctx->ac.builder, lds_base, idx, "");
+                               ac_build_indexed_store(&ctx->ac, ctx->esgs_ring, idx, out_val);
                                continue;
                        }
 
@@ -3519,7 +3555,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, true);
+                                                   1, 1, true);
                }
        }
 
@@ -3537,6 +3573,11 @@ static LLVMValueRef si_get_gs_wave_id(struct si_shader_context *ctx)
 
 static void emit_gs_epilogue(struct si_shader_context *ctx)
 {
+       if (ctx->shader->key.as_ngg) {
+               gfx10_ngg_gs_emit_epilogue(ctx);
+               return;
+       }
+
        ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_NOP | AC_SENDMSG_GS_DONE,
                         si_get_gs_wave_id(ctx));
 
@@ -3597,7 +3638,7 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
        if (ctx->shader->key.mono.u.vs_export_prim_id) {
                outputs[i].semantic_name = TGSI_SEMANTIC_PRIMID;
                outputs[i].semantic_index = 0;
-               outputs[i].values[0] = ac_to_float(&ctx->ac, get_primitive_id(ctx, 0));
+               outputs[i].values[0] = ac_to_float(&ctx->ac, si_get_primitive_id(ctx, 0));
                for (j = 1; j < 4; j++)
                        outputs[i].values[j] = LLVMConstReal(ctx->f32, 0);
 
@@ -4174,6 +4215,12 @@ static void si_llvm_emit_vertex(struct ac_shader_abi *abi,
                                LLVMValueRef *addrs)
 {
        struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+
+       if (ctx->shader->key.as_ngg) {
+               gfx10_ngg_gs_emit_vertex(ctx, stream, addrs);
+               return;
+       }
+
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
        struct si_shader *shader = ctx->shader;
        struct lp_build_if_state if_state;
@@ -4231,7 +4278,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, true);
+                                                   1, 1, true);
                }
        }
 
@@ -4266,6 +4313,11 @@ static void si_llvm_emit_primitive(struct ac_shader_abi *abi,
 {
        struct si_shader_context *ctx = si_shader_context_from_abi(abi);
 
+       if (ctx->shader->key.as_ngg) {
+               LLVMBuildStore(ctx->ac.builder, ctx->ac.i32_0, ctx->gs_curprim_verts[stream]);
+               return;
+       }
+
        /* Signal primitive cut */
        ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_CUT | AC_SENDMSG_GS | (stream << 8),
                         si_get_gs_wave_id(ctx));
@@ -4394,6 +4446,10 @@ static void declare_streamout_params(struct si_shader_context *ctx,
 static unsigned si_get_max_workgroup_size(const struct si_shader *shader)
 {
        switch (shader->selector->type) {
+       case PIPE_SHADER_VERTEX:
+       case PIPE_SHADER_TESS_EVAL:
+               return shader->key.as_ngg ? 128 : 0;
+
        case PIPE_SHADER_TESS_CTRL:
                /* Return this so that LLVM doesn't remove s_barrier
                 * instructions on chips where we use s_barrier. */
@@ -4491,12 +4547,23 @@ static void declare_vs_input_vgprs(struct si_shader_context *ctx,
        add_arg_assign(fninfo, ARG_VGPR, ctx->i32, &ctx->abi.vertex_id);
        if (shader->key.as_ls) {
                ctx->param_rel_auto_id = add_arg(fninfo, ARG_VGPR, ctx->i32);
+               if (ctx->screen->info.chip_class >= GFX10) {
+                       add_arg(fninfo, ARG_VGPR, ctx->i32); /* user VGPR */
+                       add_arg_assign(fninfo, ARG_VGPR, ctx->i32, &ctx->abi.instance_id);
+               } else {
+                       add_arg_assign(fninfo, ARG_VGPR, ctx->i32, &ctx->abi.instance_id);
+                       add_arg(fninfo, ARG_VGPR, ctx->i32); /* unused */
+               }
+       } else if (ctx->screen->info.chip_class == GFX10 &&
+                  !shader->is_gs_copy_shader) {
+               add_arg(fninfo, ARG_VGPR, ctx->i32); /* user vgpr */
+               add_arg(fninfo, ARG_VGPR, ctx->i32); /* user vgpr */
                add_arg_assign(fninfo, ARG_VGPR, ctx->i32, &ctx->abi.instance_id);
        } else {
                add_arg_assign(fninfo, ARG_VGPR, ctx->i32, &ctx->abi.instance_id);
                ctx->param_vs_prim_id = add_arg(fninfo, ARG_VGPR, ctx->i32);
+               add_arg(fninfo, ARG_VGPR, ctx->i32); /* unused */
        }
-       add_arg(fninfo, ARG_VGPR, ctx->i32); /* unused */
 
        if (!shader->is_gs_copy_shader) {
                /* Vertex load indices. */
@@ -4564,7 +4631,7 @@ static void create_function(struct si_shader_context *ctx)
        if (ctx->screen->info.chip_class >= GFX9) {
                if (shader->key.as_ls || type == PIPE_SHADER_TESS_CTRL)
                        type = SI_SHADER_MERGED_VERTEX_TESSCTRL; /* LS or HS */
-               else if (shader->key.as_es || type == PIPE_SHADER_GEOMETRY)
+               else if (shader->key.as_es || shader->key.as_ngg || type == PIPE_SHADER_GEOMETRY)
                        type = SI_SHADER_MERGED_VERTEX_OR_TESSEVAL_GEOMETRY;
        }
 
@@ -4690,7 +4757,12 @@ static void create_function(struct si_shader_context *ctx)
                /* SPI_SHADER_USER_DATA_ADDR_LO/HI_GS */
                declare_per_stage_desc_pointers(ctx, &fninfo,
                                                ctx->type == PIPE_SHADER_GEOMETRY);
-               ctx->param_gs2vs_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
+
+               if (ctx->shader->key.as_ngg)
+                       add_arg_assign(&fninfo, ARG_SGPR, ctx->i32, &ctx->gs_tg_info);
+               else
+                       ctx->param_gs2vs_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
+
                ctx->param_merged_wave_info = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_tcs_offchip_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_merged_scratch_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
@@ -4698,11 +4770,17 @@ static void create_function(struct si_shader_context *ctx)
                add_arg(&fninfo, ARG_SGPR, ctx->i32); /* unused (SPI_SHADER_PGM_LO/HI_GS >> 24) */
 
                declare_global_desc_pointers(ctx, &fninfo);
-               declare_per_stage_desc_pointers(ctx, &fninfo,
-                                               (ctx->type == PIPE_SHADER_VERTEX ||
-                                                ctx->type == PIPE_SHADER_TESS_EVAL));
+               if (ctx->type != PIPE_SHADER_VERTEX || !vs_blit_property) {
+                       declare_per_stage_desc_pointers(ctx, &fninfo,
+                                                       (ctx->type == PIPE_SHADER_VERTEX ||
+                                                        ctx->type == PIPE_SHADER_TESS_EVAL));
+               }
+
                if (ctx->type == PIPE_SHADER_VERTEX) {
-                       declare_vs_specific_input_sgprs(ctx, &fninfo);
+                       if (vs_blit_property)
+                               declare_vs_blit_inputs(ctx, &fninfo, vs_blit_property);
+                       else
+                               declare_vs_specific_input_sgprs(ctx, &fninfo);
                } else {
                        ctx->param_vs_state_bits = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                        ctx->param_tcs_offchip_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
@@ -4729,8 +4807,9 @@ static void create_function(struct si_shader_context *ctx)
                        declare_tes_input_vgprs(ctx, &fninfo);
                }
 
-               if (ctx->type == PIPE_SHADER_VERTEX ||
-                   ctx->type == PIPE_SHADER_TESS_EVAL) {
+               if (ctx->shader->key.as_es &&
+                   (ctx->type == PIPE_SHADER_VERTEX ||
+                    ctx->type == PIPE_SHADER_TESS_EVAL)) {
                        unsigned num_user_sgprs;
 
                        if (ctx->type == PIPE_SHADER_VERTEX)
@@ -4909,11 +4988,21 @@ static void create_function(struct si_shader_context *ctx)
        assert(shader->info.num_input_vgprs >= num_prolog_vgprs);
        shader->info.num_input_vgprs -= num_prolog_vgprs;
 
-       if (shader->key.as_ls ||
-           ctx->type == PIPE_SHADER_TESS_CTRL ||
-           /* GFX9 has the ESGS ring buffer in LDS. */
-           type == SI_SHADER_MERGED_VERTEX_OR_TESSEVAL_GEOMETRY)
-               ac_declare_lds_as_pointer(&ctx->ac);
+       if (shader->key.as_ls || ctx->type == PIPE_SHADER_TESS_CTRL) {
+               if (USE_LDS_SYMBOLS && HAVE_LLVM >= 0x0900) {
+                       /* The LSHS size is not known until draw time, so we append it
+                        * at the end of whatever LDS use there may be in the rest of
+                        * the shader (currently none, unless LLVM decides to do its
+                        * own LDS-based lowering).
+                        */
+                       ctx->ac.lds = LLVMAddGlobalInAddressSpace(
+                               ctx->ac.module, LLVMArrayType(ctx->i32, 0),
+                               "__lds_end", AC_ADDR_SPACE_LDS);
+                       LLVMSetAlignment(ctx->ac.lds, 256);
+               } else {
+                       ac_declare_lds_as_pointer(&ctx->ac);
+               }
+       }
 }
 
 /**
@@ -4927,15 +5016,33 @@ static void preload_ring_buffers(struct si_shader_context *ctx)
        LLVMValueRef buf_ptr = LLVMGetParam(ctx->main_fn,
                                            ctx->param_rw_buffers);
 
-       if (ctx->screen->info.chip_class <= GFX8 &&
-           (ctx->shader->key.as_es || ctx->type == PIPE_SHADER_GEOMETRY)) {
-               unsigned ring =
-                       ctx->type == PIPE_SHADER_GEOMETRY ? SI_GS_RING_ESGS
-                                                            : SI_ES_RING_ESGS;
-               LLVMValueRef offset = LLVMConstInt(ctx->i32, ring, 0);
+       if (ctx->shader->key.as_es || ctx->type == PIPE_SHADER_GEOMETRY) {
+               if (ctx->screen->info.chip_class <= GFX8) {
+                       unsigned ring =
+                               ctx->type == PIPE_SHADER_GEOMETRY ? SI_GS_RING_ESGS
+                                                                 : SI_ES_RING_ESGS;
+                       LLVMValueRef offset = LLVMConstInt(ctx->i32, ring, 0);
 
-               ctx->esgs_ring =
-                       ac_build_load_to_sgpr(&ctx->ac, buf_ptr, offset);
+                       ctx->esgs_ring =
+                               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);
+                       } else {
+                               ac_declare_lds_as_pointer(&ctx->ac);
+                               ctx->esgs_ring = ctx->ac.lds;
+                       }
+               }
        }
 
        if (ctx->shader->is_gs_copy_shader) {
@@ -4996,18 +5103,27 @@ static void preload_ring_buffers(struct si_shader_context *ctx)
                        ring = LLVMBuildInsertElement(builder, ring,
                                        LLVMConstInt(ctx->i32, num_records, 0),
                                        LLVMConstInt(ctx->i32, 2, 0), "");
+
+                       uint32_t rsrc3 =
+                                       S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+                                       S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+                                       S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+                                       S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
+                                       S_008F0C_INDEX_STRIDE(1) | /* index_stride = 16 (elements) */
+                                       S_008F0C_ADD_TID_ENABLE(1);
+
+                       if (ctx->ac.chip_class >= GFX10) {
+                               rsrc3 |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
+                                        S_008F0C_OOB_SELECT(2) |
+                                        S_008F0C_RESOURCE_LEVEL(1);
+                       } else {
+                               rsrc3 |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+                                        S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32) |
+                                        S_008F0C_ELEMENT_SIZE(1); /* element_size = 4 (bytes) */
+                       }
+
                        ring = LLVMBuildInsertElement(builder, ring,
-                               LLVMConstInt(ctx->i32,
-                                            S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
-                                            S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
-                                            S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
-                                            S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
-                                            S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
-                                            S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32) |
-                                            S_008F0C_ELEMENT_SIZE(1) | /* element_size = 4 (bytes) */
-                                            S_008F0C_INDEX_STRIDE(1) | /* index_stride = 16 (elements) */
-                                            S_008F0C_ADD_TID_ENABLE(1),
-                                            0),
+                               LLVMConstInt(ctx->i32, rsrc3, false),
                                LLVMConstInt(ctx->i32, 3, 0), "");
 
                        ctx->gsvs_ring[stream] = ring;
@@ -5045,168 +5161,203 @@ static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
        ac_build_kill_if_false(&ctx->ac, bit);
 }
 
-void si_shader_apply_scratch_relocs(struct si_shader *shader,
-                                   uint64_t scratch_va)
+/* For the UMR disassembler. */
+#define DEBUGGER_END_OF_CODE_MARKER    0xbf9f0000 /* invalid instruction */
+#define DEBUGGER_NUM_MARKERS           5
+
+static bool si_shader_binary_open(struct si_screen *screen,
+                                 struct si_shader *shader,
+                                 struct ac_rtld_binary *rtld)
 {
-       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);
-               }
+       const struct si_shader_selector *sel = shader->selector;
+       enum pipe_shader_type shader_type = sel ? sel->type : PIPE_SHADER_COMPUTE;
+       const char *part_elfs[5];
+       size_t part_sizes[5];
+       unsigned num_parts = 0;
+
+#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++; \
        }
+
+       add_part(shader->prolog);
+       add_part(shader->previous_stage);
+       add_part(shader->prolog2);
+       add_part(shader);
+       add_part(shader->epilog);
+
+#undef add_part
+
+       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) {
+               /* We add this symbol even on LLVM <= 8 to ensure that
+                * shader->config.lds_size is set correctly below.
+                */
+               struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
+               sym->name = "esgs_ring";
+               sym->size = shader->gs_info.esgs_ring_size;
+               sym->align = 64 * 1024;
+       }
+
+       if (shader->key.as_ngg && sel->type == PIPE_SHADER_GEOMETRY) {
+               struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
+               sym->name = "ngg_emit";
+               sym->size = shader->ngg.ngg_emit_size * 4;
+               sym->align = 4;
+       }
+
+       bool ok = ac_rtld_open(rtld, (struct ac_rtld_open_info){
+                       .info = &screen->info,
+                       .options = {
+                               .halt_at_entry = screen->options.halt_shaders,
+                       },
+                       .shader_type = tgsi_processor_to_shader_stage(shader_type),
+                       .num_parts = num_parts,
+                       .elf_ptrs = part_elfs,
+                       .elf_sizes = part_sizes,
+                       .num_shared_lds_symbols = num_lds_symbols,
+                       .shared_lds_symbols = lds_symbols });
+
+       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;
+       }
+
+       return ok;
 }
 
-/* For the UMR disassembler. */
-#define DEBUGGER_END_OF_CODE_MARKER    0xbf9f0000 /* invalid instruction */
-#define DEBUGGER_NUM_MARKERS           5
+static unsigned si_get_shader_binary_size(struct si_screen *screen, struct si_shader *shader)
+{
+       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;
+       }
 
-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);
+       return false;
+}
+
+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);
-                               }
+       if (nbytes > INT_MAX)
+               goto out;
 
-                               if (!*p)
-                                       break;
-                               line = p + 1;
+       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 + line);
+
+                       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");
        }
+
+       if (file) {
+               fprintf(file, "Shader %s disassembly:\n", name);
+               fprintf(file, "%*s", (int)nbytes, disasm);
+       }
+
+out:
+       ac_rtld_close(&rtld_binary);
 }
 
 static void si_calculate_max_simd_waves(struct si_shader *shader)
@@ -5264,24 +5415,28 @@ static void si_calculate_max_simd_waves(struct si_shader *shader)
        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 ac_shader_config *conf = &shader->config;
 
+       if (screen->options.debug_disassembly)
+               si_shader_dump_disassembly(screen, &shader->binary, debug, "main", NULL);
+
        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,
                           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)
@@ -5311,7 +5466,7 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
                        conf->num_sgprs, conf->num_vgprs,
                        conf->spilled_sgprs, conf->spilled_vgprs,
                        shader->info.private_mem_vgprs,
-                       si_get_shader_binary_size(shader),
+                       si_get_shader_binary_size(sscreen, shader),
                        conf->lds_size, conf->scratch_bytes_per_wave,
                        shader->info.max_simd_waves);
        }
@@ -5327,6 +5482,8 @@ const char *si_get_shader_name(const struct si_shader *shader, unsigned processo
                        return "Vertex Shader as LS";
                else if (shader->key.opt.vs_as_prim_discard_cs)
                        return "Vertex Shader as Primitive Discard CS";
+               else if (shader->key.as_ngg)
+                       return "Vertex Shader as ESGS";
                else
                        return "Vertex Shader as VS";
        case PIPE_SHADER_TESS_CTRL:
@@ -5334,6 +5491,8 @@ const char *si_get_shader_name(const struct si_shader *shader, unsigned processo
        case PIPE_SHADER_TESS_EVAL:
                if (shader->key.as_es)
                        return "Tessellation Evaluation Shader as ES";
+               else if (shader->key.as_ngg)
+                       return "Tessellation Evaluation Shader as ESGS";
                else
                        return "Tessellation Evaluation Shader as VS";
        case PIPE_SHADER_GEOMETRY:
@@ -5350,7 +5509,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)
 {
@@ -5377,19 +5536,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");
        }
@@ -5399,7 +5558,7 @@ 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_binary *binary,
                           struct ac_shader_config *conf,
                           struct ac_llvm_compiler *compiler,
                           LLVMModuleRef mod,
@@ -5408,7 +5567,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)) {
@@ -5428,13 +5586,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;
        }
 
-       ac_shader_binary_read_config(binary, conf, 0, false);
+       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.
@@ -5450,24 +5619,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)
@@ -5490,7 +5642,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);
@@ -5599,22 +5751,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 {
@@ -5845,6 +6001,8 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
                        ctx->abi.emit_outputs = si_llvm_emit_es_epilogue;
                else if (shader->key.opt.vs_as_prim_discard_cs)
                        ctx->abi.emit_outputs = si_llvm_emit_prim_discard_cs_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;
@@ -5868,8 +6026,12 @@ 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
-                       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:
@@ -5903,6 +6065,40 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
        create_function(ctx);
        preload_ring_buffers(ctx);
 
+       if (ctx->type == PIPE_SHADER_TESS_CTRL &&
+           sel->tcs_info.tessfactors_are_def_in_all_invocs) {
+               for (unsigned i = 0; i < 6; i++) {
+                       ctx->invoc0_tess_factors[i] =
+                               ac_build_alloca_undef(&ctx->ac, ctx->i32, "");
+               }
+       }
+
+       if (ctx->type == PIPE_SHADER_GEOMETRY) {
+               for (unsigned i = 0; i < 4; i++) {
+                       ctx->gs_next_vertex[i] =
+                               ac_build_alloca(&ctx->ac, ctx->i32, "");
+               }
+               if (shader->key.as_ngg) {
+                       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);
+                       ctx->gs_ngg_scratch = LLVMAddGlobalInAddressSpace(ctx->ac.module,
+                               a8i32, "ngg_scratch", AC_ADDR_SPACE_LDS);
+                       LLVMSetInitializer(ctx->gs_ngg_scratch, LLVMGetUndef(a8i32));
+                       LLVMSetAlignment(ctx->gs_ngg_scratch, 4);
+
+                       ctx->gs_ngg_emit = LLVMAddGlobalInAddressSpace(ctx->ac.module,
+                               LLVMArrayType(ctx->i32, 0), "ngg_emit", AC_ADDR_SPACE_LDS);
+                       LLVMSetLinkage(ctx->gs_ngg_emit, LLVMExternalLinkage);
+                       LLVMSetAlignment(ctx->gs_ngg_emit, 4);
+               }
+       }
+
        /* For GFX9 merged shaders:
         * - Set EXEC for the first shader. If the prolog is present, set
         *   EXEC there instead.
@@ -5914,6 +6110,10 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
         *
         * For monolithic merged shaders, the first shader is wrapped in an
         * if-block together with its prolog in si_build_wrapper_function.
+        *
+        * NGG vertex and tess eval shaders running as the last
+        * vertex/geometry stage handle execution explicitly using
+        * if-statements.
         */
        if (ctx->screen->info.chip_class >= GFX9) {
                if (!shader->is_monolithic &&
@@ -5925,44 +6125,58 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
                        si_init_exec_from_input(ctx,
                                                ctx->param_merged_wave_info, 0);
                } else if (ctx->type == PIPE_SHADER_TESS_CTRL ||
-                          ctx->type == PIPE_SHADER_GEOMETRY) {
-                       if (!shader->is_monolithic)
+                          ctx->type == PIPE_SHADER_GEOMETRY ||
+                          shader->key.as_ngg) {
+                       LLVMValueRef num_threads;
+                       bool nested_barrier;
+
+                       if (!shader->is_monolithic ||
+                           (ctx->type == PIPE_SHADER_TESS_EVAL &&
+                            shader->key.as_ngg))
                                ac_init_exec_full_mask(&ctx->ac);
 
-                       LLVMValueRef num_threads = si_unpack_param(ctx, ctx->param_merged_wave_info, 8, 8);
+                       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);
+                       } else {
+                               /* Number of vertices */
+                               num_threads = si_unpack_param(ctx, ctx->param_merged_wave_info, 0, 8);
+                               nested_barrier = false;
+                       }
+
                        LLVMValueRef ena =
                                LLVMBuildICmp(ctx->ac.builder, LLVMIntULT,
                                            ac_get_thread_id(&ctx->ac), num_threads, "");
                        lp_build_if(&ctx->merged_wrap_if_state, &ctx->gallivm, ena);
 
-                       /* The barrier must execute for all shaders in a
-                        * threadgroup.
-                        *
-                        * Execute the barrier inside the conditional block,
-                        * so that empty waves can jump directly to s_endpgm,
-                        * which will also signal the barrier.
-                        *
-                        * If the shader is TCS and the TCS epilog is present
-                        * and contains a barrier, it will wait there and then
-                        * reach s_endpgm.
-                        */
-                       si_llvm_emit_barrier(NULL, bld_base, NULL);
-               }
-       }
-
-       if (ctx->type == PIPE_SHADER_TESS_CTRL &&
-           sel->tcs_info.tessfactors_are_def_in_all_invocs) {
-               for (unsigned i = 0; i < 6; i++) {
-                       ctx->invoc0_tess_factors[i] =
-                               ac_build_alloca_undef(&ctx->ac, ctx->i32, "");
-               }
-       }
-
-       if (ctx->type == PIPE_SHADER_GEOMETRY) {
-               int i;
-               for (i = 0; i < 4; i++) {
-                       ctx->gs_next_vertex[i] =
-                               ac_build_alloca(&ctx->ac, ctx->i32, "");
+                       if (nested_barrier) {
+                               /* Execute a barrier before the second shader in
+                                * a merged shader.
+                                *
+                                * Execute the barrier inside the conditional block,
+                                * so that empty waves can jump directly to s_endpgm,
+                                * which will also signal the barrier.
+                                *
+                                * This is possible in gfx9, because an empty wave
+                                * for the second shader does not participate in
+                                * the epilogue. With NGG, empty waves may still
+                                * be required to export data (e.g. GS output vertices),
+                                * so we cannot let them exit early.
+                                *
+                                * If the shader is TCS and the TCS epilog is present
+                                * and contains a barrier, it will wait there and then
+                                * reach s_endpgm.
+                                */
+                               si_llvm_emit_barrier(NULL, bld_base, NULL);
+                       }
                }
        }
 
@@ -6011,6 +6225,7 @@ static void si_get_vs_prolog_key(const struct tgsi_shader_info *info,
        key->vs_prolog.last_input = MAX2(1, info->num_inputs) - 1;
        key->vs_prolog.as_ls = shader_out->key.as_ls;
        key->vs_prolog.as_es = shader_out->key.as_es;
+       key->vs_prolog.as_ngg = shader_out->key.as_ngg;
 
        if (shader_out->selector->type == PIPE_SHADER_TESS_CTRL) {
                key->vs_prolog.as_ls = 1;
@@ -6018,6 +6233,8 @@ static void si_get_vs_prolog_key(const struct tgsi_shader_info *info,
        } else if (shader_out->selector->type == PIPE_SHADER_GEOMETRY) {
                key->vs_prolog.as_es = 1;
                key->vs_prolog.num_merged_next_stage_vgprs = 5;
+       } else if (shader_out->key.as_ngg) {
+               key->vs_prolog.num_merged_next_stage_vgprs = 5;
        }
 
        /* Enable loading the InstanceID VGPR. */
@@ -6060,7 +6277,8 @@ static void si_get_ps_prolog_key(struct si_shader *shader,
                        /* BCOLORs are stored after the last input. */
                        key->ps_prolog.num_interp_inputs = info->num_inputs;
                        key->ps_prolog.face_vgpr_index = shader->info.face_vgpr_index;
-                       shader->config.spi_ps_input_ena |= S_0286CC_FRONT_FACE_ENA(1);
+                       if (separate_prolog)
+                               shader->config.spi_ps_input_ena |= S_0286CC_FRONT_FACE_ENA(1);
                }
 
                for (unsigned i = 0; i < 2; i++) {
@@ -6091,18 +6309,24 @@ static void si_get_ps_prolog_key(struct si_shader *shader,
                                switch (location) {
                                case TGSI_INTERPOLATE_LOC_SAMPLE:
                                        key->ps_prolog.color_interp_vgpr_index[i] = 0;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_PERSP_SAMPLE_ENA(1);
+                                       if (separate_prolog) {
+                                               shader->config.spi_ps_input_ena |=
+                                                       S_0286CC_PERSP_SAMPLE_ENA(1);
+                                       }
                                        break;
                                case TGSI_INTERPOLATE_LOC_CENTER:
                                        key->ps_prolog.color_interp_vgpr_index[i] = 2;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_PERSP_CENTER_ENA(1);
+                                       if (separate_prolog) {
+                                               shader->config.spi_ps_input_ena |=
+                                                       S_0286CC_PERSP_CENTER_ENA(1);
+                                       }
                                        break;
                                case TGSI_INTERPOLATE_LOC_CENTROID:
                                        key->ps_prolog.color_interp_vgpr_index[i] = 4;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_PERSP_CENTROID_ENA(1);
+                                       if (separate_prolog) {
+                                               shader->config.spi_ps_input_ena |=
+                                                       S_0286CC_PERSP_CENTROID_ENA(1);
+                                       }
                                        break;
                                default:
                                        assert(0);
@@ -6123,20 +6347,26 @@ static void si_get_ps_prolog_key(struct si_shader *shader,
                                case TGSI_INTERPOLATE_LOC_SAMPLE:
                                        key->ps_prolog.color_interp_vgpr_index[i] =
                                                separate_prolog ? 6 : 9;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_LINEAR_SAMPLE_ENA(1);
+                                       if (separate_prolog) {
+                                               shader->config.spi_ps_input_ena |=
+                                                       S_0286CC_LINEAR_SAMPLE_ENA(1);
+                                       }
                                        break;
                                case TGSI_INTERPOLATE_LOC_CENTER:
                                        key->ps_prolog.color_interp_vgpr_index[i] =
                                                separate_prolog ? 8 : 11;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_LINEAR_CENTER_ENA(1);
+                                       if (separate_prolog) {
+                                               shader->config.spi_ps_input_ena |=
+                                                       S_0286CC_LINEAR_CENTER_ENA(1);
+                                       }
                                        break;
                                case TGSI_INTERPOLATE_LOC_CENTROID:
                                        key->ps_prolog.color_interp_vgpr_index[i] =
                                                separate_prolog ? 10 : 13;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_LINEAR_CENTROID_ENA(1);
+                                       if (separate_prolog) {
+                                               shader->config.spi_ps_input_ena |=
+                                                       S_0286CC_LINEAR_CENTROID_ENA(1);
+                                       }
                                        break;
                                default:
                                        assert(0);
@@ -6456,7 +6686,7 @@ static void si_build_wrapper_function(struct si_shader_context *ctx,
 
                /* Merged shaders are executed conditionally depending
                 * on the number of enabled threads passed in the input SGPRs. */
-               if (is_merged_shader(ctx) && part == 0) {
+               if (is_multi_part_shader(ctx) && part == 0) {
                        LLVMValueRef ena, count = initial[3];
 
                        count = LLVMBuildAnd(builder, count,
@@ -6516,9 +6746,9 @@ static void si_build_wrapper_function(struct si_shader_context *ctx,
                        out_idx += param_size;
                }
 
-               ret = LLVMBuildCall(builder, parts[part], in, num_params, "");
+               ret = ac_build_call(&ctx->ac, parts[part], in, num_params);
 
-               if (is_merged_shader(ctx) &&
+               if (is_multi_part_shader(ctx) &&
                    part + 1 == next_shader_first_part) {
                        lp_build_endif(&if_state);
 
@@ -6908,7 +7138,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;
 }
 
@@ -6964,6 +7194,7 @@ si_get_shader_part(struct si_screen *sscreen,
        case PIPE_SHADER_VERTEX:
                shader.key.as_ls = key->vs_prolog.as_ls;
                shader.key.as_es = key->vs_prolog.as_es;
+               shader.key.as_ngg = key->vs_prolog.as_ngg;
                break;
        case PIPE_SHADER_TESS_CTRL:
                assert(!prolog);
@@ -7096,7 +7327,10 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
        }
 
        unsigned vertex_id_vgpr = first_vs_vgpr;
-       unsigned instance_id_vgpr = first_vs_vgpr + (key->vs_prolog.as_ls ? 2 : 1);
+       unsigned instance_id_vgpr =
+               ctx->screen->info.chip_class >= GFX10 ?
+                       first_vs_vgpr + 3 :
+                       first_vs_vgpr + (key->vs_prolog.as_ls ? 2 : 1);
 
        ctx->abi.vertex_id = input_vgprs[vertex_id_vgpr];
        ctx->abi.instance_id = input_vgprs[instance_id_vgpr];
@@ -7132,6 +7366,21 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
                                           key->vs_prolog.num_input_sgprs + i, "");
        }
 
+       struct lp_build_if_state wrap_if_state;
+       LLVMValueRef original_ret = ret;
+       bool wrapped = false;
+
+       if (key->vs_prolog.is_monolithic && key->vs_prolog.as_ngg) {
+               LLVMValueRef num_threads;
+               LLVMValueRef ena;
+
+               num_threads = si_unpack_param(ctx, 3, 0, 8);
+               ena = LLVMBuildICmp(ctx->ac.builder, LLVMIntULT,
+                                       ac_get_thread_id(&ctx->ac), num_threads, "");
+               lp_build_if(&wrap_if_state, &ctx->gallivm, ena);
+               wrapped = true;
+       }
+
        /* Compute vertex load indices from instance divisors. */
        LLVMValueRef instance_divisor_constbuf = NULL;
 
@@ -7187,6 +7436,20 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
                                           fninfo.num_params + i, "");
        }
 
+       if (wrapped) {
+               lp_build_endif(&wrap_if_state);
+
+               LLVMValueRef values[2] = {
+                       ret,
+                       original_ret
+               };
+               LLVMBasicBlockRef bbs[2] = {
+                       wrap_if_state.true_block,
+                       wrap_if_state.entry_block
+               };
+               ret = ac_build_phi(&ctx->ac, LLVMTypeOf(ret), 2, values, bbs);
+       }
+
        si_llvm_build_ret(ctx, ret);
 }
 
@@ -7881,7 +8144,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)
 {
@@ -7892,6 +8155,9 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
        /* LS, ES, VS are compiled on demand if the main part hasn't been
         * compiled for that stage.
         *
+        * GS are compiled on demand if the main part hasn't been compiled
+        * for the chosen NGG-ness.
+        *
         * Vertex shaders are compiled on demand when a vertex fetch
         * workaround must be applied.
         */
@@ -7901,7 +8167,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:
                 *
@@ -7919,7 +8185,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;
@@ -7940,21 +8206,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.
@@ -8006,18 +8272,24 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                si_calculate_max_simd_waves(shader);
        }
 
+       if (shader->key.as_ngg) {
+               assert(!shader->key.as_es && !shader->key.as_ls);
+               gfx10_ngg_calculate_subgroup_info(shader);
+       } else if (sscreen->info.chip_class >= GFX9 && sel->type == PIPE_SHADER_GEOMETRY) {
+               gfx9_get_gs_info(shader->previous_stage_sel, sel, &shader->gs_info);
+       }
+
        si_fix_resource_usage(sscreen, shader);
        si_shader_dump(sscreen, shader, debug, sel->info.processor,
                       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)
@@ -8028,7 +8300,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);
 }