mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-23 23:30:22 +01:00
tu: Use safe-const binning VS when safe-const full VS is used
Otherwise we can have a case where binning VS uses more consts than full VS (when safe variant is used for full VS), that will result in a rendering issue because SP_VS_CONST_CONFIG.CONSTLEN is shared between full and binning VS in PROGRAM_CONFIG state and gets the value from the full VS. There are two alternative solutions that can allow binning VS to always use maximum constlen: - Move constlen emission to per-XS config. This interferes PROGRAM_CONFIG state which uploads consts and does SP_UPDATE_CNTL. Consts would need to be uploaded after constlen is defined, while SP_UPDATE_CNTL must be done before per-XS state is emitted. Also having SP_UPDATE_CNTL in a draw state that is always DIRTY isn't great. Something didn't work out on A6XX, so this idea was dropped. - Emit constlen again in VS_BINNING draw state. This seem to work but also likely an undefined behaviour since constlen is changed after some consts are uploaded. Cc: mesa-stable Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36203>
This commit is contained in:
parent
a0a9c12124
commit
6003a89b89
2 changed files with 25 additions and 12 deletions
|
|
@ -2302,7 +2302,9 @@ tu_emit_program_state(struct tu_cs *sub_cs,
|
|||
prog->vs_binning_state = prog->vs_state;
|
||||
} else {
|
||||
prog->vs_binning_state =
|
||||
shaders[MESA_SHADER_VERTEX]->binning_state;
|
||||
(safe_variants & (1u << MESA_SHADER_VERTEX))
|
||||
? shaders[MESA_SHADER_VERTEX]->safe_const_binning_state
|
||||
: shaders[MESA_SHADER_VERTEX]->binning_state;
|
||||
}
|
||||
|
||||
prog->hs_state = draw_states[MESA_SHADER_TESS_CTRL];
|
||||
|
|
|
|||
|
|
@ -2343,9 +2343,13 @@ tu_upload_shader(struct tu_device *dev,
|
|||
const struct ir3_shader_variant *v = shader->variant;
|
||||
const struct ir3_shader_variant *binning = v ? v->binning : NULL;
|
||||
const struct ir3_shader_variant *safe_const = shader->safe_const_variant;
|
||||
const struct ir3_shader_variant *safe_const_binning =
|
||||
safe_const && v->type == MESA_SHADER_VERTEX ? safe_const->binning : NULL;
|
||||
|
||||
if (v->type == MESA_SHADER_VERTEX && v->stream_output.num_outputs != 0)
|
||||
if (v->type == MESA_SHADER_VERTEX && v->stream_output.num_outputs != 0) {
|
||||
binning = v;
|
||||
safe_const_binning = safe_const;
|
||||
}
|
||||
|
||||
uint32_t size = 0;
|
||||
if (v->type == MESA_SHADER_VERTEX)
|
||||
|
|
@ -2354,16 +2358,11 @@ tu_upload_shader(struct tu_device *dev,
|
|||
const unsigned xs_size = 128;
|
||||
const unsigned vpc_size = 32 + (v->stream_output.num_outputs != 0 ? 256 : 0);
|
||||
|
||||
size += xs_size + tu_xs_get_additional_cs_size_dwords(v);
|
||||
size += v->info.size / 4;
|
||||
if (binning) {
|
||||
size += xs_size + tu_xs_get_additional_cs_size_dwords(binning);
|
||||
size += binning->info.size / 4;
|
||||
}
|
||||
|
||||
if (safe_const) {
|
||||
size += xs_size + tu_xs_get_additional_cs_size_dwords(safe_const);
|
||||
size += safe_const->info.size / 4;
|
||||
for (auto& variant : {v, binning, safe_const, safe_const_binning}) {
|
||||
if (variant) {
|
||||
size += xs_size + tu_xs_get_additional_cs_size_dwords(variant);
|
||||
size += variant->info.size / 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* We emit an empty VPC including streamout state in the binning draw state */
|
||||
|
|
@ -2416,6 +2415,7 @@ tu_upload_shader(struct tu_device *dev,
|
|||
uint64_t iova = tu_upload_variant(&shader->cs, v);
|
||||
uint64_t binning_iova = tu_upload_variant(&shader->cs, binning);
|
||||
uint64_t safe_const_iova = tu_upload_variant(&shader->cs, safe_const);
|
||||
uint64_t safe_const_binning_iova = tu_upload_variant(&shader->cs, safe_const_binning);
|
||||
|
||||
struct tu_cs sub_cs;
|
||||
tu_cs_begin_sub_stream(&shader->cs, xs_size +
|
||||
|
|
@ -2445,6 +2445,17 @@ tu_upload_shader(struct tu_device *dev,
|
|||
shader->binning_state = tu_cs_end_draw_state(&shader->cs, &sub_cs);
|
||||
}
|
||||
|
||||
if (safe_const_binning) {
|
||||
tu_cs_begin_sub_stream(&shader->cs, xs_size + vpc_size +
|
||||
tu_xs_get_additional_cs_size_dwords(safe_const_binning), &sub_cs);
|
||||
TU_CALLX(dev, tu6_emit_variant)(
|
||||
&sub_cs, v->type, safe_const_binning, &pvtmem_config, shader->view_mask,
|
||||
safe_const_binning_iova);
|
||||
/* emit an empty VPC */
|
||||
TU_CALLX(dev, tu6_emit_vpc)(&sub_cs, safe_const_binning, NULL, NULL, NULL, NULL);
|
||||
shader->safe_const_binning_state = tu_cs_end_draw_state(&shader->cs, &sub_cs);
|
||||
}
|
||||
|
||||
/* We don't support binning variants for GS, so the same draw state is used
|
||||
* when binning and when drawing, but the VPC draw state is not executed
|
||||
* when binning so we still need to generate an appropriate VPC config for
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue