diff options
author | Jason Macnak <jmacnak@nvidia.com> | 2019-07-09 15:47:02 -0700 |
---|---|---|
committer | Mark Lobodzinski <mark@lunarg.com> | 2019-07-17 11:43:33 -0600 |
commit | d218cbad77960f9aaa701f73f9bca5323c3710b2 (patch) | |
tree | 53281fc72b6453a121ce5d5b9426b32ef61e5a9e /tests/vklayertests_others.cpp | |
parent | 5c9549500debef00541c8f515bb0d870d7d1247d (diff) | |
download | vulkan-validation-layers-d218cbad77960f9aaa701f73f9bca5323c3710b2.tar.gz |
tests: Add acceleration structure validation tests
More extension information:
- https://www.khronos.org/registry/vulkan/specs/1.1-extensions/
html/vkspec.html#VK_NV_ray_tracing
Change-Id: I6eaf05a86c8dd1e7238ae22d762a5a048b58f37f
Diffstat (limited to 'tests/vklayertests_others.cpp')
-rw-r--r-- | tests/vklayertests_others.cpp | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/tests/vklayertests_others.cpp b/tests/vklayertests_others.cpp index b8eda5e28..5621654f2 100644 --- a/tests/vklayertests_others.cpp +++ b/tests/vklayertests_others.cpp @@ -4148,3 +4148,483 @@ TEST_F(VkLayerTest, WarningSwapchainCreateInfoPreTransform) { InitSwapchain(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR); m_errorMonitor->VerifyFound(); } + +bool InitFrameworkForRayTracingTest(VkRenderFramework *renderFramework, std::vector<const char *> &instance_extension_names, + std::vector<const char *> &device_extension_names, void *user_data) { + const std::array<const char *, 1> required_instance_extensions = {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}; + for (const char *required_instance_extension : required_instance_extensions) { + if (renderFramework->InstanceExtensionSupported(required_instance_extension)) { + instance_extension_names.push_back(required_instance_extension); + } else { + printf("%s %s instance extension not supported, skipping test\n", kSkipPrefix, required_instance_extension); + return false; + } + } + renderFramework->InitFramework(myDbgFunc, user_data); + + if (renderFramework->DeviceIsMockICD() || renderFramework->DeviceSimulation()) { + printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix); + return false; + } + + const std::array<const char *, 2> required_device_extensions = { + VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, + VK_NV_RAY_TRACING_EXTENSION_NAME, + }; + for (const char *required_device_extension : required_device_extensions) { + if (renderFramework->DeviceExtensionSupported(renderFramework->gpu(), nullptr, required_device_extension)) { + device_extension_names.push_back(required_device_extension); + } else { + printf("%s %s device extension not supported, skipping test\n", kSkipPrefix, required_device_extension); + return false; + } + } + renderFramework->InitState(); + return true; +} + +void GetSimpleGeometryForAccelerationStructureTests(const VkDeviceObj &device, VkBufferObj *vbo, VkBufferObj *ibo, + VkGeometryNV *geometry) { + vbo->init(device, 1024); + ibo->init(device, 1024); + + *geometry = {}; + geometry->sType = VK_STRUCTURE_TYPE_GEOMETRY_NV; + geometry->geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV; + geometry->geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV; + geometry->geometry.triangles.vertexData = vbo->handle(); + geometry->geometry.triangles.vertexOffset = 0; + geometry->geometry.triangles.vertexCount = 3; + geometry->geometry.triangles.vertexStride = 12; + geometry->geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT; + geometry->geometry.triangles.indexData = ibo->handle(); + geometry->geometry.triangles.indexOffset = 0; + geometry->geometry.triangles.indexCount = 3; + geometry->geometry.triangles.indexType = VK_INDEX_TYPE_UINT32; + geometry->geometry.triangles.transformData = VK_NULL_HANDLE; + geometry->geometry.triangles.transformOffset = 0; + geometry->geometry.aabbs = {}; + geometry->geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV; +} + +TEST_F(VkLayerTest, ValidateCreateAccelerationStructureNV) { + TEST_DESCRIPTION("Validate acceleration structure creation."); + if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) { + return; + } + + PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV = reinterpret_cast<PFN_vkCreateAccelerationStructureNV>( + vkGetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureNV")); + assert(vkCreateAccelerationStructureNV != nullptr); + + VkBufferObj vbo; + VkBufferObj ibo; + VkGeometryNV geometry; + GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry); + + VkAccelerationStructureCreateInfoNV as_create_info = {}; + as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; + as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + + // Top level can not have geometry + VkAccelerationStructureCreateInfoNV bad_top_level_create_info = as_create_info; + bad_top_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV; + bad_top_level_create_info.info.instanceCount = 0; + bad_top_level_create_info.info.geometryCount = 1; + bad_top_level_create_info.info.pGeometries = &geometry; + VkAccelerationStructureNV as = VK_NULL_HANDLE; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-type-02425"); + vkCreateAccelerationStructureNV(m_device->handle(), &bad_top_level_create_info, nullptr, &as); + m_errorMonitor->VerifyFound(); + + // Bot level can not have instances + VkAccelerationStructureCreateInfoNV bad_bot_level_create_info = as_create_info; + bad_bot_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + bad_bot_level_create_info.info.instanceCount = 1; + bad_bot_level_create_info.info.geometryCount = 0; + bad_bot_level_create_info.info.pGeometries = nullptr; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-type-02426"); + vkCreateAccelerationStructureNV(m_device->handle(), &bad_bot_level_create_info, nullptr, &as); + m_errorMonitor->VerifyFound(); + + // Can not prefer both fast trace and fast build + VkAccelerationStructureCreateInfoNV bad_flags_level_create_info = as_create_info; + bad_flags_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + bad_flags_level_create_info.info.instanceCount = 0; + bad_flags_level_create_info.info.geometryCount = 1; + bad_flags_level_create_info.info.pGeometries = &geometry; + bad_flags_level_create_info.info.flags = + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV | VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-flags-02592"); + vkCreateAccelerationStructureNV(m_device->handle(), &bad_flags_level_create_info, nullptr, &as); + m_errorMonitor->VerifyFound(); + + // Can not have geometry or instance for compacting + VkAccelerationStructureCreateInfoNV bad_compacting_as_create_info = as_create_info; + bad_compacting_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + bad_compacting_as_create_info.info.instanceCount = 0; + bad_compacting_as_create_info.info.geometryCount = 1; + bad_compacting_as_create_info.info.pGeometries = &geometry; + bad_compacting_as_create_info.info.flags = 0; + bad_compacting_as_create_info.compactedSize = 1024; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkAccelerationStructureCreateInfoNV-compactedSize-02421"); + vkCreateAccelerationStructureNV(m_device->handle(), &bad_compacting_as_create_info, nullptr, &as); + m_errorMonitor->VerifyFound(); +} + +TEST_F(VkLayerTest, ValidateBindAccelerationStructureNV) { + TEST_DESCRIPTION("Validate acceleration structure binding."); + if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) { + return; + } + + PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV = + reinterpret_cast<PFN_vkBindAccelerationStructureMemoryNV>( + vkGetDeviceProcAddr(m_device->handle(), "vkBindAccelerationStructureMemoryNV")); + assert(vkBindAccelerationStructureMemoryNV != nullptr); + + VkBufferObj vbo; + VkBufferObj ibo; + VkGeometryNV geometry; + GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry); + + VkAccelerationStructureCreateInfoNV as_create_info = {}; + as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; + as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + as_create_info.info.geometryCount = 1; + as_create_info.info.pGeometries = &geometry; + as_create_info.info.instanceCount = 0; + + VkAccelerationStructureObj as(*m_device, as_create_info, false); + m_errorMonitor->VerifyNotFound(); + + VkMemoryRequirements as_memory_requirements = as.memory_requirements().memoryRequirements; + + VkBindAccelerationStructureMemoryInfoNV as_bind_info = {}; + as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV; + as_bind_info.accelerationStructure = as.handle(); + + VkMemoryAllocateInfo as_memory_alloc = {}; + as_memory_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + as_memory_alloc.allocationSize = as_memory_requirements.size; + ASSERT_TRUE(m_device->phy().set_memory_type(as_memory_requirements.memoryTypeBits, &as_memory_alloc, 0)); + + // Can not bind already freed memory + { + VkDeviceMemory as_memory_freed = VK_NULL_HANDLE; + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_freed)); + vkFreeMemory(device(), as_memory_freed, NULL); + + VkBindAccelerationStructureMemoryInfoNV as_bind_info_freed = as_bind_info; + as_bind_info_freed.memory = as_memory_freed; + as_bind_info_freed.memoryOffset = 0; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkBindAccelerationStructureMemoryInfoNV-memory-parameter"); + (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_freed); + m_errorMonitor->VerifyFound(); + } + + // Can not bind with bad alignment + if (as_memory_requirements.alignment > 1) { + VkMemoryAllocateInfo as_memory_alloc_bad_alignment = as_memory_alloc; + as_memory_alloc_bad_alignment.allocationSize += 1; + + VkDeviceMemory as_memory_bad_alignment = VK_NULL_HANDLE; + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc_bad_alignment, NULL, &as_memory_bad_alignment)); + + VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_alignment = as_bind_info; + as_bind_info_bad_alignment.memory = as_memory_bad_alignment; + as_bind_info_bad_alignment.memoryOffset = 1; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-02594"); + (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_alignment); + m_errorMonitor->VerifyFound(); + + vkFreeMemory(device(), as_memory_bad_alignment, NULL); + } + + // Can not bind with offset outside the allocation + { + VkDeviceMemory as_memory_bad_offset = VK_NULL_HANDLE; + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_bad_offset)); + + VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_offset = as_bind_info; + as_bind_info_bad_offset.memory = as_memory_bad_offset; + as_bind_info_bad_offset.memoryOffset = + (as_memory_alloc.allocationSize + as_memory_requirements.alignment) & ~(as_memory_requirements.alignment - 1); + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-02451"); + (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_offset); + m_errorMonitor->VerifyFound(); + + vkFreeMemory(device(), as_memory_bad_offset, NULL); + } + + // Can not bind with offset that doesn't leave enough size + { + VkDeviceSize offset = (as_memory_requirements.size - 1) & ~(as_memory_requirements.alignment - 1); + if (offset > 0 && (as_memory_requirements.size < (as_memory_alloc.allocationSize - as_memory_requirements.alignment))) { + VkDeviceMemory as_memory_bad_offset = VK_NULL_HANDLE; + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_bad_offset)); + + VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_offset = as_bind_info; + as_bind_info_bad_offset.memory = as_memory_bad_offset; + as_bind_info_bad_offset.memoryOffset = offset; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkBindAccelerationStructureMemoryInfoNV-size-02595"); + (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_offset); + m_errorMonitor->VerifyFound(); + + vkFreeMemory(device(), as_memory_bad_offset, NULL); + } + } + + // Can not bind with memory that has unsupported memory type + { + VkPhysicalDeviceMemoryProperties memory_properties = {}; + vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memory_properties); + + uint32_t supported_memory_type_bits = as_memory_requirements.memoryTypeBits; + uint32_t unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~supported_memory_type_bits; + if (unsupported_mem_type_bits != 0) { + VkMemoryAllocateInfo as_memory_alloc_bad_type = as_memory_alloc; + ASSERT_TRUE(m_device->phy().set_memory_type(unsupported_mem_type_bits, &as_memory_alloc_bad_type, 0)); + + VkDeviceMemory as_memory_bad_type = VK_NULL_HANDLE; + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc_bad_type, NULL, &as_memory_bad_type)); + + VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_type = as_bind_info; + as_bind_info_bad_type.memory = as_memory_bad_type; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkBindAccelerationStructureMemoryInfoNV-memory-02593"); + (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_type); + m_errorMonitor->VerifyFound(); + + vkFreeMemory(device(), as_memory_bad_type, NULL); + } + } + + // Can not bind memory twice + { + VkAccelerationStructureObj as_twice(*m_device, as_create_info, false); + + VkDeviceMemory as_memory_twice_1 = VK_NULL_HANDLE; + VkDeviceMemory as_memory_twice_2 = VK_NULL_HANDLE; + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_twice_1)); + ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_twice_2)); + VkBindAccelerationStructureMemoryInfoNV as_bind_info_twice_1 = as_bind_info; + VkBindAccelerationStructureMemoryInfoNV as_bind_info_twice_2 = as_bind_info; + as_bind_info_twice_1.accelerationStructure = as_twice.handle(); + as_bind_info_twice_2.accelerationStructure = as_twice.handle(); + as_bind_info_twice_1.memory = as_memory_twice_1; + as_bind_info_twice_2.memory = as_memory_twice_2; + + ASSERT_VK_SUCCESS(vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_twice_1)); + m_errorMonitor->VerifyNotFound(); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkBindAccelerationStructureMemoryInfoNV-accelerationStructure-02450"); + (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_twice_2); + m_errorMonitor->VerifyFound(); + + vkFreeMemory(device(), as_memory_twice_1, NULL); + vkFreeMemory(device(), as_memory_twice_2, NULL); + } +} + +TEST_F(VkLayerTest, ValidateCmdBuildAccelerationStructureNV) { + TEST_DESCRIPTION("Validate acceleration structure building."); + if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) { + return; + } + + PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV = + reinterpret_cast<PFN_vkCmdBuildAccelerationStructureNV>( + vkGetDeviceProcAddr(m_device->handle(), "vkCmdBuildAccelerationStructureNV")); + assert(vkCmdBuildAccelerationStructureNV != nullptr); + + VkBufferObj vbo; + VkBufferObj ibo; + VkGeometryNV geometry; + GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry); + + VkAccelerationStructureCreateInfoNV bot_level_as_create_info = {}; + bot_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; + bot_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + bot_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + bot_level_as_create_info.info.instanceCount = 0; + bot_level_as_create_info.info.geometryCount = 1; + bot_level_as_create_info.info.pGeometries = &geometry; + + VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info); + m_errorMonitor->VerifyNotFound(); + + VkBufferObj bot_level_as_scratch; + bot_level_as.create_scratch_buffer(*m_device, &bot_level_as_scratch); + + // Command buffer must be in recording state + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-vkCmdBuildAccelerationStructureNV-commandBuffer-recording"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE, + bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyFound(); + + m_commandBuffer->begin(); + + // Incompatible type + VkAccelerationStructureInfoNV as_build_info_with_incompatible_type = bot_level_as_create_info.info; + as_build_info_with_incompatible_type.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV; + as_build_info_with_incompatible_type.instanceCount = 1; + as_build_info_with_incompatible_type.geometryCount = 0; + + // This is duplicated since it triggers one error for different types and one error for lower instance count - the + // build info is incompatible but still needs to be valid to get past the stateless checks. + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488"); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_type, VK_NULL_HANDLE, 0, VK_FALSE, + bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyFound(); + + // Incompatible flags + VkAccelerationStructureInfoNV as_build_info_with_incompatible_flags = bot_level_as_create_info.info; + as_build_info_with_incompatible_flags.flags = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_flags, VK_NULL_HANDLE, 0, + VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyFound(); + + // Incompatible build size + VkGeometryNV geometry_with_more_vertices = geometry; + geometry_with_more_vertices.geometry.triangles.vertexCount += 1; + + VkAccelerationStructureInfoNV as_build_info_with_incompatible_geometry = bot_level_as_create_info.info; + as_build_info_with_incompatible_geometry.pGeometries = &geometry_with_more_vertices; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_geometry, VK_NULL_HANDLE, 0, + VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyFound(); + + // Scratch buffer too small + VkBufferCreateInfo too_small_scratch_buffer_info = {}; + too_small_scratch_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + too_small_scratch_buffer_info.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV; + too_small_scratch_buffer_info.size = 1; + VkBufferObj too_small_scratch_buffer(*m_device, too_small_scratch_buffer_info); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02491"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE, + bot_level_as.handle(), VK_NULL_HANDLE, too_small_scratch_buffer.handle(), 0); + m_errorMonitor->VerifyFound(); + + // Scratch buffer with offset too small + VkDeviceSize scratch_buffer_offset = 5; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02491"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE, + bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), scratch_buffer_offset); + m_errorMonitor->VerifyFound(); + + // Src must have been built before + VkAccelerationStructureObj bot_level_as_updated(*m_device, bot_level_as_create_info); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02489"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_TRUE, + bot_level_as_updated.handle(), bot_level_as.handle(), bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyFound(); + + // Src must have been built before with the VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV flag + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE, + bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyNotFound(); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02489"); + vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_TRUE, + bot_level_as_updated.handle(), bot_level_as.handle(), bot_level_as_scratch.handle(), 0); + m_errorMonitor->VerifyFound(); +} + +TEST_F(VkLayerTest, ValidateGetAccelerationStructureHandleNV) { + TEST_DESCRIPTION("Validate acceleration structure handle querying."); + if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) { + return; + } + + PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV = + reinterpret_cast<PFN_vkGetAccelerationStructureHandleNV>( + vkGetDeviceProcAddr(m_device->handle(), "vkGetAccelerationStructureHandleNV")); + assert(vkGetAccelerationStructureHandleNV != nullptr); + + VkBufferObj vbo; + VkBufferObj ibo; + VkGeometryNV geometry; + GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry); + + VkAccelerationStructureCreateInfoNV bot_level_as_create_info = {}; + bot_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; + bot_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + bot_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + bot_level_as_create_info.info.instanceCount = 0; + bot_level_as_create_info.info.geometryCount = 1; + bot_level_as_create_info.info.pGeometries = &geometry; + + VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info); + m_errorMonitor->VerifyNotFound(); + + uint64_t handle = 0; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetAccelerationStructureHandleNV-dataSize-02240"); + vkGetAccelerationStructureHandleNV(m_device->handle(), bot_level_as.handle(), sizeof(uint8_t), &handle); + m_errorMonitor->VerifyFound(); +} + +TEST_F(VkLayerTest, ValidateCmdCopyAccelerationStructureNV) { + TEST_DESCRIPTION("Validate acceleration structure copying."); + if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) { + return; + } + + PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV = reinterpret_cast<PFN_vkCmdCopyAccelerationStructureNV>( + vkGetDeviceProcAddr(m_device->handle(), "vkCmdCopyAccelerationStructureNV")); + assert(vkCmdCopyAccelerationStructureNV != nullptr); + + VkBufferObj vbo; + VkBufferObj ibo; + VkGeometryNV geometry; + GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry); + + VkAccelerationStructureCreateInfoNV as_create_info = {}; + as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; + as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; + as_create_info.info.instanceCount = 0; + as_create_info.info.geometryCount = 1; + as_create_info.info.pGeometries = &geometry; + + VkAccelerationStructureObj src_as(*m_device, as_create_info); + VkAccelerationStructureObj dst_as(*m_device, as_create_info); + VkAccelerationStructureObj dst_as_without_mem(*m_device, as_create_info, false); + m_errorMonitor->VerifyNotFound(); + + // Command buffer must be in recording state + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-vkCmdCopyAccelerationStructureNV-commandBuffer-recording"); + vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(), + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV); + m_errorMonitor->VerifyFound(); + + m_commandBuffer->begin(); + + // Src must have been created with allow compaction flag + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyAccelerationStructureNV-src-02497"); + vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(), + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV); + m_errorMonitor->VerifyFound(); + + // Dst must have been bound with memory + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkAccelerationStructureNV"); + vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as_without_mem.handle(), src_as.handle(), + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV); + m_errorMonitor->VerifyFound(); +} |