Add validation support for the ray tracing built-in variables (#4041)

* Add validation for ray tracing builtins

- Remove existing InstanceId testing that was combined with VertexId in awkward ways.
- Rather than adding a new set of functions for each ray tracing builtin, add
  an error table that maps the builtin ID to the 3 common VUIDs for each builtin
  (I could see this being extended for other builtins in the future).
- add F32 matrix validation function
- augment existing PrimitiveId validation to verify Input storage class for the
  RT stages this is accepted in, and correct the list of stages that it is actually
  accepted in (only Intersection / Any Hit / Closest Hit)

* add testing for ray tracing builtins

- remove exising InstanceId testing as it was tangled in with VertexId in now weird ways
  and combine it with the new tests
- add testing for ray tracing builtins
- builtins accepted in the same stages and of the same types are combined into test functions
- add some new matrix types to the code generator so they can be used for testing
This commit is contained in:
Daniel Koch 2020-12-01 11:42:37 -05:00 committed by GitHub
parent 7046c05d2f
commit 32573bb216
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1067 additions and 129 deletions

View File

@ -16,6 +16,7 @@
// Validates correctness of built-in variables.
#include <array>
#include <functional>
#include <list>
#include <map>
@ -134,6 +135,114 @@ bool IsBuiltInValidForWebGPU(SpvBuiltIn label) {
return false;
}
typedef enum VUIDError_ {
VUIDErrorExecutionModel = 0,
VUIDErrorStorageClass = 1,
VUIDErrorType = 2,
VUIDErrorMax,
} VUIDError;
const static uint32_t NumRtBuiltins = 16;
typedef struct {
SpvBuiltIn builtIn;
uint32_t vuid[VUIDErrorMax]; // execution mode, storage class, type VUIDs
} RtBuiltinVUIDMapping;
std::array<RtBuiltinVUIDMapping, NumRtBuiltins> rtBuiltinInfo = {{
// clang-format off
{SpvBuiltInHitKindKHR, {4242, 4243, 4244}},
{SpvBuiltInHitTNV, {4245, 4246, 4247}},
{SpvBuiltInInstanceCustomIndexKHR, {4251, 4252, 4253}},
{SpvBuiltInInstanceId, {4254, 4255, 4256}},
{SpvBuiltInRayGeometryIndexKHR, {4345, 4346, 4347}},
{SpvBuiltInObjectRayDirectionKHR, {4299, 4300, 4301}},
{SpvBuiltInObjectRayOriginKHR, {4302, 4303, 4304}},
{SpvBuiltInObjectToWorldKHR, {4305, 4306, 4307}},
{SpvBuiltInWorldToObjectKHR, {4434, 4435, 4436}},
{SpvBuiltInIncomingRayFlagsKHR, {4248, 4249, 4250}},
{SpvBuiltInRayTminKHR, {4351, 4352, 4353}},
{SpvBuiltInRayTmaxKHR, {4348, 4349, 4350}},
{SpvBuiltInWorldRayDirectionKHR, {4428, 4429, 4430}},
{SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}},
{SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}},
{SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}},
// clang-format off
} };
uint32_t GetVUIDForRTBuiltin(SpvBuiltIn builtIn, VUIDError type) {
uint32_t vuid = 0;
for (const auto& iter: rtBuiltinInfo) {
if (iter.builtIn == builtIn) {
assert(type < VUIDErrorMax);
vuid = iter.vuid[type];
break;
}
}
return vuid;
}
bool IsExecutionModelValidForRtBuiltIn(SpvBuiltIn builtin,
SpvExecutionModel stage) {
switch (builtin) {
case SpvBuiltInHitKindKHR:
case SpvBuiltInHitTNV:
if (stage == SpvExecutionModelAnyHitKHR ||
stage == SpvExecutionModelClosestHitKHR) {
return true;
}
break;
case SpvBuiltInInstanceCustomIndexKHR:
case SpvBuiltInInstanceId:
case SpvBuiltInRayGeometryIndexKHR:
case SpvBuiltInObjectRayDirectionKHR:
case SpvBuiltInObjectRayOriginKHR:
case SpvBuiltInObjectToWorldKHR:
case SpvBuiltInWorldToObjectKHR:
switch (stage) {
case SpvExecutionModelIntersectionKHR:
case SpvExecutionModelAnyHitKHR:
case SpvExecutionModelClosestHitKHR:
return true;
default:
return false;
}
break;
case SpvBuiltInIncomingRayFlagsKHR:
case SpvBuiltInRayTminKHR:
case SpvBuiltInRayTmaxKHR:
case SpvBuiltInWorldRayDirectionKHR:
case SpvBuiltInWorldRayOriginKHR:
switch (stage) {
case SpvExecutionModelIntersectionKHR:
case SpvExecutionModelAnyHitKHR:
case SpvExecutionModelClosestHitKHR:
case SpvExecutionModelMissKHR:
return true;
default:
return false;
}
break;
case SpvBuiltInLaunchIdKHR:
case SpvBuiltInLaunchSizeKHR:
switch (stage) {
case SpvExecutionModelRayGenerationKHR:
case SpvExecutionModelIntersectionKHR:
case SpvExecutionModelAnyHitKHR:
case SpvExecutionModelClosestHitKHR:
case SpvExecutionModelMissKHR:
case SpvExecutionModelCallableKHR:
return true;
default:
return false;
}
break;
default:
break;
}
return false;
}
// Helper class managing validation of built-ins.
// TODO: Generic functionality of this class can be moved into
// ValidationState_t to be made available to other users.
@ -200,8 +309,8 @@ class BuiltInsValidator {
const Instruction& inst);
spv_result_t ValidateVertexIndexAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateVertexIdOrInstanceIdAtDefinition(
const Decoration& decoration, const Instruction& inst);
spv_result_t ValidateVertexIdAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateLocalInvocationIndexAtDefinition(
const Decoration& decoration, const Instruction& inst);
spv_result_t ValidateWorkgroupSizeAtDefinition(const Decoration& decoration,
@ -237,6 +346,9 @@ class BuiltInsValidator {
spv_result_t ValidateShadingRateAtDefinition(const Decoration& decoration,
const Instruction& inst);
spv_result_t ValidateRayTracingBuiltinsAtDefinition(
const Decoration& decoration, const Instruction& inst);
// The following section contains functions which are called when id defined
// by |referenced_inst| is
// 1. referenced by |referenced_from_inst|
@ -269,11 +381,6 @@ class BuiltInsValidator {
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateInstanceIdAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateInstanceIndexAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
@ -400,6 +507,11 @@ class BuiltInsValidator {
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
spv_result_t ValidateRayTracingBuiltinsAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
// Validates that |built_in_inst| is not (even indirectly) referenced from
// within a function which can be called with |execution_model|.
//
@ -476,6 +588,10 @@ class BuiltInsValidator {
uint32_t num_components,
const std::function<spv_result_t(const std::string& message)>& diag,
uint32_t underlying_type);
spv_result_t ValidateF32Mat(
const Decoration& decoration, const Instruction& inst,
uint32_t req_num_rows, uint32_t req_num_columns,
const std::function<spv_result_t(const std::string& message)>& diag);
// Generates strings like "Member #0 of struct ID <2>".
std::string GetDefinitionDesc(const Decoration& decoration,
@ -909,6 +1025,32 @@ spv_result_t BuiltInsValidator::ValidateF32ArrHelper(
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateF32Mat(
const Decoration& decoration, const Instruction& inst,
uint32_t req_num_rows, uint32_t req_num_columns,
const std::function<spv_result_t(const std::string& message)>& diag) {
uint32_t underlying_type = 0;
uint32_t num_rows = 0;
uint32_t num_cols = 0;
uint32_t col_type = 0;
uint32_t component_type = 0;
if (spv_result_t error =
GetUnderlyingType(_, decoration, inst, &underlying_type)) {
return error;
}
if (!_.GetMatrixTypeInfo(underlying_type, &num_rows, &num_cols, &col_type,
&component_type) ||
num_rows != req_num_rows || num_cols != req_num_columns) {
std::ostringstream ss;
ss << GetDefinitionDesc(decoration, inst) << " has columns " << num_cols
<< " and rows " << num_rows << " not equal to expected "
<< req_num_columns << "x" << req_num_rows << ".";
return diag(ss.str());
}
return ValidateF32VecHelper(decoration, inst, req_num_rows, diag, col_type);
}
spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel(
int vuid, const char* comment, SpvExecutionModel execution_model,
const Decoration& decoration, const Instruction& built_in_inst,
@ -1947,6 +2089,27 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference(
"Fragment.",
SpvExecutionModelFragment, 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, 4334,
"Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for "
"variables with Output storage class if execution model is "
"IntersectionKHR.",
SpvExecutionModelIntersectionKHR, 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, 4334,
"Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for "
"variables with Output storage class if execution model is "
"AnyHitKHR.",
SpvExecutionModelAnyHitKHR, 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, 4334,
"Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for "
"variables with Output storage class if execution model is "
"ClosestHitKHR.",
SpvExecutionModelClosestHitKHR, decoration, built_in_inst,
referenced_from_inst, std::placeholders::_1));
}
for (const SpvExecutionModel execution_model : execution_models_) {
@ -1956,12 +2119,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference(
case SpvExecutionModelTessellationEvaluation:
case SpvExecutionModelGeometry:
case SpvExecutionModelMeshNV:
case SpvExecutionModelRayGenerationNV:
case SpvExecutionModelIntersectionNV:
case SpvExecutionModelAnyHitNV:
case SpvExecutionModelClosestHitNV:
case SpvExecutionModelMissNV:
case SpvExecutionModelCallableNV: {
case SpvExecutionModelIntersectionKHR:
case SpvExecutionModelAnyHitKHR:
case SpvExecutionModelClosestHitKHR: {
// Ok.
break;
}
@ -1971,7 +2131,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference(
<< _.VkErrorID(4330)
<< "Vulkan spec allows BuiltIn PrimitiveId to be used only "
"with Fragment, TessellationControl, "
"TessellationEvaluation or Geometry execution models. "
"TessellationEvaluation, Geometry, MeshNV, "
"IntersectionKHR, "
"AnyHitKHR, and ClosestHitKHR execution models. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
@ -2372,54 +2534,13 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtDefinition(
return ValidateVertexIndexAtReference(decoration, inst, inst, inst);
}
spv_result_t BuiltInsValidator::ValidateVertexIdOrInstanceIdAtDefinition(
spv_result_t BuiltInsValidator::ValidateVertexIdAtDefinition(
const Decoration& decoration, const Instruction& inst) {
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
bool allow_instance_id = (_.HasCapability(SpvCapabilityRayTracingNV) ||
_.HasCapability(SpvCapabilityRayTracingKHR)) &&
label == SpvBuiltInInstanceId;
if (spvIsVulkanEnv(_.context()->target_env) && !allow_instance_id) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< "Vulkan spec doesn't allow BuiltIn VertexId/InstanceId "
"to be used.";
}
if (label == SpvBuiltInInstanceId) {
return ValidateInstanceIdAtReference(decoration, inst, inst, inst);
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateInstanceIdAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
(void)decoration;
if (spvIsVulkanEnv(_.context()->target_env)) {
for (const SpvExecutionModel execution_model : execution_models_) {
switch (execution_model) {
case SpvExecutionModelIntersectionNV:
case SpvExecutionModelClosestHitNV:
case SpvExecutionModelAnyHitNV:
// Do nothing, valid stages
break;
default:
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< "Vulkan spec allows BuiltIn InstanceId to be used "
"only with IntersectionNV, ClosestHitNV and AnyHitNV "
"execution models. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst);
break;
}
}
}
if (function_id_ == 0) {
// Propagate this rule to all dependant ids in the global scope.
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateInstanceIdAtReference, this, decoration,
built_in_inst, referenced_from_inst, std::placeholders::_1));
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< "Vulkan spec doesn't allow BuiltIn VertexId "
"to be used.";
}
return SPV_SUCCESS;
@ -3474,6 +3595,174 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition(
const Decoration& decoration, const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
switch (builtin) {
case SpvBuiltInHitTNV:
case SpvBuiltInRayTminKHR:
case SpvBuiltInRayTmaxKHR:
// f32 scalar
if (spv_result_t error = ValidateF32(
decoration, inst,
[this, &inst,
builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid)
<< "According to the Vulkan spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " variable needs to be a 32-bit float scalar. "
<< message;
})) {
return error;
}
break;
case SpvBuiltInHitKindKHR:
case SpvBuiltInInstanceCustomIndexKHR:
case SpvBuiltInInstanceId:
case SpvBuiltInRayGeometryIndexKHR:
case SpvBuiltInIncomingRayFlagsKHR:
// i32 scalar
if (spv_result_t error = ValidateI32(
decoration, inst,
[this, &inst,
builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid)
<< "According to the Vulkan spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " variable needs to be a 32-bit int scalar. "
<< message;
})) {
return error;
}
break;
case SpvBuiltInObjectRayDirectionKHR:
case SpvBuiltInObjectRayOriginKHR:
case SpvBuiltInWorldRayDirectionKHR:
case SpvBuiltInWorldRayOriginKHR:
// f32 vec3
if (spv_result_t error = ValidateF32Vec(
decoration, inst, 3,
[this, &inst,
builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid)
<< "According to the Vulkan spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " variable needs to be a 3-component 32-bit float "
"vector. "
<< message;
})) {
return error;
}
break;
case SpvBuiltInLaunchIdKHR:
case SpvBuiltInLaunchSizeKHR:
// i32 vec3
if (spv_result_t error = ValidateI32Vec(
decoration, inst, 3,
[this, &inst,
builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid)
<< "According to the Vulkan spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " variable needs to be a 3-component 32-bit int "
"vector. "
<< message;
})) {
return error;
}
break;
case SpvBuiltInObjectToWorldKHR:
case SpvBuiltInWorldToObjectKHR:
// f32 mat4x3
if (spv_result_t error = ValidateF32Mat(
decoration, inst, 3, 4,
[this, &inst,
builtin](const std::string& message) -> spv_result_t {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< _.VkErrorID(vuid)
<< "According to the Vulkan spec BuiltIn "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_BUILT_IN, builtin)
<< " variable needs to be a matrix with"
<< " 4 columns of 3-component vectors of 32-bit "
"floats. "
<< message;
})) {
return error;
}
break;
default:
assert(0 && "Unexpected ray tracing builtin");
break;
}
}
// Seed at reference checks with this built-in.
return ValidateRayTracingBuiltinsAtReference(decoration, inst, inst, inst);
}
spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassInput) {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorStorageClass);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
decoration.params()[0])
<< " to be only used for variables with Input storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
<< " " << GetStorageClassDesc(referenced_from_inst);
}
for (const SpvExecutionModel execution_model : execution_models_) {
if (!IsExecutionModelValidForRtBuiltIn(builtin, execution_model)) {
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorExecutionModel);
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(vuid) << "Vulkan spec does not allow BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
decoration.params()[0])
<< " to be used with the execution model "
<< _.grammar().lookupOperandName(
SPV_OPERAND_TYPE_EXECUTION_MODEL, execution_model)
<< ".\n"
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
}
}
if (function_id_ == 0) {
// Propagate this rule to all dependant ids in the global scope.
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
std::bind(&BuiltInsValidator::ValidateRayTracingBuiltinsAtReference,
this, decoration, built_in_inst, referenced_from_inst,
std::placeholders::_1));
}
return SPV_SUCCESS;
}
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
const Decoration& decoration, const Instruction& inst) {
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
@ -3596,9 +3885,8 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInWorkgroupSize: {
return ValidateWorkgroupSizeAtDefinition(decoration, inst);
}
case SpvBuiltInVertexId:
case SpvBuiltInInstanceId: {
return ValidateVertexIdOrInstanceIdAtDefinition(decoration, inst);
case SpvBuiltInVertexId: {
return ValidateVertexIdAtDefinition(decoration, inst);
}
case SpvBuiltInLocalInvocationIndex: {
return ValidateLocalInvocationIndexAtDefinition(decoration, inst);
@ -3622,6 +3910,27 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInDeviceIndex: {
return ValidateDeviceIndexAtDefinition(decoration, inst);
}
// Ray tracing builtins
case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV
case SpvBuiltInHitTNV: // NOT present in KHR
case SpvBuiltInInstanceId:
case SpvBuiltInLaunchIdKHR: // alias SpvBuiltInLaunchIdNV
case SpvBuiltInLaunchSizeKHR: // alias SpvBuiltInLaunchSizeNV
case SpvBuiltInWorldRayOriginKHR: // alias SpvBuiltInWorldRayOriginNV
case SpvBuiltInWorldRayDirectionKHR: // alias SpvBuiltInWorldRayDirectionNV
case SpvBuiltInObjectRayOriginKHR: // alias SpvBuiltInObjectRayOriginNV
case SpvBuiltInObjectRayDirectionKHR: // alias
// SpvBuiltInObjectRayDirectionNV
case SpvBuiltInRayTminKHR: // alias SpvBuiltInRayTminNV
case SpvBuiltInRayTmaxKHR: // alias SpvBuiltInRayTmaxNV
case SpvBuiltInInstanceCustomIndexKHR: // alias
// SpvBuiltInInstanceCustomIndexNV
case SpvBuiltInObjectToWorldKHR: // alias SpvBuiltInObjectToWorldNV
case SpvBuiltInWorldToObjectKHR: // alias SpvBuiltInWorldToObjectNV
case SpvBuiltInIncomingRayFlagsKHR: // alias SpvBuiltInIncomingRayFlagsNV
case SpvBuiltInRayGeometryIndexKHR: { // NOT present in NV
return ValidateRayTracingBuiltinsAtDefinition(decoration, inst);
}
case SpvBuiltInWorkDim:
case SpvBuiltInGlobalSize:
case SpvBuiltInEnqueuedWorkgroupSize:
@ -3657,27 +3966,13 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInFragmentSizeNV: // alias SpvBuiltInFragSizeEXT
case SpvBuiltInInvocationsPerPixelNV: // alias
// SpvBuiltInFragInvocationCountEXT
case SpvBuiltInLaunchIdNV:
case SpvBuiltInLaunchSizeNV:
case SpvBuiltInWorldRayOriginNV:
case SpvBuiltInWorldRayDirectionNV:
case SpvBuiltInObjectRayOriginNV:
case SpvBuiltInObjectRayDirectionNV:
case SpvBuiltInRayTminNV:
case SpvBuiltInRayTmaxNV:
case SpvBuiltInInstanceCustomIndexNV:
case SpvBuiltInObjectToWorldNV:
case SpvBuiltInWorldToObjectNV:
case SpvBuiltInHitTNV:
case SpvBuiltInHitKindNV:
case SpvBuiltInIncomingRayFlagsNV:
case SpvBuiltInRayGeometryIndexKHR: {
// No validation rules (for the moment).
break;
case SpvBuiltInPrimitiveShadingRateKHR:
case SpvBuiltInPrimitiveShadingRateKHR: {
return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
case SpvBuiltInShadingRateKHR:
}
case SpvBuiltInShadingRateKHR: {
return ValidateShadingRateAtDefinition(decoration, inst);
}
}

View File

@ -1363,6 +1363,36 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240);
case 4241:
return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241);
case 4242:
return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242);
case 4243:
return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243);
case 4244:
return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244);
case 4245:
return VUID_WRAP(VUID-HitTNV-HitTNV-04245);
case 4246:
return VUID_WRAP(VUID-HitTNV-HitTNV-04246);
case 4247:
return VUID_WRAP(VUID-HitTNV-HitTNV-04247);
case 4248:
return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248);
case 4249:
return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249);
case 4250:
return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250);
case 4251:
return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251);
case 4252:
return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252);
case 4253:
return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253);
case 4254:
return VUID_WRAP(VUID-InstanceId-InstanceId-04254);
case 4255:
return VUID_WRAP(VUID-InstanceId-InstanceId-04255);
case 4256:
return VUID_WRAP(VUID-InstanceId-InstanceId-04256);
case 4257:
return VUID_WRAP(VUID-InvocationId-InvocationId-04257);
case 4258:
@ -1375,6 +1405,18 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264);
case 4265:
return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265);
case 4266:
return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266);
case 4267:
return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267);
case 4268:
return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268);
case 4269:
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269);
case 4270:
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270);
case 4271:
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
case 4272:
return VUID_WRAP(VUID-Layer-Layer-04272);
case 4274:
@ -1395,6 +1437,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297);
case 4298:
return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298);
case 4299:
return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299);
case 4300:
return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300);
case 4301:
return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301);
case 4302:
return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302);
case 4303:
return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303);
case 4304:
return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304);
case 4305:
return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305);
case 4306:
return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306);
case 4307:
return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307);
case 4308:
return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308);
case 4309:
@ -1427,6 +1487,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334);
case 4337:
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337);
case 4345:
return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345);
case 4346:
return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346);
case 4347:
return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347);
case 4348:
return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348);
case 4349:
return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349);
case 4350:
return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350);
case 4351:
return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351);
case 4352:
return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352);
case 4353:
return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353);
case 4354:
return VUID_WRAP(VUID-SampleId-SampleId-04354);
case 4355:
@ -1491,6 +1569,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426);
case 4427:
return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427);
case 4428:
return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428);
case 4429:
return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429);
case 4430:
return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430);
case 4431:
return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431);
case 4432:
return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432);
case 4433:
return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433);
case 4434:
return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434);
case 4435:
return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435);
case 4436:
return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436);
case 4484:
return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484);
case 4485:

