summaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2019-10-14 11:27:32 +0200
committerSamuel Pitoiset <[email protected]>2019-10-18 16:55:58 +0200
commit7c50214aab0b590059fea15e4b7550cfa99855c2 (patch)
treefabebac160fea7a5b9daf582a47490a5aa972318 /src/amd
parent2c2aaf275c1edba38c552ac74de4d46bb2ebfbe8 (diff)
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 <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/vulkan/radv_device.c38
-rw-r--r--src/amd/vulkan/radv_extensions.py1
-rw-r--r--src/amd/vulkan/radv_nir_to_llvm.c10
-rw-r--r--src/amd/vulkan/radv_shader.c1
-rw-r--r--src/amd/vulkan/radv_shader.h2
-rw-r--r--src/amd/vulkan/radv_shader_info.c1
6 files changed, 50 insertions, 3 deletions
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;
}