Mesa (master): radeonsi: implement uniform buffer objects

Marek Olšák mareko at kemper.freedesktop.org
Mon Nov 4 18:11:06 UTC 2013


Module: Mesa
Branch: master
Commit: 2fd42001231b70ba1764b1455d642037d2d5fff5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2fd42001231b70ba1764b1455d642037d2d5fff5

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Fri Oct 25 11:45:47 2013 +0200

radeonsi: implement uniform buffer objects

---

 src/gallium/drivers/radeonsi/radeonsi_pipe.c   |    2 +-
 src/gallium/drivers/radeonsi/radeonsi_shader.c |   65 +++++++++++++----------
 src/gallium/drivers/radeonsi/si_state.c        |    2 +-
 src/gallium/drivers/radeonsi/si_state.h        |    3 +-
 4 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index 6da4c5e..f4d3233 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -444,7 +444,7 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
 	case PIPE_SHADER_CAP_MAX_CONSTS:
 		return 4096; /* actually only memory limits this */
 	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
-		return 1;
+		return NUM_PIPE_CONST_BUFFERS;
 	case PIPE_SHADER_CAP_MAX_PREDS:
 		return 0; /* FIXME */
 	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index dff8be0..352ff19 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -66,11 +66,11 @@ struct si_shader_context
 	int param_vertex_id;
 	int param_instance_id;
 	LLVMValueRef const_md;
-	LLVMValueRef const_resource;
+	LLVMValueRef const_resource[NUM_CONST_BUFFERS];
 #if HAVE_LLVM >= 0x0304
 	LLVMValueRef ddxy_lds;
 #endif
-	LLVMValueRef *constants;
+	LLVMValueRef *constants[NUM_CONST_BUFFERS];
 	LLVMValueRef *resources;
 	LLVMValueRef *samplers;
 	LLVMValueRef so_buffers[4];
@@ -444,7 +444,7 @@ static LLVMValueRef fetch_constant(
 	struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
 	struct lp_build_context * base = &bld_base->base;
 	const struct tgsi_ind_register *ireg = &reg->Indirect;
-	unsigned idx;
+	unsigned buf, idx;
 
 	LLVMValueRef args[2];
 	LLVMValueRef addr;
@@ -459,11 +459,13 @@ static LLVMValueRef fetch_constant(
 		return lp_build_gather_values(bld_base->base.gallivm, values, 4);
 	}
 
+	buf = reg->Register.Dimension ? reg->Dimension.Index : 0;
 	idx = reg->Register.Index * 4 + swizzle;
+
 	if (!reg->Register.Indirect)
-		return bitcast(bld_base, type, si_shader_ctx->constants[idx]);
+		return bitcast(bld_base, type, si_shader_ctx->constants[buf][idx]);
 
-	args[0] = si_shader_ctx->const_resource;
+	args[0] = si_shader_ctx->const_resource[buf];
 	args[1] = lp_build_const_int32(base->gallivm, idx * 4);
 	addr = si_shader_ctx->radeon_bld.soa.addr[ireg->Index][ireg->Swizzle];
 	addr = LLVMBuildLoad(base->gallivm->builder, addr, "load addr reg");
@@ -624,7 +626,8 @@ static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
 	LLVMValueRef out_elts[4];
 	LLVMValueRef base_elt;
 	LLVMValueRef ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST);
-	LLVMValueRef const_resource = build_indexed_load(si_shader_ctx, ptr, uint->one);
+	LLVMValueRef constbuf_index = lp_build_const_int32(base->gallivm, NUM_PIPE_CONST_BUFFERS);
+	LLVMValueRef const_resource = build_indexed_load(si_shader_ctx, ptr, constbuf_index);
 
 	for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
 		LLVMValueRef out_ptr = si_shader_ctx->radeon_bld.soa.outputs[index][chan];
@@ -1701,29 +1704,33 @@ static void preload_constants(struct si_shader_context *si_shader_ctx)
 	struct lp_build_tgsi_context * bld_base = &si_shader_ctx->radeon_bld.soa.bld_base;
 	struct gallivm_state * gallivm = bld_base->base.gallivm;
 	const struct tgsi_shader_info * info = bld_base->info;
