radeonsi: implement SAMPLEPOS fragment shader input

The sample positions are read from a constant buffer.
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index d021caa..6818106 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -557,6 +557,8 @@
 {
 	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 @@
 		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;