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;
/* 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;
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 = 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;
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:
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;
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);
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 ||
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 {
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);
}
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 ||
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)))
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);
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);
}
/* 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;
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;
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) |
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;
sctx->framebuffer.CB_has_shader_readable_metadata = false;
sctx->framebuffer.DB_has_shader_readable_metadata = false;
sctx->framebuffer.all_DCC_pipe_aligned = true;
+ sctx->framebuffer.min_bytes_per_pixel = 0;
for (i = 0; i < state->nr_cbufs; i++) {
if (!state->cbufs[i])
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. */
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);
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)
/* 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));
}
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);
+ 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);
/* 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,
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;
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));
}
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) {