radeonsi: make sure that DSA state != NULL and remove all NULL checking
[mesa.git] / src / gallium / drivers / radeonsi / si_state.c
index 8a540082364c67eca3c5e729f2dc6534c8b9bc6a..fad027a13f28dda850b7e273a0ea079feb426aec 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;
@@ -102,12 +100,12 @@ static void si_emit_cb_render_state(struct si_context *sctx)
        /* GFX9: Flush DFSM when CB_TARGET_MASK changes.
         * I think we don't have to do anything between IBs.
         */
-       if (sctx->screen->dfsm_allowed &&
+       if (sctx->screen->dpbb_allowed &&
            sctx->last_cb_target_mask != cb_target_mask) {
                sctx->last_cb_target_mask = cb_target_mask;
 
                radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
-               radeon_emit(cs, EVENT_TYPE(V_028A90_FLUSH_DFSM) | EVENT_INDEX(0));
+               radeon_emit(cs, EVENT_TYPE(V_028A90_BREAK_BATCH) | EVENT_INDEX(0));
        }
 
        unsigned initial_cdw = cs->current.cdw;
@@ -115,21 +113,18 @@ static void si_emit_cb_render_state(struct si_context *sctx)
                                   SI_TRACKED_CB_TARGET_MASK, cb_target_mask);
 
        if (sctx->chip_class >= GFX8) {
-               /* DCC MSAA workaround for blending.
+               /* DCC MSAA workaround.
                 * Alternatively, we can set CB_COLORi_DCC_CONTROL.OVERWRITE_-
                 * COMBINER_DISABLE, but that would be more complicated.
                 */
-               bool oc_disable = (sctx->chip_class == GFX8 ||
-                                  sctx->chip_class == GFX9) &&
-                                 blend &&
-                                 blend->blend_enable_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;
 
                radeon_opt_set_context_reg(
                                sctx, R_028424_CB_DCC_CONTROL,
                                SI_TRACKED_CB_DCC_CONTROL,
-                               S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(1) |
+                               S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(sctx->chip_class <= GFX9) |
                                S_028424_OVERWRITE_COMBINER_WATERMARK(watermark) |
                                S_028424_OVERWRITE_COMBINER_DISABLE(oc_disable) |
                                S_028424_DISABLE_CONSTANT_ENCODE_REG(sctx->screen->has_dcc_constant_encode));
@@ -150,8 +145,15 @@ static void si_emit_cb_render_state(struct si_context *sctx)
                        unsigned format, swap, spi_format, colormask;
                        bool has_alpha, has_rgb;
 
-                       if (!surf)
+                       if (!surf) {
+                               /* If the color buffer is not set, the driver sets 32_R
+                                * as the SPI color format, because the hw doesn't allow
+                                * holes between color outputs, so also set this to
+                                * enable RB+.
+                                */
+                               sx_ps_downconvert |= V_028754_SX_RT_EXPORT_32_R << (i * 4);
                                continue;
+                       }
 
                        format = G_028C70_FORMAT(surf->cb_color_info);
                        swap = G_028C70_COMP_SWAP(surf->cb_color_info);
@@ -245,10 +247,8 @@ static void si_emit_cb_render_state(struct si_context *sctx)
                                break;
 
                        case V_028C70_COLOR_10_11_11:
-                               if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
+                               if (spi_format == V_028714_SPI_SHADER_FP16_ABGR)
                                        sx_ps_downconvert |= V_028754_SX_RT_EXPORT_10_11_11 << (i * 4);
-                                       sx_blend_opt_epsilon |= V_028758_11BIT_FORMAT << (i * 4);
-                               }
                                break;
 
                        case V_028C70_COLOR_2_10_10_10:
@@ -260,6 +260,12 @@ static void si_emit_cb_render_state(struct si_context *sctx)
                        }
                }
 
