From: Marek Olšák Date: Fri, 25 Oct 2013 09:45:47 +0000 (+0200) Subject: radeonsi: implement uniform buffer objects X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2fd42001231b70ba1764b1455d642037d2d5fff5;p=mesa.git radeonsi: implement uniform buffer objects --- diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c index 6da4c5ebb53..f4d323310d8 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 dff8be0f0e5..352ff194cb2 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 = ®->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 d23b28ab400..f6400d8c51a 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 afd0388162a..f3d402348e3 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.