From 4c456f7da67c5437a6fb7d4d20d78e2a5ae2acf2 Mon Sep 17 00:00:00 2001 From: Pankaj Mistry <63069047+pmistryNV@users.noreply.github.com> Date: Thu, 1 Sep 2022 17:36:15 -0700 Subject: [PATCH] Implement tool changes for SPV_EXT_mesh_shader. (#4915) - Added validation rule to support EXT_mesh_shader from SPIRV 1.4 onwards --- DEPS | 2 +- source/opt/instrument_pass.cpp | 7 ++- source/val/validate_atomics.cpp | 8 ++- source/val/validate_barriers.cpp | 3 +- source/val/validate_builtins.cpp | 71 ++++++++++++++++++------ source/val/validate_extensions.cpp | 6 +- source/val/validate_memory.cpp | 3 +- source/val/validate_mode_setting.cpp | 30 +++++++--- source/val/validate_scopes.cpp | 13 +++-- source/val/validation_state.cpp | 5 +- test/operand_capabilities_test.cpp | 32 +++++++---- test/val/val_atomics_test.cpp | 4 +- test/val/val_barriers_test.cpp | 46 ++++++++------- test/val/val_builtins_test.cpp | 83 ++++++++++++++-------------- 14 files changed, 196 insertions(+), 117 deletions(-) diff --git a/DEPS b/DEPS index 78c9dd349..e0b4c5541 100644 --- a/DEPS +++ b/DEPS @@ -6,7 +6,7 @@ vars = { 'effcee_revision': 'ddf5e2bb92957dc8a12c5392f8495333d6844133', 'googletest_revision': '548b13dc3c02b93f60eeff9a0cc6e11c1ea722ca', 're2_revision': '5723bb8950318135ed9cf4fc76bed988a087f536', - 'spirv_headers_revision': 'b2a156e1c0434bc8c99aaebba1c7be98be7ac580', + 'spirv_headers_revision': '87d5b782bec60822aa878941e6b13c0a9a954c9b', } deps = { diff --git a/source/opt/instrument_pass.cpp b/source/opt/instrument_pass.cpp index 3d48b321b..d143d5959 100644 --- a/source/opt/instrument_pass.cpp +++ b/source/opt/instrument_pass.cpp @@ -245,7 +245,9 @@ void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx, } break; case SpvExecutionModelGLCompute: case SpvExecutionModelTaskNV: - case SpvExecutionModelMeshNV: { + case SpvExecutionModelMeshNV: + case SpvExecutionModelTaskEXT: + case SpvExecutionModelMeshEXT: { // Load and store GlobalInvocationId. uint32_t load_id = GenVarLoad( context()->GetBuiltinInputVarId(SpvBuiltInGlobalInvocationId), @@ -1064,7 +1066,8 @@ bool InstrumentPass::InstProcessEntryPointCallTree(InstProcessFunction& pfn) { stage != SpvExecutionModelAnyHitNV && stage != SpvExecutionModelClosestHitNV && stage != SpvExecutionModelMissNV && - stage != SpvExecutionModelCallableNV) { + stage != SpvExecutionModelCallableNV && + stage != SpvExecutionModelTaskEXT && stage != SpvExecutionModelMeshEXT) { if (consumer()) { std::string message = "Stage not supported by instrumentation"; consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); diff --git a/source/val/validate_atomics.cpp b/source/val/validate_atomics.cpp index 3b0a7fa8e..bf565c310 100644 --- a/source/val/validate_atomics.cpp +++ b/source/val/validate_atomics.cpp @@ -40,6 +40,7 @@ bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) { case SpvStorageClassImage: case SpvStorageClassFunction: case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassTaskPayloadWorkgroupEXT: return true; break; default: @@ -206,12 +207,13 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { (storage_class != SpvStorageClassStorageBuffer) && (storage_class != SpvStorageClassWorkgroup) && (storage_class != SpvStorageClassImage) && - (storage_class != SpvStorageClassPhysicalStorageBuffer)) { + (storage_class != SpvStorageClassPhysicalStorageBuffer) && + (storage_class != SpvStorageClassTaskPayloadWorkgroupEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4686) << spvOpcodeString(opcode) << ": Vulkan spec only allows storage classes for atomic to " - "be: Uniform, Workgroup, Image, StorageBuffer, or " - "PhysicalStorageBuffer."; + "be: Uniform, Workgroup, Image, StorageBuffer, " + "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT."; } } else if (storage_class == SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) diff --git a/source/val/validate_barriers.cpp b/source/val/validate_barriers.cpp index 3a9e3e7c5..03225d86a 100644 --- a/source/val/validate_barriers.cpp +++ b/source/val/validate_barriers.cpp @@ -50,7 +50,8 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { *message = "OpControlBarrier requires one of the following " "Execution " - "Models: TessellationControl, GLCompute or Kernel"; + "Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV"; } return false; } diff --git a/source/val/validate_builtins.cpp b/source/val/validate_builtins.cpp index 379705ac0..40a36d062 100644 --- a/source/val/validate_builtins.cpp +++ b/source/val/validate_builtins.cpp @@ -1179,9 +1179,16 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " - "Vertex.", + "MeshNV.", SpvExecutionModelMeshNV, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " + "used for variables with Input storage class if execution model is " + "MeshEXT.", + SpvExecutionModelMeshEXT, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); } if (storage_class == SpvStorageClassOutput) { @@ -1224,7 +1231,8 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( case SpvExecutionModelTessellationControl: case SpvExecutionModelTessellationEvaluation: case SpvExecutionModelGeometry: - case SpvExecutionModelMeshNV: { + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: { if (decoration.struct_member_index() != Decoration::kInvalidMember) { // The outer level of array is applied on the variable. if (spv_result_t error = ValidateF32Arr( @@ -1856,7 +1864,8 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( case SpvExecutionModelTessellationControl: case SpvExecutionModelTessellationEvaluation: case SpvExecutionModelGeometry: - case SpvExecutionModelMeshNV: { + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: { // PointSize can be a per-vertex variable for tessellation control, // tessellation evaluation and geometry shader stages. In such cases // variables will have an array of 32-bit floats. @@ -1957,6 +1966,13 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( "with Input storage class if execution model is MeshNV.", SpvExecutionModelMeshNV, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, + "Vulkan spec doesn't allow BuiltIn Position to be used " + "for variables " + "with Input storage class if execution model is MeshEXT.", + SpvExecutionModelMeshEXT, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); } for (const SpvExecutionModel execution_model : execution_models_) { @@ -1980,7 +1996,8 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( case SpvExecutionModelGeometry: case SpvExecutionModelTessellationControl: case SpvExecutionModelTessellationEvaluation: - case SpvExecutionModelMeshNV: { + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: { // Position can be a per-vertex variable for tessellation control, // tessellation evaluation, geometry and mesh shader stages. In such // cases variables will have an array of 4-component 32-bit float @@ -2151,6 +2168,7 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( case SpvExecutionModelTessellationEvaluation: case SpvExecutionModelGeometry: case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: case SpvExecutionModelIntersectionKHR: case SpvExecutionModelAnyHitKHR: case SpvExecutionModelClosestHitKHR: { @@ -2163,9 +2181,8 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( << _.VkErrorID(4330) << "Vulkan spec allows BuiltIn PrimitiveId to be used only " "with Fragment, TessellationControl, " - "TessellationEvaluation, Geometry, MeshNV, " - "IntersectionKHR, " - "AnyHitKHR, and ClosestHitKHR execution models. " + "TessellationEvaluation, Geometry, MeshNV, MeshEXT, " + "IntersectionKHR, AnyHitKHR, and ClosestHitKHR execution models. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); } @@ -2713,7 +2730,8 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( assert(function_id_ == 0); for (const auto em : {SpvExecutionModelVertex, SpvExecutionModelTessellationEvaluation, - SpvExecutionModelGeometry, SpvExecutionModelMeshNV}) { + SpvExecutionModelGeometry, SpvExecutionModelMeshNV, + SpvExecutionModelMeshEXT}) { id_to_at_reference_checks_[referenced_from_inst.id()].push_back( std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, ((operand == SpvBuiltInLayer) ? 4274 : 4406), @@ -2721,7 +2739,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( "ViewportIndex to be " "used for variables with Input storage class if " "execution model is Vertex, TessellationEvaluation, " - "Geometry, or MeshNV.", + "Geometry, MeshNV or MeshEXT.", em, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } @@ -2746,6 +2764,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( case SpvExecutionModelGeometry: case SpvExecutionModelFragment: case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: // Ok. break; case SpvExecutionModelVertex: @@ -2925,7 +2944,10 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( for (const SpvExecutionModel execution_model : execution_models_) { bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || execution_model == SpvExecutionModelTaskNV || - execution_model == SpvExecutionModelMeshNV; + execution_model == SpvExecutionModelMeshNV || + execution_model == SpvExecutionModelTaskEXT || + execution_model == SpvExecutionModelMeshEXT; + if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -2933,7 +2955,8 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) - << " to be used only with GLCompute, MeshNV, or TaskNV execution model. " + << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or" + << " TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); } @@ -3007,7 +3030,9 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( for (const SpvExecutionModel execution_model : execution_models_) { bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || execution_model == SpvExecutionModelTaskNV || - execution_model == SpvExecutionModelMeshNV; + execution_model == SpvExecutionModelMeshNV || + execution_model == SpvExecutionModelTaskEXT || + execution_model == SpvExecutionModelMeshEXT; if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -3015,7 +3040,8 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) - << " to be used only with GLCompute, MeshNV, or TaskNV execution model. " + << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " + << "TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); } @@ -3159,14 +3185,17 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference( for (const SpvExecutionModel execution_model : execution_models_) { if (execution_model != SpvExecutionModelGLCompute && execution_model != SpvExecutionModelTaskNV && - execution_model != SpvExecutionModelMeshNV) { + execution_model != SpvExecutionModelMeshNV && + execution_model != SpvExecutionModelTaskEXT && + execution_model != SpvExecutionModelMeshEXT) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4425) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) - << " to be used only with GLCompute, MeshNV, or TaskNV execution model. " + << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " + << "TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); } @@ -3297,12 +3326,15 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( for (const SpvExecutionModel execution_model : execution_models_) { if (execution_model != SpvExecutionModelVertex && execution_model != SpvExecutionModelMeshNV && - execution_model != SpvExecutionModelTaskNV) { + execution_model != SpvExecutionModelTaskNV && + execution_model != SpvExecutionModelMeshEXT && + execution_model != SpvExecutionModelTaskEXT) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4207) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, operand) - << " to be used only with Vertex, MeshNV, or TaskNV execution " + << " to be used only with Vertex, MeshNV, TaskNV , MeshEXT or" + << " TaskEXT execution " "model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3818,6 +3850,7 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( case SpvExecutionModelVertex: case SpvExecutionModelGeometry: case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: break; default: { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -4276,6 +4309,10 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( case SpvBuiltInMeshViewCountNV: case SpvBuiltInMeshViewIndicesNV: case SpvBuiltInCurrentRayTimeNV: + case SpvBuiltInPrimitivePointIndicesEXT: + case SpvBuiltInPrimitiveLineIndicesEXT: + case SpvBuiltInPrimitiveTriangleIndicesEXT: + case SpvBuiltInCullPrimitiveEXT: // No validation rules (for the moment). break; diff --git a/source/val/validate_extensions.cpp b/source/val/validate_extensions.cpp index fcf04e207..1e69cb37f 100644 --- a/source/val/validate_extensions.cpp +++ b/source/val/validate_extensions.cpp @@ -756,10 +756,10 @@ spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) { if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) { std::string extension = GetExtensionString(&(inst->c_inst())); if (extension == - ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout)) { + ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) || + extension == ExtensionToString(kSPV_EXT_mesh_shader)) { return _.diag(SPV_ERROR_WRONG_VERSION, inst) - << "SPV_KHR_workgroup_memory_explicit_layout extension " - "requires SPIR-V version 1.4 or later."; + << extension << " extension requires SPIR-V version 1.4 or later."; } } diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index d4fca84ab..e4ad0e027 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -442,7 +442,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { storage_class != SpvStorageClassIncomingRayPayloadKHR && storage_class != SpvStorageClassHitAttributeKHR && storage_class != SpvStorageClassCallableDataKHR && - storage_class != SpvStorageClassIncomingCallableDataKHR) { + storage_class != SpvStorageClassIncomingCallableDataKHR && + storage_class != SpvStorageClassTaskPayloadWorkgroupEXT) { bool storage_input_or_output = storage_class == SpvStorageClassInput || storage_class == SpvStorageClassOutput; bool builtin = false; diff --git a/source/val/validate_mode_setting.cpp b/source/val/validate_mode_setting.cpp index 67b10c5ac..09a9d48e1 100644 --- a/source/val/validate_mode_setting.cpp +++ b/source/val/validate_mode_setting.cpp @@ -12,13 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#include "source/val/validate.h" - #include #include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/val/instruction.h" +#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -359,14 +358,18 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, return true; case SpvExecutionModelMeshNV: return _.HasCapability(SpvCapabilityMeshShadingNV); + case SpvExecutionModelMeshEXT: + return _.HasCapability( + SpvCapabilityMeshShadingEXT); default: return false; } })) { - if (_.HasCapability(SpvCapabilityMeshShadingNV)) { + if (_.HasCapability(SpvCapabilityMeshShadingNV) || + _.HasCapability(SpvCapabilityMeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Execution mode can only be used with the Geometry or " - "MeshNV execution model."; + << "Execution mode can only be used with the Geometry " + "MeshNV or MeshEXT execution model."; } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Geometry " @@ -421,14 +424,18 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, return true; case SpvExecutionModelMeshNV: return _.HasCapability(SpvCapabilityMeshShadingNV); + case SpvExecutionModelMeshEXT: + return _.HasCapability( + SpvCapabilityMeshShadingEXT); default: return false; } })) { - if (_.HasCapability(SpvCapabilityMeshShadingNV)) { + if (_.HasCapability(SpvCapabilityMeshShadingNV) || + _.HasCapability(SpvCapabilityMeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Geometry, " - "tessellation or MeshNV execution model."; + "tessellation, MeshNV or MeshEXT execution model."; } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Geometry or " @@ -494,14 +501,19 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, case SpvExecutionModelTaskNV: case SpvExecutionModelMeshNV: return _.HasCapability(SpvCapabilityMeshShadingNV); + case SpvExecutionModelTaskEXT: + case SpvExecutionModelMeshEXT: + return _.HasCapability( + SpvCapabilityMeshShadingEXT); default: return false; } })) { - if (_.HasCapability(SpvCapabilityMeshShadingNV)) { + if (_.HasCapability(SpvCapabilityMeshShadingNV) || + _.HasCapability(SpvCapabilityMeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Kernel, GLCompute, " - "MeshNV, or TaskNV execution model."; + "MeshNV, MeshEXT, TaskNV or TaskEXT execution model."; } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Kernel or " diff --git a/source/val/validate_scopes.cpp b/source/val/validate_scopes.cpp index a5f3db14f..5fb661b0d 100644 --- a/source/val/validate_scopes.cpp +++ b/source/val/validate_scopes.cpp @@ -144,14 +144,16 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, [errorVUID](SpvExecutionModel model, std::string* message) { if (model != SpvExecutionModelTaskNV && model != SpvExecutionModelMeshNV && + model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT && model != SpvExecutionModelTessellationControl && model != SpvExecutionModelGLCompute) { if (message) { *message = errorVUID + "in Vulkan environment, Workgroup execution scope is " - "only for TaskNV, MeshNV, TessellationControl, and " - "GLCompute execution models"; + "only for TaskNV, MeshNV, TaskEXT, MeshEXT, " + "TessellationControl, and GLCompute execution models"; } return false; } @@ -269,11 +271,14 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, [errorVUID](SpvExecutionModel model, std::string* message) { if (model != SpvExecutionModelGLCompute && model != SpvExecutionModelTaskNV && - model != SpvExecutionModelMeshNV) { + model != SpvExecutionModelMeshNV && + model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT) { if (message) { *message = errorVUID + "Workgroup Memory Scope is limited to MeshNV, " - "TaskNV, and GLCompute execution model"; + "TaskNV, MeshEXT, TaskEXT and GLCompute " + "execution model"; } return false; } diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index 3501e8ceb..2e1fa31ae 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -639,7 +639,9 @@ void ValidationState_t::RegisterStorageClassConsumer( std::string* message) { if (model != SpvExecutionModelGLCompute && model != SpvExecutionModelTaskNV && - model != SpvExecutionModelMeshNV) { + model != SpvExecutionModelMeshNV && + model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT) { if (message) { *message = errorVUID + @@ -1522,6 +1524,7 @@ bool ValidationState_t::IsValidStorageClass( case SpvStorageClassCallableDataKHR: case SpvStorageClassIncomingCallableDataKHR: case SpvStorageClassShaderRecordBufferKHR: + case SpvStorageClassTaskPayloadWorkgroupEXT: return true; default: return false; diff --git a/test/operand_capabilities_test.cpp b/test/operand_capabilities_test.cpp index bc0ee0551..60503461e 100644 --- a/test/operand_capabilities_test.cpp +++ b/test/operand_capabilities_test.cpp @@ -97,6 +97,14 @@ TEST_P(EnumCapabilityTest, Sample) { } \ } +#define CASE6(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4, CAP5, CAP6) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP1, SpvCapability##CAP2, SpvCapability##CAP3, \ + SpvCapability##CAP4, SpvCapability##CAP5, SpvCapability##CAP6 \ + } \ + } + // See SPIR-V Section 3.3 Execution Model INSTANTIATE_TEST_SUITE_P( ExecutionModel, EnumCapabilityTest, @@ -168,10 +176,10 @@ INSTANTIATE_TEST_SUITE_P( Geometry), CASE1(EXECUTION_MODE, ExecutionModeQuads, Tessellation), CASE1(EXECUTION_MODE, ExecutionModeIsolines, Tessellation), - CASE3(EXECUTION_MODE, ExecutionModeOutputVertices, Geometry, - Tessellation, MeshShadingNV), - CASE2(EXECUTION_MODE, ExecutionModeOutputPoints, Geometry, - MeshShadingNV), + CASE4(EXECUTION_MODE, ExecutionModeOutputVertices, Geometry, + Tessellation, MeshShadingNV, MeshShadingEXT), + CASE3(EXECUTION_MODE, ExecutionModeOutputPoints, Geometry, + MeshShadingNV, MeshShadingEXT), CASE1(EXECUTION_MODE, ExecutionModeOutputLineStrip, Geometry), CASE1(EXECUTION_MODE, ExecutionModeOutputTriangleStrip, Geometry), CASE1(EXECUTION_MODE, ExecutionModeVecTypeHint, Kernel), @@ -486,11 +494,11 @@ INSTANTIATE_TEST_SUITE_P( CASE1(BUILT_IN, BuiltInCullDistance, CullDistance), // Bug 1407, 15234 CASE1(BUILT_IN, BuiltInVertexId, Shader), CASE1(BUILT_IN, BuiltInInstanceId, Shader), - CASE5(BUILT_IN, BuiltInPrimitiveId, Geometry, Tessellation, - RayTracingNV, RayTracingKHR, MeshShadingNV), + CASE6(BUILT_IN, BuiltInPrimitiveId, Geometry, Tessellation, + RayTracingNV, RayTracingKHR, MeshShadingNV, MeshShadingEXT), CASE2(BUILT_IN, BuiltInInvocationId, Geometry, Tessellation), - CASE3(BUILT_IN, BuiltInLayer, Geometry, ShaderViewportIndexLayerEXT, MeshShadingNV), - CASE3(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT, MeshShadingNV), // Bug 15234 + CASE4(BUILT_IN, BuiltInLayer, Geometry, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), + CASE4(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), // Bug 15234 CASE1(BUILT_IN, BuiltInTessLevelOuter, Tessellation), CASE1(BUILT_IN, BuiltInTessLevelInner, Tessellation), CASE1(BUILT_IN, BuiltInTessCoord, Tessellation), @@ -533,11 +541,11 @@ INSTANTIATE_TEST_SUITE_P( Values(SPV_ENV_UNIVERSAL_1_5), ValuesIn(std::vector{ // SPIR-V 1.5 adds new capabilities to enable these two builtins. - CASE4(BUILT_IN, BuiltInLayer, Geometry, ShaderLayer, - ShaderViewportIndexLayerEXT, MeshShadingNV), - CASE4(BUILT_IN, BuiltInViewportIndex, MultiViewport, + CASE5(BUILT_IN, BuiltInLayer, Geometry, ShaderLayer, + ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), + CASE5(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndex, ShaderViewportIndexLayerEXT, - MeshShadingNV), + MeshShadingNV, MeshShadingEXT), }))); // See SPIR-V Section 3.22 Selection Control diff --git a/test/val/val_atomics_test.cpp b/test/val/val_atomics_test.cpp index a0308d599..a7e4055af 100644 --- a/test/val/val_atomics_test.cpp +++ b/test/val/val_atomics_test.cpp @@ -778,8 +778,8 @@ OpAtomicStore %f32_var_function %device %relaxed %f32_1 EXPECT_THAT( getDiagnosticString(), HasSubstr("AtomicStore: Vulkan spec only allows storage classes for " - "atomic to be: Uniform, Workgroup, Image, StorageBuffer, or " - "PhysicalStorageBuffer.")); + "atomic to be: Uniform, Workgroup, Image, StorageBuffer, " + "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT.")); } TEST_F(ValidateAtomics, AtomicStoreFunctionPointerStorageType) { diff --git a/test/val/val_barriers_test.cpp b/test/val/val_barriers_test.cpp index df5ee1678..2569de0d0 100644 --- a/test/val/val_barriers_test.cpp +++ b/test/val/val_barriers_test.cpp @@ -254,8 +254,9 @@ OpControlBarrier %device %device %none ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2)); EXPECT_THAT( getDiagnosticString(), - HasSubstr("OpControlBarrier requires one of the following Execution " - "Models: TessellationControl, GLCompute or Kernel")); + HasSubstr("OpControlBarrier requires one of the following " + "Execution Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV")); } TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv13) { @@ -417,8 +418,9 @@ OpControlBarrier %subgroup %workgroup %acquire EXPECT_THAT(getDiagnosticString(), AnyVUID("VUID-StandaloneSpirv-None-04639")); EXPECT_THAT(getDiagnosticString(), - HasSubstr("Workgroup Memory Scope is limited to MeshNV, TaskNV, " - "and GLCompute execution model")); + HasSubstr("Workgroup Memory Scope is limited to MeshNV, " + "TaskNV, MeshEXT, TaskEXT and GLCompute " + "execution model")); } TEST_F(ValidateBarriers, @@ -433,8 +435,8 @@ OpControlBarrier %workgroup %subgroup %acquire AnyVUID("VUID-StandaloneSpirv-None-04637")); EXPECT_THAT(getDiagnosticString(), HasSubstr("in Vulkan environment, Workgroup execution scope is " - "only for TaskNV, MeshNV, TessellationControl, and " - "GLCompute execution models")); + "only for TaskNV, MeshNV, TaskEXT, MeshEXT, " + "TessellationControl, and GLCompute execution models")); } TEST_F(ValidateBarriers, OpControlBarrierVulkan1p1WorkgroupComputeSuccess) { @@ -544,10 +546,11 @@ OpControlBarrier %subgroup %workgroup %acquire_release CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpControlBarrier requires one of the following Execution " - "Models: TessellationControl, GLCompute or Kernel")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpControlBarrier requires one of the following " + "Execution " + "Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV")); } TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionVertex1p1) { @@ -588,8 +591,9 @@ OpControlBarrier %subgroup %workgroup %acquire_release ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); EXPECT_THAT( getDiagnosticString(), - HasSubstr("OpControlBarrier requires one of the following Execution " - "Models: TessellationControl, GLCompute or Kernel")); + HasSubstr("OpControlBarrier requires one of the following " + "Execution Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV")); } TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionGeometry1p1) { @@ -631,10 +635,11 @@ OpControlBarrier %subgroup %workgroup %acquire_release GenerateShaderCode(body, "OpCapability Geometry\n", "Geometry"), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpControlBarrier requires one of the following Execution " - "Models: TessellationControl, GLCompute or Kernel")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpControlBarrier requires one of the following " + "Execution " + "Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV")); } TEST_F(ValidateBarriers, @@ -679,10 +684,11 @@ OpControlBarrier %subgroup %workgroup %acquire_release "TessellationEvaluation"), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpControlBarrier requires one of the following Execution " - "Models: TessellationControl, GLCompute or Kernel")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpControlBarrier requires one of the following " + "Execution " + "Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV")); } TEST_F(ValidateBarriers, OpMemoryBarrierSuccess) { diff --git a/test/val/val_builtins_test.cpp b/test/val/val_builtins_test.cpp index 2cbe9a8ae..40832e024 100644 --- a/test/val/val_builtins_test.cpp +++ b/test/val/val_builtins_test.cpp @@ -784,8 +784,8 @@ INSTANTIATE_TEST_SUITE_P( "VUID-NumWorkgroups-NumWorkgroups-04296 " "VUID-WorkgroupId-WorkgroupId-04422"), Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with GLCompute, MeshNV, or " - "TaskNV execution model")))); + "to be used only with GLCompute, MeshNV, " + "TaskNV, MeshEXT or TaskEXT execution model")))); INSTANTIATE_TEST_SUITE_P( ComputeShaderInputInt32Vec3NotInput, @@ -1006,7 +1006,7 @@ INSTANTIATE_TEST_SUITE_P( Values("VUID-Layer-Layer-04274 VUID-ViewportIndex-ViewportIndex-04406"), Values(TestResult(SPV_ERROR_INVALID_DATA, "Input storage class if execution model is Vertex, " - "TessellationEvaluation, Geometry, or MeshNV", + "TessellationEvaluation, Geometry, MeshNV or MeshEXT", "which is called with execution model")))); INSTANTIATE_TEST_SUITE_P( @@ -1311,14 +1311,14 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( PrimitiveIdInvalidExecutionModel, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("PrimitiveId"), Values("Vertex", "GLCompute"), - Values("Input"), Values("%u32"), - Values("VUID-PrimitiveId-PrimitiveId-04330"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be used only with Fragment, TessellationControl, " - "TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, " - "AnyHitKHR, and ClosestHitKHR execution models")))); + Combine( + Values("PrimitiveId"), Values("Vertex", "GLCompute"), Values("Input"), + Values("%u32"), Values("VUID-PrimitiveId-PrimitiveId-04330"), + Values(TestResult(SPV_ERROR_INVALID_DATA, + "to be used only with Fragment, TessellationControl, " + "TessellationEvaluation, Geometry, MeshNV, MeshEXT, " + "IntersectionKHR, " + "AnyHitKHR, and ClosestHitKHR execution models")))); INSTANTIATE_TEST_SUITE_P( PrimitiveIdFragmentNotInput, @@ -1867,16 +1867,18 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( DrawIndexInvalidExecutionModel, ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult, - Combine(Values("DrawIndex"), - Values("Fragment", "GLCompute", "Geometry", "TessellationControl", - "TessellationEvaluation"), - Values("Input"), Values("%u32"), - Values("OpCapability DrawParameters\n"), - Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"), - Values("VUID-DrawIndex-DrawIndex-04207"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with Vertex, MeshNV, or TaskNV " - "execution model")))); + Combine( + Values("DrawIndex"), + Values("Fragment", "GLCompute", "Geometry", "TessellationControl", + "TessellationEvaluation"), + Values("Input"), Values("%u32"), + Values("OpCapability DrawParameters\n"), + Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"), + Values("VUID-DrawIndex-DrawIndex-04207"), + Values(TestResult( + SPV_ERROR_INVALID_DATA, + "to be used only with Vertex, MeshNV, TaskNV , MeshEXT or TaskEXT " + "execution model")))); INSTANTIATE_TEST_SUITE_P( DrawIndexNotInput, @@ -2164,17 +2166,17 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( PrimitiveIdRTNotExecutionMode, ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult, - Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"), - Values("RayGenerationKHR", "MissKHR", "CallableKHR"), - Values("Input"), Values("%u32"), - Values("OpCapability RayTracingKHR\n"), - Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), - Values("VUID-PrimitiveId-PrimitiveId-04330"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be used only with Fragment, TessellationControl, " - "TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, " - "AnyHitKHR, and ClosestHitKHR execution models")))); + Combine( + Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"), + Values("RayGenerationKHR", "MissKHR", "CallableKHR"), Values("Input"), + Values("%u32"), Values("OpCapability RayTracingKHR\n"), + Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), + Values("VUID-PrimitiveId-PrimitiveId-04330"), + Values(TestResult(SPV_ERROR_INVALID_DATA, + "to be used only with Fragment, TessellationControl, " + "TessellationEvaluation, Geometry, MeshNV, MeshEXT, " + "IntersectionKHR, " + "AnyHitKHR, and ClosestHitKHR execution models")))); INSTANTIATE_TEST_SUITE_P( PrimitiveIdRTNotInput, @@ -2896,10 +2898,10 @@ TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeFragment) { CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Vulkan spec allows BuiltIn WorkgroupSize to be used " - "only with GLCompute, MeshNV, or TaskNV execution model")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Vulkan spec allows BuiltIn WorkgroupSize to be used " + "only with GLCompute, MeshNV, TaskNV, MeshEXT or " + "TaskEXT execution model")); EXPECT_THAT(getDiagnosticString(), HasSubstr("is referencing ID <2> (OpConstantComposite) which is " "decorated with BuiltIn WorkgroupSize in function <1> " @@ -3356,7 +3358,7 @@ OpReturn OpFunctionEnd )"; - generator.add_at_the_end_ = function_body; + generator.add_at_the_end_ = function_body; return generator; } @@ -3419,7 +3421,7 @@ OpReturn OpFunctionEnd )"; - generator.add_at_the_end_ = function_body; + generator.add_at_the_end_ = function_body; return generator; } @@ -3437,7 +3439,6 @@ TEST_F(ValidateBuiltIns, HasSubstr("VUID-FragDepth-FragDepth-04216")); } - TEST_F(ValidateBuiltIns, AllowInstanceIdWithIntersectionShader) { CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.capabilities_ += R"( @@ -3766,8 +3767,8 @@ INSTANTIATE_TEST_SUITE_P( Values("VUID-SubgroupId-SubgroupId-04367 " "VUID-NumSubgroups-NumSubgroups-04293"), Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with GLCompute, MeshNV, or " - "TaskNV execution model")))); + "to be used only with GLCompute, MeshNV, " + "TaskNV, MeshEXT or TaskEXT execution model")))); INSTANTIATE_TEST_SUITE_P( SubgroupNumAndIdNotU32, ValidateVulkanSubgroupBuiltIns,