* The information about LDS and other non-compile-time parameters is then
* written to userdata SGPRs.
*/
-static bool si_emit_derived_tess_state(struct si_context *sctx,
+static void si_emit_derived_tess_state(struct si_context *sctx,
const struct pipe_draw_info *info,
unsigned *num_patches)
{
(!has_primid_instancing_bug ||
(sctx->last_tess_uses_primid == tess_uses_primid))) {
*num_patches = sctx->last_num_patches;
- return false;
+ return;
}
sctx->last_ls = ls_current;
ls_hs_config);
}
sctx->last_ls_hs_config = ls_hs_config;
- return true; /* true if the context rolls */
+ sctx->context_roll = true;
}
- return false;
}
static unsigned si_num_prims_for_vertices(const struct pipe_draw_info *info)
}
/* rast_prim is the primitive type after GS. */
-static bool si_emit_rasterizer_prim_state(struct si_context *sctx)
+static void si_emit_rasterizer_prim_state(struct si_context *sctx)
{
struct radeon_cmdbuf *cs = sctx->gfx_cs;
enum pipe_prim_type rast_prim = sctx->current_rast_prim;
/* Skip this if not rendering lines. */
if (!util_prim_is_lines(rast_prim))
- return false;
+ return;
if (rast_prim == sctx->last_rast_prim &&
rs->pa_sc_line_stipple == sctx->last_sc_line_stipple)
- return false;
+ return;
/* For lines, reset the stipple pattern at each primitive. Otherwise,
* reset the stipple pattern at each packet (line strips, line loops).
sctx->last_rast_prim = rast_prim;
sctx->last_sc_line_stipple = rs->pa_sc_line_stipple;
- return true; /* true if the context rolls */
+ sctx->context_roll = true;
}
static void si_emit_vs_state(struct si_context *sctx,
radeon_set_context_reg(cs, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX,
info->restart_index);
sctx->last_restart_index = info->restart_index;
+ sctx->context_roll = true;
}
}
radeon_emit(cs, 0); /* CP_COHER_BASE */
radeon_emit(cs, 0x0000000A); /* POLL_INTERVAL */
}
+
+ /* ACQUIRE_MEM has an implicit context roll if the current context
+ * is busy. */
+ if (sctx->has_graphics)
+ sctx->context_roll = true;
}
void si_emit_cache_flush(struct si_context *sctx)
unsigned skip_atom_mask)
{
unsigned num_patches = 0;
- /* Vega10/Raven scissor bug workaround. When any context register is
- * written (i.e. the GPU rolls the context), PA_SC_VPORT_SCISSOR
- * registers must be written too.
- */
- bool handle_scissor_bug = (sctx->family == CHIP_VEGA10 || sctx->family == CHIP_RAVEN) &&
- !si_is_atom_dirty(sctx, &sctx->atoms.s.scissors);
- bool context_roll = false; /* set correctly for GFX9 only */
- context_roll |= si_emit_rasterizer_prim_state(sctx);
+ si_emit_rasterizer_prim_state(sctx);
if (sctx->tes_shader.cso)
- context_roll |= si_emit_derived_tess_state(sctx, info, &num_patches);
-
- if (handle_scissor_bug &&
- (info->count_from_stream_output ||
- sctx->dirty_atoms & si_atoms_that_always_roll_context() ||
- sctx->dirty_states & si_states_that_always_roll_context() ||
- si_prim_restart_index_changed(sctx, info)))
- context_roll = true;
-
- sctx->context_roll_counter = 0;
+ si_emit_derived_tess_state(sctx, info, &num_patches);
/* Emit state atoms. */
unsigned mask = sctx->dirty_atoms & ~skip_atom_mask;
}
sctx->dirty_states = 0;
- if (handle_scissor_bug &&
- (context_roll || sctx->context_roll_counter)) {
- sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
- sctx->atoms.s.scissors.emit(sctx);
- }
-
/* Emit draw states. */
si_emit_vs_state(sctx, info);
si_emit_draw_registers(sctx, info, num_patches);
if (!si_upload_vertex_buffer_descriptors(sctx))
goto return_cleanup;
+ /* Vega10/Raven scissor bug workaround. When any context register is
+ * written (i.e. the GPU rolls the context), PA_SC_VPORT_SCISSOR
+ * registers must be written too.
+ */
+ bool has_gfx9_scissor_bug = sctx->screen->has_gfx9_scissor_bug;
+ unsigned masked_atoms = 0;
+
+ if (has_gfx9_scissor_bug) {
+ masked_atoms |= si_get_atom_bit(sctx, &sctx->atoms.s.scissors);
+
+ if (info->count_from_stream_output ||
+ sctx->dirty_atoms & si_atoms_that_always_roll_context() ||
+ sctx->dirty_states & si_states_that_always_roll_context())
+ sctx->context_roll = true;
+ }
+
/* Use optimal packet order based on whether we need to sync the pipeline. */
if (unlikely(sctx->flags & (SI_CONTEXT_FLUSH_AND_INV_CB |
SI_CONTEXT_FLUSH_AND_INV_DB |
* Then draw and prefetch at the end. This ensures that the time
* the CUs are idle is very short.
*/
- unsigned masked_atoms = 0;
-
if (unlikely(sctx->flags & SI_CONTEXT_FLUSH_FOR_RENDER_COND))
masked_atoms |= si_get_atom_bit(sctx, &sctx->atoms.s.render_cond);
if (si_is_atom_dirty(sctx, &sctx->atoms.s.render_cond))
sctx->atoms.s.render_cond.emit(sctx);
+
+ if (has_gfx9_scissor_bug &&
+ (sctx->context_roll ||
+ si_is_atom_dirty(sctx, &sctx->atoms.s.scissors))) {
+ sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
+ sctx->atoms.s.scissors.emit(sctx);
+ }
sctx->dirty_atoms = 0;
si_emit_draw_packets(sctx, info, indexbuf, index_size, index_offset);
if (!si_upload_graphics_shader_descriptors(sctx))
return;
- si_emit_all_states(sctx, info, 0);
+ si_emit_all_states(sctx, info, masked_atoms);
+
+ if (has_gfx9_scissor_bug &&
+ (sctx->context_roll ||
+ si_is_atom_dirty(sctx, &sctx->atoms.s.scissors))) {
+ sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
+ sctx->atoms.s.scissors.emit(sctx);
+ }
+ sctx->dirty_atoms = 0;
+
si_emit_draw_packets(sctx, info, indexbuf, index_size, index_offset);
/* Prefetch the remaining shaders after the draw has been
cik_emit_prefetch_L2(sctx, false);
}
+ /* Clear the context roll flag after the draw call. */
+ sctx->context_roll = false;
+
if (unlikely(sctx->current_saved_cs)) {
si_trace_emit(sctx);
si_log_draw_state(sctx, sctx->log);