+               /* If there are no color outputs, the first color export is
+                * always enabled as 32_R, so also set this to enable RB+.
+                */
+               if (!sx_ps_downconvert)
+                       sx_ps_downconvert = V_028754_SX_RT_EXPORT_32_R;
+
                /* SX_PS_DOWNCONVERT, SX_BLEND_OPT_EPSILON, SX_BLEND_OPT_CONTROL */
                radeon_opt_set_context_reg3(sctx, R_028754_SX_PS_DOWNCONVERT,
                                            SI_TRACKED_SX_PS_DOWNCONVERT,
@@ -468,6 +474,8 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
        struct si_pm4_state *pm4 = &blend->pm4;
        uint32_t sx_mrt_blend_opt[8] = {0};
        uint32_t color_control = 0;
+       bool logicop_enable = state->logicop_enable &&
+                             state->logicop_func != PIPE_LOGICOP_COPY;
 
        if (!blend)
                return NULL;
@@ -475,9 +483,9 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
        blend->alpha_to_coverage = state->alpha_to_coverage;
        blend->alpha_to_one = state->alpha_to_one;
        blend->dual_src_blend = util_blend_state_is_dual(state, 0);
-       blend->logicop_enable = state->logicop_enable;
+       blend->logicop_enable = logicop_enable;
 
-       if (state->logicop_enable) {
+       if (logicop_enable) {
                color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
        } else {
                color_control |= S_028808_ROP3(0xcc);
@@ -610,6 +618,9 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
 
                blend->blend_enable_4bit |= 0xfu << (i * 4);
 
+               if (sctx->family <= CHIP_NAVI14)
+                       blend->dcc_msaa_corruption_4bit |= 0xfu << (i * 4);
+
                /* This is only important for formats without alpha. */
                if (srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
                    dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
@@ -620,6 +631,9 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
                        blend->need_src_alpha_4bit |= 0xfu << (i * 4);
        }
 
+       if (sctx->family <= CHIP_NAVI14 && logicop_enable)
+               blend->dcc_msaa_corruption_4bit |= blend->cb_target_enabled_4bit;
+
        if (blend->cb_target_mask) {
                color_control |= S_028808_MODE(mode);
        } else {
@@ -643,7 +657,7 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
                                       sx_mrt_blend_opt[i]);
 
                /* RB+ doesn't work with dual source blending, logic op, and RESOLVE. */
-               if (blend->dual_src_blend || state->logicop_enable ||
+               if (blend->dual_src_blend || logicop_enable ||
                    mode == V_028808_CB_RESOLVE)
                        color_control |= S_028808_DISABLE_DUAL_QUAD(1);
        }
@@ -664,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 ||
@@ -687,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)))
@@ -894,6 +904,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        rs->clamp_fragment_color = state->clamp_fragment_color;
        rs->clamp_vertex_color = state->clamp_vertex_color;
        rs->flatshade = state->flatshade;
+       rs->flatshade_first = state->flatshade_first;
        rs->sprite_coord_enable = state->sprite_coord_enable;
        rs->rasterizer_discard = state->rasterizer_discard;
        rs->pa_sc_line_stipple = state->line_stipple_enable ?
@@ -1292,8 +1303,8 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
        struct si_state_dsa *old_dsa = sctx->queued.named.dsa;
         struct si_state_dsa *dsa = state;
 
-        if (!state)
-                return;
+        if (!dsa)
+                dsa = (struct si_state_dsa *)sctx->noop_dsa;
 
        si_pm4_bind_state(sctx, dsa, dsa);
 
@@ -1303,19 +1314,17 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
                si_mark_atom_dirty(sctx, &sctx->atoms.s.stencil_ref);
        }
 
