freedreno/ir3: switch fragcoord to sysval

Because who are we kidding... it is a sysval.

Signed-off-by: Rob Clark <robdclark@chromium.org>
This commit is contained in:
Rob Clark
2019-04-26 14:40:17 -07:00
parent 11518384c4
commit da327afb2a
2 changed files with 45 additions and 48 deletions
+44 -48
View File
@@ -1176,6 +1176,46 @@ get_barycentric_pixel(struct ir3_context *ctx)
return ctx->ij_pixel;
}
static struct ir3_instruction *
get_frag_coord(struct ir3_context *ctx)
{
if (!ctx->frag_coord) {
struct ir3_block *b = ctx->block;
struct ir3_instruction *xyzw[4];
struct ir3_instruction *hw_frag_coord;
hw_frag_coord = create_input_compmask(ctx, 0, 0xf);
ir3_split_dest(ctx->block, xyzw, hw_frag_coord, 0, 4);
/* for frag_coord.xy, we get unsigned values.. we need
* to subtract (integer) 8 and divide by 16 (right-
* shift by 4) then convert to float:
*
* sub.s tmp, src, 8
* shr.b tmp, tmp, 4
* mov.u32f32 dst, tmp
*
*/
for (int i = 0; i < 2; i++) {
xyzw[i] = ir3_SUB_S(b, xyzw[i], 0,
create_immed(b, 8), 0);
xyzw[i] = ir3_SHR_B(b, xyzw[i], 0,
create_immed(b, 4), 0);
xyzw[i] = ir3_COV(b, xyzw[i], TYPE_U32, TYPE_F32);
}
ctx->frag_coord = ir3_create_collect(ctx, xyzw, 4);
add_sysval_input_compmask(ctx,
SYSTEM_VALUE_FRAG_COORD,
0xf, hw_frag_coord);
ctx->so->frag_coord = true;
}
return ctx->frag_coord;
}
static void
emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
{
@@ -1217,6 +1257,9 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_load_ubo:
emit_intrinsic_load_ubo(ctx, intr, dst);
break;
case nir_intrinsic_load_frag_coord:
ir3_split_dest(b, dst, get_frag_coord(ctx), 0, 4);
break;
case nir_intrinsic_load_sample_pos_from_id: {
/* NOTE: blob seems to always use TYPE_F16 and then cov.f16f32,
* but that doesn't seem necessary.
@@ -2298,46 +2341,6 @@ emit_function(struct ir3_context *ctx, nir_function_impl *impl)
ir3_END(ctx->block);
}
static struct ir3_instruction *
create_frag_coord(struct ir3_context *ctx, unsigned comp)
{
struct ir3_block *block = ctx->block;
struct ir3_instruction *instr;
if (!ctx->frag_coord) {
ctx->frag_coord = create_input_compmask(ctx, 0, 0xf);
/* defer add_sysval_input() until after all inputs created */
}
ir3_split_dest(block, &instr, ctx->frag_coord, comp, 1);
switch (comp) {
case 0: /* .x */
case 1: /* .y */
/* for frag_coord, we get unsigned values.. we need
* to subtract (integer) 8 and divide by 16 (right-
* shift by 4) then convert to float:
*
* sub.s tmp, src, 8
* shr.b tmp, tmp, 4
* mov.u32f32 dst, tmp
*
*/
instr = ir3_SUB_S(block, instr, 0,
create_immed(block, 8), 0);
instr = ir3_SHR_B(block, instr, 0,
create_immed(block, 4), 0);
instr = ir3_COV(block, instr, TYPE_U32, TYPE_F32);
return instr;
case 2: /* .z */
case 3: /* .w */
default:
/* seems that we can use these as-is: */
return instr;
}
}
static void
setup_input(struct ir3_context *ctx, nir_variable *in)
{
@@ -2371,9 +2374,7 @@ setup_input(struct ir3_context *ctx, nir_variable *in)
unsigned idx = (n * 4) + i + frac;
if (slot == VARYING_SLOT_POS) {
so->inputs[n].bary = false;
so->frag_coord = true;
instr = create_frag_coord(ctx, i);
ir3_context_error(ctx, "fragcoord should be a sysval!\n");
} else if (slot == VARYING_SLOT_PNTC) {
/* see for example st_nir_fixup_varying_slots().. this is
* maybe a bit mesa/st specific. But we need things to line
@@ -2678,11 +2679,6 @@ emit_instructions(struct ir3_context *ctx)
0x3, vcoord);
}
if (ctx->frag_coord) {
add_sysval_input_compmask(ctx, SYSTEM_VALUE_FRAG_COORD,
0xf, ctx->frag_coord);
}
/* Setup outputs: */
nir_foreach_variable(var, &ctx->s->outputs) {
setup_output(ctx, var);
@@ -355,6 +355,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 0;
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
if (is_ir3(screen))
return 1;
return 0;