On Wed, May 7, 2014 at 10:00 AM, Marek Olšák <mar...@gmail.com> wrote: > From: Marek Olšák <marek.ol...@amd.com> > > The sample positions are read from a constant buffer.
FWIW I had to do the same thing in both nv50 and nvc0. I had proposed that this should actually be done directly by the state tracker, but I think claims were made to the effect that there might be hw which can look up the positions directly. I figured radeon was such hw, but I guess not. Anyways, seems like a nice refactor would be to have mesa/st (or mesa/main) supply the constbufs and rip out the extra logic from nv50/nvc0/radeonsi. [Certainly don't have to do it now, esp now that you've done it this way.] The sample count is already handled this way by mesa core. -ilia > --- > src/gallium/drivers/radeon/cayman_msaa.c | 17 +++++++++++++++++ > src/gallium/drivers/radeon/r600_pipe_common.c | 1 + > src/gallium/drivers/radeon/r600_pipe_common.h | 10 ++++++++++ > src/gallium/drivers/radeonsi/si_shader.c | 23 +++++++++++++++++++++++ > src/gallium/drivers/radeonsi/si_state.c | 25 +++++++++++++++++++++++++ > 5 files changed, 76 insertions(+) > > diff --git a/src/gallium/drivers/radeon/cayman_msaa.c > b/src/gallium/drivers/radeon/cayman_msaa.c > index 8727f3e..47fc5c4 100644 > --- a/src/gallium/drivers/radeon/cayman_msaa.c > +++ b/src/gallium/drivers/radeon/cayman_msaa.c > @@ -123,6 +123,23 @@ void cayman_get_sample_position(struct pipe_context > *ctx, unsigned sample_count, > } > } > > +void cayman_init_msaa(struct pipe_context *ctx) > +{ > + struct r600_common_context *rctx = (struct r600_common_context*)ctx; > + int i; > + > + cayman_get_sample_position(ctx, 1, 0, rctx->sample_locations_1x[0]); > + > + for (i = 0; i < 2; i++) > + cayman_get_sample_position(ctx, 2, i, > rctx->sample_locations_2x[i]); > + for (i = 0; i < 4; i++) > + cayman_get_sample_position(ctx, 4, i, > rctx->sample_locations_4x[i]); > + for (i = 0; i < 8; i++) > + cayman_get_sample_position(ctx, 8, i, > rctx->sample_locations_8x[i]); > + for (i = 0; i < 16; i++) > + cayman_get_sample_position(ctx, 16, i, > rctx->sample_locations_16x[i]); > +} > + > void cayman_emit_msaa_sample_locs(struct radeon_winsys_cs *cs, int > nr_samples) > { > switch (nr_samples) { > diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c > b/src/gallium/drivers/radeon/r600_pipe_common.c > index 70c4d1a..4c6cf0e 100644 > --- a/src/gallium/drivers/radeon/r600_pipe_common.c > +++ b/src/gallium/drivers/radeon/r600_pipe_common.c > @@ -154,6 +154,7 @@ bool r600_common_context_init(struct r600_common_context > *rctx, > r600_init_context_texture_functions(rctx); > r600_streamout_init(rctx); > r600_query_init(rctx); > + cayman_init_msaa(&rctx->b); > > rctx->allocator_so_filled_size = u_suballocator_create(&rctx->b, > 4096, 4, > 0, > PIPE_USAGE_DEFAULT, TRUE); > diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h > b/src/gallium/drivers/radeon/r600_pipe_common.h > index 4c3e9ce..8862d31 100644 > --- a/src/gallium/drivers/radeon/r600_pipe_common.h > +++ b/src/gallium/drivers/radeon/r600_pipe_common.h > @@ -357,6 +357,15 @@ struct r600_common_context { > boolean saved_render_cond_cond; > unsigned saved_render_cond_mode; > > + /* MSAA sample locations. > + * The first index is the sample index. > + * The second index is the coordinate: X, Y. */ > + float sample_locations_1x[1][2]; > + float sample_locations_2x[2][2]; > + float sample_locations_4x[4][2]; > + float sample_locations_8x[8][2]; > + float sample_locations_16x[16][2]; > + > /* Copy one resource to another using async DMA. */ > void (*dma_copy)(struct pipe_context *ctx, > struct pipe_resource *dst, > @@ -472,6 +481,7 @@ extern const uint32_t eg_sample_locs_4x[4]; > extern const unsigned eg_max_dist_4x; > void cayman_get_sample_position(struct pipe_context *ctx, unsigned > sample_count, > unsigned sample_index, float *out_value); > +void cayman_init_msaa(struct pipe_context *ctx); > void cayman_emit_msaa_sample_locs(struct radeon_winsys_cs *cs, int > nr_samples); > void cayman_emit_msaa_config(struct radeon_winsys_cs *cs, int nr_samples, > int ps_iter_samples); > diff --git a/src/gallium/drivers/radeonsi/si_shader.c > b/src/gallium/drivers/radeonsi/si_shader.c > index 0195e54..d8b7b9c 100644 > --- a/src/gallium/drivers/radeonsi/si_shader.c > +++ b/src/gallium/drivers/radeonsi/si_shader.c > @@ -559,6 +559,8 @@ static void declare_system_value( > { > struct si_shader_context *si_shader_ctx = > si_shader_context(&radeon_bld->soa.bld_base); > + struct lp_build_context *uint_bld = > &radeon_bld->soa.bld_base.uint_bld; > + struct gallivm_state *gallivm = &radeon_bld->gallivm; > LLVMValueRef value = 0; > > switch (decl->Semantic.Name) { > @@ -576,6 +578,27 @@ static void declare_system_value( > value = get_sample_id(radeon_bld); > break; > > + case TGSI_SEMANTIC_SAMPLEPOS: > + { > + LLVMBuilderRef builder = gallivm->builder; > + LLVMValueRef desc = > LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST); > + LLVMValueRef buf_index = lp_build_const_int32(gallivm, > NUM_PIPE_CONST_BUFFERS); > + LLVMValueRef resource = build_indexed_load(si_shader_ctx, > desc, buf_index); > + > + /* offset = sample_id * 8 (8 = 2 floats containing > samplepos.xy) */ > + LLVMValueRef offset0 = lp_build_mul_imm(uint_bld, > get_sample_id(radeon_bld), 8); > + LLVMValueRef offset1 = LLVMBuildAdd(builder, offset0, > lp_build_const_int32(gallivm, 4), ""); > + > + LLVMValueRef pos[4] = { > + load_const(builder, resource, offset0, > radeon_bld->soa.bld_base.base.elem_type), > + load_const(builder, resource, offset1, > radeon_bld->soa.bld_base.base.elem_type), > + lp_build_const_float(gallivm, 0), > + lp_build_const_float(gallivm, 0) > + }; > + value = lp_build_gather_values(gallivm, pos, 4); > + break; > + } > + > default: > assert(!"unknown system value"); > return; > diff --git a/src/gallium/drivers/radeonsi/si_state.c > b/src/gallium/drivers/radeonsi/si_state.c > index fd9de05..3c1af06 100644 > --- a/src/gallium/drivers/radeonsi/si_state.c > +++ b/src/gallium/drivers/radeonsi/si_state.c > @@ -1859,6 +1859,7 @@ static void si_set_framebuffer_state(struct > pipe_context *ctx, > const struct pipe_framebuffer_state > *state) > { > struct si_context *sctx = (struct si_context *)ctx; > + struct pipe_constant_buffer constbuf = {0}; > struct r600_surface *surf = NULL; > struct r600_texture *rtex; > int i; > @@ -1924,6 +1925,30 @@ static void si_set_framebuffer_state(struct > pipe_context *ctx, > sctx->framebuffer.atom.num_dw += 18; /* MSAA sample locations */ > sctx->framebuffer.atom.dirty = true; > sctx->msaa_config.dirty = true; > + > + /* Set sample locations as fragment shader constants. */ > + switch (sctx->framebuffer.nr_samples) { > + case 1: > + constbuf.user_buffer = sctx->b.sample_locations_1x; > + break; > + case 2: > + constbuf.user_buffer = sctx->b.sample_locations_2x; > + break; > + case 4: > + constbuf.user_buffer = sctx->b.sample_locations_4x; > + break; > + case 8: > + constbuf.user_buffer = sctx->b.sample_locations_8x; > + break; > + case 16: > + constbuf.user_buffer = sctx->b.sample_locations_16x; > + break; > + default: > + assert(0); > + } > + constbuf.buffer_size = sctx->framebuffer.nr_samples * 2 * 4; > + ctx->set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, > + NUM_PIPE_CONST_BUFFERS, &constbuf); > } > > static void si_emit_framebuffer_state(struct si_context *sctx, struct > r600_atom *atom) > -- > 1.9.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev