From: Rob Clark Date: Thu, 16 Apr 2020 17:53:03 +0000 (-0700) Subject: gallium: add # of MRT to blend state X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=85f84ea148474554af42ca513b9cb7c43a78a738;p=mesa.git gallium: add # of MRT to blend state 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 Reviewed-by: Kristian H. Kristensen Reviewed-by: Eric Anholt Reviewed-by: Marek Olšák Part-of: --- diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.c b/src/gallium/auxiliary/driver_trace/tr_dump_state.c index bd0d7204cff..49d2109101a 100644 --- a/src/gallium/auxiliary/driver_trace/tr_dump_state.c +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.c @@ -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(); diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index fd7813aae11..d5b886ca36f 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -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; } } diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index 422dc86754f..f57a5923ad0 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -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); } diff --git a/src/gallium/docs/source/cso/blend.rst b/src/gallium/docs/source/cso/blend.rst index 7316e5c71cf..be5a2ef7956 100644 --- a/src/gallium/docs/source/cso/blend.rst +++ b/src/gallium/docs/source/cso/blend.rst @@ -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 diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 736649acd2f..c557ecc1869 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -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]; }; diff --git a/src/gallium/state_trackers/nine/nine_pipe.c b/src/gallium/state_trackers/nine/nine_pipe.c index dd858aef743..7531845efd6 100644 --- a/src/gallium/state_trackers/nine/nine_pipe.c +++ b/src/gallium/state_trackers/nine/nine_pipe.c @@ -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]; */ diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 0d429dac460..10e9b6a38c4 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -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; diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 3cf4c79f083..b7d44d2c1b5 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -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)))