radeonsi: make sure that blend state != NULL and remove all NULL checking

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
This commit is contained in:
Marek Olšák 2019-07-30 17:43:41 -04:00
parent 8b68511ebc
commit b758eed9c3
7 changed files with 51 additions and 54 deletions

View file

@ -340,6 +340,13 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
return &ctx->base; 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, static void bind_vs_pos_only(struct blitter_context_priv *ctx,
unsigned num_so_channels) unsigned num_so_channels)
{ {

View file

@ -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_destroy(struct blitter_context *blitter);
void util_blitter_cache_all_shaders(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. * Return the pipe context associated with a blitter context.

View file

@ -543,6 +543,10 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen,
goto fail; goto fail;
sctx->blitter->skip_viewport_restore = true; 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_init_draw_functions(sctx);
si_initialize_prim_discard_tunables(sctx); si_initialize_prim_discard_tunables(sctx);
} }

View file

@ -886,6 +886,7 @@ struct si_context {
void (*emit_cache_flush)(struct si_context *ctx); void (*emit_cache_flush)(struct si_context *ctx);
struct blitter_context *blitter; struct blitter_context *blitter;
void *noop_blend;
void *custom_dsa_flush; void *custom_dsa_flush;
void *custom_blend_resolve; void *custom_blend_resolve;
void *custom_blend_fmask_decompress; void *custom_blend_fmask_decompress;

View file

@ -82,19 +82,17 @@ static void si_emit_cb_render_state(struct si_context *sctx)
struct si_state_blend *blend = sctx->queued.named.blend; struct si_state_blend *blend = sctx->queued.named.blend;
/* CB_COLORn_INFO.FORMAT=INVALID should disable unbound colorbuffers, /* CB_COLORn_INFO.FORMAT=INVALID should disable unbound colorbuffers,
* but you never know. */ * 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; unsigned i;
if (blend)
cb_target_mask &= blend->cb_target_mask;
/* Avoid a hang that happens when dual source blending is enabled /* Avoid a hang that happens when dual source blending is enabled
* but there is not enough color outputs. This is undefined behavior, * but there is not enough color outputs. This is undefined behavior,
* so disable color writes completely. * so disable color writes completely.
* *
* Reproducible with Unigine Heaven 4.0 and drirc missing. * 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 &&
(sctx->ps_shader.cso->info.colors_written & 0x3) != 0x3) (sctx->ps_shader.cso->info.colors_written & 0x3) != 0x3)
cb_target_mask = 0; 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_- * Alternatively, we can set CB_COLORi_DCC_CONTROL.OVERWRITE_-
* COMBINER_DISABLE, but that would be more complicated. * COMBINER_DISABLE, but that would be more complicated.
*/ */
bool oc_disable = blend && bool oc_disable = blend->dcc_msaa_corruption_4bit & cb_target_mask &&
blend->dcc_msaa_corruption_4bit & cb_target_mask &&
sctx->framebuffer.nr_samples >= 2; sctx->framebuffer.nr_samples >= 2;
unsigned watermark = sctx->framebuffer.dcc_overwrite_combiner_watermark; 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 *old_blend = sctx->queued.named.blend;
struct si_state_blend *blend = (struct si_state_blend *)state; struct si_state_blend *blend = (struct si_state_blend *)state;
if (!state) if (!blend)
return; 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 || if (old_blend->cb_target_mask != blend->cb_target_mask ||
old_blend->cb_target_mask != blend->cb_target_mask ||
old_blend->dual_src_blend != blend->dual_src_blend || old_blend->dual_src_blend != blend->dual_src_blend ||
(old_blend->blend_enable_4bit != blend->blend_enable_4bit && (old_blend->blend_enable_4bit != blend->blend_enable_4bit &&
sctx->framebuffer.nr_samples >= 2 && sctx->framebuffer.nr_samples >= 2 &&
sctx->screen->dcc_msaa_allowed)) sctx->screen->dcc_msaa_allowed))
si_mark_atom_dirty(sctx, &sctx->atoms.s.cb_render_state); si_mark_atom_dirty(sctx, &sctx->atoms.s.cb_render_state);
if (!old_blend || if (old_blend->cb_target_mask != blend->cb_target_mask ||
old_blend->cb_target_mask != blend->cb_target_mask ||
old_blend->alpha_to_coverage != blend->alpha_to_coverage || old_blend->alpha_to_coverage != blend->alpha_to_coverage ||
old_blend->alpha_to_one != blend->alpha_to_one || old_blend->alpha_to_one != blend->alpha_to_one ||
old_blend->dual_src_blend != blend->dual_src_blend || 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; sctx->do_update_shaders = true;
if (sctx->screen->dpbb_allowed && 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->blend_enable_4bit != blend->blend_enable_4bit ||
old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit)) old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit))
si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state); si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state);
if (sctx->screen->has_out_of_order_rast && 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->cb_target_enabled_4bit != blend->cb_target_enabled_4bit ||
old_blend->commutative_4bit != blend->commutative_4bit || old_blend->commutative_4bit != blend->commutative_4bit ||
old_blend->logicop_enable != blend->logicop_enable))) 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; unsigned colormask = sctx->framebuffer.colorbuf_enabled_4bit;
if (blend) { colormask &= blend->cb_target_enabled_4bit;
colormask &= blend->cb_target_enabled_4bit;
} else {
colormask = 0;
}
/* Conservative: No logic op. */ /* Conservative: No logic op. */
if (colormask && blend->logicop_enable) if (colormask && blend->logicop_enable)

