layers: Improve validation of float controls

Vulkan header version 1.1.116 changd the declaration of
VkPhysicalDeviceFloatControlsPropertiesKHR to use enums instead of
booleans for denorm and rounding mode independence.  The validation
layers were subsequently updated to throw correct errors.  However the
changes were not as granular as they could be.  This commit makes things
a bit finer-grained.

Change-Id: Ia92f23b2c22b5f0db05d65532eaf38dae5576823
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 5c281e7..8f02a8d 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -2348,13 +2348,32 @@
                     if (first_denorm_execution_mode.first == spv::ExecutionModeMax) {
                         // Register the first denorm execution mode found
                         first_denorm_execution_mode = std::make_pair(static_cast<spv::ExecutionMode>(mode), bit_width);
-                    } else if (first_denorm_execution_mode.first != mode && first_denorm_execution_mode.second != bit_width &&
-                               enabled_features.float_controls.denormBehaviorIndependence ==
-                                   VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR) {
-                        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                        kVUID_Core_Shader_FeatureNotEnabled,
-                                        "Shader uses independent denorm execution modes for different bit widths but that is not "
-                                        "supported on the device");
+                    } else if (first_denorm_execution_mode.first != mode && first_denorm_execution_mode.second != bit_width) {
+                        switch (enabled_features.float_controls.denormBehaviorIndependence) {
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR:
+                                if (first_rounding_mode.second != 32 && bit_width != 32) {
+                                    skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                    "Shader uses different denorm execution modes for 16 and 64-bit but "
+                                                    "denormBehaviorIndependence is "
+                                                    "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR on the device");
+                                }
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR:
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR:
+                                skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                                0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                "Shader uses different denorm execution modes for different bit widths but "
+                                                "denormBehaviorIndependence is "
+                                                "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR on the device");
+                                break;
+
+                            default:
+                                break;
+                        }
                     }
                     break;
                 }
@@ -2373,13 +2392,32 @@
                     if (first_denorm_execution_mode.first == spv::ExecutionModeMax) {
                         // Register the first denorm execution mode found
                         first_denorm_execution_mode = std::make_pair(static_cast<spv::ExecutionMode>(mode), bit_width);
-                    } else if (first_denorm_execution_mode.first != mode && first_denorm_execution_mode.second != bit_width &&
-                               enabled_features.float_controls.denormBehaviorIndependence ==
-                                   VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR) {
-                        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                        kVUID_Core_Shader_FeatureNotEnabled,
-                                        "Shader uses independent denorm execution modes for different bit widths but that is not "
-                                        "supported on the device");
+                    } else if (first_denorm_execution_mode.first != mode && first_denorm_execution_mode.second != bit_width) {
+                        switch (enabled_features.float_controls.denormBehaviorIndependence) {
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR:
+                                if (first_rounding_mode.second != 32 && bit_width != 32) {
+                                    skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                    "Shader uses different denorm execution modes for 16 and 64-bit but "
+                                                    "denormBehaviorIndependence is "
+                                                    "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR on the device");
+                                }
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR:
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR:
+                                skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                                0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                "Shader uses different denorm execution modes for different bit widths but "
+                                                "denormBehaviorIndependence is "
+                                                "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR on the device");
+                                break;
+
+                            default:
+                                break;
+                        }
                     }
                     break;
                 }
@@ -2398,13 +2436,32 @@
                     if (first_rounding_mode.first == spv::ExecutionModeMax) {
                         // Register the first rounding mode found
                         first_rounding_mode = std::make_pair(static_cast<spv::ExecutionMode>(mode), bit_width);
-                    } else if (first_rounding_mode.first != mode && first_rounding_mode.second != bit_width &&
-                               enabled_features.float_controls.roundingModeIndependence ==
-                                   VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR) {
-                        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                        kVUID_Core_Shader_FeatureNotEnabled,
-                                        "Shader uses independent rounding modes for different bit widths but that is not supported "
-                                        "on the device");
+                    } else if (first_rounding_mode.first != mode && first_rounding_mode.second != bit_width) {
+                        switch (enabled_features.float_controls.roundingModeIndependence) {
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR:
+                                if (first_rounding_mode.second != 32 && bit_width != 32) {
+                                    skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                    "Shader uses different rounding modes for 16 and 64-bit but "
+                                                    "roundingModeIndependence is "
+                                                    "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR on the device");
+                                }
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR:
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR:
+                                skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                                0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                "Shader uses different rounding modes for different bit widths but "
+                                                "roundingModeIndependence is "
+                                                "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR on the device");
+                                break;
+
+                            default:
+                                break;
+                        }
                     }
                     break;
                 }
@@ -2423,13 +2480,32 @@
                     if (first_rounding_mode.first == spv::ExecutionModeMax) {
                         // Register the first rounding mode found
                         first_rounding_mode = std::make_pair(static_cast<spv::ExecutionMode>(mode), bit_width);
-                    } else if (first_rounding_mode.first != mode && first_rounding_mode.second != bit_width &&
-                               enabled_features.float_controls.roundingModeIndependence ==
-                                   VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR) {
-                        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                        kVUID_Core_Shader_FeatureNotEnabled,
-                                        "Shader uses independent rounding modes for different bit widths but that is not supported "
-                                        "on the device");
+                    } else if (first_rounding_mode.first != mode && first_rounding_mode.second != bit_width) {
+                        switch (enabled_features.float_controls.roundingModeIndependence) {
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR:
+                                if (first_rounding_mode.second != 32 && bit_width != 32) {
+                                    skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                    "Shader uses different rounding modes for 16 and 64-bit but "
+                                                    "roundingModeIndependence is "
+                                                    "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR on the device");
+                                }
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR:
+                                break;
+
+                            case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR:
+                                skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                                0, kVUID_Core_Shader_FeatureNotEnabled,
+                                                "Shader uses different rounding modes for different bit widths but "
+                                                "roundingModeIndependence is "
+                                                "VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR on the device");
+                                break;
+
+                            default:
+                                break;
+                        }
                     }
                     break;
                 }