aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/panfrost/bifrost/bifrost.h4
-rw-r--r--src/panfrost/bifrost/bifrost_compile.c82
2 files changed, 86 insertions, 0 deletions
diff --git a/src/panfrost/bifrost/bifrost.h b/src/panfrost/bifrost/bifrost.h
index eba95f7d615..c4fd86b72bc 100644
--- a/src/panfrost/bifrost/bifrost.h
+++ b/src/panfrost/bifrost/bifrost.h
@@ -579,6 +579,10 @@ enum bifrost_interp_mode {
#define BIFROST_ADD_OP_LD_VAR_16 (0x1a << 1)
#define BIFROST_ADD_OP_LD_VAR_32 (0x0a << 1)
+/* Fixed location for gl_FragCoord.zw */
+#define BIFROST_FRAGZ (23)
+#define BIFROST_FRAGW (22)
+
struct bifrost_ld_var {
unsigned src0 : 3;
diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c
index 8037e239d53..a14314b6ad3 100644
--- a/src/panfrost/bifrost/bifrost_compile.c
+++ b/src/panfrost/bifrost/bifrost_compile.c
@@ -273,6 +273,84 @@ bi_emit_sysval(bi_context *ctx, nir_instr *instr,
bi_emit(ctx, load);
}
+/* gl_FragCoord.xy = u16_to_f32(R59.xy) + 0.5
+ * gl_FragCoord.z = ld_vary(fragz)
+ * gl_FragCoord.w = ld_vary(fragw)
+ */
+
+static void
+bi_emit_ld_frag_coord(bi_context *ctx, nir_intrinsic_instr *instr)
+{
+ /* Future proofing for mediump fragcoord at some point.. */
+ nir_alu_type T = nir_type_float32;
+
+ /* First, sketch a combine */
+ bi_instruction combine = {
+ .type = BI_COMBINE,
+ .dest_type = nir_type_uint32,
+ .dest = pan_dest_index(&instr->dest),
+ .src_types = { T, T, T, T },
+ };
+
+ /* Second, handle xy */
+ for (unsigned i = 0; i < 2; ++i) {
+ bi_instruction conv = {
+ .type = BI_CONVERT,
+ .dest_type = T,
+ .dest = bi_make_temp(ctx),
+ .src = {
+ /* TODO: RA XXX */
+ BIR_INDEX_REGISTER | 59
+ },
+ .src_types = { nir_type_uint16 },
+ .swizzle = { { i } }
+ };
+
+ bi_instruction add = {
+ .type = BI_ADD,
+ .dest_type = T,
+ .dest = bi_make_temp(ctx),
+ .src = { conv.dest, BIR_INDEX_CONSTANT },
+ .src_types = { T, T },
+ };
+
+ float half = 0.5;
+ memcpy(&add.constant.u32, &half, sizeof(float));
+
+ bi_emit(ctx, conv);
+ bi_emit(ctx, add);
+
+ combine.src[i] = add.dest;
+ }
+
+ /* Third, zw */
+ for (unsigned i = 0; i < 2; ++i) {
+ bi_instruction load = {
+ .type = BI_LOAD_VAR,
+ .load_vary = {
+ .interp_mode = BIFROST_INTERP_DEFAULT,
+ .reuse = false,
+ .flat = true
+ },
+ .vector_channels = 1,
+ .dest_type = nir_type_float32,
+ .dest = bi_make_temp(ctx),
+ .src = { BIR_INDEX_CONSTANT, BIR_INDEX_ZERO },
+ .src_types = { nir_type_uint32, nir_type_uint32 },
+ .constant = {
+ .u32 = (i == 0) ? BIFROST_FRAGZ : BIFROST_FRAGW
+ }
+ };
+
+ bi_emit(ctx, load);
+
+ combine.src[i + 2] = load.dest;
+ }
+
+ /* Finally, emit the combine */
+ bi_emit(ctx, combine);
+}
+
static void
emit_intrinsic(bi_context *ctx, nir_intrinsic_instr *instr)
{
@@ -305,6 +383,10 @@ emit_intrinsic(bi_context *ctx, nir_intrinsic_instr *instr)
bi_emit_ld_uniform(ctx, instr);
break;
+ case nir_intrinsic_load_frag_coord:
+ bi_emit_ld_frag_coord(ctx, instr);
+ break;
+
case nir_intrinsic_load_ssbo_address:
bi_emit_sysval(ctx, &instr->instr, 1, 0);
break;