From 450d6cd61b02e1d2291b80013673ea37ad733054 Mon Sep 17 00:00:00 2001 From: alan-baker Date: Tue, 11 Aug 2020 18:51:49 -0400 Subject: [PATCH] Only validation locations for appropriate execution models (#3656) Fixes #3653 * Only validate locations for fragment, vertex, geometry and tessellation shaders --- source/val/validate_interfaces.cpp | 13 +++++++++++ test/val/val_interfaces_test.cpp | 35 ++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/source/val/validate_interfaces.cpp b/source/val/validate_interfaces.cpp index 833734f4d9..d16d48e269 100644 --- a/source/val/validate_interfaces.cpp +++ b/source/val/validate_interfaces.cpp @@ -437,6 +437,19 @@ spv_result_t GetLocationsForVariable( spv_result_t ValidateLocations(ValidationState_t& _, const Instruction* entry_point) { + // According to Vulkan 14.1 only the following execution models have + // locations assigned. + switch (entry_point->GetOperandAs(0)) { + case SpvExecutionModelVertex: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + case SpvExecutionModelGeometry: + case SpvExecutionModelFragment: + break; + default: + return SPV_SUCCESS; + } + // Locations are stored as a combined location and component values. std::unordered_set input_locations; std::unordered_set output_locations_index0; diff --git a/test/val/val_interfaces_test.cpp b/test/val/val_interfaces_test.cpp index f2fb45a263..6869e79445 100644 --- a/test/val/val_interfaces_test.cpp +++ b/test/val/val_interfaces_test.cpp @@ -1220,9 +1220,11 @@ OpFunctionEnd TEST_F(ValidateInterfacesTest, VulkanLocationsIndexGLCompute) { const std::string text = R"( OpCapability Shader +OpCapability Geometry OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" %var1 -OpExecutionMode %main LocalSize 1 1 1 +OpEntryPoint Geometry %main "main" %var1 +OpExecutionMode %main Triangles +OpExecutionMode %main OutputPoints OpDecorate %var1 Location 1 OpDecorate %var1 Index 1 %void = OpTypeVoid @@ -1379,6 +1381,35 @@ TEST_F(ValidateInterfacesTest, VulkanLocationsLargeLocation) { EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); } +TEST_F(ValidateInterfacesTest, VulkanLocationMeshShader) { + const std::string text = R"( +OpCapability Shader +OpCapability MeshShadingNV +OpExtension "SPV_NV_mesh_shader" +OpMemoryModel Logical GLSL450 +OpEntryPoint MeshNV %foo "foo" %in +OpExecutionMode %foo LocalSize 1 1 1 +OpDecorate %block Block +OpMemberDecorate %block 0 PerTaskNV +OpMemberDecorate %block 0 Offset 0 +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%int_32 = OpConstant %int 32 +%array = OpTypeArray %int %int_32 +%block = OpTypeStruct %array +%ptr_input_block = OpTypePointer Input %block +%in = OpVariable %ptr_input_block Input +%void_fn = OpTypeFunction %void +%foo = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(text, SPV_ENV_VULKAN_1_2); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); +} + } // namespace } // namespace val } // namespace spvtools