panfrost: Prepack fragment properties/preload
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 21 Aug 2020 17:14:09 +0000 (13:14 -0400)
committerTomeu Vizoso <tomeu.vizoso@collabora.com>
Tue, 25 Aug 2020 15:05:37 +0000 (17:05 +0200)
This isn't as clean as vertex shaders, since some of this state is only
known at draw-time (e.g. some reasons we might disable early-Z). But we
can still pack as much as we can ahead-of-time and then OR together
what's left at draw-time.

Thank you to Kristian for this one crazy trick (blob developers hate
it! er...)

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6440>

src/gallium/drivers/panfrost/pan_assemble.c
src/gallium/drivers/panfrost/pan_cmdstream.c

index f84bf5db9fc546238493aad35935d6fb16d09341..21c1810de7532fdf6e570c991affe84ca4eb0e1f 100644 (file)
@@ -45,9 +45,19 @@ pan_pack_midgard_props(struct panfrost_shader_state *state,
         pan_pack(&state->properties, MIDGARD_PROPERTIES, cfg) {
                 cfg.uniform_buffer_count = state->ubo_count;
                 cfg.uniform_count = state->uniform_count;
-                cfg.work_register_count = state->work_reg_count;
                 cfg.writes_globals = state->writes_global;
                 cfg.suppress_inf_nan = true; /* XXX */
+
+                if (stage == MESA_SHADER_FRAGMENT) {
+                        /* Work register count, early-z, reads at draw-time */
+                        cfg.stencil_from_shader = state->writes_stencil;
+                        cfg.helper_invocation_enable = state->helper_invocations;
+                        cfg.depth_source = state->writes_depth ?
+                                MALI_DEPTH_SOURCE_SHADER :
+                                MALI_DEPTH_SOURCE_FIXED_FUNCTION;
+                } else {
+                        cfg.work_register_count = state->work_reg_count;
+                }
         }
 }
 
@@ -70,7 +80,18 @@ pan_pack_bifrost_props(struct panfrost_shader_state *state,
 
                 break;
         case MESA_SHADER_FRAGMENT:
-                /* TODO */
+                pan_pack(&state->properties, BIFROST_PROPERTIES, cfg) {
+                        /* Early-Z set at draw-time */
+
+                        cfg.unknown = 0x950020; /* XXX */
+                        cfg.uniform_buffer_count = state->ubo_count;
+                }
+
+                pan_pack(&state->preload, PRELOAD_FRAGMENT, cfg) {
+                        cfg.uniform_count = state->uniform_count;
+                        cfg.fragment_position = state->reads_frag_coord;
+                }
+
                 break;
         default:
                 unreachable("TODO");
index 2a3cb4dd90179813ad760365fb2c3ceac79cd8bc..ad8906b33379fb94a8ee11f4b4af50da601ef866 100644 (file)
@@ -553,7 +553,6 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx,
 
         if (dev->quirks & IS_BIFROST) {
                 struct mali_bifrost_properties_packed prop;
-                struct mali_preload_fragment_packed preload;
 
                 bool no_blend = true;
 
@@ -561,18 +560,14 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx,
                         no_blend &= (!blend[i].load_dest | blend[i].no_colour);
 
                 pan_pack(&prop, BIFROST_PROPERTIES, cfg) {
-                        cfg.unknown = 0x950020; /* XXX */
-                        cfg.uniform_buffer_count = fs->ubo_count;
                         cfg.early_z_enable = !fs->can_discard && !fs->writes_depth && no_blend;
                 }
 
-                pan_pack(&preload, PRELOAD_FRAGMENT, cfg) {
-                        cfg.uniform_count = fs->uniform_count;
-                        cfg.fragment_position = fs->reads_frag_coord;
-                }
+                /* Combine with prepacked properties */
+                prop.opaque[0] |= fs->properties.opaque[0];
 
                 memcpy(&fragmeta->bifrost_props, &prop, sizeof(prop));
-                memcpy(&fragmeta->bifrost_preload, &preload, sizeof(preload));
+                memcpy(&fragmeta->bifrost_preload, &fs->preload, sizeof(fs->preload));
         } else {
                 struct mali_midgard_properties_packed prop;
 
@@ -594,28 +589,19 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx,
                         has_blend_shader |= blend[c].is_shader;
 
                 pan_pack(&prop, MIDGARD_PROPERTIES, cfg) {
-                        cfg.uniform_buffer_count = fs->ubo_count;
-                        cfg.uniform_count = fs->uniform_count;
-                        cfg.work_register_count = fs->work_reg_count;
-                        cfg.writes_globals = fs->writes_global;
-                        cfg.suppress_inf_nan = true; /* XXX */
-
                         /* TODO: Reduce this limit? */
                         if (has_blend_shader)
-                                cfg.work_register_count = MAX2(cfg.work_register_count, 8);
-
-                        cfg.stencil_from_shader = fs->writes_stencil;
-                        cfg.helper_invocation_enable = fs->helper_invocations;
-                        cfg.depth_source = fs->writes_depth ?
-                                MALI_DEPTH_SOURCE_SHADER :
-                                MALI_DEPTH_SOURCE_FIXED_FUNCTION;
+                                cfg.work_register_count = MAX2(fs->work_reg_count, 8);
+                        else
+                                cfg.work_register_count = fs->work_reg_count;
 
-                        /* Depend on other state */
                         cfg.early_z_enable = !(late_z || alpha_to_coverage);
                         cfg.reads_tilebuffer = fs->outputs_read || (!zs_enabled && fs->can_discard);
                         cfg.reads_depth_stencil = zs_enabled && fs->can_discard;
                 }
 
+                /* Combine with prepacked properties */
+                prop.opaque[0] |= fs->properties.opaque[0];
                 memcpy(&fragmeta->midgard_props, &prop, sizeof(prop));
         }