Implement tool changes for SPV_EXT_mesh_shader. (#4915)

- Added validation rule to support EXT_mesh_shader from SPIRV 1.4 onwards
This commit is contained in:
Pankaj Mistry 2022-09-01 17:36:15 -07:00 committed by GitHub
parent 33113abf45
commit 4c456f7da6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 196 additions and 117 deletions

2
DEPS
View File

@ -6,7 +6,7 @@ vars = {
'effcee_revision': 'ddf5e2bb92957dc8a12c5392f8495333d6844133',
'googletest_revision': '548b13dc3c02b93f60eeff9a0cc6e11c1ea722ca',
're2_revision': '5723bb8950318135ed9cf4fc76bed988a087f536',
'spirv_headers_revision': 'b2a156e1c0434bc8c99aaebba1c7be98be7ac580',
'spirv_headers_revision': '87d5b782bec60822aa878941e6b13c0a9a954c9b',
}
deps = {

View File

@ -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());

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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.";
}
}

View File

@ -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;

View File

@ -12,13 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "source/val/validate.h"
#include <algorithm>
#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 "

View File

@ -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;
}

View File

@ -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;

View File

@ -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<EnumCapabilityCase>{
// 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

View File

@ -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) {

View File

@ -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) {

View File

@ -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,