diff --git a/.pick_status.json b/.pick_status.json index b8b47294e59..ddc5070246a 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -3734,7 +3734,7 @@ "description": "radeonsi: account for outputs_written when updating spi_shader_col_format", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 6fc93276dba..bf258713393 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2005,7 +2005,7 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler shader->info.writes_sample_mask &= !shader->key.ps.part.epilog.kill_samplemask; shader->info.uses_discard |= shader->key.ps.part.prolog.poly_stipple || shader->key.ps.part.epilog.alpha_func != PIPE_FUNC_ALWAYS; - si_shader_update_spi_shader_formats(shader); + si_shader_update_spi_shader_formats(shader, NULL); break; default:; } diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 356555e8c66..7b777b29019 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -159,6 +159,6 @@ void si_get_late_shader_variant_info(struct si_shader *shader, struct si_shader_ nir_shader *nir); void si_set_spi_ps_input_config_for_separate_prolog(struct si_shader *shader); void si_fixup_spi_ps_input_config(struct si_shader *shader); -void si_shader_update_spi_shader_formats(struct si_shader *shader); +void si_shader_update_spi_shader_formats(struct si_shader *shader, nir_shader *nir); #endif diff --git a/src/gallium/drivers/radeonsi/si_shader_variant_info.c b/src/gallium/drivers/radeonsi/si_shader_variant_info.c index 9a495589e3a..99d47b699c2 100644 --- a/src/gallium/drivers/radeonsi/si_shader_variant_info.c +++ b/src/gallium/drivers/radeonsi/si_shader_variant_info.c @@ -11,21 +11,34 @@ /* The spi_shader_*_format fields depend on the framebuffer state and the * NIR shader (monolithic or main part). */ -void si_shader_update_spi_shader_formats(struct si_shader *shader) +void si_shader_update_spi_shader_formats(struct si_shader *shader, nir_shader *nir) { unsigned spi_shader_col_format = shader->key.ps.part.epilog.spi_shader_col_format; unsigned value = 0, num_mrts = 0; unsigned i, num_targets = (util_last_bit(spi_shader_col_format) + 3) / 4; + uint64_t colors_written = UINT64_MAX; shader->info.spi_shader_z_format = ac_get_spi_shader_z_format(shader->info.writes_z, shader->info.writes_stencil, shader->info.writes_sample_mask, shader->key.ps.part.epilog.alpha_to_coverage_via_mrtz); + if (nir) { + colors_written = (nir->info.outputs_written >> FRAG_RESULT_DATA0) & BITFIELD_MASK(8); + if (nir->info.outputs_written & BITFIELD_BIT(FRAG_RESULT_DUAL_SRC_BLEND)) + colors_written |= 0x2; + if (nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_COLOR)) { + if (colors_written == 0) + colors_written = UINT64_MAX; /* color0_writes_all_cbufs */ + else + colors_written |= 0x1; + } + } + /* Remove holes in spi_shader_col_format. */ for (i = 0; i < num_targets; i++) { unsigned spi_format = (spi_shader_col_format >> (i * 4)) & 0xf; - if (spi_format) { + if (spi_format && (colors_written & 1u << num_mrts)) { value |= spi_format << (num_mrts * 4); num_mrts++; } @@ -346,7 +359,7 @@ void si_get_shader_variant_info(struct si_shader *shader, } } - si_shader_update_spi_shader_formats(shader); + si_shader_update_spi_shader_formats(shader, nir); /* ACO needs spi_ps_input_ena before si_init_shader_args. */ shader->config.spi_ps_input_ena =