SPV_KHR_opacity_micromap (#6670)
diff --git a/source/val/validate_extensions.cpp b/source/val/validate_extensions.cpp
index f079954..d986442 100644
--- a/source/val/validate_extensions.cpp
+++ b/source/val/validate_extensions.cpp
@@ -1345,6 +1345,7 @@
if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) {
if (extension ==
ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) ||
+ extension == ExtensionToString(kSPV_KHR_opacity_micromap) ||
extension == ExtensionToString(kSPV_EXT_mesh_shader) ||
extension == ExtensionToString(kSPV_NV_shader_invocation_reorder) ||
extension == ExtensionToString(kSPV_EXT_shader_invocation_reorder) ||
diff --git a/source/val/validate_mode_setting.cpp b/source/val/validate_mode_setting.cpp
index 261f4af..dd1c731 100644
--- a/source/val/validate_mode_setting.cpp
+++ b/source/val/validate_mode_setting.cpp
@@ -549,6 +549,7 @@
case spv::ExecutionMode::SubgroupsPerWorkgroupId:
case spv::ExecutionMode::LocalSizeHintId:
case spv::ExecutionMode::LocalSizeId:
+ case spv::ExecutionMode::OpacityMicromapIdKHR:
case spv::ExecutionMode::FPFastMathDefault:
case spv::ExecutionMode::MaximumRegistersIdINTEL:
case spv::ExecutionMode::IsApiEntryAMDX:
@@ -635,6 +636,16 @@
}
}
break;
+ case spv::ExecutionMode::OpacityMicromapIdKHR: {
+ spv::Op operand_opcode = operand_inst->opcode();
+ if (!spvOpcodeIsConstant(operand_opcode) ||
+ !_.IsBoolScalarType(operand_inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, operand_inst)
+ << "OpacityMicromapIdKHR's operand must be an <id> "
+ "of a constant instruction of OpTypeBool.";
+ }
+ break;
+ }
default:
break;
}
diff --git a/source/val/validate_ray_query.cpp b/source/val/validate_ray_query.cpp
index 980144d..ac5ef1e 100644
--- a/source/val/validate_ray_query.cpp
+++ b/source/val/validate_ray_query.cpp
@@ -99,6 +99,13 @@
<< "Ray Flags must be a 32-bit int scalar";
}
+ if (!_.CheckForceOpacityMicromap2StateKHRCapabilityRequirement(inst, 2)) {
+ return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
+ << "The ForceOpacityMicromap2StateKHR flag requires the "
+ "RayTracingOpacityMicromapKHR and RayQueryKHR or "
+ "RayTracingKHR capabilities";
+ }
+
const uint32_t cull_mask = _.GetOperandTypeId(inst, 3);
if (!_.IsIntScalarType(cull_mask, 32)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
diff --git a/source/val/validate_ray_tracing.cpp b/source/val/validate_ray_tracing.cpp
index 5fa14cc..a7b23a8 100644
--- a/source/val/validate_ray_tracing.cpp
+++ b/source/val/validate_ray_tracing.cpp
@@ -58,6 +58,13 @@
<< "Cull Mask must be a 32-bit int scalar";
}
+ if (!_.CheckForceOpacityMicromap2StateKHRCapabilityRequirement(inst, 1)) {
+ return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
+ << "The ForceOpacityMicromap2StateKHR flag requires the "
+ "RayTracingOpacityMicromapKHR and RayQueryKHR or "
+ "RayTracingKHR capabilities";
+ }
+
const uint32_t sbt_offset = _.GetOperandTypeId(inst, 3);
if (!_.IsIntScalarType(sbt_offset, 32)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
diff --git a/source/val/validation_state.h b/source/val/validation_state.h
index 0ab0ebd..59a62b3 100644
--- a/source/val/validation_state.h
+++ b/source/val/validation_state.h
@@ -932,6 +932,23 @@
return SpvDecorationString(uint32_t(decoration));
}
+ bool CheckForceOpacityMicromap2StateKHRCapabilityRequirement(
+ const Instruction* inst, uint32_t flag_operand) {
+ bool retval = true;
+ uint64_t flag_val = 0;
+ if (EvalConstantValUint64(inst->GetOperandAs<uint32_t>(flag_operand),
+ &flag_val)) {
+ if ((flag_val & static_cast<uint64_t>(
+ spv::RayFlagsMask::ForceOpacityMicromap2StateKHR)) !=
+ 0) {
+ assert(HasCapability(spv::Capability::RayQueryKHR) ||
+ HasCapability(spv::Capability::RayTracingKHR));
+ retval = HasCapability(spv::Capability::RayTracingOpacityMicromapKHR);
+ }
+ }
+ return retval;
+ }
+
// Returns whether type result_type_id and type m2 are cooperative matrices
// with the same "shape" (matching scope, rows, cols). If any are
// specialization constants, we assume they can match because we can't prove
diff --git a/test/val/val_ray_query_test.cpp b/test/val/val_ray_query_test.cpp
index c383b93..35e6270 100644
--- a/test/val/val_ray_query_test.cpp
+++ b/test/val/val_ray_query_test.cpp
@@ -870,6 +870,249 @@
"point vector as Result Type"));
}
+TEST_F(ValidateRayQuery, RayQueryOpacityMicromapSpvVersionCheck) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapExecutionModeKHR
+ OpExtension "SPV_KHR_ray_query"
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %enable
+ OpDecorate %enable SpecId 4
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %enable = OpSpecConstantFalse %bool
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_3);
+ ASSERT_EQ(SPV_ERROR_WRONG_VERSION,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("SPV_KHR_opacity_micromap extension requires SPIR-V "
+ "version 1.4 or later."));
+}
+
+TEST_F(ValidateRayQuery, OpacityMicromapExtensionStringIsMissing) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapExecutionModeKHR
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %enable
+ OpDecorate %enable SpecId 4
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %enable = OpSpecConstantFalse %bool
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("requires one of these extensions: SPV_KHR_opacity_micromap"));
+}
+
+TEST_F(ValidateRayQuery,
+ OpacityMicromapExecutionModeRejectsEXTExtensionString) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapExecutionModeKHR
+ OpExtension "SPV_KHR_ray_query"
+ OpExtension "SPV_EXT_opacity_micromap"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %enable
+ OpDecorate %enable SpecId 4
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %enable = OpSpecConstantFalse %bool
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("requires one of these extensions: SPV_KHR_opacity_micromap"));
+}
+
+TEST_F(ValidateRayQuery, RayQueryOpacityMicromapId_1) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapExecutionModeKHR
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %omm
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %i32 = OpTypeInt 32 0
+ %omm = OpConstant %i32 9
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpacityMicromapIdKHR's operand must be an <id> of a "
+ "constant instruction of OpTypeBool"));
+}
+
+TEST_F(ValidateRayQuery, RayQueryOpacityMicromapId_2) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapExecutionModeKHR
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %omm
+ OpDecorate %omm SpecId 4
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %i32 = OpTypeInt 32 0
+ %omm = OpSpecConstant %i32 9
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpacityMicromapIdKHR's operand must be an <id> of a "
+ "constant instruction of OpTypeBool"));
+}
+
+TEST_F(ValidateRayQuery, RayQueryOpacityMicromapId_4) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapKHR
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %omm
+ OpDecorate %omm SpecId 4
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %omm = OpSpecConstantFalse %bool
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Operand 2 of ExecutionModeId requires one of these "
+ "capabilities: RayTracingOpacityMicromapExecutionModeKHR"));
+}
+
+TEST_F(ValidateRayQuery,
+ RayQueryInitializeForceOpacityMicromap2StateKHRCapabilityCheck) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %4725
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %_st_4530 = OpTypeStruct %uint
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+ %type_rq = OpTypeRayQueryKHR
+ %4723 = OpTypeAccelerationStructureKHR
+%_ptr_UniformConstant_4723 = OpTypePointer UniformConstant %4723
+ %rq_ptr = OpTypePointer Private %type_rq
+ %4725 = OpVariable %_ptr_UniformConstant_4723 UniformConstant
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %flag = OpConstant %uint 1024
+ %float_1 = OpConstant %float 1
+ %v3float_1 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+ %ptr_rq = OpTypePointer Function %type_rq
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ %ray_query = OpVariable %ptr_rq Function
+ %4726 = OpLoad %4723 %4725
+ OpRayQueryInitializeKHR %ray_query %4726 %flag %uint_1 %v3float_1 %float_1 %v3float_1 %float_1
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("The ForceOpacityMicromap2StateKHR flag requires the "
+ "RayTracingOpacityMicromapKHR and RayQueryKHR or "
+ "RayTracingKHR capabilities"));
+}
+
+TEST_F(ValidateRayQuery, RayQueryOpacityMicromapGood) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpCapability RayTracingOpacityMicromapKHR
+ OpCapability RayTracingOpacityMicromapExecutionModeKHR
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionModeId %main OpacityMicromapIdKHR %omm
+ OpDecorate %omm SpecId 4
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %omm = OpSpecConstantFalse %bool
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/test/val/val_ray_tracing_test.cpp b/test/val/val_ray_tracing_test.cpp
index 476b228..977bfae 100644
--- a/test/val/val_ray_tracing_test.cpp
+++ b/test/val/val_ray_tracing_test.cpp
@@ -698,6 +698,46 @@
"RayTracingPositionFetchKHR"));
}
+TEST_F(ValidateRayTracing, ForceOpacityMicromap2StateKHRCapabilityCheck) {
+ const std::string shader = R"(
+ OpCapability Shader
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_opacity_micromap"
+ OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint RayGenerationKHR %main "main" %4725 %payload
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %_st_4530 = OpTypeStruct %uint
+ %_ptr = OpTypePointer RayPayloadKHR %_st_4530
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+ %4723 = OpTypeAccelerationStructureKHR
+%_ptr_UniformConstant_4723 = OpTypePointer UniformConstant %4723
+ %4725 = OpVariable %_ptr_UniformConstant_4723 UniformConstant
+ %payload = OpVariable %_ptr RayPayloadKHR
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %flag = OpConstant %uint 1024
+ %float_1 = OpConstant %float 1
+ %v3float_1 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+ %main = OpFunction %void None %3
+ %main_label = OpLabel
+ %4726 = OpLoad %4723 %4725
+ OpTraceRayKHR %4726 %flag %uint_1 %uint_2 %uint_1 %uint_2 %v3float_1 %float_1 %v3float_1 %float_1 %payload
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(shader.c_str(), SPV_ENV_UNIVERSAL_1_4);
+ ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("The ForceOpacityMicromap2StateKHR flag requires the "
+ "RayTracingOpacityMicromapKHR and RayQueryKHR or "
+ "RayTracingKHR capabilities"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools