summaryrefslogtreecommitdiffstats
path: root/src/amd/common
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-04-03 04:38:12 +0100
committerDave Airlie <airlied@redhat.com>2017-04-04 05:55:15 +1000
commit1171b304f30f77b6780891b2b0561b52234a1ec5 (patch)
tree3a3a50fd4390e6ceb8fc4005a5c29ea058a1020e /src/amd/common
parent471c1bc7ccd33caa38bbf7124691ccf6884ac5f8 (diff)
radv: overhaul fragment shader sample positions.
The current code was broken, and I decided to redesign it instead. This puts the sample positions for all samples into the queue constant descriptor buffer after all the spill/ring descriptors. It then uses a single offset register to point how far into the samples the samples for num_samples are. This saves one user sgpr and means we only generate the sample position data in the rare single case where we need it currently. This doesn't fix the failing CTS tests without the followup fix. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/amd/common')
-rw-r--r--src/amd/common/ac_nir_to_llvm.c31
-rw-r--r--src/amd/common/ac_nir_to_llvm.h4
2 files changed, 20 insertions, 15 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index c8ea0da7740..dfe2732f78d 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -109,7 +109,7 @@ struct nir_to_llvm_context {
LLVMValueRef hs_ring_tess_factor;
LLVMValueRef prim_mask;
- LLVMValueRef sample_positions;
+ LLVMValueRef sample_pos_offset;
LLVMValueRef persp_sample, persp_center, persp_centroid;
LLVMValueRef linear_sample, linear_center, linear_centroid;
LLVMValueRef front_face;
@@ -573,6 +573,7 @@ static void create_function(struct nir_to_llvm_context *ctx)
ctx->stage == MESA_SHADER_VERTEX ||
ctx->stage == MESA_SHADER_TESS_CTRL ||
ctx->stage == MESA_SHADER_TESS_EVAL ||
+ ctx->stage == MESA_SHADER_FRAGMENT ||
ctx->is_gs_copy_shader)
need_ring_offsets = true;
@@ -584,7 +585,7 @@ static void create_function(struct nir_to_llvm_context *ctx)
need_push_constants = false;
if (need_ring_offsets && !ctx->options->supports_spill) {
- arg_types[arg_idx++] = const_array(ctx->v16i8, 8); /* address of rings */
+ arg_types[arg_idx++] = const_array(ctx->v16i8, 16); /* address of rings */
}
/* 1 for each descriptor set */
@@ -679,7 +680,7 @@ static void create_function(struct nir_to_llvm_context *ctx)
arg_types[arg_idx++] = ctx->i32; // GS instance id
break;
case MESA_SHADER_FRAGMENT:
- arg_types[arg_idx++] = const_array(ctx->f32, 32); /* sample positions */
+ arg_types[arg_idx++] = ctx->i32; /* sample position offset */
user_sgpr_count = arg_idx;
arg_types[arg_idx++] = ctx->i32; /* prim mask */
sgpr_count = arg_idx;
@@ -735,7 +736,7 @@ static void create_function(struct nir_to_llvm_context *ctx)
LLVMPointerType(ctx->i8, CONST_ADDR_SPACE),
NULL, 0, AC_FUNC_ATTR_READNONE);
ctx->ring_offsets = LLVMBuildBitCast(ctx->builder, ctx->ring_offsets,
- const_array(ctx->v16i8, 8), "");
+ const_array(ctx->v16i8, 16), "");
} else
ctx->ring_offsets = LLVMGetParam(ctx->main_function, arg_idx++);
}
@@ -844,9 +845,9 @@ static void create_function(struct nir_to_llvm_context *ctx)
ctx->gs_invocation_id = LLVMGetParam(ctx->main_function, arg_idx++);
break;
case MESA_SHADER_FRAGMENT:
- set_userdata_location_shader(ctx, AC_UD_PS_SAMPLE_POS, user_sgpr_idx, 2);
- user_sgpr_idx += 2;
- ctx->sample_positions = LLVMGetParam(ctx->main_function, arg_idx++);
+ set_userdata_location_shader(ctx, AC_UD_PS_SAMPLE_POS_OFFSET, user_sgpr_idx, 1);
+ user_sgpr_idx += 1;
+ ctx->sample_pos_offset = LLVMGetParam(ctx->main_function, arg_idx++);
ctx->prim_mask = LLVMGetParam(ctx->main_function, arg_idx++);
ctx->persp_sample = LLVMGetParam(ctx->main_function, arg_idx++);
ctx->persp_center = LLVMGetParam(ctx->main_function, arg_idx++);
@@ -3518,15 +3519,17 @@ static LLVMValueRef lookup_interp_param(struct nir_to_llvm_context *ctx,
static LLVMValueRef load_sample_position(struct nir_to_llvm_context *ctx,
LLVMValueRef sample_id)
{
- /* offset = sample_id * 8 (8 = 2 floats containing samplepos.xy) */
- LLVMValueRef offset0 = LLVMBuildMul(ctx->builder, sample_id, LLVMConstInt(ctx->i32, 8, false), "");
- LLVMValueRef offset1 = LLVMBuildAdd(ctx->builder, offset0, LLVMConstInt(ctx->i32, 4, false), "");
- LLVMValueRef result[2];
+ LLVMValueRef result;
+ LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->i32, RING_PS_SAMPLE_POSITIONS, false));
- result[0] = ac_build_indexed_load_const(&ctx->ac, ctx->sample_positions, offset0);
- result[1] = ac_build_indexed_load_const(&ctx->ac, ctx->sample_positions, offset1);
+ ptr = LLVMBuildBitCast(ctx->builder, ptr,
+ const_array(ctx->v2f32, 64), "");
- return ac_build_gather_values(&ctx->ac, result, 2);
+ sample_id = LLVMBuildAdd(ctx->builder, sample_id, ctx->sample_pos_offset, "");
+ result = ac_build_indexed_load(&ctx->ac, ptr, sample_id, false);
+
+ ctx->shader_info->fs.uses_sample_positions = true;
+ return result;
}
static LLVMValueRef load_sample_pos(struct nir_to_llvm_context *ctx)
diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h
index c468d93f428..3d0b456f9f5 100644
--- a/src/amd/common/ac_nir_to_llvm.h
+++ b/src/amd/common/ac_nir_to_llvm.h
@@ -88,7 +88,7 @@ enum ac_ud_index {
AC_UD_VS_BASE_VERTEX_START_INSTANCE,
AC_UD_VS_LS_TCS_IN_LAYOUT,
AC_UD_VS_MAX_UD,
- AC_UD_PS_SAMPLE_POS = AC_UD_SHADER_START,
+ AC_UD_PS_SAMPLE_POS_OFFSET = AC_UD_SHADER_START,
AC_UD_PS_MAX_UD,
AC_UD_CS_GRID_SIZE = AC_UD_SHADER_START,
AC_UD_CS_MAX_UD,
@@ -109,6 +109,7 @@ enum ac_ud_index {
#define RING_GSVS_GS 4
#define RING_HS_TESS_FACTOR 5
#define RING_HS_TESS_OFFCHIP 6
+#define RING_PS_SAMPLE_POSITIONS 7
// Match MAX_SETS from radv_descriptor_set.h
#define AC_UD_MAX_SETS MAX_SETS
@@ -165,6 +166,7 @@ struct ac_shader_variant_info {
bool force_persample;
bool prim_id_input;
bool layer_input;
+ bool uses_sample_positions;
} fs;
struct {
unsigned block_size[3];