panfrost: Use packs for attributes
[mesa.git] / src / gallium / drivers / panfrost / pan_blend_cso.c
index 1dd211e6b4c6075e565dd05b1597bb849ee7956f..01b4fd33a105fa4873056d2224ab9d0d44579c74 100644 (file)
@@ -65,7 +65,7 @@
  * befast, suitable for calling every draw to avoid wacky dirty
  * tracking paths. If the cache hits, boom, done. */
 
-static struct panfrost_blend_shader *
+struct panfrost_blend_shader *
 panfrost_get_blend_shader(
         struct panfrost_context *ctx,
         struct panfrost_blend_state *blend,
@@ -107,8 +107,6 @@ panfrost_create_blend_state(struct pipe_context *pipe,
         so->base = *blend;
 
         /* TODO: The following features are not yet implemented */
-        assert(!blend->logicop_enable);
-        assert(!blend->alpha_to_coverage);
         assert(!blend->alpha_to_one);
 
         for (unsigned c = 0; c < PIPE_MAX_COLOR_BUFS; ++c) {
@@ -119,15 +117,17 @@ panfrost_create_blend_state(struct pipe_context *pipe,
 
                 /* Without indep blending, the first RT settings replicate */
 
-                unsigned g =
-                        blend->independent_blend_enable ? c : 0;
+                if (!blend->logicop_enable) {
+                        unsigned g =
+                                blend->independent_blend_enable ? c : 0;
 
-                rt->has_fixed_function =
-                        panfrost_make_fixed_blend_mode(
-                                &blend->rt[g],
-                                &rt->equation,
-                                &rt->constant_mask,
-                                blend->rt[g].colormask);
+                        rt->has_fixed_function =
+                                panfrost_make_fixed_blend_mode(
+                                        &blend->rt[g],
+                                        &rt->equation,
+                                        &rt->constant_mask,
+                                        blend->rt[g].colormask);
+                }
 
                 /* Regardless if that works, we also need to initialize
                  * the blend shaders */
@@ -143,20 +143,12 @@ panfrost_bind_blend_state(struct pipe_context *pipe,
                           void *cso)
 {
         struct panfrost_context *ctx = pan_context(pipe);
-        struct panfrost_screen *screen = pan_screen(ctx->base.screen);
         struct pipe_blend_state *blend = (struct pipe_blend_state *) cso;
         struct panfrost_blend_state *pblend = (struct panfrost_blend_state *) cso;
         ctx->blend = pblend;
 
         if (!blend)
                 return;
-
-        if (screen->quirks & MIDGARD_SFBD) {
-                SET_BIT(ctx->fragment_shader_core.unknown2_4, MALI_NO_DITHER, !blend->dither);
-        }
-
-        /* Shader itself is not dirty, but the shader core is */
-        ctx->dirty |= PAN_DIRTY_FS;
 }
 
 static void
@@ -227,7 +219,7 @@ panfrost_blend_constant(float *out, float *in, unsigned mask)
 /* Create a final blend given the context */
 
 struct panfrost_blend_final
-panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti)
+panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti, struct panfrost_bo **bo, unsigned *shader_offset)
 {
         struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
 
@@ -262,6 +254,8 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti)
                                 (rt->equation.alpha_mode == 0x122) &&
                                 (rt->equation.color_mask == 0xf);
 
+                        final.no_colour = (rt->equation.color_mask == 0x0);
+
                         return final;
                 }
         }
@@ -270,26 +264,36 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti)
         struct panfrost_blend_shader *shader = panfrost_get_blend_shader(ctx, blend, fmt, rti);
         final.is_shader = true;
         final.no_blending = false;
+        final.no_colour = false;
         final.shader.work_count = shader->work_count;
         final.shader.first_tag = shader->first_tag;
 
-        /* Upload the shader */
-        final.shader.bo = panfrost_batch_create_bo(batch, shader->size,
-                                                   PAN_BO_EXECUTE,
-                                                   PAN_BO_ACCESS_PRIVATE |
-                                                   PAN_BO_ACCESS_READ |
-                                                   PAN_BO_ACCESS_VERTEX_TILER |
-                                                   PAN_BO_ACCESS_FRAGMENT);
-        memcpy(final.shader.bo->cpu, shader->buffer, shader->size);
+        /* Upload the shader, sharing a BO */
+        if (!(*bo)) {
+                *bo = panfrost_batch_create_bo(batch, 4096,
+                   PAN_BO_EXECUTE,
+                   PAN_BO_ACCESS_PRIVATE |
+                   PAN_BO_ACCESS_READ |
+                   PAN_BO_ACCESS_VERTEX_TILER |
+                   PAN_BO_ACCESS_FRAGMENT);
+        }
+
+        /* Size check */
+        assert((*shader_offset + shader->size) < 4096);
+
+        memcpy((*bo)->cpu + *shader_offset, shader->buffer, shader->size);
+        final.shader.gpu = (*bo)->gpu + *shader_offset;
 
         if (shader->patch_index) {
                 /* We have to specialize the blend shader to use constants, so
                  * patch in the current constants */
 
-                float *patch = (float *) (final.shader.bo->cpu + shader->patch_index);
+                float *patch = (float *) ((*bo)->cpu + *shader_offset + shader->patch_index);
                 memcpy(patch, ctx->blend_color.color, sizeof(float) * 4);
         }
 
+        *shader_offset += shader->size;
+
         return final;
 }