[Mesa-dev] [PATCH 08/29] radv/ac: start setting up the geom shader rings (v2)

Dave Airlie airlied at gmail.com
Mon Jan 30 06:02:42 UTC 2017


From: Dave Airlie <airlied at redhat.com>

This sets up the rings and adds the variables
needed to make them work.

v2: rework for sharing ring and scratch
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/amd/common/ac_nir_to_llvm.c | 63 +++++++++++++++++++++++++++++++++++++++--
 src/amd/common/ac_nir_to_llvm.h |  3 +-
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 976984f..d8e5c82 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -72,6 +72,7 @@ struct nir_to_llvm_context {
 	struct hash_table *phis;
 
 	LLVMValueRef descriptor_sets[AC_UD_MAX_SETS];
+	LLVMValueRef ring_offsets;
 	LLVMValueRef push_constants;
 	LLVMValueRef num_work_groups;
 	LLVMValueRef workgroup_ids;
@@ -93,6 +94,9 @@ struct nir_to_llvm_context {
 	LLVMValueRef gs_vtx_offset[6];
 	LLVMValueRef gs_prim_id, gs_invocation_id;
 
+	LLVMValueRef esgs_ring;
+	LLVMValueRef gsvs_ring;
+
 	LLVMValueRef prim_mask;
 	LLVMValueRef sample_positions;
 	LLVMValueRef persp_sample, persp_center, persp_centroid;
@@ -146,6 +150,10 @@ struct nir_to_llvm_context {
 	unsigned num_culls;
 
 	bool has_ds_bpermute;
+
+	bool is_gs_copy_shader;
+	LLVMValueRef gs_next_vertex;
+	unsigned gs_max_out_vertices;
 };
 
 struct ac_tex_info {
@@ -400,6 +408,13 @@ static void create_function(struct nir_to_llvm_context *ctx)
 	unsigned num_sets = ctx->options->layout ? ctx->options->layout->num_sets : 0;
 	unsigned user_sgpr_idx;
 	bool need_push_constants;
+	bool need_ring_offsets = false;
+
+	/* until we sort out scratch/global buffers always assign ring offsets for gs/vs/es */
+	if (ctx->stage == MESA_SHADER_GEOMETRY ||
+	    ctx->stage == MESA_SHADER_VERTEX ||
+	    ctx->is_gs_copy_shader)
+		need_ring_offsets = true;
 
 	need_push_constants = true;
 	if (!ctx->options->layout)
@@ -408,6 +423,10 @@ static void create_function(struct nir_to_llvm_context *ctx)
 		 !ctx->options->layout->dynamic_offset_count)
 		need_push_constants = false;
 
+	if (need_ring_offsets && !ctx->options->supports_spill) {
+		arg_types[arg_idx++] = const_array(ctx->v16i8, 8); /* address of rings */
+	}
+
 	/* 1 for each descriptor set */
 	for (unsigned i = 0; i < num_sets; ++i) {
 		if (ctx->options->layout->set[i].layout->shader_stages & (1 << ctx->stage)) {
@@ -507,9 +526,17 @@ static void create_function(struct nir_to_llvm_context *ctx)
 	arg_idx = 0;
 	user_sgpr_idx = 0;
 
-	if (ctx->options->supports_spill) {
-		set_userdata_location_shader(ctx, AC_UD_SCRATCH, user_sgpr_idx, 2);
+	if (ctx->options->supports_spill || need_ring_offsets) {
+		set_userdata_location_shader(ctx, AC_UD_SCRATCH_RING_OFFSETS, user_sgpr_idx, 2);
 		user_sgpr_idx += 2;
+		if (ctx->options->supports_spill) {
+			ctx->ring_offsets = ac_emit_llvm_intrinsic(&ctx->ac, "llvm.amdgcn.implicit.buffer.ptr",
+								   LLVMPointerType(ctx->i8, CONST_ADDR_SPACE),
+								   NULL, 0, AC_FUNC_ATTR_READNONE);
+			ctx->ring_offsets = LLVMBuildBitCast(ctx->builder, ctx->ring_offsets,
+							     const_array(ctx->v16i8, 8), "");
+		} else
+			ctx->ring_offsets = LLVMGetParam(ctx->main_function, arg_idx++);
 	}
 
 	for (unsigned i = 0; i < num_sets; ++i) {
@@ -4464,6 +4491,32 @@ static void ac_llvm_finalize_module(struct nir_to_llvm_context * ctx)
 	LLVMDisposePassManager(passmgr);
 }
 
+static void
+ac_setup_rings(struct nir_to_llvm_context *ctx)
+{
+	if (ctx->stage == MESA_SHADER_VERTEX && ctx->options->key.vs.as_es) {
+		ctx->esgs_ring = build_indexed_load_const(ctx, ctx->ring_offsets, ctx->i32one);
+	}
+
+	if (ctx->is_gs_copy_shader) {
+		ctx->gsvs_ring = build_indexed_load_const(ctx, ctx->ring_offsets, LLVMConstInt(ctx->i32, 3, false));
+	}
+	if (ctx->stage == MESA_SHADER_GEOMETRY) {
+		LLVMValueRef tmp;
+		ctx->esgs_ring = build_indexed_load_const(ctx, ctx->ring_offsets, LLVMConstInt(ctx->i32, 2, false));
+		ctx->gsvs_ring = build_indexed_load_const(ctx, ctx->ring_offsets, LLVMConstInt(ctx->i32, 4, false));
+
+		ctx->gsvs_ring = LLVMBuildBitCast(ctx->builder, ctx->gsvs_ring, ctx->v4i32, "");
+
+		ctx->gsvs_ring = LLVMBuildInsertElement(ctx->builder, ctx->gsvs_ring, ctx->gsvs_num_entries, LLVMConstInt(ctx->i32, 2, false), "");
+		tmp = LLVMBuildExtractElement(ctx->builder, ctx->gsvs_ring, ctx->i32one, "");
+		tmp = LLVMBuildOr(ctx->builder, tmp, ctx->gsvs_ring_stride, "");
+		ctx->gsvs_ring = LLVMBuildInsertElement(ctx->builder, ctx->gsvs_ring, tmp, ctx->i32one, "");
+
+		ctx->gsvs_ring = LLVMBuildBitCast(ctx->builder, ctx->gsvs_ring, ctx->v16i8, "");
+	}
+}
+
 static
 LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
                                        struct nir_shader *nir,
@@ -4521,8 +4574,14 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
 			LLVMSetAlignment(var, 4);
 			ctx.shared_memory = LLVMBuildBitCast(ctx.builder, var, i8p, "");
 		}
+	} else if (nir->stage == MESA_SHADER_GEOMETRY) {
+		ctx.gs_next_vertex = ac_build_alloca(&ctx, ctx.i32, "gs_next_vertex");
+
+		ctx.gs_max_out_vertices = nir->info->gs.vertices_out;
 	}
 
+	ac_setup_rings(&ctx);
+
 	nir_foreach_variable(variable, &nir->inputs)
 		handle_shader_input_decl(&ctx, variable);
 
diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h
index 089cfe1..c457cea 100644
--- a/src/amd/common/ac_nir_to_llvm.h
+++ b/src/amd/common/ac_nir_to_llvm.h
@@ -36,6 +36,7 @@ struct radv_pipeline_layout;
 
 struct ac_vs_variant_key {
 	uint32_t instance_rate_inputs;
+	uint32_t as_es:1;
 };
 
 struct ac_fs_variant_key {
@@ -65,7 +66,7 @@ struct ac_userdata_info {
 };
 
 enum ac_ud_index {
-	AC_UD_SCRATCH = 0,
+	AC_UD_SCRATCH_RING_OFFSETS = 0,
 	AC_UD_PUSH_CONSTANTS = 1,
 	AC_UD_SHADER_START = 2,
 	AC_UD_VS_VERTEX_BUFFERS = AC_UD_SHADER_START,
-- 
2.9.3



More information about the mesa-dev mailing list