It's a pseudo-code that would be inserted at the beginning of the shader by the shader compiler. gl_SamplePos is always read-only from a user's point of view.
Marek On Wed, May 7, 2014 at 6:02 PM, Ilia Mirkin <imir...@alum.mit.edu> wrote: > On Wed, May 7, 2014 at 11:56 AM, Marek Olšák <mar...@gmail.com> wrote: >> I could enable interpolation of gl_FragCoord at the sample instead of >> centroid and do: >> >> gl_SamplePos = fract(gl_FragCoord.xy); > > Is that legal? I didn't think that sample position could be an output, > at least not with ARB_sample_shading (and not even with > ARB_gpu_shader5). Perhaps some other extension adds it. > >> 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