radeonsi: don't flush and wait for CB after depth-only rendering
[mesa.git] / src / gallium / drivers / radeonsi / si_state.c
index c4063a8a8d6d5dca0d41dc11a5424db429a40270..b236bed306542bafe612a0b6293693e57f098dd5 100644 (file)
@@ -603,9 +603,27 @@ static void *si_create_blend_state(struct pipe_context *ctx,
 static void si_bind_blend_state(struct pipe_context *ctx, void *state)
 {
        struct si_context *sctx = (struct si_context *)ctx;
-       si_pm4_bind_state(sctx, blend, (struct si_state_blend *)state);
-       si_mark_atom_dirty(sctx, &sctx->cb_render_state);
-       sctx->do_update_shaders = true;
+       struct si_state_blend *old_blend = sctx->queued.named.blend;
+       struct si_state_blend *blend = (struct si_state_blend *)state;
+
+       if (!state)
+               return;
+
+       if (!old_blend ||
+            old_blend->cb_target_mask != blend->cb_target_mask ||
+            old_blend->dual_src_blend != blend->dual_src_blend)
+               si_mark_atom_dirty(sctx, &sctx->cb_render_state);
+
+       si_pm4_bind_state(sctx, blend, state);
+
+       if (!old_blend ||
+           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 ||
+           old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
+           old_blend->need_src_alpha_4bit != blend->need_src_alpha_4bit)
+               sctx->do_update_shaders = true;
 }
 
 static void si_delete_blend_state(struct pipe_context *ctx, void *state)
@@ -619,9 +637,6 @@ static void si_set_blend_color(struct pipe_context *ctx,
 {
        struct si_context *sctx = (struct si_context *)ctx;
 
-       if (memcmp(&sctx->blend_color.state, state, sizeof(*state)) == 0)
-               return;
-
        sctx->blend_color.state = *state;
        si_mark_atom_dirty(sctx, &sctx->blend_color.atom);
 }
@@ -666,24 +681,21 @@ static void si_emit_clip_state(struct si_context *sctx, struct r600_atom *atom)
        radeon_emit_array(cs, (uint32_t*)sctx->clip_state.state.ucp, 6*4);
 }
 
-#define SIX_BITS 0x3F
-
 static void si_emit_clip_regs(struct si_context *sctx, struct r600_atom *atom)
 {
        struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
        struct si_shader *vs = si_get_vs_state(sctx);
-       struct tgsi_shader_info *info = si_get_vs_info(sctx);
+       struct si_shader_selector *vs_sel = vs->selector;
+       struct tgsi_shader_info *info = &vs_sel->info;
        struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
        unsigned window_space =
           info->properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION];
-       unsigned clipdist_mask =
-               info->writes_clipvertex ? SIX_BITS : info->clipdist_writemask;
+       unsigned clipdist_mask = vs_sel->clipdist_mask;
        unsigned ucp_mask = clipdist_mask ? 0 : rs->clip_plane_enable & SIX_BITS;
-       unsigned culldist_mask = info->culldist_writemask << info->num_written_clipdistance;
+       unsigned culldist_mask = vs_sel->culldist_mask;
        unsigned total_mask;
-       bool misc_vec_ena;
 
-       if (vs->key.opt.hw_vs.clip_disable) {
+       if (vs->key.opt.clip_disable) {
                assert(!info->culldist_writemask);
                clipdist_mask = 0;
                culldist_mask = 0;
@@ -699,27 +711,21 @@ static void si_emit_clip_regs(struct si_context *sctx, struct r600_atom *atom)
        clipdist_mask &= rs->clip_plane_enable;
        culldist_mask |= clipdist_mask;
 
-       misc_vec_ena = info->writes_psize || info->writes_edgeflag ||
-                      info->writes_layer || info->writes_viewport_index;
-
        radeon_set_context_reg(cs, R_02881C_PA_CL_VS_OUT_CNTL,
-               S_02881C_USE_VTX_POINT_SIZE(info->writes_psize) |
-               S_02881C_USE_VTX_EDGE_FLAG(info->writes_edgeflag) |
-               S_02881C_USE_VTX_RENDER_TARGET_INDX(info->writes_layer) |
-               S_02881C_USE_VTX_VIEWPORT_INDX(info->writes_viewport_index) |
+               vs_sel->pa_cl_vs_out_cntl |
                S_02881C_VS_OUT_CCDIST0_VEC_ENA((total_mask & 0x0F) != 0) |
                S_02881C_VS_OUT_CCDIST1_VEC_ENA((total_mask & 0xF0) != 0) |
-               S_02881C_VS_OUT_MISC_VEC_ENA(misc_vec_ena) |
-               S_02881C_VS_OUT_MISC_SIDE_BUS_ENA(misc_vec_ena) |
                clipdist_mask | (culldist_mask << 8));
        radeon_set_context_reg(cs, R_028810_PA_CL_CLIP_CNTL,
                rs->pa_cl_clip_cntl |
                ucp_mask |
                S_028810_CLIP_DISABLE(window_space));
 
-       /* reuse needs to be set off if we write oViewport */
-       radeon_set_context_reg(cs, R_028AB4_VGT_REUSE_OFF,
-                              S_028AB4_REUSE_OFF(info->writes_viewport_index));
+       if (sctx->b.chip_class <= VI) {
+               /* reuse needs to be set off if we write oViewport */
+               radeon_set_context_reg(cs, R_028AB4_VGT_REUSE_OFF,
+                                      S_028AB4_REUSE_OFF(info->writes_viewport_index));
+       }
 }
 
 /*
@@ -796,6 +802,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        rs->uses_poly_offset = state->offset_point || state->offset_line ||
                               state->offset_tri;
        rs->clamp_fragment_color = state->clamp_fragment_color;
+       rs->clamp_vertex_color = state->clamp_vertex_color;
        rs->flatshade = state->flatshade;
        rs->sprite_coord_enable = state->sprite_coord_enable;
        rs->rasterizer_discard = state->rasterizer_discard;
@@ -862,8 +869,15 @@ static void *si_create_rs_state(struct pipe_context *ctx,
                                   state->fill_back != PIPE_POLYGON_MODE_FILL) |
                S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) |
                S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back)));
-       si_pm4_set_reg(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0 +
-                      SI_SGPR_VS_STATE_BITS * 4, state->clamp_vertex_color);
+
+       if (!rs->uses_poly_offset)
+               return rs;
+
+       rs->pm4_poly_offset = CALLOC(3, sizeof(struct si_pm4_state));
+       if (!rs->pm4_poly_offset) {
+               FREE(rs);
+               return NULL;
+       }
 
        /* Precalculate polygon offset states for 16-bit, 24-bit, and 32-bit zbuffers. */
        for (i = 0; i < 3; i++) {
@@ -921,29 +935,52 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
                si_mark_atom_dirty(sctx, &sctx->db_render_state);
 
                /* Update the small primitive filter workaround if necessary. */
-               if (sctx->b.family >= CHIP_POLARIS10 &&
+               if (sctx->screen->has_msaa_sample_loc_bug &&
                    sctx->framebuffer.nr_samples > 1)
                        si_mark_atom_dirty(sctx, &sctx->msaa_sample_locs.atom);
        }
 
+       sctx->current_vs_state &= C_VS_STATE_CLAMP_VERTEX_COLOR;
+       sctx->current_vs_state |= S_VS_STATE_CLAMP_VERTEX_COLOR(rs->clamp_vertex_color);
+
        r600_viewport_set_rast_deps(&sctx->b, rs->scissor_enable, rs->clip_halfz);
 
        si_pm4_bind_state(sctx, rasterizer, rs);
        si_update_poly_offset_state(sctx);
 
-       si_mark_atom_dirty(sctx, &sctx->clip_regs);
+       if (!old_rs ||
+           old_rs->clip_plane_enable != rs->clip_plane_enable ||
+           old_rs->pa_cl_clip_cntl != rs->pa_cl_clip_cntl)
+               si_mark_atom_dirty(sctx, &sctx->clip_regs);
+
        sctx->ia_multi_vgt_param_key.u.line_stipple_enabled =
                rs->line_stipple_enable;
-       sctx->do_update_shaders = true;
+
+       if (!old_rs ||
+           old_rs->clip_plane_enable != rs->clip_plane_enable ||
+           old_rs->rasterizer_discard != rs->rasterizer_discard ||
+           old_rs->sprite_coord_enable != rs->sprite_coord_enable ||
+           old_rs->flatshade != rs->flatshade ||
+           old_rs->two_side != rs->two_side ||
+           old_rs->multisample_enable != rs->multisample_enable ||
+           old_rs->poly_stipple_enable != rs->poly_stipple_enable ||
+           old_rs->poly_smooth != rs->poly_smooth ||
+           old_rs->line_smooth != rs->line_smooth ||
+           old_rs->clamp_fragment_color != rs->clamp_fragment_color ||
+           old_rs->force_persample_interp != rs->force_persample_interp)
+               sctx->do_update_shaders = true;
 }
 
 static void si_delete_rs_state(struct pipe_context *ctx, void *state)
 {
        struct si_context *sctx = (struct si_context *)ctx;
+       struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state;
 
        if (sctx->queued.named.rasterizer == state)
                si_pm4_bind_state(sctx, poly_offset, NULL);
-       si_pm4_delete_state(sctx, rasterizer, (struct si_state_rasterizer *)state);
+
+       FREE(rs->pm4_poly_offset);
+       si_pm4_delete_state(sctx, rasterizer, rs);
 }
 
 /*
@@ -1060,7 +1097,8 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
        }
 
        si_pm4_set_reg(pm4, R_028800_DB_DEPTH_CONTROL, db_depth_control);
-       si_pm4_set_reg(pm4, R_02842C_DB_STENCIL_CONTROL, db_stencil_control);
+       if (state->stencil[0].enabled)
+               si_pm4_set_reg(pm4, R_02842C_DB_STENCIL_CONTROL, db_stencil_control);
        if (state->depth.bounds_test) {
                si_pm4_set_reg(pm4, R_028020_DB_DEPTH_BOUNDS_MIN, fui(state->depth.bounds_min));
                si_pm4_set_reg(pm4, R_028024_DB_DEPTH_BOUNDS_MAX, fui(state->depth.bounds_max));
@@ -1072,6 +1110,7 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
 static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
 {
         struct si_context *sctx = (struct si_context *)ctx;
+       struct si_state_dsa *old_dsa = sctx->queued.named.dsa;
         struct si_state_dsa *dsa = state;
 
         if (!state)
@@ -1084,7 +1123,9 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
                sctx->stencil_ref.dsa_part = dsa->stencil_ref;
                si_mark_atom_dirty(sctx, &sctx->stencil_ref.atom);
        }
-       sctx->do_update_shaders = true;
+
+       if (!old_dsa || old_dsa->alpha_func != dsa->alpha_func)
+               sctx->do_update_shaders = true;
 }
 
 static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
@@ -2288,7 +2329,7 @@ static void si_init_depth_surface(struct si_context *sctx,
                                      S_02801C_Y_MAX(rtex->resource.b.b.height0 - 1);
 
                /* Only use HTILE for the first level. */
-               if (rtex->htile_buffer && !level) {
+               if (rtex->htile_offset && !level) {
                        z_info |= S_028038_TILE_SURFACE_ENABLE(1) |
                                  S_028038_ALLOW_EXPCLEAR(1);
 
@@ -2314,7 +2355,8 @@ static void si_init_depth_surface(struct si_context *sctx,
                                s_info |= S_02803C_TILE_STENCIL_DISABLE(1);
                        }
 
-                       surf->db_htile_data_base = rtex->htile_buffer->gpu_address >> 8;
+                       surf->db_htile_data_base = (rtex->resource.gpu_address +
+                                                   rtex->htile_offset) >> 8;
                        surf->db_htile_surface = S_028ABC_FULL_CACHE(1) |
                                                 S_028ABC_PIPE_ALIGNED(rtex->surface.u.gfx9.htile.pipe_aligned) |
                                                 S_028ABC_RB_ALIGNED(rtex->surface.u.gfx9.htile.rb_aligned);
@@ -2366,7 +2408,7 @@ static void si_init_depth_surface(struct si_context *sctx,
                                                                levelinfo->nblk_y) / 64 - 1);
 
                /* Only use HTILE for the first level. */
-               if (rtex->htile_buffer && !level) {
+               if (rtex->htile_offset && !level) {
                        z_info |= S_028040_TILE_SURFACE_ENABLE(1) |
                                  S_028040_ALLOW_EXPCLEAR(1);
 
@@ -2392,7 +2434,8 @@ static void si_init_depth_surface(struct si_context *sctx,
                                s_info |= S_028044_TILE_STENCIL_DISABLE(1);
                        }
 
-                       surf->db_htile_data_base = rtex->htile_buffer->gpu_address >> 8;
+                       surf->db_htile_data_base = (rtex->resource.gpu_address +
+                                                   rtex->htile_offset) >> 8;
                        surf->db_htile_surface = S_028ABC_FULL_CACHE(1);
 
                        if (rtex->tc_compatible_htile) {
@@ -2438,6 +2481,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
        struct r600_texture *rtex;
        bool old_any_dst_linear = sctx->framebuffer.any_dst_linear;
        unsigned old_nr_samples = sctx->framebuffer.nr_samples;
+       bool unbound = false;
        int i;
 
        for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
@@ -2449,18 +2493,70 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
                        vi_separate_dcc_stop_query(ctx, rtex);
        }
 
+       /* Disable DCC if the formats are incompatible. */
+       for (i = 0; i < state->nr_cbufs; i++) {
+               if (!state->cbufs[i])
+                       continue;
+
+               surf = (struct r600_surface*)state->cbufs[i];
+               rtex = (struct r600_texture*)surf->base.texture;
+
+               if (!surf->dcc_incompatible)
+                       continue;
+
+               /* Since the DCC decompression calls back into set_framebuffer-
+                * _state, we need to unbind the framebuffer, so that
+                * vi_separate_dcc_stop_query isn't called twice with the same
+                * color buffer.
+                */
+               if (!unbound) {
+                       util_copy_framebuffer_state(&sctx->framebuffer.state, NULL);
+                       unbound = true;
+               }
+
+               if (vi_dcc_enabled(rtex, surf->base.u.tex.level))
+                       if (!r600_texture_disable_dcc(&sctx->b, rtex))
+                               sctx->b.decompress_dcc(ctx, rtex);
+
+               surf->dcc_incompatible = false;
+       }
+
        /* Only flush TC when changing the framebuffer state, because
         * the only client not using TC that can change textures is
         * the framebuffer.
         *
-        * Flush all CB and DB caches here because all buffers can be used
-        * for write by both TC (with shader image stores) and CB/DB.
+        * Wait for compute shaders because of possible transitions:
+        * - FB write -> shader read
+        * - shader write -> FB read
+        *
+        * DB caches are flushed on demand (using si_decompress_textures).
+        *
+        * When MSAA is enabled, CB and TC caches are flushed on demand
+        * (after FMASK decompression). Shader write -> FB read transitions
+        * cannot happen for MSAA textures, because MSAA shader images are
+        * not supported.
+        *
+        * Only flush and wait for CB if there is actually a bound color buffer.
+        */
+       if (sctx->framebuffer.nr_samples <= 1 &&
+           sctx->framebuffer.state.nr_cbufs) {
+               sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 |
+                                SI_CONTEXT_INV_GLOBAL_L2 |
+                                SI_CONTEXT_FLUSH_AND_INV_CB;
+       }
+       sctx->b.flags |= SI_CONTEXT_CS_PARTIAL_FLUSH;
+
+       /* u_blitter doesn't invoke depth decompression when it does multiple
+        * blits in a row, but the only case when it matters for DB is when
+        * doing generate_mipmap. So here we flush DB manually between
+        * individual generate_mipmap blits.
+        * Note that lower mipmap levels aren't compressed.
         */
-       sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 |
-                        SI_CONTEXT_INV_GLOBAL_L2 |
-                        SI_CONTEXT_FLUSH_AND_INV_CB |
-                        SI_CONTEXT_FLUSH_AND_INV_DB |
-                        SI_CONTEXT_CS_PARTIAL_FLUSH;
+       if (sctx->generate_mipmap_for_depth) {
+               sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 |
+                                SI_CONTEXT_INV_GLOBAL_L2 |
+                                SI_CONTEXT_FLUSH_AND_INV_DB;
+       }
 
        /* Take the maximum of the old and new count. If the new count is lower,
         * dirtying is needed to disable the unbound colorbuffers.
@@ -2578,9 +2674,15 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
                si_mark_atom_dirty(sctx, &sctx->msaa_sample_locs.atom);
        }
 
-       sctx->need_check_render_feedback = true;
        sctx->do_update_shaders = true;
-       sctx->framebuffer.do_update_surf_dirtiness = true;
+
+       if (!sctx->decompression_enabled) {
+               /* Prevent textures decompression when the framebuffer state
+                * changes come from the decompression passes themselves.
+                */
+               sctx->need_check_render_feedback = true;
+               sctx->framebuffer.do_update_surf_dirtiness = true;
+       }
 }
 
 static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom *atom)
@@ -2637,7 +2739,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                        cb_color_fmask = (tex->resource.gpu_address + tex->fmask.offset) >> 8;
 
                /* Set up DCC. */
-               if (tex->dcc_offset && cb->base.u.tex.level < tex->surface.num_dcc_levels) {
+               if (vi_dcc_enabled(tex, cb->base.u.tex.level)) {
                        bool is_msaa_resolve_dst = state->cbufs[0] &&
                                                   state->cbufs[0]->texture->nr_samples > 1 &&
                                                   state->cbufs[1] == &cb->base &&
@@ -2752,12 +2854,6 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                                              RADEON_PRIO_DEPTH_BUFFER_MSAA :
                                              RADEON_PRIO_DEPTH_BUFFER);
 
-               if (zb->db_htile_data_base) {
-                       radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-                                             rtex->htile_buffer, RADEON_USAGE_READWRITE,
-                                             RADEON_PRIO_HTILE);
-               }
-
                if (sctx->b.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 */
@@ -2831,6 +2927,7 @@ static void si_emit_msaa_sample_locs(struct si_context *sctx,
 {
        struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
        unsigned nr_samples = sctx->framebuffer.nr_samples;
+       bool has_msaa_sample_loc_bug = sctx->screen->has_msaa_sample_loc_bug;
 
        /* Smoothing (only possible with nr_samples == 1) uses the same
         * sample locations as the MSAA it simulates.
@@ -2841,7 +2938,7 @@ static void si_emit_msaa_sample_locs(struct si_context *sctx,
        /* On Polaris, the small primitive filter uses the sample locations
         * even when MSAA is off, so we need to make sure they're set to 0.
         */
-       if (sctx->b.family >= CHIP_POLARIS10)
+       if (has_msaa_sample_loc_bug)
                nr_samples = MAX2(nr_samples, 1);
 
        if (nr_samples >= 1 &&
@@ -2854,13 +2951,16 @@ static void si_emit_msaa_sample_locs(struct si_context *sctx,
                struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
                unsigned small_prim_filter_cntl =
                        S_028830_SMALL_PRIM_FILTER_ENABLE(1) |
-                       S_028830_LINE_FILTER_DISABLE(sctx->b.chip_class == VI); /* line bug */
+                       /* line bug */
+                       S_028830_LINE_FILTER_DISABLE(sctx->b.family <= CHIP_POLARIS12);
 
                /* The alternative of setting sample locations to 0 would
                 * require a DB flush to avoid Z errors, see
                 * https://bugs.freedesktop.org/show_bug.cgi?id=96908
                 */
-               if (sctx->framebuffer.nr_samples > 1 && rs && !rs->multisample_enable)
+               if (has_msaa_sample_loc_bug &&
+                   sctx->framebuffer.nr_samples > 1 &&
+                   rs && !rs->multisample_enable)
                        small_prim_filter_cntl &= C_028830_SMALL_PRIM_FILTER_ENABLE;
 
                radeon_set_context_reg(cs, R_028830_PA_SU_SMALL_PRIM_FILTER_CNTL,
@@ -2941,7 +3041,40 @@ si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
        num_records = size / stride;
        num_records = MIN2(num_records, (buf->b.b.width0 - offset) / stride);
 
-       if (screen->b.chip_class == VI)
+       /* The NUM_RECORDS field has a different meaning depending on the chip,
+        * instruction type, STRIDE, and SWIZZLE_ENABLE.
+        *
+        * SI-CIK:
+        * - If STRIDE == 0, it's in byte units.
+        * - If STRIDE != 0, it's in units of STRIDE, used with inst.IDXEN.
+        *
+        * VI:
+        * - For SMEM and STRIDE == 0, it's in byte units.
+        * - For SMEM and STRIDE != 0, it's in units of STRIDE.
+        * - For VMEM and STRIDE == 0 or SWIZZLE_ENABLE == 0, it's in byte units.
+        * - For VMEM and STRIDE != 0 and SWIZZLE_ENABLE == 1, it's in units of STRIDE.
+        * NOTE: There is incompatibility between VMEM and SMEM opcodes due to SWIZZLE_-
+        *       ENABLE. The workaround is to set STRIDE = 0 if SWIZZLE_ENABLE == 0 when
+        *       using SMEM. This can be done in the shader by clearing STRIDE with s_and.
+        *       That way the same descriptor can be used by both SMEM and VMEM.
+        *
+        * GFX9:
+        * - For SMEM and STRIDE == 0, it's in byte units.
+        * - For SMEM and STRIDE != 0, it's in units of STRIDE.
+        * - For VMEM and inst.IDXEN == 0 or STRIDE == 0, it's in byte units.
+        * - For VMEM and inst.IDXEN == 1 and STRIDE != 0, it's in units of STRIDE.
+        */
+       if (screen->b.chip_class >= GFX9)
+               /* When vindex == 0, LLVM sets IDXEN = 0, thus changing units
+                * from STRIDE to bytes. This works around it by setting
+                * NUM_RECORDS to at least the size of one element, so that
+                * the first element is readable when IDXEN == 0.
+                *
+                * TODO: Fix this in LLVM, but do we need a new intrinsic where
+                *       IDXEN is enforced?
+                */
+               num_records = num_records ? MAX2(num_records, stride) : 0;
+       else if (screen->b.chip_class == VI)
                num_records *= stride;
 
        state[4] = 0;
@@ -3118,10 +3251,17 @@ si_make_texture_descriptor(struct si_screen *screen,
                data_format = V_008F14_IMG_DATA_FORMAT_24_8;
        }
 
+       /* S8 with Z32 HTILE needs a special format. */
+       if (screen->b.chip_class >= GFX9 &&
+           pipe_format == PIPE_FORMAT_S8_UINT &&
+           tex->tc_compatible_htile)
+               data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
+
        if (!sampler &&
            (res->target == PIPE_TEXTURE_CUBE ||
             res->target == PIPE_TEXTURE_CUBE_ARRAY ||
-            res->target == PIPE_TEXTURE_3D)) {
+            (screen->b.chip_class <= VI &&
+             res->target == PIPE_TEXTURE_3D))) {
                /* For the purpose of shader images, treat cube maps and 3D
                 * textures as 2D arrays. For 3D textures, the address
                 * calculations for mipmaps are different, so we rely on the
@@ -3221,7 +3361,7 @@ si_make_texture_descriptor(struct si_screen *screen,
                                num_format = V_008F14_IMG_FMASK_32_8_8;
                                break;
                        default:
-                               assert(0);
+                               unreachable("invalid nr_samples");
                        }
                } else {
                        switch (res->nr_samples) {
@@ -3235,7 +3375,7 @@ si_make_texture_descriptor(struct si_screen *screen,
                                data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
                                break;
                        default:
-                               assert(0);
+                               unreachable("invalid nr_samples");
                        }
                        num_format = V_008F14_IMG_NUM_FORMAT_UINT;
                }
@@ -3407,9 +3547,10 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
                }
        }
 
-       vi_dcc_disable_if_incompatible_format(&sctx->b, texture,
-                                             state->u.tex.first_level,
-                                             state->format);
+       view->dcc_incompatible =
+               vi_dcc_formats_are_incompatible(texture,
+                                               state->u.tex.first_level,
+                                               state->format);
 
        si_make_texture_descriptor(sctx->screen, tmp, true,
                                   state->target, pipe_format, state_swizzle,
@@ -3605,7 +3746,7 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
                                       const struct pipe_vertex_element *elements)
 {
        struct si_screen *sscreen = (struct si_screen*)ctx->screen;
-       struct si_vertex_element *v = CALLOC_STRUCT(si_vertex_element);
+       struct si_vertex_elements *v = CALLOC_STRUCT(si_vertex_elements);
        bool used[SI_NUM_VERTEX_BUFFERS] = {};
        int i;
 
@@ -3629,6 +3770,11 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
                        return NULL;
                }
 
+               if (elements[i].instance_divisor) {
+                       v->uses_instance_divisors = true;
+                       v->instance_divisors[i] = elements[i].instance_divisor;
+               }
+
                if (!used[vbo_index]) {
                        v->first_vb_use_mask |= 1 << i;
                        used[vbo_index] = true;
@@ -3642,6 +3788,8 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
                memcpy(swizzle, desc->swizzle, sizeof(swizzle));
 
                v->format_size[i] = desc->block.bits / 8;
+               v->src_offset[i] = elements[i].src_offset;
+               v->vertex_buffer_index[i] = vbo_index;
 
                /* The hardware always treats the 2-bit alpha channel as
                 * unsigned, so a shader workaround is needed. The affected
@@ -3734,19 +3882,25 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
                                   S_008F0C_NUM_FORMAT(num_format) |
                                   S_008F0C_DATA_FORMAT(data_format);
        }
-       memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count);
-
        return v;
 }
 
 static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
 {
        struct si_context *sctx = (struct si_context *)ctx;
-       struct si_vertex_element *v = (struct si_vertex_element*)state;
+       struct si_vertex_elements *old = sctx->vertex_elements;
+       struct si_vertex_elements *v = (struct si_vertex_elements*)state;
 
        sctx->vertex_elements = v;
        sctx->vertex_buffers_dirty = true;
-       sctx->do_update_shaders = true;
+
+       if (v &&
+           (!old ||
+            old->count != v->count ||
+            old->uses_instance_divisors != v->uses_instance_divisors ||
+            v->uses_instance_divisors || /* we don't check which divisors changed */
+            memcmp(old->fix_fetch, v->fix_fetch, sizeof(v->fix_fetch[0]) * v->count)))
+               sctx->do_update_shaders = true;
 }
 
 static void si_delete_vertex_element(struct pipe_context *ctx, void *state)
@@ -3772,59 +3926,23 @@ static void si_set_vertex_buffers(struct pipe_context *ctx,
                for (i = 0; i < count; i++) {
                        const struct pipe_vertex_buffer *src = buffers + i;
                        struct pipe_vertex_buffer *dsti = dst + i;
-
-                       if (unlikely(src->user_buffer)) {
-                               /* Zero-stride attribs only. */
-                               assert(src->stride == 0);
-
-                               /* Assume that the user_buffer comes from
-                                * gl_current_attrib, which implies it has
-                                * 4 * 8 bytes (for dvec4 attributes).
-                                *
-                                * Use const_uploader to upload into VRAM directly.
-                                */
-                               u_upload_data(sctx->b.b.const_uploader, 0, 32, 32,
-                                             src->user_buffer,
-                                             &dsti->buffer_offset,
-                                             &dsti->buffer);
-                               dsti->stride = 0;
-                       } else {
-                               struct pipe_resource *buf = src->buffer;
-
-                               pipe_resource_reference(&dsti->buffer, buf);
-                               dsti->buffer_offset = src->buffer_offset;
-                               dsti->stride = src->stride;
-                               r600_context_add_resource_size(ctx, buf);
-                               if (buf)
-                                       r600_resource(buf)->bind_history |= PIPE_BIND_VERTEX_BUFFER;
-                       }
+                       struct pipe_resource *buf = src->buffer.resource;
+
+                       pipe_resource_reference(&dsti->buffer.resource, buf);
+                       dsti->buffer_offset = src->buffer_offset;
+                       dsti->stride = src->stride;
+                       r600_context_add_resource_size(ctx, buf);
+                       if (buf)
+                               r600_resource(buf)->bind_history |= PIPE_BIND_VERTEX_BUFFER;
                }
        } else {
                for (i = 0; i < count; i++) {
-                       pipe_resource_reference(&dst[i].buffer, NULL);
+                       pipe_resource_reference(&dst[i].buffer.resource, NULL);
                }
        }
        sctx->vertex_buffers_dirty = true;
 }
 
-static void si_set_index_buffer(struct pipe_context *ctx,
-                               const struct pipe_index_buffer *ib)
-{
-       struct si_context *sctx = (struct si_context *)ctx;
-
-       if (ib) {
-               struct pipe_resource *buf = ib->buffer;
-
-               pipe_resource_reference(&sctx->index_buffer.buffer, buf);
-               memcpy(&sctx->index_buffer, ib, sizeof(*ib));
-               r600_context_add_resource_size(ctx, buf);
-               if (buf)
-                       r600_resource(buf)->bind_history |= PIPE_BIND_INDEX_BUFFER;
-       } else {
-               pipe_resource_reference(&sctx->index_buffer.buffer, NULL);
-       }
-}
-
 /*
  * Misc
  */
@@ -3856,9 +3974,12 @@ static void si_texture_barrier(struct pipe_context *ctx, unsigned flags)
 {
        struct si_context *sctx = (struct si_context *)ctx;
 
-       sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 |
-                        SI_CONTEXT_INV_GLOBAL_L2 |
-                        SI_CONTEXT_FLUSH_AND_INV_CB;
+       /* Multisample surfaces are flushed in si_decompress_textures. */
+       if (sctx->framebuffer.nr_samples <= 1) {
+               sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 |
+                                SI_CONTEXT_INV_GLOBAL_L2 |
+                                SI_CONTEXT_FLUSH_AND_INV_CB;
+       }
        sctx->framebuffer.do_update_surf_dirtiness = true;
 }
 
@@ -3896,12 +4017,18 @@ static void si_memory_barrier(struct pipe_context *ctx, unsigned flags)
                        sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2;
        }
 
-       if (flags & PIPE_BARRIER_FRAMEBUFFER)
+       /* MSAA color, any depth and any stencil are flushed in
+        * si_decompress_textures when needed.
+        */
+       if (flags & PIPE_BARRIER_FRAMEBUFFER &&
+           sctx->framebuffer.nr_samples <= 1) {
                sctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_CB |
-                                SI_CONTEXT_FLUSH_AND_INV_DB;
+                                SI_CONTEXT_WRITEBACK_GLOBAL_L2;
+       }
 
-       if (flags & (PIPE_BARRIER_FRAMEBUFFER |
-                    PIPE_BARRIER_INDIRECT_BUFFER))
+       /* Indirect buffers use TC L2 on GFX9, but not older hw. */
+       if (sctx->screen->b.chip_class <= VI &&
+           flags & PIPE_BARRIER_INDIRECT_BUFFER)
                sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2;
 }
 
@@ -3957,8 +4084,8 @@ void si_init_state_functions(struct si_context *sctx)
 
        sctx->custom_dsa_flush = si_create_db_flush_dsa(sctx);
        sctx->custom_blend_resolve = si_create_blend_custom(sctx, V_028808_CB_RESOLVE);
-       sctx->custom_blend_decompress = si_create_blend_custom(sctx, V_028808_CB_FMASK_DECOMPRESS);
-       sctx->custom_blend_fastclear = si_create_blend_custom(sctx, V_028808_CB_ELIMINATE_FAST_CLEAR);
+       sctx->custom_blend_fmask_decompress = si_create_blend_custom(sctx, V_028808_CB_FMASK_DECOMPRESS);
+       sctx->custom_blend_eliminate_fastclear = si_create_blend_custom(sctx, V_028808_CB_ELIMINATE_FAST_CLEAR);
        sctx->custom_blend_dcc_decompress = si_create_blend_custom(sctx, V_028808_CB_DCC_DECOMPRESS);
 
        sctx->b.b.set_clip_state = si_set_clip_state;
@@ -3979,7 +4106,6 @@ void si_init_state_functions(struct si_context *sctx)
        sctx->b.b.bind_vertex_elements_state = si_bind_vertex_elements;
        sctx->b.b.delete_vertex_elements_state = si_delete_vertex_element;
        sctx->b.b.set_vertex_buffers = si_set_vertex_buffers;
-       sctx->b.b.set_index_buffer = si_set_index_buffer;
 
        sctx->b.b.texture_barrier = si_texture_barrier;
        sctx->b.b.memory_barrier = si_memory_barrier;
@@ -4261,14 +4387,19 @@ static void si_init_config(struct si_context *sctx)
        si_pm4_set_reg(pm4, R_028A1C_VGT_HOS_MIN_TESS_LEVEL, fui(0));
 
        /* FIXME calculate these values somehow ??? */
-       si_pm4_set_reg(pm4, R_028A54_VGT_GS_PER_ES, SI_GS_PER_ES);
-       si_pm4_set_reg(pm4, R_028A58_VGT_ES_PER_GS, 0x40);
+       if (sctx->b.chip_class <= VI) {
+               si_pm4_set_reg(pm4, R_028A54_VGT_GS_PER_ES, SI_GS_PER_ES);
+               si_pm4_set_reg(pm4, R_028A58_VGT_ES_PER_GS, 0x40);
+       }
        si_pm4_set_reg(pm4, R_028A5C_VGT_GS_PER_VS, 0x2);
 
        si_pm4_set_reg(pm4, R_028A8C_VGT_PRIMITIVEID_RESET, 0x0);
        si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
 
        si_pm4_set_reg(pm4, R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0x0);
+       si_pm4_set_reg(pm4, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 1);
+       if (sctx->b.chip_class >= GFX9)
+               si_pm4_set_reg(pm4, R_028AB4_VGT_REUSE_OFF, 0);
        si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0x0);
        if (sctx->b.chip_class < CIK)
                si_pm4_set_reg(pm4, R_008A14_PA_CL_ENHANCE, S_008A14_NUM_CLIP_SEQ(3) |
@@ -4412,20 +4543,20 @@ static void si_init_config(struct si_context *sctx)
        }
 
        if (sctx->b.chip_class >= CIK) {
-               /* If this is 0, Bonaire can hang even if GS isn't being used.
-                * Other chips are unaffected. These are suboptimal values,
-                * but we don't use on-chip GS.
-                */
-               si_pm4_set_reg(pm4, R_028A44_VGT_GS_ONCHIP_CNTL,
-                              S_028A44_ES_VERTS_PER_SUBGRP(64) |
-                              S_028A44_GS_PRIMS_PER_SUBGRP(4));
-
                if (sctx->b.chip_class >= GFX9) {
                        si_pm4_set_reg(pm4, R_00B41C_SPI_SHADER_PGM_RSRC3_HS, S_00B41C_CU_EN(0xffff));
                } else {
                        si_pm4_set_reg(pm4, R_00B51C_SPI_SHADER_PGM_RSRC3_LS, S_00B51C_CU_EN(0xffff));
                        si_pm4_set_reg(pm4, R_00B41C_SPI_SHADER_PGM_RSRC3_HS, 0);
                        si_pm4_set_reg(pm4, R_00B31C_SPI_SHADER_PGM_RSRC3_ES, S_00B31C_CU_EN(0xffff));
+
+                       /* If this is 0, Bonaire can hang even if GS isn't being used.
+                        * Other chips are unaffected. These are suboptimal values,
+                        * but we don't use on-chip GS.
+                        */
+                       si_pm4_set_reg(pm4, R_028A44_VGT_GS_ONCHIP_CNTL,
+                                      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));
 
@@ -4491,15 +4622,33 @@ static void si_init_config(struct si_context *sctx)
                      RADEON_PRIO_BORDER_COLORS);
 
        if (sctx->b.chip_class >= GFX9) {
-               si_pm4_set_reg(pm4, R_028060_DB_DFSM_CONTROL, 0);
+               unsigned num_se = sscreen->b.info.max_se;
+               unsigned pc_lines = 0;
+
+               switch (sctx->b.family) {
+               case CHIP_VEGA10:
+                       pc_lines = 4096;
+                       break;
+               case CHIP_RAVEN:
+                       pc_lines = 1024;
+                       break;
+               default:
+                       assert(0);
+               }
+
+               si_pm4_set_reg(pm4, R_028060_DB_DFSM_CONTROL,
+                              S_028060_PUNCHOUT_MODE(V_028060_FORCE_OFF));
                si_pm4_set_reg(pm4, R_028064_DB_RENDER_FILTER, 0);
                /* TODO: We can use this to disable RBs for rendering to GART: */
                si_pm4_set_reg(pm4, R_02835C_PA_SC_TILE_STEERING_OVERRIDE, 0);
                si_pm4_set_reg(pm4, R_02883C_PA_SU_OVER_RASTERIZATION_CNTL, 0);
                /* TODO: Enable the binner: */
                si_pm4_set_reg(pm4, R_028C44_PA_SC_BINNER_CNTL_0,
-                              S_028C44_BINNING_MODE(V_028C44_DISABLE_BINNING_USE_LEGACY_SC));
-               si_pm4_set_reg(pm4, R_028C48_PA_SC_BINNER_CNTL_1, 0);
+                              S_028C44_BINNING_MODE(V_028C44_DISABLE_BINNING_USE_LEGACY_SC) |
+                              S_028C44_DISABLE_START_OF_PRIM(1));
+               si_pm4_set_reg(pm4, R_028C48_PA_SC_BINNER_CNTL_1,
+                              S_028C48_MAX_ALLOC_COUNT(MIN2(128, pc_lines / (4 * num_se))) |
+                              S_028C48_MAX_PRIM_PER_BATCH(1023));
                si_pm4_set_reg(pm4, R_028C4C_PA_SC_CONSERVATIVE_RASTERIZATION_CNTL,
                               S_028C4C_NULL_SQUAD_AA_MASK_ENABLE(1));
                si_pm4_set_reg(pm4, R_030968_VGT_INSTANCE_BASE_ID, 0);