diff --git a/layers/core_checks/cc_cmd_buffer_dynamic.cpp b/layers/core_checks/cc_cmd_buffer_dynamic.cpp index 0ff70eb9683..9b21baecfe1 100644 --- a/layers/core_checks/cc_cmd_buffer_dynamic.cpp +++ b/layers/core_checks/cc_cmd_buffer_dynamic.cpp @@ -922,6 +922,11 @@ bool CoreChecks::ValidateDrawDynamicStateVertex(const LastBound& last_bound_stat const spirv::Instruction* var_base_type = vert_spirv_state.FindDef(var_base_type_id); const uint32_t var_numeric_type = vert_spirv_state.GetNumericType(*var_base_type); + if (var_numeric_type == spirv::NumericTypeUnknown && variable_ptr->type_struct_info) { + // TODO https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/12281 + continue; + } + const bool attribute64 = vkuFormatIs64bit(attrib->desc.format); const bool shader64 = vert_spirv_state.GetBaseTypeInstruction(var_base_type)->GetBitWidth() == 64; diff --git a/layers/core_checks/cc_shader_interface.cpp b/layers/core_checks/cc_shader_interface.cpp index 3fdc61f943b..97c4a350fe4 100644 --- a/layers/core_checks/cc_shader_interface.cpp +++ b/layers/core_checks/cc_shader_interface.cpp @@ -117,6 +117,7 @@ bool CoreChecks::ValidateInterfaceVertexInput(const vvl::Pipeline& pipeline, con for (const auto& [location, attribute_info] : location_map) { const auto attribute_input = attribute_info.attribute_input; const auto shader_input = attribute_info.shader_input; + const auto variable_ptr = attribute_info.variable_ptr; if (attribute_input && !shader_input) { skip |= LogPerformanceWarning("WARNING-Shader-OutputNotConsumed", module_state.handle(), vi_loc, @@ -128,7 +129,7 @@ bool CoreChecks::ValidateInterfaceVertexInput(const vvl::Pipeline& pipeline, con "does not have a Location %" PRIu32 ", but %s has %s at that Location. (This can be valid if " "either the vertexAttributeRobustness or maintenance9 feature is enabled)", - location, entrypoint.Describe().c_str(), attribute_info.variable_ptr->Describe().c_str()); + location, entrypoint.Describe().c_str(), variable_ptr->Describe().c_str()); } } else if (attribute_input && shader_input) { const VkFormat attribute_format = *attribute_input; @@ -137,31 +138,33 @@ bool CoreChecks::ValidateInterfaceVertexInput(const vvl::Pipeline& pipeline, con const spirv::Instruction* var_base_type = module_state.FindDef(var_base_type_id); const uint32_t var_numeric_type = module_state.GetNumericType(*var_base_type); + if (var_numeric_type == spirv::NumericTypeUnknown && variable_ptr->type_struct_info) { + // TODO https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/12281 + continue; + } + const bool attribute64 = vkuFormatIs64bit(attribute_format); const bool shader64 = module_state.GetBaseTypeInstruction(var_base_type)->GetBitWidth() == 64; // Type checking if ((attribute_type & var_numeric_type) == 0) { - skip |= - LogError("VUID-VkGraphicsPipelineCreateInfo-Input-08733", module_state.handle(), - vi_loc.dot(Field::pVertexAttributeDescriptions, attribute_info.attribute_index).dot(Field::format), - "(%s) at Location %" PRIu32 " does not match %s %s type of (%s).", string_VkFormat(attribute_format), - location, entrypoint.Describe().c_str(), attribute_info.variable_ptr->Describe().c_str(), - module_state.DescribeType(var_base_type_id).c_str()); + skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-Input-08733", module_state.handle(), + vi_loc.dot(Field::pVertexAttributeDescriptions, attribute_info.attribute_index).dot(Field::format), + "(%s) at Location %" PRIu32 " does not match %s %s type of (%s).", + string_VkFormat(attribute_format), location, entrypoint.Describe().c_str(), + variable_ptr->Describe().c_str(), module_state.DescribeType(var_base_type_id).c_str()); } else if (attribute64 && !shader64) { skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-08929", module_state.handle(), vi_loc.dot(Field::pVertexAttributeDescriptions, attribute_info.attribute_index).dot(Field::format), "(%s) is a 64-bit format, but the %s %s at Location %" PRIu32 " is a 32-bit type of (%s).", - string_VkFormat(attribute_format), entrypoint.Describe().c_str(), - attribute_info.variable_ptr->Describe().c_str(), location, - module_state.DescribeType(var_base_type_id).c_str()); + string_VkFormat(attribute_format), entrypoint.Describe().c_str(), variable_ptr->Describe().c_str(), + location, module_state.DescribeType(var_base_type_id).c_str()); } else if (!attribute64 && shader64) { skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-08930", module_state.handle(), vi_loc.dot(Field::pVertexAttributeDescriptions, attribute_info.attribute_index).dot(Field::format), "(%s) is a 64-bit format, but the %s %s at Location %" PRIu32 " is a 64-bit type of (%s).", - string_VkFormat(attribute_format), entrypoint.Describe().c_str(), - attribute_info.variable_ptr->Describe().c_str(), location, - module_state.DescribeType(var_base_type_id).c_str()); + string_VkFormat(attribute_format), entrypoint.Describe().c_str(), variable_ptr->Describe().c_str(), + location, module_state.DescribeType(var_base_type_id).c_str()); } else if (attribute64 && shader64) { const uint32_t attribute_components = vkuFormatComponentCount(attribute_format); const uint32_t input_components = module_state.GetNumComponentsInBaseType(shader_input); @@ -173,7 +176,7 @@ bool CoreChecks::ValidateInterfaceVertexInput(const vvl::Pipeline& pipeline, con "-wide 64-bit type of (%s). (64-bit vertex input don't have default values and require " "components to match what is used in the shader)", string_VkFormat(attribute_format), attribute_components, entrypoint.Describe().c_str(), - attribute_info.variable_ptr->Describe().c_str(), location, input_components, + variable_ptr->Describe().c_str(), location, input_components, module_state.DescribeType(var_base_type_id).c_str()); } } @@ -599,8 +602,12 @@ bool CoreChecks::ValidateFsOutputsAgainstRenderPass(const spirv::Module& module_ } } else { const uint32_t attachment_type = spirv::GetFormatNumericType(attachment->format); - const spirv::Instruction* type_inst = module_state.FindDef(output->type_id); - const uint32_t output_type = module_state.GetNumericType(*type_inst); + const uint32_t output_type = module_state.GetNumericType(output->base_type); + + if (output_type == spirv::NumericTypeUnknown && output->type_struct_info) { + // TODO https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/12281 + continue; + } // Type checking if ((output_type & attachment_type) == 0) { @@ -770,8 +777,12 @@ bool CoreChecks::ValidateDrawDynamicRenderingFsOutputs(const LastBound& last_bou } } else { const uint32_t attachment_type = spirv::GetFormatNumericType(image_view_state->create_info.format); - const spirv::Instruction* type_inst = module_state->FindDef(output->type_id); - const uint32_t output_type = module_state->GetNumericType(*type_inst); + const uint32_t output_type = module_state->GetNumericType(output->base_type); + + if (output_type == spirv::NumericTypeUnknown && output->type_struct_info) { + // TODO https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/12281 + continue; + } // Type checking if ((output_type & attachment_type) == 0) { diff --git a/layers/state_tracker/shader_module.cpp b/layers/state_tracker/shader_module.cpp index d3f9b63f6e2..b2cef0adbe9 100644 --- a/layers/state_tracker/shader_module.cpp +++ b/layers/state_tracker/shader_module.cpp @@ -1841,8 +1841,11 @@ uint32_t Module::GetComponentsConsumedByType(const Instruction* insn) const { } } -// characterizes a SPIR-V type appearing in an interface to a FF stage, for comparison to a VkFormat's characterization above. -// also used for input attachments, as we statically know their format. +// "Numeric Type" is the spec language to help map a SPIR-V format to a VkFormat +// Currently only used in +// 1. Vertex Input +// 2. Fragment Output +// 3. Tensor interface NumericType Module::GetNumericType(const Instruction& insn) const { switch (insn.Opcode()) { case spv::OpTypeBool: @@ -1860,6 +1863,9 @@ NumericType Module::GetNumericType(const Instruction& insn) const { return GetNumericType(*FindDef(insn.Word(2))); case spv::OpTypePointer: return GetNumericType(*FindDef(insn.Word(3))); + case spv::OpTypeStruct: + // TODO - // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/12281 + return NumericTypeUnknown; default: return NumericTypeUnknown; } diff --git a/tests/unit/shader_interface_positive.cpp b/tests/unit/shader_interface_positive.cpp index 20dae56cc66..cd2ecce5809 100644 --- a/tests/unit/shader_interface_positive.cpp +++ b/tests/unit/shader_interface_positive.cpp @@ -1734,3 +1734,65 @@ TEST_F(PositiveShaderInterface, MeshFragmentSlang) { pipe.shader_stages_ = {ms.GetStageCreateInfo(), fs.GetStageCreateInfo()}; pipe.CreateGraphicsPipeline(); } + +TEST_F(PositiveShaderInterface, BlockFragmentLocation) { + TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/12281"); + RETURN_IF_SKIP(Init()); + m_errorMonitor->ExpectSuccess(kWarningBit | kErrorBit); + InitRenderTarget(); + + const char* vs_source = R"glsl( + #version 450 + layout(location=0) out vec4 x; + void main(){ + x = vec4(0); + } + )glsl"; + + const char* fs_source = R"( + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %6 "main" %9 %10 + OpExecutionMode %6 OriginUpperLeft + OpSource Unknown 0 + OpMemberName %FsOut 0 "color" + OpName %FsOut "FsOut" + OpMemberDecorate %FsOut 0 Offset 0 + OpDecorate %FsOut Block + OpMemberDecorate %FsOut 0 Location 0 + OpMemberDecorate %ShaderLink 0 Offset 0 + OpDecorate %ShaderLink Block + OpMemberDecorate %ShaderLink 0 Location 0 + %void = OpTypeVoid + %int = OpTypeInt 32 1 + %uint = OpTypeInt 32 0 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %int_0 = OpConstant %int 0 + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %FsOut = OpTypeStruct %v4float +%_ptr_Output_FsOut = OpTypePointer Output %FsOut + %ShaderLink = OpTypeStruct %v4float +%_ptr_Input_ShaderLink = OpTypePointer Input %ShaderLink + %50 = OpTypeFunction %void + %9 = OpVariable %_ptr_Input_ShaderLink Input + %10 = OpVariable %_ptr_Output_FsOut Output + %6 = OpFunction %void None %50 + %59 = OpLabel + %60 = OpAccessChain %_ptr_Output_v4float %10 %int_0 + %61 = OpAccessChain %_ptr_Input_v4float %9 %int_0 + %62 = OpLoad %v4float %61 + OpStore %60 %62 + OpReturn + OpFunctionEnd + )"; + + VkShaderObj vs(*m_device, vs_source, VK_SHADER_STAGE_VERTEX_BIT); + VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM); + + CreatePipelineHelper pipe(*this); + pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; + pipe.CreateGraphicsPipeline(); +} \ No newline at end of file