View file

@ -483,7 +483,7 @@ void si_emit_dpbb_state(struct si_context *sctx)
assert(sctx->chip_class >= GFX9); 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); si_emit_dpbb_disable(sctx);
return; return;
} }

View file

@ -1759,13 +1759,11 @@ static void si_shader_selector_key_hw_vs(struct si_context *sctx,
/* Find out if PS is disabled. */ /* Find out if PS is disabled. */
bool ps_disabled = true; bool ps_disabled = true;
if (ps) { 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 || bool ps_modifies_zs = ps->info.uses_kill ||
ps->info.writes_z || ps->info.writes_z ||
ps->info.writes_stencil || ps->info.writes_stencil ||
ps->info.writes_samplemask || ps->info.writes_samplemask ||
alpha_to_coverage || sctx->queued.named.blend->alpha_to_coverage ||
si_get_alpha_test_func(sctx) != PIPE_FUNC_ALWAYS; si_get_alpha_test_func(sctx) != PIPE_FUNC_ALWAYS;
unsigned ps_colormask = si_get_total_colormask(sctx); 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) sel->info.colors_written == 0x1)
key->part.ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1; key->part.ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1;
if (blend) { /* Select the shader color format based on whether
/* Select the shader color format based on whether * blending or alpha are needed.
* blending or alpha are needed. */
*/ key->part.ps.epilog.spi_shader_col_format =
key->part.ps.epilog.spi_shader_col_format = (blend->blend_enable_4bit & blend->need_src_alpha_4bit &
(blend->blend_enable_4bit & blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format_blend_alpha) |
sctx->framebuffer.spi_shader_col_format_blend_alpha) | (blend->blend_enable_4bit & ~blend->need_src_alpha_4bit &
(blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format_blend) |
sctx->framebuffer.spi_shader_col_format_blend) | (~blend->blend_enable_4bit & blend->need_src_alpha_4bit &
(~blend->blend_enable_4bit & blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format_alpha) |
sctx->framebuffer.spi_shader_col_format_alpha) | (~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit &
(~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format);
sctx->framebuffer.spi_shader_col_format); key->part.ps.epilog.spi_shader_col_format &= blend->cb_target_enabled_4bit;
key->part.ps.epilog.spi_shader_col_format &= blend->cb_target_enabled_4bit;
/* The output for dual source blending should have /* The output for dual source blending should have
* the same format as the first output. * the same format as the first output.
*/ */
if (blend->dual_src_blend) if (blend->dual_src_blend) {
key->part.ps.epilog.spi_shader_col_format |= key->part.ps.epilog.spi_shader_col_format |=
(key->part.ps.epilog.spi_shader_col_format & 0xf) << 4; (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;
/* If alpha-to-coverage is enabled, we have to export alpha /* If alpha-to-coverage is enabled, we have to export alpha
* even if there is no color buffer. * even if there is no color buffer.
*/ */
if (!(key->part.ps.epilog.spi_shader_col_format & 0xf) && 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; 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 /* 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.color_two_side = rs->two_side && sel->info.colors_read;
key->part.ps.prolog.flatshade_colors = rs->flatshade && 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 = blend->alpha_to_one &&
key->part.ps.epilog.alpha_to_one = sctx->queued.named.blend->alpha_to_one && rs->multisample_enable;
rs->multisample_enable;
}
key->part.ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly; key->part.ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly;
key->part.ps.epilog.poly_line_smoothing = ((is_poly && rs->poly_smooth) || key->part.ps.epilog.poly_line_smoothing = ((is_poly && rs->poly_smooth) ||