Skip to content

Commit d7b4c83

Browse files
committed
layers: Add VK_EXT_ray_tracing_invocation_reorder checks (KhronosGroup#11525)
tests: Add tests for VK_EXT_ray_tracing_invocation_reorder (KhronosGroup#11525)
1 parent 3a139d6 commit d7b4c83

File tree

15 files changed

+1244
-146
lines changed

15 files changed

+1244
-146
lines changed

layers/chassis/dispatch_object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct DeviceExtensionProperties {
116116
#endif
117117
VkPhysicalDeviceMemoryDecompressionPropertiesEXT memory_decompression_props;
118118
VkPhysicalDevicePerformanceCountersByRegionPropertiesARM renderpass_counter_by_region_props;
119+
VkPhysicalDeviceRayTracingInvocationReorderPropertiesEXT ray_tracing_invocation_reorder_props;
119120
VkPhysicalDeviceShaderLongVectorPropertiesEXT shader_long_vector_props;
120121
};
121122

layers/chassis/dispatch_object_manual.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,8 @@ StatelessDeviceData::StatelessDeviceData(vvl::dispatch::Instance *instance, VkPh
396396
&phys_dev_ext_props.ray_tracing_props_nv);
397397
instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_ray_tracing_pipeline,
398398
&phys_dev_ext_props.ray_tracing_props_khr);
399+
instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_ray_tracing_invocation_reorder,
400+
&phys_dev_ext_props.ray_tracing_invocation_reorder_props);
399401
instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_acceleration_structure,
400402
&phys_dev_ext_props.acc_structure_props);
401403
instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_fragment_density_map,