-       if (!old_dsa || old_dsa->alpha_func != dsa->alpha_func)
+       if (old_dsa->alpha_func != dsa->alpha_func)
                sctx->do_update_shaders = true;
 
        if (sctx->screen->dpbb_allowed &&
-           (!old_dsa ||
-            (old_dsa->depth_enabled != dsa->depth_enabled ||
+           ((old_dsa->depth_enabled != dsa->depth_enabled ||
              old_dsa->stencil_enabled != dsa->stencil_enabled ||
              old_dsa->db_can_write != dsa->db_can_write)))
                si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state);
 
        if (sctx->screen->has_out_of_order_rast &&
-           (!old_dsa ||
-            memcmp(old_dsa->order_invariance, dsa->order_invariance,
+           (memcmp(old_dsa->order_invariance, dsa->order_invariance,
                    sizeof(old_dsa->order_invariance))))
                si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_config);
 }
@@ -1335,7 +1344,7 @@ static void *si_create_db_flush_dsa(struct si_context *sctx)
 
 /* DB RENDER STATE */
 
-static void si_set_active_query_state(struct pipe_context *ctx, boolean enable)
+static void si_set_active_query_state(struct pipe_context *ctx, bool enable)
 {
        struct si_context *sctx = (struct si_context*)ctx;
 
@@ -1423,6 +1432,7 @@ static void si_emit_db_render_state(struct si_context *sctx)
        if (sctx->num_occlusion_queries > 0 &&
            !sctx->occlusion_queries_disabled) {
                bool perfect = sctx->num_perfect_occlusion_queries > 0;
+               bool gfx10_perfect = sctx->chip_class >= GFX10 && perfect;
 
                if (sctx->chip_class >= GFX7) {
                        unsigned log_sample_rate = sctx->framebuffer.log_samples;
@@ -1435,6 +1445,7 @@ static void si_emit_db_render_state(struct si_context *sctx)
 
                        db_count_control =
                                S_028004_PERFECT_ZPASS_COUNTS(perfect) |
+                               S_028004_DISABLE_CONSERVATIVE_ZPASS_COUNTS(gfx10_perfect) |
                                S_028004_SAMPLE_RATE(log_sample_rate) |
                                S_028004_ZPASS_ENABLE(1) |
                                S_028004_SLICE_EVEN_ENABLE(1) |
@@ -1973,7 +1984,7 @@ static unsigned si_tex_dim(struct si_screen *sscreen, struct si_texture *tex,
        /* GFX9 allocates 1D textures as 2D. */
        if ((res_target == PIPE_TEXTURE_1D ||
             res_target == PIPE_TEXTURE_1D_ARRAY) &&
-           sscreen->info.chip_class >= GFX9 &&
+           sscreen->info.chip_class == GFX9 &&
            tex->surface.u.gfx9.resource_type == RADEON_RESOURCE_2D) {
                if (res_target == PIPE_TEXTURE_1D)
                        res_target = PIPE_TEXTURE_2D;
@@ -2201,12 +2212,12 @@ static bool si_is_zs_format_supported(enum pipe_format format)
        return si_translate_dbformat(format) != V_028040_Z_INVALID;
 }
 
-static boolean si_is_format_supported(struct pipe_screen *screen,
-                                     enum pipe_format format,
-                                     enum pipe_texture_target target,
-                                     unsigned sample_count,
-                                     unsigned storage_sample_count,
-                                     unsigned usage)
+static bool si_is_format_supported(struct pipe_screen *screen,
+                                  enum pipe_format format,
+                                  enum pipe_texture_target target,
+                                  unsigned sample_count,
+                                  unsigned storage_sample_count,
+                                  unsigned usage)
 {
        struct si_screen *sscreen = (struct si_screen *)screen;
        unsigned retval = 0;
@@ -2580,7 +2591,7 @@ static void si_initialize_color_surface(struct si_context *sctx,
                surf->cb_color_attrib3 = S_028EE0_MIP0_DEPTH(mip0_depth) |
                                         S_028EE0_RESOURCE_TYPE(tex->surface.u.gfx9.resource_type) |
                                         S_028EE0_RESOURCE_LEVEL(1);
-       } else if (sctx->chip_class >= GFX9) {
+       } else if (sctx->chip_class == GFX9) {
                color_view |= S_028C6C_MIP_LEVEL_GFX9(surf->base.u.tex.level);
                color_attrib |= S_028C74_MIP0_DEPTH(mip0_depth) |
                                S_028C74_RESOURCE_TYPE(tex->surface.u.gfx9.resource_type);
@@ -2648,7 +2659,7 @@ static void si_init_depth_surface(struct si_context *sctx,
                surf->db_depth_size = S_02801C_X_MAX(tex->buffer.b.b.width0 - 1) |
                                      S_02801C_Y_MAX(tex->buffer.b.b.height0 - 1);
 
-               if (si_htile_enabled(tex, level)) {
+               if (si_htile_enabled(tex, level, PIPE_MASK_ZS)) {
                        z_info |= S_028038_TILE_SURFACE_ENABLE(1) |
                                  S_028038_ALLOW_EXPCLEAR(1);
 
@@ -2663,14 +2674,14 @@ static void si_init_depth_surface(struct si_context *sctx,
 
                                if (sctx->chip_class >= GFX10) {
                                        z_info |= S_028040_ITERATE_FLUSH(1);
-                                       s_info |= S_028044_ITERATE_FLUSH(1);
+                                       s_info |= S_028044_ITERATE_FLUSH(!tex->htile_stencil_disabled);
                                } else {
                                        z_info |= S_028038_ITERATE_FLUSH(1);
                                        s_info |= S_02803C_ITERATE_FLUSH(1);
                                }
                        }
 
-                       if (tex->surface.has_stencil) {
+                       if (tex->surface.has_stencil && !tex->htile_stencil_disabled) {
                                /* Stencil buffer workaround ported from the GFX6-GFX8 code.
                                 * See that for explanation.
                                 */
@@ -2735,7 +2746,7 @@ static void si_init_depth_surface(struct si_context *sctx,
                surf->db_depth_slice = S_02805C_SLICE_TILE_MAX((levelinfo->nblk_x *
                                                                levelinfo->nblk_y) / 64 - 1);
 
-               if (si_htile_enabled(tex, level)) {
+               if (si_htile_enabled(tex, level, PIPE_MASK_ZS)) {
                        z_info |= S_028040_TILE_SURFACE_ENABLE(1) |
                                  S_028040_ALLOW_EXPCLEAR(1);
 
@@ -2963,7 +2974,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
        sctx->framebuffer.CB_has_shader_readable_metadata = false;
        sctx->framebuffer.DB_has_shader_readable_metadata = false;
        sctx->framebuffer.all_DCC_pipe_aligned = true;
-       unsigned num_bpp64_colorbufs = 0;
+       sctx->framebuffer.min_bytes_per_pixel = 0;
 
        for (i = 0; i < state->nr_cbufs; i++) {
                if (!state->cbufs[i])
@@ -3010,8 +3021,6 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 
                if (tex->surface.is_linear)
                        sctx->framebuffer.any_dst_linear = true;
-               if (tex->surface.bpe >= 8)
-                       num_bpp64_colorbufs++;
 
                if (vi_dcc_enabled(tex, surf->base.u.tex.level)) {
                        sctx->framebuffer.CB_has_shader_readable_metadata = true;
@@ -3030,15 +3039,18 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
                        sctx->framebuffer.compressed_cb_mask |= 1 << i;
                        vi_separate_dcc_start_query(sctx, tex);
                }
+
+               /* Update the minimum but don't keep 0. */
+               if (!sctx->framebuffer.min_bytes_per_pixel ||
+                   tex->surface.bpe < sctx->framebuffer.min_bytes_per_pixel)
+                       sctx->framebuffer.min_bytes_per_pixel = tex->surface.bpe;
        }
 
        /* For optimal DCC performance. */
-       if (sctx->chip_class == GFX8)
-               sctx->framebuffer.dcc_overwrite_combiner_watermark = 4;
-       else if (num_bpp64_colorbufs >= 5)
-               sctx->framebuffer.dcc_overwrite_combiner_watermark = 8;
-       else
+       if (sctx->chip_class >= GFX10)
                sctx->framebuffer.dcc_overwrite_combiner_watermark = 6;
+       else
+               sctx->framebuffer.dcc_overwrite_combiner_watermark = 4;
 
        struct si_texture *zstex = NULL;
 
@@ -3050,10 +3062,16 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
                        si_init_depth_surface(sctx, surf);
                }
 
-               if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level))
+               if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level,
+                                              PIPE_MASK_ZS))
                        sctx->framebuffer.DB_has_shader_readable_metadata = true;
 
                si_context_add_resource_size(sctx, surf->base.texture);
+
+               /* Update the minimum but don't keep 0. */
+               if (!sctx->framebuffer.min_bytes_per_pixel ||
+                   zstex->surface.bpe < sctx->framebuffer.min_bytes_per_pixel)
+                       sctx->framebuffer.min_bytes_per_pixel = zstex->surface.bpe;
        }
 
        si_update_ps_colorbuf0_slot(sctx);
@@ -3245,7 +3263,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx)
                                               cb->cb_color_attrib2);
                        radeon_set_context_reg(cs, R_028EE0_CB_COLOR0_ATTRIB3 + i * 4,
                                               cb_color_attrib3);
-               } else if (sctx->chip_class >= GFX9) {
+               } else if (sctx->chip_class == GFX9) {
                        struct gfx9_surf_meta_flags meta;
 
                        if (tex->dcc_offset)
@@ -3380,7 +3398,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx)
                        radeon_emit(cs, zb->db_depth_base >> 32);       /* DB_Z_WRITE_BASE_HI */
                        radeon_emit(cs, zb->db_stencil_base >> 32);     /* DB_STENCIL_WRITE_BASE_HI */
                        radeon_emit(cs, zb->db_htile_data_base >> 32);  /* DB_HTILE_DATA_BASE_HI */
-               } else if (sctx->chip_class >= GFX9) {
+               } else if (sctx->chip_class == GFX9) {
                        radeon_set_context_reg_seq(cs, R_028014_DB_HTILE_DATA_BASE, 3);
                        radeon_emit(cs, zb->db_htile_data_base);        /* DB_HTILE_DATA_BASE */
                        radeon_emit(cs, S_028018_BASE_HI(zb->db_htile_data_base >> 32)); /* DB_HTILE_DATA_BASE_HI */
@@ -3516,11 +3534,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)
@@ -3908,7 +3922,7 @@ gfx10_make_texture_descriptor(struct si_screen *screen,
                        /*
                         * X24S8 is implemented as an 8_8_8_8 data format, to
                         * fix texture gathers. This affects at least
-                        * GL45-CTS.texture_cube_map_array.sampling on VI.
+                        * GL45-CTS.texture_cube_map_array.sampling on GFX8.
                         */
                        util_format_compose_swizzles(swizzle_wwww, state_swizzle, swizzle);
                        is_stencil = true;
@@ -3981,7 +3995,7 @@ gfx10_make_texture_descriptor(struct si_screen *screen,
        if (tex->dcc_offset) {
                state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
                            S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B) |
-                           S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(pipe_format));
+                           S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(screen, pipe_format));
        }
 
        /* Initialize the sampler view for FMASK. */
@@ -4188,7 +4202,7 @@ si_make_texture_descriptor(struct si_screen *screen,
        }
 
        /* S8 with Z32 HTILE needs a special format. */
-       if (screen->info.chip_class >= GFX9 &&
+       if (screen->info.chip_class == GFX9 &&
            pipe_format == PIPE_FORMAT_S8_UINT &&
            tex->tc_compatible_htile)
                data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
@@ -4240,7 +4254,7 @@ si_make_texture_descriptor(struct si_screen *screen,
        state[6] = 0;
        state[7] = 0;
 
-       if (screen->info.chip_class >= GFX9) {
+       if (screen->info.chip_class == GFX9) {
                unsigned bc_swizzle = gfx9_border_color_swizzle(desc->swizzle);
 
                /* Depth is the the last accessible layer on Gfx9.
@@ -4262,7 +4276,7 @@ si_make_texture_descriptor(struct si_screen *screen,
        }
 
        if (tex->dcc_offset) {
-               state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(pipe_format));
+               state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(screen, pipe_format));
        } else {
                /* The last dword is unused by hw. The shader uses it to clear
                 * bits in the first dword of sampler state.
@@ -4282,7 +4296,7 @@ si_make_texture_descriptor(struct si_screen *screen,
                va = tex->buffer.gpu_address + tex->fmask_offset;
 
 #define FMASK(s,f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f)))
-               if (screen->info.chip_class >= GFX9) {
+               if (screen->info.chip_class == GFX9) {
                        data_format = V_008F14_IMG_DATA_FORMAT_FMASK;
                        switch (FMASK(res->nr_samples, res->nr_storage_samples)) {
                        case FMASK(2,1):
@@ -4391,7 +4405,7 @@ si_make_texture_descriptor(struct si_screen *screen,
                fmask_state[6] = 0;
                fmask_state[7] = 0;
 
-               if (screen->info.chip_class >= GFX9) {
+               if (screen->info.chip_class == GFX9) {
                        fmask_state[3] |= S_008F1C_SW_MODE(tex->surface.u.gfx9.fmask.swizzle_mode);
                        fmask_state[4] |= S_008F20_DEPTH(last_layer) |
                                          S_008F20_PITCH(tex->surface.u.gfx9.fmask.epitch);
@@ -4972,7 +4986,9 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
                 * into account would complicate the fast path (where everything
                 * is nicely aligned).
                 */
-               bool check_alignment = log_hw_load_size >= 1 && sscreen->info.chip_class == GFX6;
+               bool check_alignment =
+                       log_hw_load_size >= 1 &&
+                       (sscreen->info.chip_class == GFX6 || sscreen->info.chip_class == GFX10);
                bool opencode = sscreen->options.vs_fetch_always_opencode;
 
                if (check_alignment &&
@@ -5389,10 +5405,6 @@ static void si_init_config(struct si_context *sctx)
        bool has_clear_state = sscreen->has_clear_state;
        struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
 
-       /* GFX6, radeon kernel disabled CLEAR_STATE. */
-       assert(has_clear_state || sscreen->info.chip_class == GFX6 ||
-              !sscreen->info.is_amdgpu);
-
        if (!pm4)
                return;
 
@@ -5436,7 +5448,7 @@ static void si_init_config(struct si_context *sctx)
        /* CLEAR_STATE doesn't clear these correctly on certain generations.
         * I don't know why. Deduced by trial and error.
         */
-       if (sctx->chip_class <= GFX7) {
+       if (sctx->chip_class <= GFX7 || !has_clear_state) {
                si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
                si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, S_028204_WINDOW_OFFSET_DISABLE(1));
                si_pm4_set_reg(pm4, R_028240_PA_SC_GENERIC_SCISSOR_TL, S_028240_WINDOW_OFFSET_DISABLE(1));
@@ -5465,10 +5477,13 @@ static void si_init_config(struct si_context *sctx)
        }
 
        if (sctx->chip_class >= GFX10) {
+               si_pm4_set_reg(pm4, R_028A98_VGT_DRAW_PAYLOAD_CNTL, 0);
                si_pm4_set_reg(pm4, R_030964_GE_MAX_VTX_INDX, ~0);
                si_pm4_set_reg(pm4, R_030924_GE_MIN_VTX_INDX, 0);
                si_pm4_set_reg(pm4, R_030928_GE_INDX_OFFSET, 0);
-       } else if (sctx->chip_class >= GFX9) {
+               si_pm4_set_reg(pm4, R_03097C_GE_STEREO_CNTL, 0);
+               si_pm4_set_reg(pm4, R_030988_GE_USER_VGPR_EN, 0);
+       } else if (sctx->chip_class == GFX9) {
                si_pm4_set_reg(pm4, R_030920_VGT_MAX_VTX_INDX, ~0);
                si_pm4_set_reg(pm4, R_030924_VGT_MIN_VTX_INDX, 0);
                si_pm4_set_reg(pm4, R_030928_VGT_INDX_OFFSET, 0);
@@ -5487,9 +5502,6 @@ static void si_init_config(struct si_context *sctx)
                        /* Logical CUs 16 - 31 */
                        si_pm4_set_reg(pm4, R_00B404_SPI_SHADER_PGM_RSRC4_HS,
                                       S_00B404_CU_EN(0xffff));
-                       si_pm4_set_reg(pm4, R_00B204_SPI_SHADER_PGM_RSRC4_GS,
-                                      S_00B204_CU_EN(0xffff) |
-                                      S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(0));
                        si_pm4_set_reg(pm4, R_00B104_SPI_SHADER_PGM_RSRC4_VS,
                                       S_00B104_CU_EN(0xffff));
                        si_pm4_set_reg(pm4, R_00B004_SPI_SHADER_PGM_RSRC4_PS,
@@ -5515,8 +5527,6 @@ static void si_init_config(struct si_context *sctx)
                                       S_028A44_ES_VERTS_PER_SUBGRP(64) |
                                       S_028A44_GS_PRIMS_PER_SUBGRP(4));
                }
-               si_pm4_set_reg(pm4, R_00B21C_SPI_SHADER_PGM_RSRC3_GS,
-                              S_00B21C_CU_EN(0xffff) | S_00B21C_WAVE_LIMIT(0x3F));
 
                /* Compute LATE_ALLOC_VS.LIMIT. */
                unsigned num_cu_per_sh = sscreen->info.num_good_cu_per_sh;
@@ -5540,13 +5550,35 @@ static void si_init_config(struct si_context *sctx)
                        late_alloc_limit = (num_cu_per_sh - 2) * 4;
                }
 
+               unsigned cu_mask_vs = 0xffff;
+               unsigned cu_mask_gs = 0xffff;
+
+               if (late_alloc_limit > 2) {
+                       if (sctx->chip_class >= GFX10) {
+                               /* CU2 & CU3 disabled because of the dual CU design */
+                               cu_mask_vs = 0xfff3;
+                               cu_mask_gs = 0xfff3; /* NGG only */
+                       } else {
+                               cu_mask_vs = 0xfffe; /* 1 CU disabled */
+                       }
+               }
+
                /* VS can't execute on one CU if the limit is > 2. */
                si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS,
-                       S_00B118_CU_EN(late_alloc_limit > 2 ? 0xfffe : 0xffff) |
+                       S_00B118_CU_EN(cu_mask_vs) |
                        S_00B118_WAVE_LIMIT(0x3F));
                si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS,
                        S_00B11C_LIMIT(late_alloc_limit));
 
+               si_pm4_set_reg(pm4, R_00B21C_SPI_SHADER_PGM_RSRC3_GS,
+                              S_00B21C_CU_EN(cu_mask_gs) | S_00B21C_WAVE_LIMIT(0x3F));
+
+               if (sctx->chip_class >= GFX10) {
+                       si_pm4_set_reg(pm4, R_00B204_SPI_SHADER_PGM_RSRC4_GS,
+                                      S_00B204_CU_EN(0xffff) |
+                                      S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(late_alloc_limit));
+               }
+
                si_pm4_set_reg(pm4, R_00B01C_SPI_SHADER_PGM_RSRC3_PS,
                               S_00B01C_CU_EN(0xffff) | S_00B01C_WAVE_LIMIT(0x3F));
        }
@@ -5563,7 +5595,35 @@ static void si_init_config(struct si_context *sctx)
                 */
                si_pm4_set_reg(pm4, R_028C50_PA_SC_NGG_MODE_CNTL,
                               S_028C50_MAX_DEALLOCS_IN_WAVE(512));
-               si_pm4_set_reg(pm4, R_028838_PA_CL_NGG_CNTL, 0); /* TODO edge flags? */
+               si_pm4_set_reg(pm4, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL, 14);
+               si_pm4_set_reg(pm4, R_02835C_PA_SC_TILE_STEERING_OVERRIDE,
+                              sscreen->info.pa_sc_tile_steering_override);
+
+               si_pm4_set_reg(pm4, R_02807C_DB_RMI_L2_CACHE_CONTROL,
+                              S_02807C_Z_WR_POLICY(V_02807C_CACHE_STREAM_WR) |
+                              S_02807C_S_WR_POLICY(V_02807C_CACHE_STREAM_WR) |
+                              S_02807C_HTILE_WR_POLICY(V_02807C_CACHE_STREAM_WR) |
+                              S_02807C_ZPCPSD_WR_POLICY(V_02807C_CACHE_STREAM_WR) |
+                              S_02807C_Z_RD_POLICY(V_02807C_CACHE_NOA_RD) |
+                              S_02807C_S_RD_POLICY(V_02807C_CACHE_NOA_RD) |
+                              S_02807C_HTILE_RD_POLICY(V_02807C_CACHE_NOA_RD));
+
+               si_pm4_set_reg(pm4, R_028410_CB_RMI_GL2_CACHE_CONTROL,
+                              S_028410_CMASK_WR_POLICY(V_028410_CACHE_STREAM_WR) |
+                              S_028410_FMASK_WR_POLICY(V_028410_CACHE_STREAM_WR) |
+                              S_028410_DCC_WR_POLICY(V_028410_CACHE_STREAM_WR) |
+                              S_028410_COLOR_WR_POLICY(V_028410_CACHE_STREAM_WR) |
+                              S_028410_CMASK_RD_POLICY(V_028410_CACHE_NOA_RD) |
+                              S_028410_FMASK_RD_POLICY(V_028410_CACHE_NOA_RD) |
+                              S_028410_DCC_RD_POLICY(V_028410_CACHE_NOA_RD) |
+                              S_028410_COLOR_RD_POLICY(V_028410_CACHE_NOA_RD));
+               si_pm4_set_reg(pm4, R_028428_CB_COVERAGE_OUT_CONTROL, 0);
+
+               si_pm4_set_reg(pm4, R_00B0C0_SPI_SHADER_REQ_CTRL_PS,
+                              S_00B0C0_SOFT_GROUPING_EN(1) |
+                              S_00B0C0_NUMBER_OF_REQUESTS_PER_CU(4 - 1));
+               si_pm4_set_reg(pm4, R_00B1C0_SPI_SHADER_REQ_CTRL_VS, 0);
+
        }
 
        if (sctx->chip_class >= GFX8) {