From b758eed9c373db14a5acc04d9522ec9d74e51f1b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 30 Jul 2019 17:43:41 -0400 Subject: [PATCH] radeonsi: make sure that blend state != NULL and remove all NULL checking Reviewed-by: Pierre-Eric Pelloux-Prayer --- src/gallium/auxiliary/util/u_blitter.c | 7 +++ src/gallium/auxiliary/util/u_blitter.h | 2 + src/gallium/drivers/radeonsi/si_pipe.c | 4 ++ src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 35 ++++-------- .../drivers/radeonsi/si_state_binning.c | 2 +- .../drivers/radeonsi/si_state_shaders.c | 56 +++++++++---------- 7 files changed, 52 insertions(+), 55 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index ffe1a8d46f0..ff4e9a721b3 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -340,6 +340,13 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) return &ctx->base; } +void *util_blitter_get_noop_blend_state(struct blitter_context *blitter) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + + return ctx->blend[0][0]; +} + static void bind_vs_pos_only(struct blitter_context_priv *ctx, unsigned num_so_channels) { diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index a57e09f5fd1..0db9c2a2816 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -154,6 +154,8 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe); void util_blitter_destroy(struct blitter_context *blitter); void util_blitter_cache_all_shaders(struct blitter_context *blitter); +void *util_blitter_get_noop_blend_state(struct blitter_context *blitter); + /** * Return the pipe context associated with a blitter context. diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 74d58d4993c..98f15db8cad 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -543,6 +543,10 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, goto fail; sctx->blitter->skip_viewport_restore = true; + /* Some states are expected to be always non-NULL. */ + sctx->noop_blend = util_blitter_get_noop_blend_state(sctx->blitter); + sctx->queued.named.blend = sctx->noop_blend; + si_init_draw_functions(sctx); si_initialize_prim_discard_tunables(sctx); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 1f9fe1c4754..6060c579ceb 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -886,6 +886,7 @@ struct si_context { void (*emit_cache_flush)(struct si_context *ctx); struct blitter_context *blitter; + void *noop_blend; void *custom_dsa_flush; void *custom_blend_resolve; void *custom_blend_fmask_decompress; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index dbc667e714a..eb191b927c4 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -82,19 +82,17 @@ static void si_emit_cb_render_state(struct si_context *sctx) struct si_state_blend *blend = sctx->queued.named.blend; /* CB_COLORn_INFO.FORMAT=INVALID should disable unbound colorbuffers, * but you never know. */ - uint32_t cb_target_mask = sctx->framebuffer.colorbuf_enabled_4bit; + uint32_t cb_target_mask = sctx->framebuffer.colorbuf_enabled_4bit & + blend->cb_target_mask; unsigned i; - if (blend) - cb_target_mask &= blend->cb_target_mask; - /* Avoid a hang that happens when dual source blending is enabled * but there is not enough color outputs. This is undefined behavior, * so disable color writes completely. * * Reproducible with Unigine Heaven 4.0 and drirc missing. */ - if (blend && blend->dual_src_blend && + if (blend->dual_src_blend && sctx->ps_shader.cso && (sctx->ps_shader.cso->info.colors_written & 0x3) != 0x3) cb_target_mask = 0; @@ -119,8 +117,7 @@ static void si_emit_cb_render_state(struct si_context *sctx) * Alternatively, we can set CB_COLORi_DCC_CONTROL.OVERWRITE_- * COMBINER_DISABLE, but that would be more complicated. */ - bool oc_disable = blend && - blend->dcc_msaa_corruption_4bit & cb_target_mask && + bool oc_disable = blend->dcc_msaa_corruption_4bit & cb_target_mask && sctx->framebuffer.nr_samples >= 2; unsigned watermark = sctx->framebuffer.dcc_overwrite_combiner_watermark; @@ -681,21 +678,19 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state) struct si_state_blend *old_blend = sctx->queued.named.blend; struct si_state_blend *blend = (struct si_state_blend *)state; - if (!state) - return; + if (!blend) + blend = (struct si_state_blend *)sctx->noop_blend; - si_pm4_bind_state(sctx, blend, state); + si_pm4_bind_state(sctx, blend, blend); - if (!old_blend || - old_blend->cb_target_mask != blend->cb_target_mask || + if (old_blend->cb_target_mask != blend->cb_target_mask || old_blend->dual_src_blend != blend->dual_src_blend || (old_blend->blend_enable_4bit != blend->blend_enable_4bit && sctx->framebuffer.nr_samples >= 2 && sctx->screen->dcc_msaa_allowed)) si_mark_atom_dirty(sctx, &sctx->atoms.s.cb_render_state); - if (!old_blend || - old_blend->cb_target_mask != blend->cb_target_mask || + if (old_blend->cb_target_mask != blend->cb_target_mask || old_blend->alpha_to_coverage != blend->alpha_to_coverage || old_blend->alpha_to_one != blend->alpha_to_one || old_blend->dual_src_blend != blend->dual_src_blend || @@ -704,15 +699,13 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state) sctx->do_update_shaders = true; if (sctx->screen->dpbb_allowed && - (!old_blend || - old_blend->alpha_to_coverage != blend->alpha_to_coverage || + (old_blend->alpha_to_coverage != blend->alpha_to_coverage || old_blend->blend_enable_4bit != blend->blend_enable_4bit || old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit)) si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state); if (sctx->screen->has_out_of_order_rast && - (!old_blend || - (old_blend->blend_enable_4bit != blend->blend_enable_4bit || + ((old_blend->blend_enable_4bit != blend->blend_enable_4bit || old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit || old_blend->commutative_4bit != blend->commutative_4bit || old_blend->logicop_enable != blend->logicop_enable))) @@ -3543,11 +3536,7 @@ static bool si_out_of_order_rasterization(struct si_context *sctx) unsigned colormask = sctx->framebuffer.colorbuf_enabled_4bit; - if (blend) { - colormask &= blend->cb_target_enabled_4bit; - } else { - colormask = 0; - } + colormask &= blend->cb_target_enabled_4bit; /* Conservative: No logic op. */ if (colormask && blend->logicop_enable) diff --git a/src/gallium/drivers/radeonsi/si_state_binning.c b/src/gallium/drivers/radeonsi/si_state_binning.c index be0dd3c1bcb..ce87acab69a 100644 --- a/src/gallium/drivers/radeonsi/si_state_binning.c +++ b/src/gallium/drivers/radeonsi/si_state_binning.c @@ -483,7 +483,7 @@ void si_emit_dpbb_state(struct si_context *sctx) assert(sctx->chip_class >= GFX9); - if (!sscreen->dpbb_allowed || !blend || !dsa || sctx->dpbb_force_off) { + if (!sscreen->dpbb_allowed || !dsa || sctx->dpbb_force_off) { si_emit_dpbb_disable(sctx); return; } diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index dbd918d58f1..81ba9410cdb 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1759,13 +1759,11 @@ static void si_shader_selector_key_hw_vs(struct si_context *sctx, /* Find out if PS is disabled. */ bool ps_disabled = true; if (ps) { - const struct si_state_blend *blend = sctx->queued.named.blend; - bool alpha_to_coverage = blend && blend->alpha_to_coverage; bool ps_modifies_zs = ps->info.uses_kill || ps->info.writes_z || ps->info.writes_stencil || ps->info.writes_samplemask || - alpha_to_coverage || + sctx->queued.named.blend->alpha_to_coverage || si_get_alpha_test_func(sctx) != PIPE_FUNC_ALWAYS; unsigned ps_colormask = si_get_total_colormask(sctx); @@ -1904,35 +1902,33 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, sel->info.colors_written == 0x1) key->part.ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1; - if (blend) { - /* Select the shader color format based on whether - * blending or alpha are needed. - */ - key->part.ps.epilog.spi_shader_col_format = - (blend->blend_enable_4bit & blend->need_src_alpha_4bit & - sctx->framebuffer.spi_shader_col_format_blend_alpha) | - (blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & - sctx->framebuffer.spi_shader_col_format_blend) | - (~blend->blend_enable_4bit & blend->need_src_alpha_4bit & - sctx->framebuffer.spi_shader_col_format_alpha) | - (~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & - sctx->framebuffer.spi_shader_col_format); - key->part.ps.epilog.spi_shader_col_format &= blend->cb_target_enabled_4bit; - - /* The output for dual source blending should have - * the same format as the first output. - */ - if (blend->dual_src_blend) - key->part.ps.epilog.spi_shader_col_format |= - (key->part.ps.epilog.spi_shader_col_format & 0xf) << 4; - } else - key->part.ps.epilog.spi_shader_col_format = sctx->framebuffer.spi_shader_col_format; + /* Select the shader color format based on whether + * blending or alpha are needed. + */ + key->part.ps.epilog.spi_shader_col_format = + (blend->blend_enable_4bit & blend->need_src_alpha_4bit & + sctx->framebuffer.spi_shader_col_format_blend_alpha) | + (blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & + sctx->framebuffer.spi_shader_col_format_blend) | + (~blend->blend_enable_4bit & blend->need_src_alpha_4bit & + sctx->framebuffer.spi_shader_col_format_alpha) | + (~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & + sctx->framebuffer.spi_shader_col_format); + key->part.ps.epilog.spi_shader_col_format &= blend->cb_target_enabled_4bit; + + /* The output for dual source blending should have + * the same format as the first output. + */ + if (blend->dual_src_blend) { + key->part.ps.epilog.spi_shader_col_format |= + (key->part.ps.epilog.spi_shader_col_format & 0xf) << 4; + } /* If alpha-to-coverage is enabled, we have to export alpha * even if there is no color buffer. */ if (!(key->part.ps.epilog.spi_shader_col_format & 0xf) && - blend && blend->alpha_to_coverage) + blend->alpha_to_coverage) key->part.ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_32_AR; /* On GFX6 and GFX7 except Hawaii, the CB doesn't clamp outputs @@ -1957,10 +1953,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, key->part.ps.prolog.color_two_side = rs->two_side && sel->info.colors_read; key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.colors_read; - if (sctx->queued.named.blend) { - key->part.ps.epilog.alpha_to_one = sctx->queued.named.blend->alpha_to_one && - rs->multisample_enable; - } + key->part.ps.epilog.alpha_to_one = blend->alpha_to_one && + rs->multisample_enable; key->part.ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly; key->part.ps.epilog.poly_line_smoothing = ((is_poly && rs->poly_smooth) || -- 2.30.2