radeonsi: implement uniform buffer objects
authorMarek Olšák <marek.olsak@amd.com>
Fri, 25 Oct 2013 09:45:47 +0000 (11:45 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 4 Nov 2013 18:07:57 +0000 (19:07 +0100)
src/gallium/drivers/radeonsi/radeonsi_pipe.c
src/gallium/drivers/radeonsi/radeonsi_shader.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h

index 6da4c5ebb5340fb65a27009bf1fe62494b1c5e92..f4d323310d8864e3984eb1efd06092265f945d65 100644 (file)
@@ -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:
index dff8be0f0e54d5293b527194399ce8e25d2bbfb9..352ff194cb291192cb8b412e013ff9c8f0acff61 100644 (file)
@@ -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);
 
index d23b28ab4000db81636c49398224446d6c7a6553..f6400d8c51a87e5e6a6f5694fc580bc70888dba5 100644 (file)
@@ -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);
index afd0388162ae1b3d558c5581d5e234e04102f2bc..f3d402348e394fde77c2cd394f44736500b0456e 100644 (file)
@@ -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.