| /* Copyright (c) 2023-2025 The Khronos Group Inc. |
| * Copyright (c) 2023-2025 Valve Corporation |
| * Copyright (c) 2023-2025 LunarG, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/pipeline_helper.h" |
| #include "../framework/descriptor_helper.h" |
| #include "../framework/ray_tracing_objects.h" |
| #include "../../layers/gpuav/shaders/gpuav_shaders_constants.h" |
| |
| class NegativeGpuAVRayQuery : public GpuAVRayQueryTest {}; |
| |
| TEST_F(NegativeGpuAVRayQuery, NegativeTmin) { |
| TEST_DESCRIPTION("Ray query with a negative value for Ray TMin"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform Uniforms { |
| float t_min; |
| float t_max; |
| } trace_rays_params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0), |
| trace_rays_params.t_min, vec3(0,0,1), trace_rays_params.t_max); |
| rayQueryProceedEXT(query); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer uniform_buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, uniform_buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto uniform_buffer_ptr = static_cast<float *>(uniform_buffer.Memory().Map()); |
| uniform_buffer_ptr[0] = -2.0f; // t_min |
| uniform_buffer_ptr[1] = 42.0f; // t_max |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, TMaxLessThenTmin) { |
| TEST_DESCRIPTION("Ray query with a Ray TMax less than Ray TMin"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform Uniforms { |
| float t_min; |
| float t_max; |
| } trace_rays_params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0), |
| trace_rays_params.t_min, vec3(0,0,1), trace_rays_params.t_max); |
| rayQueryProceedEXT(query); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer uniform_buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, uniform_buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto uniform_buffer_ptr = static_cast<float *>(uniform_buffer.Memory().Map()); |
| uniform_buffer_ptr[0] = 9.9f; // t_min |
| uniform_buffer_ptr[1] = 9.8f; // t_max |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06350"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, ComputeRayFlagsBothSkip) { |
| TEST_DESCRIPTION("Ray query in a compute shader, with dynamically set ray flags"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform Uniforms { |
| uint ray_query_flags; |
| } trace_rays_params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, trace_rays_params.ray_query_flags, 0xff, vec3(0), 0.1, vec3(0,0,1), 42.0); |
| rayQueryProceedEXT(query); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer uniform_buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, uniform_buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto uniform_buffer_ptr = static_cast<uint32_t *>(uniform_buffer.Memory().Map()); |
| uniform_buffer_ptr[0] = 0x100 | 0x200; // SkipTrianglesKHR and SkipAABBsKHR |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06889"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, ComputeRayFlagsOpaque) { |
| TEST_DESCRIPTION("Ray query in a compute shader, with dynamically set ray flags"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform Uniforms { |
| uint ray_query_flags; |
| } trace_rays_params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, trace_rays_params.ray_query_flags, 0xff, vec3(0), 0.1, vec3(0,0,1), 42.0); |
| rayQueryProceedEXT(query); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer uniform_buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, uniform_buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto uniform_buffer_ptr = static_cast<uint32_t *>(uniform_buffer.Memory().Map()); |
| uniform_buffer_ptr[0] = 0x1 | 0x2; // OpaqueKHR and NoOpaqueKHR |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06891"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, ComputeRayOriginNaN) { |
| TEST_DESCRIPTION("Ray query with a Ray Origin as a NaN"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform Uniforms { |
| float x; |
| float y; |
| } params; |
| |
| void main() { |
| rayQueryEXT query; |
| // fract(1.0 / 0.0) will produce a NaN |
| float bad = fract(params.x / params.y); |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0,bad,0), 1.0, vec3(0,0,1), 100); |
| rayQueryProceedEXT(query); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer uniform_buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, uniform_buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto uniform_buffer_ptr = static_cast<float *>(uniform_buffer.Memory().Map()); |
| uniform_buffer_ptr[0] = 1.0f; // x |
| uniform_buffer_ptr[1] = 0.0f; // y |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06351"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, ComputeRayOriginNonFinite) { |
| TEST_DESCRIPTION("Ray query with a Ray Origin as a non finite value"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform Uniforms { |
| float x; |
| float y; |
| } params; |
| |
| void main() { |
| rayQueryEXT query; |
| // 1.0 / 0.0 will produce positive infinity |
| float bad = 1.0 / params.x; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0,bad,0), 1.0, vec3(0,0,1), 100); |
| rayQueryProceedEXT(query); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer uniform_buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, uniform_buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto uniform_buffer_ptr = static_cast<float *>(uniform_buffer.Memory().Map()); |
| uniform_buffer_ptr[0] = 0.0f; // t_min |
| uniform_buffer_ptr[1] = 0.0f; // t_max |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06348"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, ComputeUseQueryUninit) { |
| TEST_DESCRIPTION("rayQueryInitializeEXT is never called, make sure we don't hang with an uninit query object"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| const char *shader_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) buffer SSBO { |
| float x; |
| float y; |
| } params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0,1,0), params.x, vec3(0,0,1), 100); |
| rayQueryProceedEXT(query); |
| if (rayQueryGetIntersectionTypeEXT(query, true) != gl_RayQueryCommittedIntersectionNoneEXT) { |
| params.y = rayQueryGetIntersectionTEXT(query, true); |
| } |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper pipeline(*this); |
| pipeline.cs_ = VkShaderObj(*m_device, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2); |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| pipeline.CreateComputePipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_.WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_.WriteDescriptorBufferInfo(1, buffer, 0, VK_WHOLE_SIZE, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| pipeline.descriptor_set_.UpdateDescriptorSets(); |
| |
| auto buffer_ptr = static_cast<float *>(buffer.Memory().Map()); |
| buffer_ptr[0] = -4.0f; // t_min |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.set_, 0, nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, RayGenUseQueryUninit) { |
| TEST_DESCRIPTION("rayQueryInitializeEXT is never called, make sure we don't hang with an uninit query object"); |
| AddRequiredExtensions(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::rayTracingPipeline); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| |
| vkt::rt::Pipeline pipeline(*this, m_device); |
| |
| const char *ray_gen = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(binding = 0, set = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) buffer SSBO { |
| float x; |
| float y; |
| } params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0,1,0), params.x, vec3(0,0,1), 100); |
| rayQueryProceedEXT(query); |
| if (rayQueryGetIntersectionTypeEXT(query, true) != gl_RayQueryCommittedIntersectionNoneEXT) { |
| params.y = rayQueryGetIntersectionTEXT(query, true); |
| } |
| } |
| )glsl"; |
| pipeline.SetGlslRayGenShader(ray_gen); |
| |
| pipeline.AddBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0); |
| pipeline.AddBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1); |
| pipeline.CreateDescriptorSet(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas(vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer)); |
| pipeline.GetDescriptorSet().WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer ssbo(*m_device, 4096, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, kHostVisibleMemProps); |
| auto buffer_ptr = static_cast<float *>(ssbo.Memory().Map()); |
| buffer_ptr[0] = -16.0f; |
| |
| pipeline.GetDescriptorSet().WriteDescriptorBufferInfo(1, ssbo, 0, 4096, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| |
| pipeline.GetDescriptorSet().UpdateDescriptorSets(); |
| |
| pipeline.Build(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.GetPipelineLayout(), 0, 1, |
| &pipeline.GetDescriptorSet().set_, 0, nullptr); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline); |
| vkt::rt::TraceRaysSbt trace_rays_sbt = pipeline.GetTraceRaysSbt(); |
| vk::CmdTraceRaysKHR(m_command_buffer, &trace_rays_sbt.ray_gen_sbt, &trace_rays_sbt.miss_sbt, &trace_rays_sbt.hit_sbt, |
| &trace_rays_sbt.callable_sbt, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, RayGenUseQueryUninitSelectShaders) { |
| TEST_DESCRIPTION( |
| "rayQueryInitializeEXT is never called, make sure we don't hang with an uninit query object. Selectively instrument ray " |
| "gen shader"); |
| AddRequiredExtensions(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::rayTracingPipeline); |
| AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::vertexPipelineStoresAndAtomics); |
| std::vector<VkLayerSettingEXT> layer_settings(2); |
| layer_settings[0] = {OBJECT_LAYER_NAME, "gpuav_select_instrumented_shaders", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkTrue}; |
| std::array<const char *, 3> shader_regexes = {{"vertex_foo", "fragment_.*", ".*ray.*"}}; |
| layer_settings[1] = {OBJECT_LAYER_NAME, "gpuav_shaders_to_instrument", VK_LAYER_SETTING_TYPE_STRING_EXT, size32(shader_regexes), |
| shader_regexes.data()}; |
| |
| RETURN_IF_SKIP(InitGpuAVRayQuery(layer_settings)); |
| |
| vkt::rt::Pipeline pipeline(*this, m_device); |
| |
| const char *ray_gen = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(binding = 0, set = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) buffer SSBO { |
| float x; |
| float y; |
| } params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0,1,0), params.x, vec3(0,0,1), 100); |
| rayQueryProceedEXT(query); |
| if (rayQueryGetIntersectionTypeEXT(query, true) != gl_RayQueryCommittedIntersectionNoneEXT) { |
| params.y = rayQueryGetIntersectionTEXT(query, true); |
| } |
| } |
| )glsl"; |
| pipeline.SetGlslRayGenShader(ray_gen); |
| VkShaderObj &ray_gen_shader = pipeline.GetRayGenShader(0); |
| VkDebugUtilsObjectNameInfoEXT name_info = vku::InitStructHelper(); |
| name_info.objectType = VK_OBJECT_TYPE_SHADER_MODULE; |
| name_info.pObjectName = "my_oh_my_ray_gen"; |
| name_info.objectHandle = uint64_t(ray_gen_shader.handle()); |
| vk::SetDebugUtilsObjectNameEXT(device(), &name_info); |
| |
| pipeline.AddBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0); |
| pipeline.AddBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1); |
| pipeline.CreateDescriptorSet(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas(vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer)); |
| pipeline.GetDescriptorSet().WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer ssbo(*m_device, 4096, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, kHostVisibleMemProps); |
| auto buffer_ptr = static_cast<float *>(ssbo.Memory().Map()); |
| buffer_ptr[0] = -16.0f; |
| |
| pipeline.GetDescriptorSet().WriteDescriptorBufferInfo(1, ssbo, 0, 4096, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| |
| pipeline.GetDescriptorSet().UpdateDescriptorSets(); |
| |
| m_errorMonitor->SetDesiredInfo("my_oh_my_ray_gen"); |
| pipeline.Build(); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.GetPipelineLayout(), 0, 1, |
| &pipeline.GetDescriptorSet().set_, 0, nullptr); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline); |
| vkt::rt::TraceRaysSbt trace_rays_sbt = pipeline.GetTraceRaysSbt(); |
| vk::CmdTraceRaysKHR(m_command_buffer, &trace_rays_sbt.ray_gen_sbt, &trace_rays_sbt.miss_sbt, &trace_rays_sbt.hit_sbt, |
| &trace_rays_sbt.callable_sbt, 1, 1, 1); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349"); |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeGpuAVRayQuery, FragmentUseQueryUninit) { |
| TEST_DESCRIPTION("rayQueryInitializeEXT is never called, make sure we don't hang with an uninit query object"); |
| RETURN_IF_SKIP(InitGpuAVRayQuery()); |
| InitRenderTarget(); |
| |
| const char *fragment_source = R"glsl( |
| #version 460 |
| #extension GL_EXT_ray_query : require |
| |
| layout(location=0) out vec4 color; |
| layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas; |
| layout(set = 0, binding = 1) uniform SSBO { |
| float x; |
| } params; |
| |
| void main() { |
| rayQueryEXT query; |
| rayQueryInitializeEXT(query, tlas, gl_RayFlagsTerminateOnFirstHitEXT, 0xff, vec3(0,1,0), params.x, vec3(0,0,1), 100); |
| rayQueryProceedEXT(query); |
| float x = 0.0; |
| if (rayQueryGetIntersectionTypeEXT(query, true) != gl_RayQueryCommittedIntersectionNoneEXT) { |
| x = rayQueryGetIntersectionTEXT(query, true); |
| } |
| color = vec4(x); |
| } |
| )glsl"; |
| VkShaderObj vs(*m_device, kVertexDrawPassthroughGlsl, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj fs(*m_device, fragment_source, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| CreatePipelineHelper pipeline(*this); |
| pipeline.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| pipeline.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}}; |
| pipeline.CreateGraphicsPipeline(); |
| |
| vkt::as::BuildGeometryInfoKHR tlas = vkt::as::blueprint::BuildOnDeviceTopLevel(*m_device, *m_default_queue, m_command_buffer); |
| pipeline.descriptor_set_->WriteDescriptorAccelStruct(0, 1, &tlas.GetDstAS()->handle()); |
| |
| vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, kHostVisibleMemProps); |
| pipeline.descriptor_set_->WriteDescriptorBufferInfo(1, buffer, 0, VK_WHOLE_SIZE); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| auto buffer_ptr = static_cast<float *>(buffer.Memory().Map()); |
| buffer_ptr[0] = -4.0f; // t_min |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_->set_, 0, nullptr); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpRayQueryInitializeKHR-06349", gpuav::glsl::kMaxErrorsPerCmd); |
| |
| m_default_queue->Submit(m_command_buffer); |
| m_device->Wait(); |
| m_errorMonitor->VerifyFound(); |
| } |