aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer Fricke <spencerfricke@gmail.com>2022-08-30 00:09:06 +0900
committerGitHub <noreply@github.com>2022-08-29 11:09:06 -0400
commitf76431cbaf86e7d5a148dd45ecbe2d4531fcdd21 (patch)
treed78903e8162d00ee0b98fa13dbf45ebed2b04cdc
parenta98f05d02fedcf2a20fd94b4640eb700b7df198d (diff)
downloadSPIRV-Tools-f76431cbaf86e7d5a148dd45ecbe2d4531fcdd21.tar.gz
spirv-val: Add SPV_KHR_ray_tracing storage class (#4868)
* Added VUID labels
-rw-r--r--source/val/validate_memory.cpp37
-rw-r--r--source/val/validation_state.cpp128
-rw-r--r--test/val/val_storage_test.cpp285
3 files changed, 432 insertions, 18 deletions
diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp
index 425a8d3d..5571aa64 100644
--- a/source/val/validate_memory.cpp
+++ b/source/val/validate_memory.cpp
@@ -438,11 +438,11 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
storage_class != SpvStorageClassCrossWorkgroup &&
storage_class != SpvStorageClassPrivate &&
storage_class != SpvStorageClassFunction &&
- storage_class != SpvStorageClassRayPayloadNV &&
- storage_class != SpvStorageClassIncomingRayPayloadNV &&
- storage_class != SpvStorageClassHitAttributeNV &&
- storage_class != SpvStorageClassCallableDataNV &&
- storage_class != SpvStorageClassIncomingCallableDataNV) {
+ storage_class != SpvStorageClassRayPayloadKHR &&
+ storage_class != SpvStorageClassIncomingRayPayloadKHR &&
+ storage_class != SpvStorageClassHitAttributeKHR &&
+ storage_class != SpvStorageClassCallableDataKHR &&
+ storage_class != SpvStorageClassIncomingCallableDataKHR) {
bool storage_input_or_output = storage_class == SpvStorageClassInput ||
storage_class == SpvStorageClassOutput;
bool builtin = false;
@@ -889,8 +889,11 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
<< "' is not a pointer type.";
}
- const auto pointee_type = _.FindDef(pointer_type->GetOperandAs<uint32_t>(2));
- if (!pointee_type || result_type->id() != pointee_type->id()) {
+ uint32_t pointee_data_type;
+ uint32_t storage_class;
+ if (!_.GetPointerTypeInfo(pointer_type->id(), &pointee_data_type,
+ &storage_class) ||
+ result_type->id() != pointee_data_type) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpLoad Result Type <id> '" << _.getIdName(inst->type_id())
<< "' does not match Pointer <id> '" << _.getIdName(pointer->id())
@@ -964,6 +967,26 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpStore Pointer <id> '" << _.getIdName(pointer_id)
<< "' storage class is read-only";
+ } else if (storage_class == SpvStorageClassShaderRecordBufferKHR) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "ShaderRecordBufferKHR Storage Class variables are read only";
+ } else if (storage_class == SpvStorageClassHitAttributeKHR) {
+ std::string errorVUID = _.VkErrorID(4703);
+ _.function(inst->function()->id())
+ ->RegisterExecutionModelLimitation(
+ [errorVUID](SpvExecutionModel model, std::string* message) {
+ if (model == SpvExecutionModelAnyHitKHR ||
+ model == SpvExecutionModelClosestHitKHR) {
+ if (message) {
+ *message =
+ errorVUID +
+ "HitAttributeKHR Storage Class variables are read only "
+ "with AnyHitKHR and ClosestHitKHR";
+ }
+ return false;
+ }
+ return true;
+ });
}
if (spvIsVulkanEnv(_.context()->target_env) &&
diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp
index 2702b2b0..3501e8ce 100644
--- a/source/val/validation_state.cpp
+++ b/source/val/validation_state.cpp
@@ -608,7 +608,8 @@ void ValidationState_t::RegisterStorageClassConsumer(
std::string errorVUID = VkErrorID(4644);
function(consumer->function()->id())
->RegisterExecutionModelLimitation([errorVUID](
- SpvExecutionModel model, std::string* message) {
+ SpvExecutionModel model,
+ std::string* message) {
if (model == SpvExecutionModelGLCompute ||
model == SpvExecutionModelRayGenerationKHR ||
model == SpvExecutionModelIntersectionKHR ||
@@ -634,7 +635,8 @@ void ValidationState_t::RegisterStorageClassConsumer(
std::string errorVUID = VkErrorID(4645);
function(consumer->function()->id())
->RegisterExecutionModelLimitation([errorVUID](
- SpvExecutionModel model, std::string* message) {
+ SpvExecutionModel model,
+ std::string* message) {
if (model != SpvExecutionModelGLCompute &&
model != SpvExecutionModelTaskNV &&
model != SpvExecutionModelMeshNV) {
@@ -650,6 +652,116 @@ void ValidationState_t::RegisterStorageClassConsumer(
});
}
}
+
+ if (storage_class == SpvStorageClassCallableDataKHR) {
+ std::string errorVUID = VkErrorID(4704);
+ function(consumer->function()->id())
+ ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model,
+ std::string* message) {
+ if (model != SpvExecutionModelRayGenerationKHR &&
+ model != SpvExecutionModelClosestHitKHR &&
+ model != SpvExecutionModelCallableKHR &&
+ model != SpvExecutionModelMissKHR) {
+ if (message) {
+ *message = errorVUID +
+ "CallableDataKHR Storage Class is limited to "
+ "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
+ "MissKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
+ } else if (storage_class == SpvStorageClassIncomingCallableDataKHR) {
+ std::string errorVUID = VkErrorID(4705);
+ function(consumer->function()->id())
+ ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model,
+ std::string* message) {
+ if (model != SpvExecutionModelCallableKHR) {
+ if (message) {
+ *message = errorVUID +
+ "IncomingCallableDataKHR Storage Class is limited to "
+ "CallableKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
+ } else if (storage_class == SpvStorageClassRayPayloadKHR) {
+ std::string errorVUID = VkErrorID(4698);
+ function(consumer->function()->id())
+ ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model,
+ std::string* message) {
+ if (model != SpvExecutionModelRayGenerationKHR &&
+ model != SpvExecutionModelClosestHitKHR &&
+ model != SpvExecutionModelMissKHR) {
+ if (message) {
+ *message =
+ errorVUID +
+ "RayPayloadKHR Storage Class is limited to RayGenerationKHR, "
+ "ClosestHitKHR, and MissKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
+ } else if (storage_class == SpvStorageClassHitAttributeKHR) {
+ std::string errorVUID = VkErrorID(4701);
+ function(consumer->function()->id())
+ ->RegisterExecutionModelLimitation(
+ [errorVUID](SpvExecutionModel model, std::string* message) {
+ if (model != SpvExecutionModelIntersectionKHR &&
+ model != SpvExecutionModelAnyHitKHR &&
+ model != SpvExecutionModelClosestHitKHR) {
+ if (message) {
+ *message = errorVUID +
+ "HitAttributeKHR Storage Class is limited to "
+ "IntersectionKHR, AnyHitKHR, sand ClosestHitKHR "
+ "execution model";
+ }
+ return false;
+ }
+ return true;
+ });
+ } else if (storage_class == SpvStorageClassIncomingRayPayloadKHR) {
+ std::string errorVUID = VkErrorID(4699);
+ function(consumer->function()->id())
+ ->RegisterExecutionModelLimitation(
+ [errorVUID](SpvExecutionModel model, std::string* message) {
+ if (model != SpvExecutionModelAnyHitKHR &&
+ model != SpvExecutionModelClosestHitKHR &&
+ model != SpvExecutionModelMissKHR) {
+ if (message) {
+ *message =
+ errorVUID +
+ "IncomingRayPayloadKHR Storage Class is limited to "
+ "AnyHitKHR, ClosestHitKHR, and MissKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
+ } else if (storage_class == SpvStorageClassShaderRecordBufferKHR) {
+ function(consumer->function()->id())
+ ->RegisterExecutionModelLimitation(
+ [](SpvExecutionModel model, std::string* message) {
+ if (model != SpvExecutionModelRayGenerationKHR &&
+ model != SpvExecutionModelIntersectionKHR &&
+ model != SpvExecutionModelAnyHitKHR &&
+ model != SpvExecutionModelClosestHitKHR &&
+ model != SpvExecutionModelCallableKHR &&
+ model != SpvExecutionModelMissKHR) {
+ if (message) {
+ *message =
+ "ShaderRecordBufferKHR Storage Class is limited to "
+ "RayGenerationKHR, IntersectionKHR, AnyHitKHR, "
+ "ClosestHitKHR, CallableKHR, and MissKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
+ }
}
uint32_t ValidationState_t::getIdBound() const { return id_bound_; }
@@ -1911,6 +2023,18 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
case 4686:
return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
+ case 4698:
+ return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698);
+ case 4699:
+ return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699);
+ case 4701:
+ return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701);
+ case 4703:
+ return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703);
+ case 4704:
+ return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704);
+ case 4705:
+ return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705);
case 4708:
return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708);
case 4710:
diff --git a/test/val/val_storage_test.cpp b/test/val/val_storage_test.cpp
index ae4047b9..600e5b91 100644
--- a/test/val/val_storage_test.cpp
+++ b/test/val/val_storage_test.cpp
@@ -251,30 +251,46 @@ TEST_F(ValidateStorage, RelaxedLogicalPointerFunctionParamBad) {
HasSubstr("OpFunctionCall Argument <id> '"));
}
-TEST_P(ValidateStorageExecutionModel, VulkanOutsideStoreFailure) {
- std::stringstream ss;
+std::string GenerateExecutionModelCode(const std::string& execution_model,
+ const std::string& storage_class,
+ bool store) {
+ const std::string mode = (execution_model.compare("GLCompute") == 0)
+ ? "OpExecutionMode %func LocalSize 1 1 1"
+ : "";
+ const std::string operation =
+ (store) ? "OpStore %var %int0" : "%load = OpLoad %intt %var";
+ std::ostringstream ss;
ss << R"(
OpCapability Shader
OpCapability RayTracingKHR
OpExtension "SPV_KHR_ray_tracing"
OpMemoryModel Logical GLSL450
OpEntryPoint )"
- << GetParam() << R"( %func "func" %output
- OpDecorate %output Location 0
+ << execution_model << R"( %func "func" %var
+ )" << mode << R"(
+ OpDecorate %var Location 0
%intt = OpTypeInt 32 0
%int0 = OpConstant %intt 0
%voidt = OpTypeVoid
%vfunct = OpTypeFunction %voidt
-%outputptrt = OpTypePointer Output %intt
-%output = OpVariable %outputptrt Output
+%ptr = OpTypePointer )"
+ << storage_class << R"( %intt
+%var = OpVariable %ptr )" << storage_class << R"(
%func = OpFunction %voidt None %vfunct
%funcl = OpLabel
- OpStore %output %int0
+ )" << operation << R"(
OpReturn
OpFunctionEnd
)";
- CompileSuccessfully(ss.str(), SPV_ENV_VULKAN_1_0);
+ return ss.str();
+}
+
+TEST_P(ValidateStorageExecutionModel, VulkanOutsideStoreFailure) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "Output", true).c_str(),
+ SPV_ENV_VULKAN_1_0);
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-None-04644"));
@@ -285,11 +301,262 @@ TEST_P(ValidateStorageExecutionModel, VulkanOutsideStoreFailure) {
"ClosestHitKHR, MissKHR, or CallableKHR execution models"));
}
+TEST_P(ValidateStorageExecutionModel, CallableDataStore) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "CallableDataKHR", true)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("RayGenerationKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("CallableKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-CallableDataKHR-04704"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "CallableDataKHR Storage Class is limited to RayGenerationKHR, "
+ "ClosestHitKHR, CallableKHR, and MissKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, CallableDataLoad) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "CallableDataKHR", false)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("RayGenerationKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("CallableKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-CallableDataKHR-04704"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "CallableDataKHR Storage Class is limited to RayGenerationKHR, "
+ "ClosestHitKHR, CallableKHR, and MissKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, IncomingCallableDataStore) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(GenerateExecutionModelCode(
+ execution_model, "IncomingCallableDataKHR", true)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("CallableKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-IncomingCallableDataKHR-04705"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("IncomingCallableDataKHR Storage Class is limited to "
+ "CallableKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, IncomingCallableDataLoad) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(GenerateExecutionModelCode(
+ execution_model, "IncomingCallableDataKHR", false)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("CallableKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-IncomingCallableDataKHR-04705"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("IncomingCallableDataKHR Storage Class is limited to "
+ "CallableKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, RayPayloadStore) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "RayPayloadKHR", true)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("RayGenerationKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-RayPayloadKHR-04698"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("RayPayloadKHR Storage Class is limited to RayGenerationKHR, "
+ "ClosestHitKHR, and MissKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, RayPayloadLoad) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "RayPayloadKHR", false)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("RayGenerationKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-RayPayloadKHR-04698"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("RayPayloadKHR Storage Class is limited to RayGenerationKHR, "
+ "ClosestHitKHR, and MissKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, HitAttributeStore) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "HitAttributeKHR", true)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("IntersectionKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else if (execution_model.compare("AnyHitKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0) {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04703"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("HitAttributeKHR Storage Class variables are read "
+ "only with AnyHitKHR and ClosestHitKHR"));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04701"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "HitAttributeKHR Storage Class is limited to IntersectionKHR, "
+ "AnyHitKHR, sand ClosestHitKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, HitAttributeLoad) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "HitAttributeKHR", false)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("IntersectionKHR") == 0 ||
+ execution_model.compare("AnyHitKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04701"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "HitAttributeKHR Storage Class is limited to IntersectionKHR, "
+ "AnyHitKHR, sand ClosestHitKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, IncomingRayPayloadStore) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "IncomingRayPayloadKHR", true)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("AnyHitKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("IncomingRayPayloadKHR Storage Class is limited to "
+ "AnyHitKHR, ClosestHitKHR, and MissKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, IncomingRayPayloadLoad) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(GenerateExecutionModelCode(execution_model,
+ "IncomingRayPayloadKHR", false)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("AnyHitKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("IncomingRayPayloadKHR Storage Class is limited to "
+ "AnyHitKHR, ClosestHitKHR, and MissKHR execution model"));
+ }
+}
+
+TEST_P(ValidateStorageExecutionModel, ShaderRecordBufferStore) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(
+ GenerateExecutionModelCode(execution_model, "ShaderRecordBufferKHR", true)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("ShaderRecordBufferKHR Storage Class variables are read only"));
+}
+
+TEST_P(ValidateStorageExecutionModel, ShaderRecordBufferLoad) {
+ std::string execution_model = GetParam();
+ CompileSuccessfully(GenerateExecutionModelCode(execution_model,
+ "ShaderRecordBufferKHR", false)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ if (execution_model.compare("RayGenerationKHR") == 0 ||
+ execution_model.compare("IntersectionKHR") == 0 ||
+ execution_model.compare("AnyHitKHR") == 0 ||
+ execution_model.compare("ClosestHitKHR") == 0 ||
+ execution_model.compare("CallableKHR") == 0 ||
+ execution_model.compare("MissKHR") == 0) {
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ } else {
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("ShaderRecordBufferKHR Storage Class is limited to "
+ "RayGenerationKHR, IntersectionKHR, AnyHitKHR, "
+ "ClosestHitKHR, CallableKHR, and MissKHR execution model"));
+ }
+}
+
INSTANTIATE_TEST_SUITE_P(MatrixExecutionModel, ValidateStorageExecutionModel,
::testing::Values("RayGenerationKHR",
"IntersectionKHR", "AnyHitKHR",
"ClosestHitKHR", "MissKHR",
- "CallableKHR"));
+ "CallableKHR", "GLCompute"));
} // namespace
} // namespace val