gallium: add # of MRT to blend state
authorRob Clark <robdclark@chromium.org>
Thu, 16 Apr 2020 17:53:03 +0000 (10:53 -0700)
committerMarge Bot <eric+marge@anholt.net>
Thu, 23 Apr 2020 04:49:52 +0000 (04:49 +0000)
To make it possible for drivers to avoid unnecessary blend state change
for unused MRTs.  Otherwise the driver would have to manage different
blend CSOs for different potential #s of render targets.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4619>

src/gallium/auxiliary/driver_trace/tr_dump_state.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/docs/source/cso/blend.rst
src/gallium/include/pipe/p_state.h
src/gallium/state_trackers/nine/nine_pipe.c
src/mesa/state_tracker/st_atom_blend.c
src/mesa/state_tracker/st_cb_clear.c

index bd0d7204cfff928286e19add667725aafba97af8..49d2109101a11274670601d81093042c283397b4 100644 (file)
@@ -432,7 +432,7 @@ void trace_dump_blend_state(const struct pipe_blend_state *state)
 
    trace_dump_member_begin("rt");
    if (state->independent_blend_enable)
-      valid_entries = PIPE_MAX_COLOR_BUFS;
+      valid_entries = state->max_rt + 1;
    trace_dump_struct_array(rt_blend_state, state->rt, valid_entries);
    trace_dump_member_end();
 
index fd7813aae11e059f359a0a000b7d38b24768ec0a..d5b886ca36f02e0cbed6c2d53d62d0556d6384b9 100644 (file)
@@ -1419,6 +1419,7 @@ static void *get_clear_blend_state(struct blitter_context_priv *ctx,
       for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
          if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) {
             blend.rt[i].colormask = PIPE_MASK_RGBA;
+            blend.max_rt = i;
          }
       }
 
index 422dc86754f1bbb80f1cec2964039d281ba947af..f57a5923ad0a1084267378ff515f79aef24d42c0 100644 (file)
@@ -603,6 +603,7 @@ util_dump_blend_state(FILE *stream, const struct pipe_blend_state *state)
    util_dump_member(stream, bool, state, dither);
    util_dump_member(stream, bool, state, alpha_to_coverage);
    util_dump_member(stream, bool, state, alpha_to_one);
+   util_dump_member(stream, uint, state, max_rt);
 
    util_dump_member(stream, bool, state, logicop_enable);
    if (state->logicop_enable) {
@@ -613,7 +614,7 @@ util_dump_blend_state(FILE *stream, const struct pipe_blend_state *state)
 
       util_dump_member_begin(stream, "rt");
       if (state->independent_blend_enable)
-         valid_entries = PIPE_MAX_COLOR_BUFS;
+         valid_entries = state->max_rt + 1;
       util_dump_struct_array(stream, rt_blend_state, state->rt, valid_entries);
       util_dump_member_end(stream);
    }
index 7316e5c71cf66a90204d8e014b832cb1775bbce8..be5a2ef795678c6b275cc9f1b1d44ee7dd05666c 100644 (file)
@@ -99,6 +99,10 @@ alpha_to_one
    If enabled, the fragment's alpha value will be set to one.  As with
    alpha_to_coverage, this step happens regardless of whether multisample
    is enabled or the destination buffer is multisampled.
+max_rt
+   The index of the max render target (irrespecitive of whether independent
+   blend is enabled), ie. the number of MRTs minus one.  This is provided
+   so that the driver can avoid the overhead of programming unused MRTs.
 
 
 Per-rendertarget Members
index 736649acd2f474b694b25d6c99e71acda5a79006..c557ecc186983bfc4f69e5dec9e878b0c4f2c721 100644 (file)
@@ -363,6 +363,7 @@ struct pipe_blend_state
    unsigned dither:1;
    unsigned alpha_to_coverage:1;
    unsigned alpha_to_one:1;
+   unsigned max_rt:3;            /* index of max rt, Ie. # of cbufs minus 1 */
    struct pipe_rt_blend_state rt[PIPE_MAX_COLOR_BUFS];
 };
 
index dd858aef743b7dce577a0d2e0c88c9a3c34376a4..7531845efd6aff158adc2496d7d78718ea93397b 100644 (file)
@@ -186,6 +186,7 @@ nine_convert_blend_state(struct pipe_blend_state *blend_state, const DWORD *rs)
         nine_convert_blend_state_fixup(&blend, rs); /* for BOTH[INV]SRCALPHA */
     }
 
+    blend.max_rt = 0;
     blend.rt[0].colormask = rs[D3DRS_COLORWRITEENABLE];
 
     if (rs[D3DRS_COLORWRITEENABLE1] != rs[D3DRS_COLORWRITEENABLE] ||
@@ -198,6 +199,7 @@ nine_convert_blend_state(struct pipe_blend_state *blend_state, const DWORD *rs)
         blend.rt[1].colormask = rs[D3DRS_COLORWRITEENABLE1];
         blend.rt[2].colormask = rs[D3DRS_COLORWRITEENABLE2];
         blend.rt[3].colormask = rs[D3DRS_COLORWRITEENABLE3];
+        blend.max_rt = 3;
     }
 
     /* blend.force_srgb = !!rs[D3DRS_SRGBWRITEENABLE]; */
index 0d429dac460bcd6836a54890f7f0860b449ee155..10e9b6a38c427e22ab70f7ab0d653ba28da7aca1 100644 (file)
@@ -201,6 +201,8 @@ st_update_blend( struct st_context *st )
 
    memset(blend, 0, sizeof(*blend));
 
+   blend->max_rt = MAX2(1, num_cb) - 1;
+
    if (num_cb > 1 &&
        (blend_per_rt(st, num_cb) || colormask_per_rt(ctx, num_cb))) {
       num_state = num_cb;
index 3cf4c79f083a573b0d15822e03c8b86c2693e534..b7d44d2c1b54fc7af66639ac24bfe2be73974853 100644 (file)
@@ -280,6 +280,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
          int i;
 
          blend.independent_blend_enable = num_buffers > 1;
+         blend.max_rt = num_buffers - 1;
 
          for (i = 0; i < num_buffers; i++) {
             if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))