Module: Mesa Branch: main Commit: e3a0df646830916597466e66eafaa243214b873b URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e3a0df646830916597466e66eafaa243214b873b
Author: Karol Herbst <[email protected]> Date: Sat Oct 21 10:03:36 2023 +0200 zink: emit float controls This is required by OpenCL who relies on flushing behavior to match the runtimes advertized feature, but also later once rusticl does support denorms, to flush them if applications whish to do so. Signed-off-by: Karol Herbst <[email protected]> Acked-by: Mike Blumenkrantz <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25837> --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 36 ++++++++++++++++++++++ src/gallium/drivers/zink/zink_compiler.c | 15 +++++++++ src/gallium/drivers/zink/zink_device_info.py | 2 ++ src/gallium/drivers/zink/zink_types.h | 5 +++ 4 files changed, 58 insertions(+) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index ce7efafe128..e46b1586025 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -4550,6 +4550,42 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_ emit_image(&ctx, var, get_bare_image_type(&ctx, var, false)); } + if (sinfo->float_controls.flush_denorms) { + unsigned execution_mode = s->info.float_controls_execution_mode; + 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; + + if (!sinfo->float_controls.flush_denorms_all_independence) { + bool flush = flush_16_bit && flush_64_bit; + if (!sinfo->float_controls.flush_denorms_32_bit_independence) { + flush = flush && flush_32_bit; + flush_32_bit = flush; + } + flush_16_bit = flush; + flush_64_bit = flush; + } + + if (flush_16_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(0)) { + emit_cap = 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; + 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; + spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point, + SpvExecutionModeDenormFlushToZero, 64); + } + if (emit_cap) + spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormFlushToZero); + } + switch (s->info.stage) { case MESA_SHADER_FRAGMENT: spirv_builder_emit_exec_mode(&ctx.builder, entry_point, diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 646880b7d08..41d7fff635a 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -5377,6 +5377,21 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir) ret->sinfo.have_vulkan_memory_model = screen->info.have_KHR_vulkan_memory_model; ret->sinfo.have_workgroup_memory_explicit_layout = screen->info.have_KHR_workgroup_memory_explicit_layout; + if (screen->info.have_KHR_shader_float_controls) { + if (screen->info.props12.shaderDenormFlushToZeroFloat16) + ret->sinfo.float_controls.flush_denorms |= 0x1; + if (screen->info.props12.shaderDenormFlushToZeroFloat32) + ret->sinfo.float_controls.flush_denorms |= 0x2; + if (screen->info.props12.shaderDenormFlushToZeroFloat64) + ret->sinfo.float_controls.flush_denorms |= 0x4; + + ret->sinfo.float_controls.flush_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 || + screen->info.props12.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY; + } ret->sinfo.bindless_set_idx = screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS]; util_queue_fence_init(&ret->precompile.fence); diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py index 7dc980c44fc..2c3cde855ca 100644 --- a/src/gallium/drivers/zink/zink_device_info.py +++ b/src/gallium/drivers/zink/zink_device_info.py @@ -318,6 +318,8 @@ EXTENSIONS = [ alias="demote", features=True, conditions=["$feats.shaderDemoteToHelperInvocation"]), + Extension("VK_KHR_shader_float_controls", + alias="float_controls") ] # constructor: Versions(device_version(major, minor, patch), struct_version(major, minor)) diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index f05ed5ac91c..865fa7492c1 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -774,6 +774,11 @@ struct zink_shader_info { bool have_sparse; bool have_vulkan_memory_model; 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; + } float_controls; unsigned bindless_set_idx; };
