radeonsi: make sure that blend state != NULL and remove all NULL checking
authorMarek Olšák <marek.olsak@amd.com>
Tue, 30 Jul 2019 21:43:41 +0000 (17:43 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 6 Aug 2019 21:08:39 +0000 (17:08 -0400)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_blitter.h
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_binning.c
src/gallium/drivers/radeonsi/si_state_shaders.c

index ffe1a8d46f0c75fe7ce65c2fef7affe844c95afe..ff4e9a721b365d1db5e2da26cec84a9a867d4ead 100644 (file)
@@ -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)
 {
index a57e09f5fd1fa76f6d906d90ea9065e13390a1c2..0db9c2a281639ec21f4abd572caec082c6e7514d 100644 (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_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.
index 74d58d4993c65eaf25ff1f89cb2750b1641a17ec..98f15db8cad5654fa7b3f9f156283eda4d218960 100644 (file)
@@ -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);
        }
index 1f9fe1c475495b6cd4db6fd04cbbaac1193363fd..6060c579ceb98b6c4717806207530322d66726e7 100644 (file)
@@ -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;
index dbc667e714a2b5d6c22118b72d7f52f8aebc9839..eb191b927c4dfb1a825147efebb3eca003dddd52 100644 (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;
        /* 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)
index be0dd3c1bcb0e4181fc4ab87c01a04fa9868b531..ce87acab69ad4dcb1cfa6013844507144099de9c 100644 (file)
@@ -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;
        }
index dbd918d58f13123798762013af5dbfdd058a5683..81ba9410cdb704f1e7eae494fc47949d14a129c5 100644 (file)
@@ -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) ||