summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/radeonsi
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2014-05-06 18:20:58 +0200
committerMarek Olšák <marek.olsak@amd.com>2014-06-02 12:58:22 +0200
commit99d9d7c0d69c076d84334892ee12f921fe243319 (patch)
tree4fec2ba3be5f6470af9dbe3fb2099de66ee6eaab /src/gallium/drivers/radeonsi
parent5b06fc376df8ac4e63603d1768cd0dccc9e4b491 (diff)
radeonsi: implement SAMPLEPOS fragment shader input
The sample positions are read from a constant buffer.
Diffstat (limited to 'src/gallium/drivers/radeonsi')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c23
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c25
2 files changed, 48 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index d021caaa6c4..6818106ece7 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -557,6 +557,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) {
@@ -574,6 +576,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 c08d7034c55..b85a4594156 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)