View File

@ -654,13 +654,13 @@ INSTANTIATE_TEST_SUITE_P(
"which is called with execution model Fragment."))));
INSTANTIATE_TEST_SUITE_P(
VertexIdAndInstanceIdVertexInput,
VertexIdVertexInput,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine(Values("VertexId", "InstanceId"), Values("Vertex"), Values("Input"),
Values("%u32"), Values(nullptr),
Values(TestResult(
SPV_ERROR_INVALID_DATA,
"Vulkan spec doesn't allow BuiltIn VertexId/InstanceId to be "
Combine(
Values("VertexId"), Values("Vertex"), Values("Input"), Values("%u32"),
Values(nullptr),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec doesn't allow BuiltIn VertexId to be "
"used."))));
INSTANTIATE_TEST_SUITE_P(
@ -1632,7 +1632,8 @@ INSTANTIATE_TEST_SUITE_P(
Values(TestResult(
SPV_ERROR_INVALID_DATA,
"to be used only with Fragment, TessellationControl, "
"TessellationEvaluation or Geometry execution models"))));
"TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, "
"AnyHitKHR, and ClosestHitKHR execution models"))));
INSTANTIATE_TEST_SUITE_P(
PrimitiveIdFragmentNotInput,
@ -1645,7 +1646,7 @@ INSTANTIATE_TEST_SUITE_P(
"which is called with execution model Fragment"))));
INSTANTIATE_TEST_SUITE_P(
PrimitiveIdGeometryNotInput,
PrimitiveIdTessellationNotInput,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine(Values("PrimitiveId"),
Values("TessellationControl", "TessellationEvaluation"),
@ -2362,6 +2363,581 @@ INSTANTIATE_TEST_SUITE_P(
"needs to be a 32-bit int scalar",
"is not an int scalar"))));
// Test HitKind in NV RT shaders
INSTANTIATE_TEST_SUITE_P(
HitKindNVSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindNV"),
Values("AnyHitNV", "ClosestHitNV"), Values("Input"), Values("%u32"),
Values("OpCapability RayTracingNV\n"),
Values("OpExtension \"SPV_NV_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
// HitKind is valid in AH, CH shaders as input i32 scalar
INSTANTIATE_TEST_SUITE_P(
HitKindSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
Values("AnyHitKHR", "ClosestHitKHR"), Values("Input"),
Values("%u32"), Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
HitKindNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "IntersectionKHR",
"MissKHR", "CallableKHR"),
Values("Input"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-HitKindKHR-HitKindKHR-04242"),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
HitKindNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
Values("AnyHitKHR", "ClosestHitKHR"), Values("Output"),
Values("%u32"), Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-HitKindKHR-HitKindKHR-04243"),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
HitKindNotIntScalar,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
Values("AnyHitKHR", "ClosestHitKHR"), Values("Input"),
Values("%f32", "%u32vec3"), Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-HitKindKHR-HitKindKHR-04244"),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 32-bit int scalar",
"is not an int scalar"))));
// Ensure HitT is not supported in KHR RT shaders
INSTANTIATE_TEST_SUITE_P(
HitTNVNotSupportedInKHR,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
Values("AnyHitKHR", "ClosestHitKHR"), Values("Input"),
Values("%u32"), Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult(
SPV_ERROR_INVALID_CAPABILITY,
"of MemberDecorate requires one of these capabilities"))));
// HitT is valid in AH, CH shaders as input f32 scalar (NV RT only)
INSTANTIATE_TEST_SUITE_P(
HitTNVSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
Values("AnyHitNV", "ClosestHitNV"), Values("Input"), Values("%f32"),
Values("OpCapability RayTracingNV\n"),
Values("OpExtension \"SPV_NV_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
HitTNVNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationNV", "IntersectionNV", "MissNV",
"CallableNV"),
Values("Input"), Values("%f32"),
Values("OpCapability RayTracingNV\n"),
Values("OpExtension \"SPV_NV_ray_tracing\"\n"),
Values("VUID-HitTNV-HitTNV-04245"),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
HitTNVNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
Values("AnyHitNV", "ClosestHitNV"), Values("Output"),
Values("%f32"), Values("OpCapability RayTracingNV\n"),
Values("OpExtension \"SPV_NV_ray_tracing\"\n"),
Values("VUID-HitTNV-HitTNV-04246"),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
HitTNVNotIntScalar,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
Values("AnyHitNV", "ClosestHitNV"), Values("Input"),
Values("%u32", "%f32vec3"), Values("OpCapability RayTracingNV\n"),
Values("OpExtension \"SPV_NV_ray_tracing\"\n"),
Values("VUID-HitTNV-HitTNV-04247"),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 32-bit float scalar",
"is not a float scalar"))));
// InstanceCustomIndexKHR, InstanceId, PrimitiveId, RayGeometryIndexKHR are
// valid in IS, AH, CH shaders as input i32 scalars
INSTANTIATE_TEST_SUITE_P(
RTBuiltIn3StageI32Success,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
"InstanceId", "PrimitiveId"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
RTBuiltIn3StageI32NotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
"InstanceId"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "MissKHR", "CallableKHR"),
Values("Input"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251 "
"VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345 "
"VUID-InstanceId-InstanceId-04254 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
RTBuiltIn3StageI32NotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
"InstanceId"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Output"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252 "
"VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346 "
"VUID-InstanceId-InstanceId-04255 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
RTBuiltIn3StageI32NotIntScalar,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
"InstanceId"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%f32", "%u32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253 "
"VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347 "
"VUID-InstanceId-InstanceId-04256 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 32-bit int scalar",
"is not an int scalar"))));
// PrimitiveId needs special negative testing because it has non-RT uses
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"))));
INSTANTIATE_TEST_SUITE_P(
PrimitiveIdRTNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Output"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-PrimitiveId-PrimitiveId-04334"),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Output storage class if execution model is "))));
INSTANTIATE_TEST_SUITE_P(
PrimitiveIdRTNotIntScalar,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%f32", "%u32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-PrimitiveId-PrimitiveId-04337"),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 32-bit int scalar",
"is not an int scalar"))));
// ObjectRayDirectionKHR and ObjectRayOriginKHR valid
// in IS, AH, CH shaders as input 32-bit float vec3
INSTANTIATE_TEST_SUITE_P(
ObjectRayDirectionAndOriginSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
ObjectRayDirectionAndOriginNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "MissKHR", "CallableKHR"),
Values("Input"), Values("%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299 "
"VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
ObjectRayDirectionAndOriginNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Output"), Values("%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300 "
"VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
ObjectRayDirectionAndOriginNotFloatVec3,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(
Values(SPV_ENV_VULKAN_1_2),
Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%u32vec3", "%f32", "%f32vec2", "%f32vec4"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301 "
"VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 3-component 32-bit float vector"))));
// ObjectToWorldKHR and WorldToObjectKHR valid
// in IS, AH, CH shaders as input mat4x3
INSTANTIATE_TEST_SUITE_P(
RTObjectMatrixSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectToWorldKHR", "WorldToObjectKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%f32mat34"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
RTObjectMatrixNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectToWorldKHR", "WorldToObjectKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "MissKHR", "CallableKHR"),
Values("Input"), Values("%f32mat34"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305 "
"VUID-WorldToObjectKHR-WorldToObjectKHR-04434 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
RTObjectMatrixNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectToWorldKHR", "WorldToObjectKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Output"), Values("%f32mat34"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306 "
"VUID-WorldToObjectKHR-WorldToObjectKHR-04435 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
RTObjectMatrixNotMat4x3,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("ObjectToWorldKHR", "WorldToObjectKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
Values("Input"), Values("%f32mat43", "%f32mat44", "%f32vec4"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307 "
"VUID-WorldToObjectKHR-WorldToObjectKHR-04436 "),
Values(TestResult(
SPV_ERROR_INVALID_DATA,
"variable needs to be a matrix with "
"4 columns of 3-component vectors of 32-bit floats"))));
// IncomingRayFlagsKHR is valid
// in IS, AH, CH, MS shaders as an input i32 scalar
INSTANTIATE_TEST_SUITE_P(
IncomingRayFlagsSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Input"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
IncomingRayFlagsNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "CallableKHR"),
Values("Input"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248 "
"VUID-RayTmaxKHR-RayTmaxKHR-04348 "
"VUID-RayTminKHR-RayTminKHR-04351 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
IncomingRayFlagsNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Output"), Values("%u32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249 "
"VUID-RayTmaxKHR-RayTmaxKHR-04349 "
"VUID-RayTminKHR-RayTminKHR-04352 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
IncomingRayFlagsNotIntScalar,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Input"), Values("%f32", "%u32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250 "
"VUID-RayTmaxKHR-RayTmaxKHR-04350 "
"VUID-RayTminKHR-RayTminKHR-04353 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 32-bit int scalar",
"is not an int scalar"))));
// RayTmaxKHR, RayTminKHR are all valid
// in IS, AH, CH, MS shaders as input f32 scalars
INSTANTIATE_TEST_SUITE_P(
RayTSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Input"), Values("%f32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
RayTNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "CallableKHR"),
Values("Input"), Values("%f32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248 "
"VUID-RayTmaxKHR-RayTmaxKHR-04348 "
"VUID-RayTminKHR-RayTminKHR-04351 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
RayTNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Output"), Values("%f32"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249 "
"VUID-RayTmaxKHR-RayTmaxKHR-04349 "
"VUID-RayTminKHR-RayTminKHR-04352 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
RayTNotFloatScalar,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Input"), Values("%u32", "%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250 "
"VUID-RayTmaxKHR-RayTmaxKHR-04350 "
"VUID-RayTminKHR-RayTminKHR-04353 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 32-bit float scalar",
"is not a float scalar"))));
// WorldRayDirectionKHR and WorldRayOriginKHR are valid
// in IS, AH, CH, MS shaders as input 32-bit float vec3
INSTANTIATE_TEST_SUITE_P(
WorldRayDirectionAndOriginSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Input"), Values("%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
WorldRayDirectionAndOriginNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute", "RayGenerationKHR", "CallableKHR"),
Values("Input"), Values("%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428 "
"VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
WorldRayDirectionAndOriginNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2),
Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Output"), Values("%f32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429 "
"VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
WorldRayDirectionAndOriginNotFloatVec3,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(
Values(SPV_ENV_VULKAN_1_2),
Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
Values("Input"), Values("%u32vec3", "%f32", "%f32vec2", "%f32vec4"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430 "
"VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 3-component 32-bit float vector"))));
// LaunchIdKHR and LaunchSizeKHR are valid
// in RG, IS, AH, CH, MS shaders as input 32-bit ivec3
INSTANTIATE_TEST_SUITE_P(
LaunchRTSuccess,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
Values("RayGenerationKHR", "AnyHitKHR", "ClosestHitKHR",
"IntersectionKHR", "MissKHR", "CallableKHR"),
Values("Input"), Values("%u32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
LaunchRTNotExecutionMode,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
Values("Vertex", "Fragment", "TessellationControl",
"TessellationEvaluation", "Geometry", "Fragment",
"GLCompute"),
Values("Input"), Values("%u32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-LaunchIdKHR-LaunchIdKHR-04266 "
"VUID-LaunchSizeKHR-LaunchSizeKHR-04269 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"Vulkan spec does not allow BuiltIn",
"to be used with the execution model"))));
INSTANTIATE_TEST_SUITE_P(
LaunchRTNotInput,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
Values("RayGenerationKHR", "AnyHitKHR", "ClosestHitKHR",
"IntersectionKHR", "MissKHR", "CallableKHR"),
Values("Output"), Values("%u32vec3"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-LaunchIdKHR-LaunchIdKHR-04267 "
"VUID-LaunchSizeKHR-LaunchSizeKHR-04270 "),
Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
"used for variables with Input storage class"))));
INSTANTIATE_TEST_SUITE_P(
LaunchRTNotIntVec3,
ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
Values("RayGenerationKHR", "AnyHitKHR", "ClosestHitKHR",
"IntersectionKHR", "MissKHR", "CallableKHR"),
Values("Input"), Values("%f32vec3", "%u32", "%u32vec2", "%u32vec4"),
Values("OpCapability RayTracingKHR\n"),
Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
Values("VUID-LaunchIdKHR-LaunchIdKHR-04268 "
"VUID-LaunchSizeKHR-LaunchSizeKHR-04271 "),
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 3-component 32-bit int vector"))));
CodeGenerator GetArrayedVariableCodeGenerator(spv_target_env env,
const char* const built_in,
const char* const execution_model,
@ -3358,44 +3934,6 @@ OpFunctionEnd
EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
TEST_F(ValidateBuiltIns, DisallowInstanceIdWithRayGenShader) {
CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
generator.capabilities_ += R"(
OpCapability RayTracingNV
)";
generator.extensions_ = R"(
OpExtension "SPV_NV_ray_tracing"
)";
generator.before_types_ = R"(
OpMemberDecorate %input_type 0 BuiltIn InstanceId
)";
generator.after_types_ = R"(
%input_type = OpTypeStruct %u32
%input_ptr = OpTypePointer Input %input_type
%input_ptr_u32 = OpTypePointer Input %u32
%input = OpVariable %input_ptr Input
)";
EntryPoint entry_point;
entry_point.name = "main_d_r";
entry_point.execution_model = "RayGenerationNV";
entry_point.interfaces = "%input";
entry_point.body = R"(
%input_member = OpAccessChain %input_ptr_u32 %input %u32_0
)";
generator.entry_points_.push_back(std::move(entry_point));
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 InstanceId to be used "
"only with IntersectionNV, ClosestHitNV and "
"AnyHitNV execution models"));
}
TEST_F(ValidateBuiltIns, ValidBuiltinsForMeshShader) {
CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
generator.capabilities_ += R"(

View File

@ -115,6 +115,15 @@ std::string GetDefaultShaderTypes() {
%f32vec3arr3 = OpTypeArray %f32vec3 %u32_3
%f32vec4arr3 = OpTypeArray %f32vec4 %u32_3
%f64vec4arr3 = OpTypeArray %f64vec4 %u32_3
%f32mat22 = OpTypeMatrix %f32vec2 2
%f32mat23 = OpTypeMatrix %f32vec2 3
%f32mat32 = OpTypeMatrix %f32vec3 2
%f32mat33 = OpTypeMatrix %f32vec3 3
%f64mat22 = OpTypeMatrix %f64vec2 2
%f32mat34 = OpTypeMatrix %f32vec3 4
%f32mat43 = OpTypeMatrix %f32vec4 3
%f32mat44 = OpTypeMatrix %f32vec4 4
)";
}