+	unsigned buf;
+	LLVMValueRef ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST);
 
-	unsigned i, num_const = info->file_max[TGSI_FILE_CONSTANT] + 1;
-
-	LLVMValueRef ptr;
+	for (buf = 0; buf < NUM_CONST_BUFFERS; buf++) {
+		unsigned i, num_const = info->const_file_max[buf] + 1;
 
-	if (num_const == 0)
-		return;
+		if (num_const == 0)
+			continue;
 
-	/* Allocate space for the constant values */
-	si_shader_ctx->constants = CALLOC(num_const * 4, sizeof(LLVMValueRef));
-
-	/* Load the resource descriptor */
-	ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST);
-	si_shader_ctx->const_resource = build_indexed_load(si_shader_ctx, ptr, bld_base->uint_bld.zero);
-
-	/* Load the constants, we rely on the code sinking to do the rest */
-	for (i = 0; i < num_const * 4; ++i) {
-		LLVMValueRef args[2] = {
-			si_shader_ctx->const_resource,
-			lp_build_const_int32(gallivm, i * 4)
-		};
-		si_shader_ctx->constants[i] = build_intrinsic(gallivm->builder, "llvm.SI.load.const",
-			bld_base->base.elem_type, args, 2, LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
+		/* Allocate space for the constant values */
+		si_shader_ctx->constants[buf] = CALLOC(num_const * 4, sizeof(LLVMValueRef));
+
+		/* Load the resource descriptor */
+		si_shader_ctx->const_resource[buf] =
+			build_indexed_load(si_shader_ctx, ptr, lp_build_const_int32(gallivm, buf));
+
+		/* Load the constants, we rely on the code sinking to do the rest */
+		for (i = 0; i < num_const * 4; ++i) {
+			LLVMValueRef args[2] = {
+				si_shader_ctx->const_resource[buf],
+				lp_build_const_int32(gallivm, i * 4)
+			};
+			si_shader_ctx->constants[buf][i] =
+					build_intrinsic(gallivm->builder, "llvm.SI.load.const",
+							bld_base->base.elem_type, args, 2,
+							LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
+		}
 	}
 }
 
@@ -1931,7 +1938,8 @@ int si_pipe_shader_create(
 
 	if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) {
 		fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n");
-		FREE(si_shader_ctx.constants);
+		for (int i = 0; i < NUM_CONST_BUFFERS; i++)
+			FREE(si_shader_ctx.constants[i]);
 		FREE(si_shader_ctx.resources);
 		FREE(si_shader_ctx.samplers);
 		return -EINVAL;
@@ -1945,7 +1953,8 @@ int si_pipe_shader_create(
 	radeon_llvm_dispose(&si_shader_ctx.radeon_bld);
 	tgsi_parse_free(&si_shader_ctx.parse);
 
-	FREE(si_shader_ctx.constants);
+	for (int i = 0; i < NUM_CONST_BUFFERS; i++)
+		FREE(si_shader_ctx.constants[i]);
 	FREE(si_shader_ctx.resources);
 	FREE(si_shader_ctx.samplers);
 
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d23b28a..f6400d8 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -377,7 +377,7 @@ static void si_set_clip_state(struct pipe_context *ctx,
 	cb.user_buffer = state->ucp;
 	cb.buffer_offset = 0;
 	cb.buffer_size = 4*4*8;
-	ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
+	ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, NUM_PIPE_CONST_BUFFERS, &cb);
 	pipe_resource_reference(&cb.buffer, NULL);
 
 	si_pm4_set_state(rctx, clip, pm4);
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index afd0388..f3d4023 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -110,7 +110,8 @@ union si_state {
 #define NUM_SAMPLER_VIEWS	(FMASK_TEX_OFFSET+NUM_TEX_UNITS)
 #define NUM_SAMPLER_STATES	NUM_TEX_UNITS
 
-#define NUM_CONST_BUFFERS 2
+#define NUM_PIPE_CONST_BUFFERS 16
+#define NUM_CONST_BUFFERS 17
 
 /* This represents resource descriptors in memory, such as buffer resources,
  * image resources, and sampler states.




More information about the mesa-commit mailing list