zink: handle denorm preserve execution modes

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25937>
This commit is contained in:
Karol Herbst 2023-10-27 00:31:27 +02:00
parent 049af04341
commit 6afa1b3bad
3 changed files with 51 additions and 12 deletions

View file

@ -4554,35 +4554,66 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_
bool flush_16_bit = nir_is_denorm_flush_to_zero(execution_mode, 16);
bool flush_32_bit = nir_is_denorm_flush_to_zero(execution_mode, 32);
bool flush_64_bit = nir_is_denorm_flush_to_zero(execution_mode, 64);
bool emit_cap = false;
bool preserve_16_bit = nir_is_denorm_preserve(execution_mode, 16);
bool preserve_32_bit = nir_is_denorm_preserve(execution_mode, 32);
bool preserve_64_bit = nir_is_denorm_preserve(execution_mode, 64);
bool emit_cap_flush = false;
bool emit_cap_preserve = false;
if (!sinfo->float_controls.flush_denorms_all_independence) {
if (!sinfo->float_controls.denorms_all_independence) {
bool flush = flush_16_bit && flush_64_bit;
if (!sinfo->float_controls.flush_denorms_32_bit_independence) {
bool preserve = preserve_16_bit && preserve_64_bit;
if (!sinfo->float_controls.denorms_32_bit_independence) {
flush = flush && flush_32_bit;
preserve = preserve && preserve_32_bit;
flush_32_bit = flush;
preserve_32_bit = preserve;
}
flush_16_bit = flush;
flush_64_bit = flush;
preserve_16_bit = preserve;
preserve_64_bit = preserve;
}
if (flush_16_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(0)) {
emit_cap = true;
emit_cap_flush = true;
spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
SpvExecutionModeDenormFlushToZero, 16);
}
if (flush_32_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(1)) {
emit_cap = true;
emit_cap_flush = true;
spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
SpvExecutionModeDenormFlushToZero, 32);
}
if (flush_64_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(2)) {
emit_cap = true;
emit_cap_flush = true;
spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
SpvExecutionModeDenormFlushToZero, 64);
}
if (emit_cap)
if (preserve_16_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(0)) {
emit_cap_preserve = true;
spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
SpvExecutionModeDenormPreserve, 16);
}
if (preserve_32_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(1)) {
emit_cap_preserve = true;
spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
SpvExecutionModeDenormPreserve, 32);
}
if (preserve_64_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(2)) {
emit_cap_preserve = true;
spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
SpvExecutionModeDenormPreserve, 64);
}
if (emit_cap_flush)
spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormFlushToZero);
if (emit_cap_preserve)
spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormPreserve);
}
switch (s->info.stage) {

View file

@ -5386,11 +5386,18 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir)
if (screen->info.props12.shaderDenormFlushToZeroFloat64)
ret->sinfo.float_controls.flush_denorms |= 0x4;
ret->sinfo.float_controls.flush_denorms_all_independence =
if (screen->info.props12.shaderDenormPreserveFloat16)
ret->sinfo.float_controls.preserve_denorms |= 0x1;
if (screen->info.props12.shaderDenormPreserveFloat32)
ret->sinfo.float_controls.preserve_denorms |= 0x2;
if (screen->info.props12.shaderDenormPreserveFloat64)
ret->sinfo.float_controls.preserve_denorms |= 0x4;
ret->sinfo.float_controls.denorms_all_independence =
screen->info.props12.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
ret->sinfo.float_controls.flush_denorms_32_bit_independence =
ret->sinfo.float_controls.flush_denorms_all_independence ||
ret->sinfo.float_controls.denorms_32_bit_independence =
ret->sinfo.float_controls.denorms_all_independence ||
screen->info.props12.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY;
}
ret->sinfo.bindless_set_idx = screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS];

View file

@ -776,8 +776,9 @@ struct zink_shader_info {
bool have_workgroup_memory_explicit_layout;
struct {
uint8_t flush_denorms:3; // 16, 32, 64
bool flush_denorms_32_bit_independence:1;
bool flush_denorms_all_independence:1;
uint8_t preserve_denorms:3; // 16, 32, 64
bool denorms_32_bit_independence:1;
bool denorms_all_independence:1;
} float_controls;
unsigned bindless_set_idx;
};