I could enable interpolation of gl_FragCoord at the sample instead of centroid and do:
gl_SamplePos = fract(gl_FragCoord.xy); gl_FragCoord.xy = floor(gl_FragCoord.xy) + vec2(0.5); // center However, I wouldn't be able to get gl_FragCoord at the centroid. I'm also not sure how gl_FragCoord should be interpolated if sample shading is enabled. Marek On Wed, May 7, 2014 at 5:00 PM, Ilia Mirkin <imir...@alum.mit.edu> wrote: > 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