Mesa (master): radv: implement VK_KHR_shader_float_controls

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 18 15:16:41 UTC 2019


Module: Mesa
Branch: master
Commit: 7c50214aab0b590059fea15e4b7550cfa99855c2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7c50214aab0b590059fea15e4b7550cfa99855c2

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Mon Oct 14 11:27:32 2019 +0200

radv: implement VK_KHR_shader_float_controls

This exposes what's required for DX and this is what we already
configure. The driver flushes denorms for FP32 and preserves them
for FP16/FP64. Note that we can't allow both preserving and
flushing denorms because this won't work for merged shaders. This
will require LLVM to update the float mode register to make it work.

Only enabled on GFX8+ with the LLVM path because it's untested on
previous chips and ACO doesn't support it.

This extension is required for SPIRV 1.4.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

---

 docs/relnotes/new_features.txt    |  2 +-
 src/amd/vulkan/radv_device.c      | 38 ++++++++++++++++++++++++++++++++++++++
 src/amd/vulkan/radv_extensions.py |  1 +
 src/amd/vulkan/radv_nir_to_llvm.c | 10 +++++++---
 src/amd/vulkan/radv_shader.c      |  1 +
 src/amd/vulkan/radv_shader.h      |  2 ++
 src/amd/vulkan/radv_shader_info.c |  1 +
 7 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt
index 2f7944e929c..1e146b4b06a 100644
--- a/docs/relnotes/new_features.txt
+++ b/docs/relnotes/new_features.txt
@@ -4,7 +4,7 @@ GL_EXT_demote_to_helper_invocation on iris, i965.
 OpenGL 4.6 on i965, iris.
 VK_ANDROID_external_memory_android_hardware_buffer on RADV.
 VK_KHR_shader_clock on Intel, RADV.
-VK_KHR_shader_float_controls on Intel.
+VK_KHR_shader_float_controls on Intel, RADV.
 VK_KHR_spirv_1_4 on Intel.
 VK_EXT_shader_subgroup_ballot on Intel.
 VK_EXT_shader_subgroup_vote on Intel.
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 37df820d9ca..5fdb1903c09 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -1488,6 +1488,44 @@ void radv_GetPhysicalDeviceProperties2(
 			properties->uniformTexelBufferOffsetSingleTexelAlignment = true;
 			break;
 		}
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR : {
+			VkPhysicalDeviceFloatControlsPropertiesKHR *properties =
+				(VkPhysicalDeviceFloatControlsPropertiesKHR *)ext;
+
+			/* On AMD hardware, denormals and rounding modes for
+			 * fp16/fp64 are controlled by the same config
+			 * register.
+			 */
+			properties->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
+			properties->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
+
+			/* Do not allow both preserving and flushing denorms
+			 * because different shaders in the same pipeline can
+			 * have different settings and this won't work for
+			 * merged shaders. To make it work, this requires LLVM
+			 * support for changing the register. The same logic
+			 * applies for the rounding modes because they are
+			 * configured with the same config register.
+			 */
+			properties->shaderDenormFlushToZeroFloat32 = true;
+			properties->shaderDenormPreserveFloat32 = false;
+			properties->shaderRoundingModeRTEFloat32 = true;
+			properties->shaderRoundingModeRTZFloat32 = false;
+			properties->shaderSignedZeroInfNanPreserveFloat32 = true;
+
+			properties->shaderDenormFlushToZeroFloat16 = false;
+			properties->shaderDenormPreserveFloat16 = true;
+			properties->shaderRoundingModeRTEFloat16 = true;
+			properties->shaderRoundingModeRTZFloat16 = false;
+			properties->shaderSignedZeroInfNanPreserveFloat16 = true;
+
+			properties->shaderDenormFlushToZeroFloat64 = false;
+			properties->shaderDenormPreserveFloat64 = true;
+			properties->shaderRoundingModeRTEFloat64 = true;
+			properties->shaderRoundingModeRTZFloat64 = false;
+			properties->shaderSignedZeroInfNanPreserveFloat64 = true;
+			break;
+		}
 		default:
 			break;
 		}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 91bbe70217e..11d907ed341 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -89,6 +89,7 @@ EXTENSIONS = [
     Extension('VK_KHR_shader_atomic_int64',               1, 'LLVM_VERSION_MAJOR >= 9'),
     Extension('VK_KHR_shader_clock',                      1, True),
     Extension('VK_KHR_shader_draw_parameters',            1, True),
+    Extension('VK_KHR_shader_float_controls',             1, 'device->rad_info.chip_class >= GFX8 && !device->use_aco'),
     Extension('VK_KHR_shader_float16_int8',               1, '!device->use_aco'),
     Extension('VK_KHR_storage_buffer_storage_class',      1, True),
     Extension('VK_KHR_surface',                          25, 'RADV_HAS_SURFACE'),
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index 126251193b1..85b452719f0 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -4769,9 +4769,13 @@ LLVMModuleRef ac_translate_nir_to_llvm(struct ac_llvm_compiler *ac_llvm,
 	ctx.options = options;
 	ctx.shader_info = shader_info;
 
-	enum ac_float_mode float_mode =
-		options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
-				       AC_FLOAT_MODE_DEFAULT;
+	enum ac_float_mode float_mode = AC_FLOAT_MODE_DEFAULT;
+
+	if (shader_info->float_controls_mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32) {
+		float_mode = AC_FLOAT_MODE_DENORM_FLUSH_TO_ZERO;
+	} else if (options->unsafe_math) {
+		float_mode = AC_FLOAT_MODE_UNSAFE_FP_MATH;
+	}
 
 	ac_llvm_context_init(&ctx.ac, ac_llvm, options->chip_class,
 			     options->family, float_mode, options->wave_size, 64);
diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index 91e22c9d68f..5f962ed160b 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -344,6 +344,7 @@ radv_shader_compile_to_nir(struct radv_device *device,
 				.descriptor_indexing = true,
 				.device_group = true,
 				.draw_parameters = true,
+				.float_controls = true,
 				.float16 = !device->physical_device->use_aco,
 				.float64 = true,
 				.geometry_streams = true,
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index aa8a340d2e1..fe23728cb66 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -314,6 +314,8 @@ struct radv_shader_info {
 
 	struct gfx9_gs_info gs_ring_info;
 	struct gfx10_ngg_info ngg_info;
+
+	unsigned float_controls_mode;
 };
 
 enum radv_shader_binary_type {
diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c
index 950b5bd599d..60e0cd22fb0 100644
--- a/src/amd/vulkan/radv_shader_info.c
+++ b/src/amd/vulkan/radv_shader_info.c
@@ -780,4 +780,5 @@ radv_nir_shader_info_pass(const struct nir_shader *nir,
 		es_info->esgs_itemsize = (max_output_written + 1) * 16;
 	}
 
+	info->float_controls_mode = nir->info.float_controls_execution_mode;
 }




More information about the mesa-commit mailing list