From 30d5f587b85e136194321958e81886ec0c378eb3 Mon Sep 17 00:00:00 2001 From: spencer-lunarg Date: Fri, 18 Sep 2026 09:56:42 -0400 Subject: [PATCH] layers: New Clip/Cull VUID churn --- layers/core_checks/cc_shader_interface.cpp | 22 +++++-------------- .../unimplementable_validation.h | 9 ++++++++ scripts/vk_validation_stats.py | 1 - tests/unit/shader_limits.cpp | 11 +++++----- tests/unit/shader_object_ext.cpp | 10 ++++----- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/layers/core_checks/cc_shader_interface.cpp b/layers/core_checks/cc_shader_interface.cpp index a78c00d3f5b..29dcc0a9b35 100644 --- a/layers/core_checks/cc_shader_interface.cpp +++ b/layers/core_checks/cc_shader_interface.cpp @@ -368,8 +368,6 @@ bool CoreChecks::ValidateBuiltInLimits(const spirv::Module& module_state, const uint32_t clip_distance_total = 0; uint32_t cull_distance_total = 0; - // ... so apperently Vulkan 1.0 (and like 2% of random devices don't support clip/cull somehow) - // Not sure if we should really be validating these yet // https://gitlab.khronos.org/vulkan/vulkan/-/work_items/4965 const bool skip_clip_cull = phys_dev_props.limits.maxClipDistances == 0 || phys_dev_props.limits.maxCullDistances == 0 || phys_dev_props.limits.maxCombinedClipAndCullDistances == 0; @@ -404,9 +402,7 @@ bool CoreChecks::ValidateBuiltInLimits(const spirv::Module& module_state, const const uint32_t array_size = module_state.GetFlattenArraySize(*variable->type_struct_info->members[i].insn); clip_distance_total += array_size; if (array_size > phys_dev_props.limits.maxClipDistances) { - const char* vuid = pipeline ? "VUID-VkPipelineShaderStageCreateInfo-maxClipDistances-00708" - : "VUID-VkShaderCreateInfoEXT-pCode-08448"; - skip |= LogError(vuid, module_state.handle(), loc, + skip |= LogError("VUID-RuntimeSpirv-maxClipDistances-00708", module_state.handle(), loc, "shader %s ClipDistance BuiltIn array size is %" PRIu32 " which exceeds maxClipDistances of %" PRIu32 ".", entrypoint.Describe().c_str(), array_size, phys_dev_props.limits.maxClipDistances); @@ -415,9 +411,7 @@ bool CoreChecks::ValidateBuiltInLimits(const spirv::Module& module_state, const const uint32_t array_size = module_state.GetFlattenArraySize(*variable->type_struct_info->members[i].insn); cull_distance_total += array_size; if (array_size > phys_dev_props.limits.maxCullDistances) { - const char* vuid = pipeline ? "VUID-VkPipelineShaderStageCreateInfo-maxCullDistances-00709" - : "VUID-VkShaderCreateInfoEXT-pCode-08449"; - skip |= LogError(vuid, module_state.handle(), loc, + skip |= LogError("VUID-RuntimeSpirv-maxCullDistances-00709", module_state.handle(), loc, "shader %s CullDistance BuiltIn array size is %" PRIu32 " which exceeds maxCullDistances of %" PRIu32 ".", entrypoint.Describe().c_str(), array_size, phys_dev_props.limits.maxCullDistances); @@ -427,9 +421,7 @@ bool CoreChecks::ValidateBuiltInLimits(const spirv::Module& module_state, const } else if (variable->decorations.built_in == spv::BuiltInClipDistance) { clip_distance_total += variable->array_size; if (variable->array_size > phys_dev_props.limits.maxClipDistances) { - const char* vuid = pipeline ? "VUID-VkPipelineShaderStageCreateInfo-maxClipDistances-00708" - : "VUID-VkShaderCreateInfoEXT-pCode-08448"; - skip |= LogError(vuid, module_state.handle(), loc, + skip |= LogError("VUID-RuntimeSpirv-maxClipDistances-00708", module_state.handle(), loc, "shader %s ClipDistance BuiltIn array size is %" PRIu32 " which exceeds maxClipDistances of %" PRIu32 ".", entrypoint.Describe().c_str(), variable->array_size, phys_dev_props.limits.maxClipDistances); @@ -437,9 +429,7 @@ bool CoreChecks::ValidateBuiltInLimits(const spirv::Module& module_state, const } else if (variable->decorations.built_in == spv::BuiltInCullDistance) { cull_distance_total += variable->array_size; if (variable->array_size > phys_dev_props.limits.maxCullDistances) { - const char* vuid = pipeline ? "VUID-VkPipelineShaderStageCreateInfo-maxCullDistances-00709" - : "VUID-VkShaderCreateInfoEXT-pCode-08449"; - skip |= LogError(vuid, module_state.handle(), loc, + skip |= LogError("VUID-RuntimeSpirv-maxCullDistances-00709", module_state.handle(), loc, "shader %s CullDistance BuiltIn array size is %" PRIu32 " which exceeds maxCullDistances of %" PRIu32 ".", entrypoint.Describe().c_str(), variable->array_size, phys_dev_props.limits.maxCullDistances); @@ -448,9 +438,7 @@ bool CoreChecks::ValidateBuiltInLimits(const spirv::Module& module_state, const } if (!skip_clip_cull && (clip_distance_total + cull_distance_total) > phys_dev_props.limits.maxCombinedClipAndCullDistances) { - const char* vuid = pipeline ? "VUID-VkPipelineShaderStageCreateInfo-maxCombinedClipAndCullDistances-00710" - : "VUID-VkShaderCreateInfoEXT-pCode-08450"; - skip |= LogError(vuid, module_state.handle(), loc, + skip |= LogError("VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710", module_state.handle(), loc, "shader %s has a ClipDistance BuiltIn array size of %" PRIu32 " and a CullDistance BuiltIn array size of %" PRIu32 " which sum to %" PRIu32 " and exceed maxCombinedClipAndCullDistances of %" PRIu32 ".", diff --git a/layers/error_message/unimplementable_validation.h b/layers/error_message/unimplementable_validation.h index 2d238018706..a828cbef7d9 100644 --- a/layers/error_message/unimplementable_validation.h +++ b/layers/error_message/unimplementable_validation.h @@ -828,6 +828,15 @@ const char* not_going_to_do[] = { // This falls under the failure of the sparse memory spec/testing // so going to skip until someone complains loudly "VUID-vkCmdDraw-None-08119", + + // https://gitlab.khronos.org/vulkan/vulkan/-/work_items/4965 + // Apparently some ARM devices support no clip/cull and guarded by the + // shaderClipDistance/shaderCullDistance features such that these are not possible to even hit + // This whole thing is an issue because glslang adds the Clip/Cull to the gl_vertex output struct + // but only if you use it does it use the OpCapabilty + // ... so these are just here because of the decision of glslang years ago + "VUID-RuntimeSpirv-maxClipDistances-08448", + "VUID-RuntimeSpirv-maxCullDistances-08449", }; // VUs from deprecated extensions that would require complex codegen to get working diff --git a/scripts/vk_validation_stats.py b/scripts/vk_validation_stats.py index ee2b74e223d..21f76cf3593 100755 --- a/scripts/vk_validation_stats.py +++ b/scripts/vk_validation_stats.py @@ -325,7 +325,6 @@ def __init__(self, val_json, val_source, val_tests, spirv_val): "5724" : ["03511", "03512", "03513", "03514", "03638", "03639", "03640", "03641", "03681", "03682", "03684", "03685", "03686", "03688", "03689", "03690", "03692", "03693", "03694", "04029", "04035", "04041", "04735", "04736"], "5749" : ["06289", "06290", "06291", "06292"], "6656" : ["08756", "08757"], - "6801" : ["00708", "00709", "00710", "08448", "08449", "08450"], "7141" : ["09373", "09374"], "7481" : ["03561"], "8095" : ["10795", "10796", "10797"], diff --git a/tests/unit/shader_limits.cpp b/tests/unit/shader_limits.cpp index 9e01d2a4e34..188f66ead62 100644 --- a/tests/unit/shader_limits.cpp +++ b/tests/unit/shader_limits.cpp @@ -186,11 +186,11 @@ TEST_F(NegativeShaderLimits, MaxClipDistances) { VkShaderObj fs(*m_device, source.str().c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM); // hit both limits - m_errorMonitor->SetAllowedFailureMsg("VUID-VkPipelineShaderStageCreateInfo-maxCombinedClipAndCullDistances-00710"); + m_errorMonitor->SetAllowedFailureMsg("VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710"); const auto set_fs = [&](CreatePipelineHelper& helper) { helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()}; }; - CreatePipelineHelper::OneshotTest(*this, set_fs, kErrorBit, "VUID-VkPipelineShaderStageCreateInfo-maxClipDistances-00708"); + CreatePipelineHelper::OneshotTest(*this, set_fs, kErrorBit, "VUID-RuntimeSpirv-maxClipDistances-00708"); } TEST_F(NegativeShaderLimits, MaxCullDistances) { @@ -246,11 +246,11 @@ TEST_F(NegativeShaderLimits, MaxCullDistances) { VkShaderObj vs(*m_device, source.str().c_str(), VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM); // hit both limits - m_errorMonitor->SetAllowedFailureMsg("VUID-VkPipelineShaderStageCreateInfo-maxCombinedClipAndCullDistances-00710"); + m_errorMonitor->SetAllowedFailureMsg("VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710"); const auto set_vs = [&](CreatePipelineHelper& helper) { helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()}; }; - CreatePipelineHelper::OneshotTest(*this, set_vs, kErrorBit, "VUID-VkPipelineShaderStageCreateInfo-maxCullDistances-00709"); + CreatePipelineHelper::OneshotTest(*this, set_vs, kErrorBit, "VUID-RuntimeSpirv-maxCullDistances-00709"); } TEST_F(NegativeShaderLimits, MaxCombinedClipAndCullDistances) { @@ -317,8 +317,7 @@ TEST_F(NegativeShaderLimits, MaxCombinedClipAndCullDistances) { const auto set_vs = [&](CreatePipelineHelper& helper) { helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()}; }; - CreatePipelineHelper::OneshotTest(*this, set_vs, kErrorBit, - "VUID-VkPipelineShaderStageCreateInfo-maxCombinedClipAndCullDistances-00710"); + CreatePipelineHelper::OneshotTest(*this, set_vs, kErrorBit, "VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710"); } TEST_F(NegativeShaderLimits, MinAndMaxTexelGatherOffset) { diff --git a/tests/unit/shader_object_ext.cpp b/tests/unit/shader_object_ext.cpp index 9b90c6cee61..bafbd7250df 100644 --- a/tests/unit/shader_object_ext.cpp +++ b/tests/unit/shader_object_ext.cpp @@ -4736,8 +4736,8 @@ TEST_F(NegativeShaderObjectEXT, MaxClipDistances) { VkShaderCreateInfoEXT create_info = ShaderCreateInfoEXT(spv, VK_SHADER_STAGE_FRAGMENT_BIT); VkShaderEXT shader; - m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderCreateInfoEXT-pCode-08450"); // hit both limits - m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08448"); + m_errorMonitor->SetAllowedFailureMsg("VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710"); // hit both limits + m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-maxClipDistances-00708"); vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); m_errorMonitor->VerifyFound(); } @@ -4797,8 +4797,8 @@ TEST_F(NegativeShaderObjectEXT, MaxCullDistances) { VkShaderCreateInfoEXT create_info = ShaderCreateInfoEXT(spv, VK_SHADER_STAGE_VERTEX_BIT); VkShaderEXT shader; - m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderCreateInfoEXT-pCode-08450"); // hit both limits - m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08449"); + m_errorMonitor->SetAllowedFailureMsg("VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710"); // hit both limits + m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-maxCullDistances-00709"); vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); m_errorMonitor->VerifyFound(); } @@ -4867,7 +4867,7 @@ TEST_F(NegativeShaderObjectEXT, MaxCombinedClipAndCullDistances) { VkShaderCreateInfoEXT create_info = ShaderCreateInfoEXT(spv, VK_SHADER_STAGE_VERTEX_BIT); VkShaderEXT shader; - m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08450"); + m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-maxCombinedClipAndCullDistances-00710"); vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); m_errorMonitor->VerifyFound(); }