summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/shader_enums.h20
-rw-r--r--src/compiler/shader_info.h3
-rw-r--r--src/compiler/spirv/spirv_to_nir.c72
3 files changed, 95 insertions, 0 deletions
diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h
index 0f402f42741..7eac07b5c11 100644
--- a/src/compiler/shader_enums.h
+++ b/src/compiler/shader_enums.h
@@ -858,6 +858,26 @@ enum gl_derivative_group {
DERIVATIVE_GROUP_LINEAR,
};
+enum float_controls
+{
+ FLOAT_CONTROLS_DEFAULT_FLOAT_CONTROL_MODE = 0x0000,
+ FLOAT_CONTROLS_DENORM_PRESERVE_FP16 = 0x0001,
+ FLOAT_CONTROLS_DENORM_PRESERVE_FP32 = 0x0002,
+ FLOAT_CONTROLS_DENORM_PRESERVE_FP64 = 0x0004,
+ FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16 = 0x0008,
+ FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32 = 0x0010,
+ FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64 = 0x0020,
+ FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP16 = 0x0040,
+ FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP32 = 0x0080,
+ FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP64 = 0x0100,
+ FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16 = 0x0200,
+ FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32 = 0x0400,
+ FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64 = 0x0800,
+ FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16 = 0x1000,
+ FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32 = 0x2000,
+ FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64 = 0x4000,
+};
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index ae894f3082b..8b0176f0438 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -154,6 +154,9 @@ typedef struct shader_info {
/** Was this shader linked with any transform feedback varyings? */
bool has_transform_feedback_varyings;
+ /* SPV_KHR_float_controls: execution mode for floating point ops */
+ unsigned float_controls_execution_mode;
+
union {
struct {
/* Which inputs are doubles */
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index acf73ee1952..f46b0a9bb02 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -3925,6 +3925,14 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
b->shader->info.fs.sample_interlock_unordered = true;
break;
+ case SpvExecutionModeDenormPreserve:
+ case SpvExecutionModeDenormFlushToZero:
+ case SpvExecutionModeSignedZeroInfNanPreserve:
+ case SpvExecutionModeRoundingModeRTE:
+ case SpvExecutionModeRoundingModeRTZ:
+ /* Already handled in vtn_handle_rounding_mode_in_execution_mode() */
+ break;
+
default:
vtn_fail("Unhandled execution mode: %s (%u)",
spirv_executionmode_to_string(mode->exec_mode),
@@ -3932,6 +3940,63 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
}
}
+static void
+vtn_handle_rounding_mode_in_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
+ const struct vtn_decoration *mode, void *data)
+{
+ vtn_assert(b->entry_point == entry_point);
+
+ unsigned execution_mode = 0;
+
+ switch(mode->exec_mode) {
+ case SpvExecutionModeDenormPreserve:
+ switch (mode->operands[0]) {
+ case 16: execution_mode = FLOAT_CONTROLS_DENORM_PRESERVE_FP16; break;
+ case 32: execution_mode = FLOAT_CONTROLS_DENORM_PRESERVE_FP32; break;
+ case 64: execution_mode = FLOAT_CONTROLS_DENORM_PRESERVE_FP64; break;
+ default: vtn_fail("Floating point type not supported");
+ }
+ break;
+ case SpvExecutionModeDenormFlushToZero:
+ switch (mode->operands[0]) {
+ case 16: execution_mode = FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16; break;
+ case 32: execution_mode = FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32; break;
+ case 64: execution_mode = FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64; break;
+ default: vtn_fail("Floating point type not supported");
+ }
+ break;
+ case SpvExecutionModeSignedZeroInfNanPreserve:
+ switch (mode->operands[0]) {
+ case 16: execution_mode = FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP16; break;
+ case 32: execution_mode = FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP32; break;
+ case 64: execution_mode = FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP64; break;
+ default: vtn_fail("Floating point type not supported");
+ }
+ break;
+ case SpvExecutionModeRoundingModeRTE:
+ switch (mode->operands[0]) {
+ case 16: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16; break;
+ case 32: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32; break;
+ case 64: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64; break;
+ default: vtn_fail("Floating point type not supported");
+ }
+ break;
+ case SpvExecutionModeRoundingModeRTZ:
+ switch (mode->operands[0]) {
+ case 16: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16; break;
+ case 32: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32; break;
+ case 64: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64; break;
+ default: vtn_fail("Floating point type not supported");
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ b->shader->info.float_controls_execution_mode |= execution_mode;
+}
+
static bool
vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count)
@@ -4658,6 +4723,13 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
/* Set shader info defaults */
b->shader->info.gs.invocations = 1;
+ /* Parse rounding mode execution modes. This has to happen earlier than
+ * other changes in the execution modes since they can affect, for example,
+ * the result of the floating point constants.
+ */
+ vtn_foreach_execution_mode(b, b->entry_point,
+ vtn_handle_rounding_mode_in_execution_mode, NULL);
+
b->specializations = spec;
b->num_specializations = num_spec;