Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions layers/core_checks/cc_cmd_buffer_dynamic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
47 changes: 29 additions & 18 deletions layers/core_checks/cc_shader_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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());
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 8 additions & 2 deletions layers/state_tracker/shader_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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;
}
Expand Down
62 changes: 62 additions & 0 deletions tests/unit/shader_interface_positive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Loading