diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index ccff1b16f40..aa5ca0d592d 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -275,6 +275,7 @@ fd_init_shader_caps(struct fd_screen *screen) (is_a5xx(screen) || is_a6xx(screen)) && (i == MESA_SHADER_COMPUTE || i == MESA_SHADER_FRAGMENT) && !FD_DBG(NOFP16); + caps->fp16_no_denorms = caps->fp16 && screen->gen < 8; caps->glsl_16bit_load_dst = true; caps->max_texture_samplers = diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 7f0d7919b90..e89805c287e 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -631,6 +631,8 @@ zink_init_shader_caps(struct zink_screen *screen) screen->info.feats12.shaderFloat16 || (screen->info.have_KHR_shader_float16_int8 && screen->info.shader_float16_int8_feats.shaderFloat16); + caps->fp16_no_denorms = caps->fp16 && !screen->info.props12.shaderDenormPreserveFloat16 + && screen->info.props12.shaderDenormFlushToZeroFloat16; caps->glsl_16bit_load_dst = true; caps->int16 = screen->info.feats.features.shaderInt16; diff --git a/src/gallium/frontends/rusticl/core/device.rs b/src/gallium/frontends/rusticl/core/device.rs index 85aa646009d..551497ee5d6 100644 --- a/src/gallium/frontends/rusticl/core/device.rs +++ b/src/gallium/frontends/rusticl/core/device.rs @@ -1389,12 +1389,17 @@ impl DeviceBase { } pub fn spirv_to_nir_opts(&self) -> SPIRVToNirOptions { - let spirv_float_controls = float_controls::FLOAT_CONTROLS_DENORM_PRESERVE_FP16 - | float_controls::FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32 + let mut spirv_float_controls = float_controls::FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32 | float_controls::FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16 | float_controls::FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32 | float_controls::FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64; + if self.shader_caps().fp16_no_denorms { + spirv_float_controls |= float_controls::FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16; + } else { + spirv_float_controls |= float_controls::FLOAT_CONTROLS_DENORM_PRESERVE_FP16; + } + SPIRVToNirOptions { caps: &self.spirv_caps, address_bits: self.address_bits(), diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 7d8213493b0..8854309f0d4 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -802,6 +802,7 @@ struct pipe_shader_caps { bool fp16; bool fp16_derivatives; bool fp16_const_buffers; + bool fp16_no_denorms; bool int16; bool glsl_16bit_consts; bool glsl_16bit_load_dst; /* fp16 or int16 is AND'ed with this */