gallium/u_blitter: clear color buffers using color from a constant buffer
authorIndrajit Kumar Das <indrajit-kumar.das@amd.com>
Fri, 13 May 2022 11:32:14 +0000 (17:02 +0530)
committerMarge Bot <emma+marge@anholt.net>
Thu, 19 May 2022 11:18:30 +0000 (11:18 +0000)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15318>

src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_simple_shaders.h

index bea898e..f55c580 100644 (file)
@@ -76,7 +76,7 @@ struct blitter_context_priv
    /* Fragment shaders. */
    void *fs_empty;
    void *fs_write_one_cbuf;
-   void *fs_write_all_cbufs;
+   void *fs_clear_all_cbufs;
 
    /* FS which outputs a color from a texture where
     * the 1st index indicates the texture type / destination type,
@@ -467,18 +467,16 @@ static void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx)
    ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
 }
 
-static void bind_fs_write_all_cbufs(struct blitter_context_priv *ctx)
+static void bind_fs_clear_all_cbufs(struct blitter_context_priv *ctx)
 {
    struct pipe_context *pipe = ctx->base.pipe;
 
-   if (!ctx->fs_write_all_cbufs) {
+   if (!ctx->fs_clear_all_cbufs) {
       assert(!ctx->cached_all_shaders);
-      ctx->fs_write_all_cbufs =
-         util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
-                                               TGSI_INTERPOLATE_CONSTANT, true);
+      ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe);
    }
 
-   ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs);
+   ctx->bind_fs_state(pipe, ctx->fs_clear_all_cbufs);
 }
 
 void util_blitter_destroy(struct blitter_context *blitter)
@@ -576,8 +574,8 @@ void util_blitter_destroy(struct blitter_context *blitter)
       ctx->delete_fs_state(pipe, ctx->fs_empty);
    if (ctx->fs_write_one_cbuf)
       ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf);
-   if (ctx->fs_write_all_cbufs)
-      ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs);
+   if (ctx->fs_clear_all_cbufs)
+      ctx->delete_fs_state(pipe, ctx->fs_clear_all_cbufs);
 
    for (i = 0; i < ARRAY_SIZE(ctx->fs_stencil_blit_fallback); ++i)
       if (ctx->fs_stencil_blit_fallback[i])
@@ -1354,9 +1352,7 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter)
       util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
                                             TGSI_INTERPOLATE_CONSTANT, false);
 
-   ctx->fs_write_all_cbufs =
-      util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
-                                            TGSI_INTERPOLATE_CONSTANT, true);
+   ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe);
 
    ctx->cached_all_shaders = true;
 }
@@ -1556,17 +1552,20 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
    sr.ref_value[0] = stencil & 0xff;
    pipe->set_stencil_ref(pipe, sr);
 
-   union blitter_attrib attrib;
-   memcpy(attrib.color, color->ui, sizeof(color->ui));
-
    bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0;
-   enum blitter_attrib_type type = pass_generic ? UTIL_BLITTER_ATTRIB_COLOR :
-                                                  UTIL_BLITTER_ATTRIB_NONE;
+   enum blitter_attrib_type type = UTIL_BLITTER_ATTRIB_NONE;
 
-   if (pass_generic)
-      bind_fs_write_all_cbufs(ctx);
-   else
+   if (pass_generic) {
+      struct pipe_constant_buffer cb = {
+         .user_buffer = color->f,
+         .buffer_size = 4 * sizeof(float),
+      };
+      pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
+                                false, &cb);
+      bind_fs_clear_all_cbufs(ctx);
+   } else {
       bind_fs_empty(ctx);
+   }
 
    if (num_layers > 1 && ctx->has_layered) {
       blitter_get_vs_func get_vs = get_vs_layered;
@@ -1574,7 +1573,7 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
       blitter_set_common_draw_rect_state(ctx, false, msaa);
       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
                               0, 0, width, height,
-                              (float) depth, num_layers, type, &attrib);
+                              (float) depth, num_layers, type, NULL);
    } else {
       blitter_get_vs_func get_vs;
 
@@ -1586,11 +1585,12 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
       blitter_set_common_draw_rect_state(ctx, false, msaa);
       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
                               0, 0, width, height,
-                              (float) depth, 1, type, &attrib);
+                              (float) depth, 1, type, NULL);
    }
 
    util_blitter_restore_vertex_states(blitter);
    util_blitter_restore_fragment_states(blitter);
+   util_blitter_restore_constant_buffer_state(blitter);
    util_blitter_restore_render_cond(blitter);
    util_blitter_unset_running_flag(blitter);
 }
index 07c667b..77add5b 100644 (file)
@@ -1219,3 +1219,28 @@ util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src)
 
    return pipe->create_fs_state(pipe, &state);
 }
+
+void *
+util_make_fs_clear_all_cbufs(struct pipe_context *pipe)
+{
+   static const char text[] =
+      "FRAG\n"
+      "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n"
+      "DCL OUT[0], COLOR[0]\n"
+      "DCL CONST[0][0]\n"
+
+      "MOV OUT[0], CONST[0][0]\n"
+      "END\n";
+
+   struct tgsi_token tokens[1000];
+   struct pipe_shader_state state = { 0 };
+
+   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
+      assert(0);
+      return NULL;
+   }
+
+   pipe_shader_state_from_tgsi(&state, tokens);
+
+   return pipe->create_fs_state(pipe, &state);
+}
index dfd16b9..c0f30b7 100644 (file)
@@ -176,6 +176,9 @@ util_make_tess_ctrl_passthrough_shader(struct pipe_context *pipe,
 void *
 util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src);
 
+void *
+util_make_fs_clear_all_cbufs(struct pipe_context *pipe);
+
 #ifdef __cplusplus
 }
 #endif