freedreno/a6xx: Fix VFD_CONTROL emit
[mesa.git] / src / gallium / drivers / panfrost / pan_cmdstream.c
index 733351eee235a436ce35a04a037451304c16305a..608d1799f9785057b4e9367f0bfb6f27b7d66390 100644 (file)
@@ -332,23 +332,31 @@ panfrost_shader_meta_init(struct panfrost_context *ctx,
                 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);
         }
 }
 
@@ -727,6 +735,16 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx,
                 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) {
@@ -823,10 +841,10 @@ panfrost_frag_shader_meta_init(struct panfrost_context *ctx,
                 /* 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);
@@ -1711,6 +1729,7 @@ panfrost_emit_varying_descriptor(struct panfrost_batch *batch,
 {
         /* 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;
@@ -1803,7 +1822,9 @@ panfrost_emit_varying_descriptor(struct panfrost_batch *batch,
         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 */
 
@@ -1847,16 +1868,15 @@ panfrost_emit_varying_descriptor(struct panfrost_batch *batch,
                 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
@@ -1880,6 +1900,15 @@ panfrost_emit_varying_descriptor(struct panfrost_batch *batch,
         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;