layers/gpuav/instrumentation/gpuav_shader_instrumentor.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,15 @@ void GpuShaderInstrumentor::BuildDescriptorSetLayoutInfo(const vvl::Pipeline &pi
10011001
BuildDescriptorSetLayoutInfo(*set_layout_state, set_layout_index, out_instrumentation_dsl);
10021002
}
10031003
}
1004+
1005+
// Set ray tracing pipeline flags for VUIDs 11886/11887
1006+
out_instrumentation_dsl.pipeline_has_skip_aabbs_flag =
1007+
(pipeline_state.create_flags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0;
1008+
out_instrumentation_dsl.pipeline_has_skip_triangles_flag =
1009+
(pipeline_state.create_flags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0;
1010+
// For VUID 11888 - maxShaderBindingTableRecordIndex limit
1011+
out_instrumentation_dsl.max_shader_binding_table_record_index =
1012+
phys_dev_ext_props.ray_tracing_invocation_reorder_props.maxShaderBindingTableRecordIndex;
10041013
}
10051014

10061015
void GpuShaderInstrumentor::BuildDescriptorSetLayoutInfo(const vku::safe_VkShaderCreateInfoEXT &modified_create_info,
@@ -1504,6 +1513,11 @@ bool GpuShaderInstrumentor::InstrumentShader(const vvl::span<const uint32_t> &in
15041513
module_settings.support_non_semantic_info =
15051514
IsExtEnabled(extensions.vk_khr_shader_non_semantic_info) && !IsExtEnabled(extensions.vk_khr_portability_subset);
15061515
module_settings.has_bindless_descriptors = instrumentation_dsl.has_bindless_descriptors;
1516+
// Ray tracing pipeline flags for VUIDs 11886/11887
1517+
module_settings.pipeline_has_skip_aabbs_flag = instrumentation_dsl.pipeline_has_skip_aabbs_flag;
1518+
module_settings.pipeline_has_skip_triangles_flag = instrumentation_dsl.pipeline_has_skip_triangles_flag;
1519+
// For VUID 11888 - maxShaderBindingTableRecordIndex limit
1520+
module_settings.max_shader_binding_table_record_index = instrumentation_dsl.max_shader_binding_table_record_index;
15071521

15081522
spirv::Module module(input_spirv, debug_report, module_settings, modified_features,
15091523
instrumentation_dsl.set_index_to_bindings_layout_lut);

layers/gpuav/instrumentation/gpuav_shader_instrumentor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ class GpuShaderInstrumentor : public vvl::DeviceProxy {
184184
bool has_bindless_descriptors = false;
185185
// < set , [ bindings ] >
186186
std::vector<std::vector<spirv::BindingLayout>> set_index_to_bindings_layout_lut;
187+
// Pipeline flags for ray tracing validation (VUIDs 11886/11887)
188+
bool pipeline_has_skip_aabbs_flag = false;
189+
bool pipeline_has_skip_triangles_flag = false;
190+
// For VUID 11888 - maxShaderBindingTableRecordIndex limit check
191+
uint32_t max_shader_binding_table_record_index = 0;
187192
};
188193
void BuildDescriptorSetLayoutInfo(const vvl::Pipeline &pipeline_state,
189194
InstrumentationDescriptorSetLayouts &out_instrumentation_dsl);

layers/gpuav/instrumentation/ray_query.cpp

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,58 +41,111 @@ void RegisterRayQueryValidation(Validator &gpuav, CommandBufferSubState &cb) {
4141
std::ostringstream strm;
4242

4343
const uint32_t error_sub_code = GetSubError(error_record);
44+
// opcode_type: 0 = OpRayQueryInitializeKHR, 1 = OpHitObjectTraceRayEXT, 2 = OpHitObjectTraceReorderExecuteEXT,
45+
// 3 = OpHitObjectTraceRayMotionEXT, 4 = OpHitObjectTraceMotionReorderExecuteEXT
46+
const uint32_t opcode_type = error_record[kInstRayQueryOpcodeType];
47+
const bool is_hit_object = (opcode_type >= 1);
48+
const char* opcode_name = "OpRayQueryInitializeKHR";
49+
if (opcode_type == 1) {
50+
opcode_name = "OpHitObjectTraceRayEXT";
51+
} else if (opcode_type == 2) {
52+
opcode_name = "OpHitObjectTraceReorderExecuteEXT";
53+
} else if (opcode_type == 3) {
54+
opcode_name = "OpHitObjectTraceRayMotionEXT";
55+
} else if (opcode_type == 4) {
56+
opcode_name = "OpHitObjectTraceMotionReorderExecuteEXT";
57+
}
58+
4459
switch (error_sub_code) {
4560
case kErrorSubCodeRayQueryNegativeMin: {
4661
// TODO - Figure a way to properly use GLSL floatBitsToUint and print the float values
47-
strm << "OpRayQueryInitializeKHR operand Ray Tmin value is negative. ";
48-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349";
62+
strm << opcode_name << " operand Ray Tmin value is negative. ";
63+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11879"
64+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349";
4965
} break;
5066
case kErrorSubCodeRayQueryNegativeMax: {
51-
strm << "OpRayQueryInitializeKHR operand Ray Tmax value is negative. ";
52-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349";
67+
strm << opcode_name << " operand Ray Tmax value is negative. ";
68+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11879"
69+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349";
5370
} break;
5471
case kErrorSubCodeRayQueryMinMax: {
55-
strm << "OpRayQueryInitializeKHR operand Ray Tmax is less than RayTmin. ";
56-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06350";
72+
strm << opcode_name << " operand Ray Tmax is less than RayTmin. ";
73+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11880"
74+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06350";
5775
} break;
5876
case kErrorSubCodeRayQueryMinNaN: {
59-
strm << "OpRayQueryInitializeKHR operand Ray Tmin is NaN. ";
60-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
77+
strm << opcode_name << " operand Ray Tmin is NaN. ";
78+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11881"
79+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
6180
} break;
6281
case kErrorSubCodeRayQueryMaxNaN: {
63-
strm << "OpRayQueryInitializeKHR operand Ray Tmax is NaN. ";
64-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
82+
strm << opcode_name << " operand Ray Tmax is NaN. ";
83+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11881"
84+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
6585
} break;
6686
case kErrorSubCodeRayQueryOriginNaN: {
67-
strm << "OpRayQueryInitializeKHR operand Ray Origin contains a NaN. ";
68-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
87+
strm << opcode_name << " operand Ray Origin contains a NaN. ";
88+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11881"
89+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
6990
} break;
7091
case kErrorSubCodeRayQueryDirectionNaN: {
71-
strm << "OpRayQueryInitializeKHR operand Ray Direction contains a NaN. ";
72-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
92+
strm << opcode_name << " operand Ray Direction contains a NaN. ";
93+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11881"
94+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351";
7395
} break;
7496
case kErrorSubCodeRayQueryOriginFinite: {
75-
strm << "OpRayQueryInitializeKHR operand Ray Origin contains a non-finite value. ";
76-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06348";
97+
strm << opcode_name << " operand Ray Origin contains a non-finite value. ";
98+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11878"
99+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06348";
77100
} break;
78101
case kErrorSubCodeRayQueryDirectionFinite: {
79-
strm << "OpRayQueryInitializeKHR operand Ray Direction contains a non-finite value. ";
80-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06348";
102+
strm << opcode_name << " operand Ray Direction contains a non-finite value. ";
103+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11878"
104+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06348";
81105
} break;
82106
case kErrorSubCodeRayQueryBothSkip: {
83107
const uint32_t value = error_record[kInstRayQueryParamOffset_0];
84-
strm << "OpRayQueryInitializeKHR operand Ray Flags is 0x" << std::hex << value << ". ";
85-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06889";
108+
strm << opcode_name << " operand Ray Flags is 0x" << std::hex << value << ". ";
109+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11883"
110+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06889";
86111
} break;
87112
case kErrorSubCodeRayQuerySkipCull: {
88113
const uint32_t value = error_record[kInstRayQueryParamOffset_0];
89-
strm << "OpRayQueryInitializeKHR operand Ray Flags is 0x" << std::hex << value << ". ";
90-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06890";
114+
strm << opcode_name << " operand Ray Flags is 0x" << std::hex << value << ". ";
115+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11884"
116+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06890";
91117
} break;
92118
case kErrorSubCodeRayQueryOpaque: {
93119
const uint32_t value = error_record[kInstRayQueryParamOffset_0];
94-
strm << "OpRayQueryInitializeKHR operand Ray Flags is 0x" << std::hex << value << ". ";
95-
out_vuid_msg = "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06891";
120+
strm << opcode_name << " operand Ray Flags is 0x" << std::hex << value << ". ";
121+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11885"
122+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06891";
123+
} break;
124+
case kErrorSubCodeRayQuerySkipTrianglesWithPipelineSkipAABBs: {
125+
const uint32_t value = error_record[kInstRayQueryParamOffset_0];
126+
strm << opcode_name << " operand Ray Flags (0x" << std::hex << value
127+
<< ") contains SkipTrianglesKHR, but pipeline was created with VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR. ";
128+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11886"
129+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06553";
130+
} break;
131+
case kErrorSubCodeRayQuerySkipAABBsWithPipelineSkipTriangles: {
132+
const uint32_t value = error_record[kInstRayQueryParamOffset_0];
133+
strm << opcode_name << " operand Ray Flags (0x" << std::hex << value
134+
<< ") contains SkipAABBsKHR, but pipeline was created with VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR. ";
135+
out_vuid_msg = is_hit_object ? "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11887"
136+
: "VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06554";
137+
} break;
138+
case kErrorSubCodeRayQuerySBTIndexExceedsLimit: {
139+
// For this case, param_0 contains the SBT index and opcode_type slot contains the max SBT index
140+
const uint32_t sbt_index = error_record[kInstRayQueryParamOffset_0];
141+
const uint32_t max_sbt_index = error_record[kInstRayQueryOpcodeType];
142+
strm << "OpHitObjectSetShaderBindingTableRecordIndexEXT SBT index (" << std::dec << sbt_index
143+
<< ") exceeds VkPhysicalDeviceRayTracingInvocationReorderPropertiesEXT::maxShaderBindingTableRecordIndex (" << max_sbt_index << "). ";
144+
out_vuid_msg = "VUID-RuntimeSpirv-maxShaderBindingTableRecordIndex-11888";
145+
} break;
146+
case kErrorSubCodeRayQueryTimeOutOfRange: {
147+
strm << opcode_name << " operand time is not between 0.0 and 1.0. ";
148+
out_vuid_msg = "VUID-RuntimeSpirv-OpHitObjectTraceRayEXT-11882";
96149
} break;
97150
default:
98151
error_found = false;

layers/gpuav/shaders/gpuav_error_codes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ const int kErrorSubCodeRayQueryOriginNaN = 9;
9797
const int kErrorSubCodeRayQueryDirectionNaN = 10;
9898
const int kErrorSubCodeRayQueryOriginFinite = 11;
9999
const int kErrorSubCodeRayQueryDirectionFinite = 12;
100+
const int kErrorSubCodeRayQuerySkipTrianglesWithPipelineSkipAABBs = 13;
101+
const int kErrorSubCodeRayQuerySkipAABBsWithPipelineSkipTriangles = 14;
102+
const int kErrorSubCodeRayQuerySBTIndexExceedsLimit = 15;
103+
const int kErrorSubCodeRayQueryTimeOutOfRange = 16;
100104

101105
// MeshShading
102106
//

layers/gpuav/shaders/gpuav_error_header.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ const int kMeshShadingOutputPrimitivesMask = 0xFFFF;
159159
// Ray query
160160
// ---
161161
const int kInstRayQueryParamOffset_0 = kHeaderSize;
162+
// 0 = OpRayQueryInitializeKHR, 1 = OpHitObjectTraceRayEXT, 2 = OpHitObjectTraceReorderExecuteEXT,
163+
// 3 = OpHitObjectTraceRayMotionEXT, 4 = OpHitObjectTraceMotionReorderExecuteEXT
164+
const int kInstRayQueryOpcodeType = kHeaderSize + 1;
162165

163166
// Validation commands shaders
164167
// ---

layers/gpuav/shaders/instrumentation/ray_query.comp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,20 @@
2121
#include "common_descriptor_sets.h"
2222
#include "error_payload.h"
2323

24-
bool inst_ray_query_comp(const uint inst_offset, const uint ray_flags, const vec3 ray_origin, const float ray_tmin, const vec3 ray_direction, const float ray_tmax)
24+
// opcode_type: 0 = OpRayQueryInitializeKHR, 1 = OpHitObjectTraceRayEXT, 2 = OpHitObjectTraceReorderExecuteEXT,
25+
// 3 = OpHitObjectTraceRayMotionEXT, 4 = OpHitObjectTraceMotionReorderExecuteEXT
26+
// pipeline_flags: bit 0 = pipeline has SKIP_AABBS, bit 1 = pipeline has SKIP_TRIANGLES
27+
// time: motion time parameter (only valid for opcode_type 3 and 4, pass 0.0 for others)
28+
bool inst_ray_query_comp(const uint inst_offset, const uint opcode_type, const uint ray_flags, const vec3 ray_origin, const float ray_tmin, const vec3 ray_direction, const float ray_tmax, const uint pipeline_flags, const float time)
2529
{
2630
uint error = 0u;
2731
uint param_0 = 0u;
2832

29-
if (isnan(ray_tmin)) {
33+
// VUID 11882: time must be between 0.0 and 1.0 (only for motion opcodes)
34+
const bool is_motion_opcode = (opcode_type == 3 || opcode_type == 4);
35+
if (is_motion_opcode && (time < 0.0f || time > 1.0f)) {
36+
error = kErrorSubCodeRayQueryTimeOutOfRange;
37+
} else if (isnan(ray_tmin)) {
3038
error = kErrorSubCodeRayQueryMinNaN;
3139
} else if (isnan(ray_tmax)) {
3240
error = kErrorSubCodeRayQueryMaxNaN;
@@ -55,6 +63,10 @@ bool inst_ray_query_comp(const uint inst_offset, const uint ray_flags, const vec
5563
const uint SkipTrianglesKHR = 0x00000100;
5664
const uint SkipAABBsKHR = 0x00000200;
5765

66+
// Pipeline flags
67+
const uint kPipelineHasSkipAABBs = 0x1;
68+
const uint kPipelineHasSkipTriangles = 0x2;
69+
5870
const uint both_skip = SkipTrianglesKHR | SkipAABBsKHR;
5971
uint skip_cull_mask = ray_flags &(SkipTrianglesKHR | CullBackFacingTrianglesKHR | CullFrontFacingTrianglesKHR);
6072
uint opaque_mask = ray_flags &(OpaqueKHR | NoOpaqueKHR | CullOpaqueKHR | CullNoOpaqueKHR);
@@ -68,6 +80,14 @@ bool inst_ray_query_comp(const uint inst_offset, const uint ray_flags, const vec
6880
} else if (opaque_mask != 0 && ((opaque_mask & (opaque_mask - 1)) != 0)) {
6981
error = kErrorSubCodeRayQueryOpaque;
7082
param_0 = ray_flags;
83+
} else if ((ray_flags & SkipTrianglesKHR) != 0 && (pipeline_flags & kPipelineHasSkipAABBs) != 0) {
84+
// VUID 11886: SkipTriangles ray flag with pipeline SKIP_AABBS flag
85+
error = kErrorSubCodeRayQuerySkipTrianglesWithPipelineSkipAABBs;
86+
param_0 = ray_flags;
87+
} else if ((ray_flags & SkipAABBsKHR) != 0 && (pipeline_flags & kPipelineHasSkipTriangles) != 0) {
88+
// VUID 11887: SkipAABBs ray flag with pipeline SKIP_TRIANGLES flag
89+
error = kErrorSubCodeRayQuerySkipAABBsWithPipelineSkipTriangles;
90+
param_0 = ray_flags;
7191
}
7292
}
7393

@@ -76,11 +96,27 @@ bool inst_ray_query_comp(const uint inst_offset, const uint ray_flags, const vec
7696
inst_offset,
7797
SpecConstantLinkShaderId | (kErrorGroupInstRayQuery << kErrorGroupShift) | (error << kErrorSubCodeShift),
7898
param_0,
79-
0,
99+
opcode_type, // 0 = RayQuery, 1 = HitObject
80100
0
81101
);
82102
return false;
83103
}
84104

85105
return true;
86106
}
107+
108+
// Check for VUID 11888: SBT index must be <= maxShaderBindingTableRecordIndex
109+
bool inst_sbt_index_check(const uint inst_offset, const uint sbt_index, const uint max_sbt_index)
110+
{
111+
if (sbt_index > max_sbt_index) {
112+
error_payload = ErrorPayload(
113+
inst_offset,
114+
SpecConstantLinkShaderId | (kErrorGroupInstRayQuery << kErrorGroupShift) | (kErrorSubCodeRayQuerySBTIndexExceedsLimit << kErrorSubCodeShift),
115+
sbt_index,
116+
max_sbt_index,
117+
0
118+
);
119+
return false;
120+
}
121+
return true;
122+
}

layers/gpuav/spirv/module.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ struct Settings {
5454
bool support_non_semantic_info;
5555
bool has_bindless_descriptors;
5656

57+
// For ray tracing pipelines, stores relevant pipeline create flags for validation
58+
// Used to check VUIDs 11886/11887 (SkipTriangles vs SKIP_AABBS pipeline flag, etc.)
59+
bool pipeline_has_skip_aabbs_flag = false;
60+
bool pipeline_has_skip_triangles_flag = false;
61+
62+
// For VUID 11888 - maxShaderBindingTableRecordIndex limit check
63+
uint32_t max_shader_binding_table_record_index = 0;
64+
5765
// Used if need to report error/warning
5866
const Location& loc;
5967

0 commit comments

Comments
 (0)