else {
/* First clause ATEST |= 0x4000000.
* Less than 32 regs |= 0x200 */
- meta->bifrost1.unk1 = 0x958020;
+ meta->bifrost1.unk1 = 0x950020;
}
meta->bifrost1.uniform_buffer_count = panfrost_ubo_count(ctx, st);
if (st == PIPE_SHADER_VERTEX)
meta->bifrost2.preload_regs = 0xC0;
- else
+ else {
meta->bifrost2.preload_regs = 0x1;
+ SET_BIT(meta->bifrost2.preload_regs, 0x10, ss->reads_frag_coord);
+ }
+
meta->bifrost2.uniform_count = MIN2(ss->uniform_count,
ss->uniform_cutoff);
} else {
meta->midgard1.uniform_count = MIN2(ss->uniform_count,
ss->uniform_cutoff);
meta->midgard1.work_count = ss->work_reg_count;
- meta->midgard1.flags_hi = 0x8; /* XXX */
- meta->midgard1.flags_lo = 0x220;
+
+ /* TODO: This is not conformant on ES3 */
+ meta->midgard1.flags_hi = MALI_SUPPRESS_INF_NAN;
+
+ meta->midgard1.flags_lo = 0x20;
meta->midgard1.uniform_buffer_count = panfrost_ubo_count(ctx, st);
+
+ SET_BIT(meta->midgard1.flags_hi, MALI_WRITES_GLOBAL, ss->writes_global);
}
}
return;
}
+ if (dev->quirks & IS_BIFROST) {
+ bool no_blend = true;
+
+ for (unsigned i = 0; i < rt_count; ++i)
+ no_blend &= (blend[i].no_blending | blend[i].no_colour);
+
+ SET_BIT(fragmeta->bifrost1.unk1, MALI_BIFROST_EARLY_Z,
+ !fs->can_discard && !fs->writes_depth && no_blend);
+ }
+
/* Additional blend descriptor tacked on for jobs using MFBD */
for (unsigned i = 0; i < rt_count; ++i) {
/* TODO */
} else {
/* Depending on whether it's legal to in the given shader, we try to
- * enable early-z testing (or forward-pixel kill?) */
+ * enable early-z testing. TODO: respect e-z force */
SET_BIT(fragmeta->midgard1.flags_lo, MALI_EARLY_Z,
- !fs->can_discard && !fs->writes_depth);
+ !fs->can_discard && !fs->writes_depth && !fs->writes_global);
/* Add the writes Z/S flags if needed. */
SET_BIT(fragmeta->midgard1.flags_lo, MALI_WRITES_Z, fs->writes_depth);
{
/* Load the shaders */
struct panfrost_context *ctx = batch->ctx;
+ struct panfrost_device *device = pan_device(ctx->base.screen);
struct panfrost_shader_state *vs, *fs;
unsigned int num_gen_varyings = 0;
size_t vs_size, fs_size;
signed gl_PointSize = vs->writes_point_size ? (idx++) : -1;
signed gl_PointCoord = reads_point_coord ? (idx++) : -1;
signed gl_FrontFacing = fs->reads_face ? (idx++) : -1;
- signed gl_FragCoord = fs->reads_frag_coord ? (idx++) : -1;
+ signed gl_FragCoord = (fs->reads_frag_coord &&
+ !(device->quirks & IS_BIFROST))
+ ? (idx++) : -1;
/* Emit the stream out buffers */
primitive_size->pointer = varyings_p;
}
- if (reads_point_coord)
+ if (gl_PointCoord >= 0)
varyings[gl_PointCoord].elements = MALI_VARYING_POINT_COORD;
- if (fs->reads_face)
+ if (gl_FrontFacing >= 0)
varyings[gl_FrontFacing].elements = MALI_VARYING_FRONT_FACING;
- if (fs->reads_frag_coord)
+ if (gl_FragCoord >= 0)
varyings[gl_FragCoord].elements = MALI_VARYING_FRAG_COORD;
- struct panfrost_device *device = pan_device(ctx->base.screen);
assert(!(device->quirks & IS_BIFROST) || !(reads_point_coord));
/* Let's go ahead and link varying meta to the buffer in question, now
for (unsigned i = 0; i < vs->varying_count; i++) {
gl_varying_slot loc = vs->varyings_loc[i];
+ /* If we write gl_PointSize from the vertex shader but don't
+ * consume it, no memory will be allocated for it, so if we
+ * attempted to write anyway we would dereference a NULL
+ * pointer on the GPU. Midgard seems fine with this; Bifrost
+ * faults. */
+
+ if (loc == VARYING_SLOT_PSIZ && !panfrost_writes_point_size(ctx))
+ ovs[i].format = MALI_VARYING_DISCARD;
+
bool captured = ((vs->so_mask & (1ll << loc)) ? true : false);
if (!captured)
continue;