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;
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;
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));