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