Update bottom AS's addresses during top AS deserialization
authormichal_jakubek <michal.jakubek@mobica.com>
Wed, 12 May 2021 08:53:39 +0000 (10:53 +0200)
committermichal_jakubek <michal.jakubek@mobica.com>
Fri, 2 Jul 2021 06:21:55 +0000 (08:21 +0200)
SerialStorage class has been adorned with an additional constructor
which allows to serialize or deserialize a deep copy of top-level
acceleration structure, it means top-level AS together with bottom-level
acceleration structures that it owns. In other words it reconstructs all
stuff that has been stored during serialization process.
A deserializing from SerialStorage created this way updates bottom-level
acceleration structure addresses in the top-level AS's header.

New tests:
dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.*

Components: Vulkan

VK-GL-CTS issue: 2830

Change-Id: I2e92e6a83dc9dcba67fa74b12fbfcafb4ae4c0c6

android/cts/master/vk-master-2021-03-01/ray-tracing-pipeline.txt
android/cts/master/vk-master/ray-tracing-pipeline.txt
external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp
external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp
external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingAccelerationStructuresTests.cpp
external/vulkancts/mustpass/master/vk-default/ray-tracing-pipeline.txt

index d891276..d3aac1c 100644 (file)
@@ -8063,6 +8063,12 @@ dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.cpu_
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.cpu_built.bottom
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.gpu_built.top
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.gpu_built.bottom
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.the_same_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.different_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.mix_same_diff_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.the_same_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.different_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.mix_same_diff_instances
 dEQP-VK.ray_tracing_pipeline.procedural_geometry.object_behind_bounding_boxes
 dEQP-VK.ray_tracing_pipeline.procedural_geometry.triangle_in_between
 dEQP-VK.ray_tracing_pipeline.indirect.build_structure
index d891276..d3aac1c 100644 (file)
@@ -8063,6 +8063,12 @@ dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.cpu_
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.cpu_built.bottom
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.gpu_built.top
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.gpu_built.bottom
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.the_same_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.different_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.mix_same_diff_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.the_same_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.different_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.mix_same_diff_instances
 dEQP-VK.ray_tracing_pipeline.procedural_geometry.object_behind_bounding_boxes
 dEQP-VK.ray_tracing_pipeline.procedural_geometry.triangle_in_between
 dEQP-VK.ray_tracing_pipeline.indirect.build_structure
index aeaf739..66adb74 100644 (file)
@@ -27,6 +27,7 @@
 #include "vkQueryUtil.hpp"
 #include "vkObjUtil.hpp"
 #include "vkBarrierUtil.hpp"
+#include "vkCmdUtil.hpp"
 
 #include "deStringUtil.hpp"
 
@@ -350,6 +351,23 @@ static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (const DeviceI
        return result;
 }
 
+static inline Move<VkQueryPool> makeQueryPool (const DeviceInterface&          vk,
+                                                                                          const VkDevice                               device,
+                                                                                          const VkQueryType                    queryType,
+                                                                                          deUint32                                     queryCount)
+{
+       const VkQueryPoolCreateInfo                             queryPoolCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,               // sType
+               DE_NULL,                                                                                // pNext
+               (VkQueryPoolCreateFlags)0,                                              // flags
+               queryType,                                                                              // queryType
+               queryCount,                                                                             // queryCount
+               0u,                                                                                             // pipelineStatistics
+       };
+       return createQueryPool(vk, device, &queryPoolCreateInfo);
+}
+
 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryTrianglesDataKHR& triangles)
 {
        VkAccelerationStructureGeometryDataKHR result;
@@ -536,8 +554,8 @@ SerialStorage::SerialStorage (const DeviceInterface&                                                                        vk,
                                                          Allocator&                                                                                            allocator,
                                                          const VkAccelerationStructureBuildTypeKHR                                     buildType,
                                                          const VkDeviceSize                                                                            storageSize)
-       : m_buildType (buildType)
-       , m_storageSize(storageSize)
+       : m_buildType           (buildType)
+       , m_storageSize         (storageSize)
 {
        const VkBufferCreateInfo        bufferCreateInfo        = makeBufferCreateInfo(storageSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
        try
@@ -551,6 +569,41 @@ SerialStorage::SerialStorage (const DeviceInterface&                                                                       vk,
        }
 }
 
+SerialStorage::SerialStorage (const DeviceInterface&                                           vk,
+                                                         const VkDevice                                                                device,
+                                                         Allocator&                                                                    allocator,
+                                                         const VkAccelerationStructureBuildTypeKHR             buildType,
+                                                         const SerialInfo&                                                             serialInfo)
+       : m_buildType           (buildType)
+       , m_storageSize         (serialInfo.sizes()[0]) // raise assertion if serialInfo is empty
+       , m_serialInfo          (serialInfo)
+{
+       DE_ASSERT(serialInfo.sizes().size() >= 2u);
+
+       // create buffer for top-level acceleration structure
+       {
+               const VkBufferCreateInfo        bufferCreateInfo        = makeBufferCreateInfo(m_storageSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+               m_buffer                                                                                = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
+       }
+
+       // create buffers for bottom-level acceleration structures
+       {
+               std::vector<deUint64>   addrs;
+
+               for (std::size_t i = 1; i < serialInfo.addresses().size(); ++i)
+               {
+                       const deUint64& lookAddr = serialInfo.addresses()[i];
+                       auto end = addrs.end();
+                       auto match = std::find_if(addrs.begin(), end, [&](const deUint64& item){ return item == lookAddr; });
+                       if (match == end)
+                       {
+                               addrs.emplace_back(lookAddr);
+                               m_bottoms.emplace_back(de::SharedPtr<SerialStorage>(new SerialStorage(vk, device, allocator, buildType, serialInfo.sizes()[i])));
+                       }
+               }
+       }
+}
+
 VkDeviceOrHostAddressKHR SerialStorage::getAddress (const DeviceInterface&                             vk,
                                                                                                        const VkDevice                                          device)
 {
@@ -560,9 +613,30 @@ VkDeviceOrHostAddressKHR SerialStorage::getAddress (const DeviceInterface&                         vk
                return makeDeviceOrHostAddressKHR(m_buffer->getAllocation().getHostPtr());
 }
 
-VkDeviceOrHostAddressConstKHR SerialStorage::getHostAddressConst()
+SerialStorage::AccelerationStructureHeader* SerialStorage::getASHeader ()
+{
+       return reinterpret_cast<AccelerationStructureHeader*>(getHostAddress().hostAddress);
+}
+
+bool SerialStorage::hasDeepFormat () const
+{
+       return (m_serialInfo.sizes().size() >= 2u);
+}
+
+de::SharedPtr<SerialStorage> SerialStorage::getBottomStorage (deUint32 index) const
+{
+       return m_bottoms[index];
+}
+
+VkDeviceOrHostAddressKHR SerialStorage::getHostAddress (VkDeviceSize offset)
 {
-       return makeDeviceOrHostAddressConstKHR(m_buffer->getAllocation().getHostPtr());
+       DE_ASSERT(offset < m_storageSize);
+       return makeDeviceOrHostAddressKHR(static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr()) + offset);
+}
+
+VkDeviceOrHostAddressConstKHR SerialStorage::getHostAddressConst (VkDeviceSize offset)
+{
+       return makeDeviceOrHostAddressConstKHR(static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr()) + offset);
 }
 
 VkDeviceOrHostAddressConstKHR SerialStorage::getAddressConst (const DeviceInterface&   vk,
@@ -574,11 +648,16 @@ VkDeviceOrHostAddressConstKHR SerialStorage::getAddressConst (const DeviceInterf
                return getHostAddressConst();
 }
 
-VkDeviceSize SerialStorage::getStorageSize ()
+inline VkDeviceSize SerialStorage::getStorageSize () const
 {
        return m_storageSize;
 }
 
+inline const SerialInfo& SerialStorage::getSerialInfo () const
+{
+       return m_serialInfo;
+}
+
 deUint64 SerialStorage::getDeserializedSize ()
 {
        deUint64                result          = 0;
@@ -1480,7 +1559,7 @@ void TopLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface&
        copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u);
 }
 
-void TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
+void TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface&                                   vk,
                                                                                                                          const VkDevice                                                        device,
                                                                                                                          const VkCommandBuffer                                         cmdBuffer,
                                                                                                                          Allocator&                                                            allocator,
@@ -1490,6 +1569,7 @@ void TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterf
        DE_ASSERT(storage != NULL);
        DE_ASSERT(storage->getStorageSize() >= SerialStorage::SERIAL_STORAGE_SIZE_MIN);
        create(vk, device, allocator, storage->getDeserializedSize(), deviceAddress);
+       if (storage->hasDeepFormat()) createAndDeserializeBottoms(vk, device, cmdBuffer, allocator, storage);
        deserialize(vk, device, cmdBuffer, storage);
 }
 
@@ -1636,6 +1716,15 @@ public:
                                                                                                                                                                                                                                 const VkCommandBuffer                                                  cmdBuffer,
                                                                                                                                                                                                                                 SerialStorage*                                                                 storage) override;
 
+       std::vector<VkDeviceSize>                                                               getSerializingSizes                                                                     (const DeviceInterface&                                                 vk,
+                                                                                                                                                                                                                                const VkDevice                                                                 device,
+                                                                                                                                                                                                                                const VkQueue                                                                  queue,
+                                                                                                                                                                                                                                const deUint32                                                                 queueFamilyIndex) override;
+
+       std::vector<deUint64>                                                                   getSerializingAddresses                                                         (const DeviceInterface&                                                 vk,
+                                                                                                                                                                                                                                const VkDevice                                                                 device) const override;
+
+
        const VkAccelerationStructureKHR*                                               getPtr                                                                                          (void) const override;
 
        void                                                                                                    updateInstanceMatrix                                                            (const DeviceInterface&                                                 vk,
@@ -1664,10 +1753,23 @@ protected:
        deUint32                                                                                                m_indirectBufferStride;
        bool                                                                                                    m_usePPGeometries;
 
+
        void                                                                                                    prepareInstances                                                                        (const DeviceInterface&                                                 vk,
                                                                                                                                                                                                                                 const VkDevice                                                                 device,
                                                                                                                                                                                                                                 VkAccelerationStructureGeometryKHR&                    accelerationStructureGeometryKHR,
                                                                                                                                                                                                                                 std::vector<deUint32>&                                                 maxPrimitiveCounts);
+
+       void                                                                                                    serializeBottoms                                                                        (const DeviceInterface&                                                 vk,
+                                                                                                                                                                                                                                const VkDevice                                                                 device,
+                                                                                                                                                                                                                                const VkCommandBuffer                                                  cmdBuffer,
+                                                                                                                                                                                                                                SerialStorage*                                                                 storage,
+                                                                                                                                                                                                                                VkDeferredOperationKHR                                                 deferredOperation);
+
+       void                                                                                                    createAndDeserializeBottoms                                                     (const DeviceInterface&                                                 vk,
+                                                                                                                                                                                                                                const VkDevice                                                                 device,
+                                                                                                                                                                                                                                const VkCommandBuffer                                                  cmdBuffer,
+                                                                                                                                                                                                                                Allocator&                                                                             allocator,
+                                                                                                                                                                                                                                SerialStorage*                                                                 storage) override;
 };
 
 deUint32 TopLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
@@ -2038,17 +2140,19 @@ void TopLevelAccelerationStructureKHR::serialize (const DeviceInterface&        vk,
                VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR,       // VkStructureType                                              sType;
                DE_NULL,                                                                                                                        // const void*                                                  pNext;
                *(getPtr()),                                                                                                            // VkAccelerationStructureKHR                   src;
-               storage->getAddress(vk,device),                                                                         // VkDeviceOrHostAddressKHR                             dst;
+               storage->getAddress(vk, device),                                                                        // VkDeviceOrHostAddressKHR                             dst;
                VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR                                       // VkCopyAccelerationStructureModeKHR   mode;
        };
 
        if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
        {
                vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, &copyAccelerationStructureInfo);
+               if (storage->hasDeepFormat()) serializeBottoms(vk, device, cmdBuffer, storage, DE_NULL);
        }
        else if (!m_deferredOperation)
        {
                VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, &copyAccelerationStructureInfo));
+               if (storage->hasDeepFormat()) serializeBottoms(vk, device, cmdBuffer, storage, DE_NULL);
        }
        else
        {
@@ -2058,6 +2162,7 @@ void TopLevelAccelerationStructureKHR::serialize (const DeviceInterface&  vk,
                const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, &copyAccelerationStructureInfo);
 
                DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
+               if (storage->hasDeepFormat()) serializeBottoms(vk, device, cmdBuffer, storage, deferredOperation);
 
                finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
        }
@@ -2109,6 +2214,154 @@ void TopLevelAccelerationStructureKHR::deserialize (const DeviceInterface&      vk,
        }
 }
 
+void TopLevelAccelerationStructureKHR::serializeBottoms (const DeviceInterface&        vk,
+                                                                                                                const VkDevice                 device,
+                                                                                                                const VkCommandBuffer  cmdBuffer,
+                                                                                                                SerialStorage*                 storage,
+                                                                                                                VkDeferredOperationKHR deferredOperation)
+{
+       DE_UNREF(deferredOperation);
+       DE_ASSERT(storage->hasDeepFormat());
+
+       const std::vector<deUint64>&    addresses               = storage->getSerialInfo().addresses();
+       const std::size_t                               cbottoms                = m_bottomLevelInstances.size();
+
+       deUint32                                                storageIndex    = 0;
+       std::vector<deUint64>                   matches;
+
+       for (std::size_t i = 0; i < cbottoms; ++i)
+       {
+               const deUint64& lookAddr        = addresses[i+1];
+               auto                    end                     = matches.end();
+               auto                    match           = std::find_if(matches.begin(), end, [&](const deUint64& item){ return item == lookAddr; });
+               if (match == end)
+               {
+                       matches.emplace_back(lookAddr);
+                       m_bottomLevelInstances[i].get()->serialize(vk, device, cmdBuffer, storage->getBottomStorage(storageIndex).get());
+                       storageIndex += 1;
+               }
+       }
+}
+
+void TopLevelAccelerationStructureKHR::createAndDeserializeBottoms (const DeviceInterface&     vk,
+                                                                                                                                       const VkDevice                  device,
+                                                                                                                                       const VkCommandBuffer   cmdBuffer,
+                                                                                                                                       Allocator&                              allocator,
+                                                                                                                                       SerialStorage*                  storage)
+{
+       DE_ASSERT(storage->hasDeepFormat());
+       DE_ASSERT(m_bottomLevelInstances.size() == 0);
+
+       const std::vector<deUint64>&                                    addresses               = storage->getSerialInfo().addresses();
+       const std::size_t                                                               cbottoms                = addresses.size() - 1;
+       deUint32                                                                                storageIndex    = 0;
+       std::vector<std::pair<deUint64, std::size_t>>   matches;
+
+       for (std::size_t i = 0; i < cbottoms; ++i)
+       {
+               const deUint64& lookAddr        = addresses[i+1];
+               auto                    end                     = matches.end();
+               auto                    match           = std::find_if(matches.begin(), end, [&](const std::pair<deUint64, deUint32>& item){ return item.first == lookAddr; });
+               if (match != end)
+               {
+                       m_bottomLevelInstances .emplace_back(m_bottomLevelInstances[match->second]);
+               }
+               else
+               {
+                       de::MovePtr<BottomLevelAccelerationStructure> blas = makeBottomLevelAccelerationStructure();
+                       blas->createAndDeserializeFrom(vk, device, cmdBuffer, allocator, storage->getBottomStorage(storageIndex).get());
+                       m_bottomLevelInstances.emplace_back(de::SharedPtr<BottomLevelAccelerationStructure>(blas.release()));
+                       matches.emplace_back(lookAddr, i);
+                       storageIndex += 1;
+               }
+       }
+
+       std::vector<deUint64>                                           newAddresses    = getSerializingAddresses(vk, device);
+       DE_ASSERT(addresses.size() == newAddresses.size());
+
+       SerialStorage::AccelerationStructureHeader* header                      = storage->getASHeader();
+       DE_ASSERT(cbottoms ==header->handleCount);
+
+       // finally update bottom-level AS addresses before top-level AS deserialization
+       for (std::size_t i = 0; i < cbottoms; ++i)
+       {
+               header->handleArray[i] = newAddresses[i+1];
+       }
+}
+
+std::vector<VkDeviceSize> TopLevelAccelerationStructureKHR::getSerializingSizes (const DeviceInterface&        vk,
+                                                                                                                                                                const VkDevice                 device,
+                                                                                                                                                                const VkQueue                  queue,
+                                                                                                                                                                const deUint32                 queueFamilyIndex)
+{
+       const deUint32                                                  queryCount(deUint32(m_bottomLevelInstances.size()) + 1);
+       std::vector<VkAccelerationStructureKHR> handles(queryCount);
+       std::vector<VkDeviceSize>                               sizes(queryCount);
+
+       handles[0] = m_accelerationStructureKHR.get();
+
+       for (deUint32 h = 1; h < queryCount; ++h)
+               handles[h] = *m_bottomLevelInstances[h-1].get()->getPtr();
+
+       if (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR == m_buildType)
+               queryAccelerationStructureSize(vk, device, DE_NULL, handles, m_buildType, DE_NULL, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, sizes);
+       else
+       {
+               const Move<VkCommandPool>       cmdPool         = createCommandPool(vk, device, 0, queueFamilyIndex);
+               const Move<VkCommandBuffer>     cmdBuffer       = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+               const Move<VkQueryPool>         queryPool       = makeQueryPool(vk, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
+
+               beginCommandBuffer(vk, *cmdBuffer);
+               queryAccelerationStructureSize(vk, device, *cmdBuffer, handles, m_buildType, *queryPool, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, sizes);
+               endCommandBuffer(vk, *cmdBuffer);
+               submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
+
+               VK_CHECK(vk.getQueryPoolResults(device, *queryPool, 0u, queryCount, queryCount * sizeof(VkDeviceSize), sizes.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
+       }
+
+       return sizes;
+}
+
+std::vector<deUint64> TopLevelAccelerationStructureKHR::getSerializingAddresses (const DeviceInterface& vk, const VkDevice device) const
+{
+       std::vector<deUint64> result(m_bottomLevelInstances.size() + 1);
+
+       VkAccelerationStructureDeviceAddressInfoKHR asDeviceAddressInfo =
+       {
+               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,       // VkStructureType                              sType;
+               DE_NULL,                                                                                                                        // const void*                                  pNext;
+               DE_NULL                                                                                                                         // VkAccelerationStructureKHR   accelerationStructure;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               asDeviceAddressInfo.accelerationStructure = m_accelerationStructureKHR.get();
+               result[0] = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo);
+       }
+       else
+       {
+               result[0] = deUint64(getPtr()->getInternal());
+       }
+
+       for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
+       {
+               const BottomLevelAccelerationStructure&         bottomLevelAccelerationStructure        = *m_bottomLevelInstances[instanceNdx];
+               const VkAccelerationStructureKHR                        accelerationStructureKHR                        = *bottomLevelAccelerationStructure.getPtr();
+
+               if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+               {
+                       asDeviceAddressInfo.accelerationStructure = accelerationStructureKHR;
+                       result[instanceNdx+1] = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo);
+               }
+               else
+               {
+                       result[instanceNdx+1] = deUint64(accelerationStructureKHR.getInternal());
+               }
+       }
+
+       return result;
+}
+
 const VkAccelerationStructureKHR* TopLevelAccelerationStructureKHR::getPtr (void) const
 {
        return &m_accelerationStructureKHR.get();
index 5d0e45f..d5b2c89 100644 (file)
@@ -463,6 +463,27 @@ VkDeviceAddress getBufferDeviceAddress ( const DeviceInterface&    vkd,
                                                                                 const VkBuffer                 buffer,
                                                                                 VkDeviceSize                   offset );
 
+// type used for creating a deep serialization/deserialization of top-level acceleration structures
+class SerialInfo
+{
+       std::vector<deUint64>           m_addresses;
+       std::vector<VkDeviceSize>       m_sizes;
+public:
+
+       SerialInfo() = default;
+
+       // addresses: { (owner-top-level AS address) [, (first bottom_level AS address), (second bottom_level AS address), ...] }
+       // sizes:     { (owner-top-level AS serial size) [, (first bottom_level AS serial size), (second bottom_level AS serial size), ...] }
+       SerialInfo(const std::vector<deUint64>& addresses, const std::vector<VkDeviceSize>& sizes)
+               : m_addresses(addresses), m_sizes(sizes)
+       {
+               DE_ASSERT(!addresses.empty() && addresses.size() == sizes.size());
+       }
+
+       const std::vector<deUint64>&            addresses                       () const        { return m_addresses; }
+       const std::vector<VkDeviceSize>&        sizes                           () const        { return m_sizes; }
+};
+
 class SerialStorage
 {
 public:
@@ -476,28 +497,60 @@ public:
                SERIAL_STORAGE_SIZE_MIN
        };
 
+       // An old fashion C-style structure that simplifies an access to the AS header
+       struct alignas(16) AccelerationStructureHeader
+       {
+               union {
+                       struct {
+                               deUint8 driverUUID[VK_UUID_SIZE];
+                               deUint8 compactUUID[VK_UUID_SIZE];
+                       };
+                       deUint8         uuids[VK_UUID_SIZE * 2];
+               };
+               deUint64                serializedSize;
+               deUint64                deserializedSize;
+               deUint64                handleCount;
+               VkDeviceAddress handleArray[1];
+       };
+
                                                                                        SerialStorage           () = delete;
                                                                                        SerialStorage           (const DeviceInterface&                                         vk,
                                                                                                                                 const VkDevice                                                         device,
                                                                                                                                 Allocator&                                                                     allocator,
                                                                                                                                 const VkAccelerationStructureBuildTypeKHR      buildType,
                                                                                                                                 const VkDeviceSize                                                     storageSize);
+       // An additional constructor for creating a deep copy of top-level AS's.
+                                                                                       SerialStorage           (const DeviceInterface&                                         vk,
+                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                const VkAccelerationStructureBuildTypeKHR      buildType,
+                                                                                                                                const SerialInfo&                                                      SerialInfo);
 
-       // this method will return host addres if acc was build on cpu and device addres when it was build on gpu
+       // below methods will return host addres if AS was build on cpu and device addres when it was build on gpu
        VkDeviceOrHostAddressKHR                                getAddress                      (const DeviceInterface& vk,
                                                                                                                                 const VkDevice                 device);
-       // this method retuns host addres regardles of where acc was build
-       VkDeviceOrHostAddressConstKHR                   getHostAddressConst     ();
        VkDeviceOrHostAddressConstKHR                   getAddressConst         (const DeviceInterface& vk,
                                                                                                                                 const VkDevice                 device);
-       VkDeviceSize                                                    getStorageSize          ();
+
+       // this methods retun host address regardless of where AS was built
+       VkDeviceOrHostAddressKHR                                getHostAddress          (VkDeviceSize                   offset = 0);
+       VkDeviceOrHostAddressConstKHR                   getHostAddressConst     (VkDeviceSize                   offset = 0);
+
+       // works the similar way as getHostAddressConst() but returns more readable/intuitive object
+       AccelerationStructureHeader*                    getASHeader                     ();
+       bool                                                                    hasDeepFormat           () const;
+       de::SharedPtr<SerialStorage>                    getBottomStorage        (deUint32                       index) const;
+
+       VkDeviceSize                                                    getStorageSize          () const;
+       const SerialInfo&                                               getSerialInfo           () const;
        deUint64                                                                getDeserializedSize     ();
 
 protected:
-       VkAccelerationStructureBuildTypeKHR             m_buildType;
-       de::MovePtr<BufferWithMemory>                   m_buffer;
-       VkDeviceSize                                                    m_storageSize;
-
+       const VkAccelerationStructureBuildTypeKHR       m_buildType;
+       const VkDeviceSize                                                      m_storageSize;
+       const SerialInfo                                                        m_serialInfo;
+       de::MovePtr<BufferWithMemory>                           m_buffer;
+       std::vector<de::SharedPtr<SerialStorage>>       m_bottoms;
 };
 
 class BottomLevelAccelerationStructure
@@ -663,6 +716,14 @@ public:
                                                                                                                                                                                                                 const VkCommandBuffer                                          cmdBuffer,
                                                                                                                                                                                                                 SerialStorage*                                                         storage) = DE_NULL;
 
+       virtual std::vector<VkDeviceSize>                                                               getSerializingSizes                                     (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkQueue                                                          queue,
+                                                                                                                                                                                                                const deUint32                                                         queueFamilyIndex) = DE_NULL;
+
+       virtual std::vector<deUint64>                                                                   getSerializingAddresses                         (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device) const = DE_NULL;
+
        // helper methods for typical acceleration structure creation tasks
        void                                                                                                                    createAndBuild                                          (const DeviceInterface&                                         vk,
                                                                                                                                                                                                                 const VkDevice                                                         device,
@@ -696,6 +757,12 @@ protected:
        VkDeviceSize                                                                                                    m_structureSize;
        VkDeviceSize                                                                                                    m_updateScratchSize;
        VkDeviceSize                                                                                                    m_buildScratchSize;
+
+       virtual void                                                                                                    createAndDeserializeBottoms                     (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                                SerialStorage*                                                         storage) = DE_NULL;
 };
 
 de::MovePtr<TopLevelAccelerationStructure> makeTopLevelAccelerationStructure ();
index da6784e..9942487 100644 (file)
@@ -72,7 +72,8 @@ enum BottomTestType
 enum TopTestType
 {
        TTT_IDENTICAL_INSTANCES,
-       TTT_DIFFERENT_INSTANCES
+       TTT_DIFFERENT_INSTANCES,
+       TTT_MIX_INSTANCES,
 };
 
 enum OperationTarget
@@ -2385,6 +2386,34 @@ protected:
                                        getDeviceASCompatibilityKHR                                             (const deUint8*         versionInfoData);
        std::string             getUUIDsString                                                                  (const deUint8* header) const;
 
+
+private:
+       const de::SharedPtr<TestParams> m_params;
+};
+
+// Tests for updating botto-level AS(s) address(es) in top-level AS's header
+class RayTracingHeaderBottomAddressTestInstance : public TestInstance
+{
+public:
+                                       RayTracingHeaderBottomAddressTestInstance                                               (Context&                                                                                       context,
+                                                                                                                                                                        const de::SharedPtr<TestParams>                                        params)
+                                               : TestInstance  (context)
+                                               , m_params              (params)
+                                       {
+                                       }
+       tcu::TestStatus iterate                                                                                                                 (void) override;
+
+protected:
+       de::SharedPtr<TopLevelAccelerationStructure>    prepareTopAccelerationStructure (const DeviceInterface&                                                         vk,
+                                                                                                                                                                        VkDevice                                                                                       device,
+                                                                                                                                                                        Allocator&                                                                                     allocator,
+                                                                                                                                                                        VkCommandBuffer                                                                        cmdBuffer);
+
+       bool                                                                                    areAddressesTheSame                             (const std::vector<deUint64>&                                           addresses,
+                                                                                                                                                                        const SerialStorage::AccelerationStructureHeader*      header);
+
+       bool                                                                                    areAddressesDifferent                   (const std::vector<deUint64>&                                           addresses1,
+                                                                                                                                                                        const std::vector<deUint64>&                                           addresses2);
 private:
        const de::SharedPtr<TestParams> m_params;
 };
@@ -2408,6 +2437,25 @@ private:
        de::SharedPtr<TestParams>       m_params;
 };
 
+class RayTracingHeaderBottomAddressTestCase : public TestCase
+{
+public:
+                                       RayTracingHeaderBottomAddressTestCase   (tcu::TestContext& ctx, const char* name, const de::SharedPtr<TestParams> params)
+                                               : TestCase(ctx, name, std::string())
+                                               , m_params(params)
+                                       {
+                                       }
+
+       void                    checkSupport                                                            (Context&                       context) const override;
+       TestInstance*   createInstance                                                          (Context&                       context) const override
+       {
+               return new RayTracingHeaderBottomAddressTestInstance(context, m_params);
+       }
+
+private:
+       de::SharedPtr<TestParams>       m_params;
+};
+
 void RayTracingDeviceASCompabilityKHRTestCase ::checkSupport (Context& context) const
 {
        context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
@@ -2421,6 +2469,18 @@ void RayTracingDeviceASCompabilityKHRTestCase ::checkSupport (Context& context)
        checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_params->vertexFormat);
 }
 
+void RayTracingHeaderBottomAddressTestCase ::checkSupport (Context& context) const
+{
+       context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
+
+       const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
+       if (m_params->buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE)
+               TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands");
+
+       // Check supported vertex format.
+       checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_params->vertexFormat);
+}
+
 VkAccelerationStructureCompatibilityKHR        RayTracingDeviceASCompabilityKHRTestInstance::getDeviceASCompatibilityKHR (const deUint8* versionInfoData)
 {
        const VkDevice                                                          device          = m_context.getDevice();
@@ -2633,6 +2693,193 @@ bool RayTracingDeviceASCompabilityKHRTestInstance::performTest (VkCommandPool
        return result;
 }
 
+de::SharedPtr<TopLevelAccelerationStructure>
+RayTracingHeaderBottomAddressTestInstance::prepareTopAccelerationStructure (const DeviceInterface&     vk,
+                                                                                                                                                       VkDevice                                device,
+                                                                                                                                                       Allocator&                              allocator,
+                                                                                                                                                       VkCommandBuffer                 cmdBuffer)
+{
+       const std::vector<tcu::Vec3>                                                                    geometryData =
+       {
+               { 0.0, 0.0, 0.0 },
+               { 1.0, 0.0, 0.0 },
+               { 0.0, 1.0, 0.0 },
+       };
+
+       std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>    bottoms;
+
+       if (TTT_IDENTICAL_INSTANCES == m_params->topTestType)
+       {
+               auto blas = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
+               blas->setBuildType(m_params->buildType);
+               blas->setGeometryData(geometryData, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
+               blas->createAndBuild(vk, device, cmdBuffer, allocator);
+               for (deUint32 i = 0; i < m_params->width; ++i)
+               {
+                       bottoms.emplace_back(blas);
+               }
+       }
+       else if (TTT_DIFFERENT_INSTANCES == m_params->topTestType)
+       {
+               for (deUint32 i = 0; i < m_params->width; ++i)
+               {
+                       auto blas = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
+                       blas->setBuildType(m_params->buildType);
+                       blas->setGeometryData(geometryData, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
+                       blas->createAndBuild(vk, device, cmdBuffer, allocator);
+                       bottoms.emplace_back(blas);
+               }
+       }
+       else // TTT_MIX_INSTANCES == m_params->topTestType
+       {
+               for (deUint32 i = 0; i < m_params->width; ++i)
+               {
+                       {
+                               auto blas1 = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
+                               blas1->setBuildType(m_params->buildType);
+                               blas1->setGeometryData(geometryData, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
+                               blas1->createAndBuild(vk, device, cmdBuffer, allocator);
+                               bottoms.emplace_back(blas1);
+                       }
+
+                       {
+                               auto blas2 = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
+                               blas2->setBuildType(m_params->buildType);
+                               blas2->setGeometryData(geometryData, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
+                               blas2->createAndBuild(vk, device, cmdBuffer, allocator);
+                               bottoms.emplace_back(blas2);
+                       }
+               }
+
+       }
+
+       const std::size_t                                                                                               instanceCount = bottoms.size();
+
+       de::MovePtr<TopLevelAccelerationStructure>                                              tlas = makeTopLevelAccelerationStructure();
+       tlas->setBuildType(m_params->buildType);
+       tlas->setInstanceCount(instanceCount);
+
+       for (std::size_t i = 0; i < instanceCount; ++i)
+       {
+               const VkTransformMatrixKHR      transformMatrixKHR =
+               {
+                       {       //  float       matrix[3][4];
+                               { 1.0f, 0.0f, 0.0f, (float)i },
+                               { 0.0f, 1.0f, 0.0f, (float)i },
+                               { 0.0f, 0.0f, 1.0f, 0.0f },
+                       }
+               };
+               tlas->addInstance(bottoms[i], transformMatrixKHR, 0, 0xFFu, 0u, getCullFlags((m_params->cullFlags)));
+       }
+
+       tlas->createAndBuild(vk, device, cmdBuffer, allocator);
+
+       return de::SharedPtr<TopLevelAccelerationStructure>(tlas.release());
+}
+
+tcu::TestStatus RayTracingHeaderBottomAddressTestInstance::iterate (void)
+{
+       const DeviceInterface&                                                          vkd                             = m_context.getDeviceInterface();
+       const VkDevice                                                                          device                  = m_context.getDevice();
+       const deUint32                                                                          familyIndex             = m_context.getUniversalQueueFamilyIndex();
+       const VkQueue                                                                           queue                   = m_context.getUniversalQueue();
+       Allocator&                                                                                      allocator               = m_context.getDefaultAllocator();
+
+       const Move<VkCommandPool>                                                       cmdPool                 = createCommandPool(vkd, device, 0, familyIndex);
+       const Move<VkCommandBuffer>                                                     cmdBuffer               = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+       beginCommandBuffer(vkd, *cmdBuffer, 0);
+       de::SharedPtr<TopLevelAccelerationStructure>            src                             = prepareTopAccelerationStructure(vkd, device, allocator, *cmdBuffer);
+       endCommandBuffer(vkd, *cmdBuffer);
+       submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
+
+       de::MovePtr<TopLevelAccelerationStructure>                      dst                             = makeTopLevelAccelerationStructure();
+
+       const std::vector<deUint64>                                                     inAddrs                 = src->getSerializingAddresses(vkd, device);
+       const std::vector<VkDeviceSize>                                         inSizes                 = src->getSerializingSizes(vkd, device, queue, familyIndex);
+
+       const SerialInfo                                                                        serialInfo              (inAddrs, inSizes);
+       SerialStorage                                                                           deepStorage             (vkd, device, allocator, m_params->buildType, serialInfo);
+
+       // make deep serialization - top-level AS width bottom-level structures that it owns
+       beginCommandBuffer(vkd, *cmdBuffer, 0);
+       src->serialize(vkd, device, *cmdBuffer, &deepStorage);
+       endCommandBuffer(vkd, *cmdBuffer);
+       submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
+
+       // deserialize all from the previous step to a new top-level AS
+       // bottom-level structure addresses should be updated when deep data is deserialized
+       beginCommandBuffer(vkd, *cmdBuffer, 0);
+       dst->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, &deepStorage);
+       endCommandBuffer(vkd, *cmdBuffer);
+       submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
+
+       SerialStorage                                                                           shallowStorage  (vkd, device, allocator, m_params->buildType, inSizes[0]);
+
+       // make shallow serialization - only top-level AS without bottom-level structures
+       beginCommandBuffer(vkd, *cmdBuffer, 0);
+       dst->serialize(vkd, device, *cmdBuffer, &shallowStorage);
+       endCommandBuffer(vkd, *cmdBuffer);
+       submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
+
+       // get data to verification
+       const std::vector<deUint64>                                                     outAddrs                = dst->getSerializingAddresses(vkd, device);
+       const SerialStorage::AccelerationStructureHeader*       header                  = shallowStorage.getASHeader();
+
+       return (areAddressesDifferent(inAddrs, outAddrs) && areAddressesTheSame(outAddrs, header)) ? tcu::TestStatus::pass("") : tcu::TestStatus::fail("");
+}
+
+bool RayTracingHeaderBottomAddressTestInstance::areAddressesTheSame (const std::vector<deUint64>& addresses, const SerialStorage::AccelerationStructureHeader* header)
+{
+       const deUint32 cbottoms = deUint32(addresses.size() - 1);
+
+       // header should contain the same number of handles as serialized/deserialized top-level AS
+       if (cbottoms != header->handleCount) return false;
+
+       std::set<deUint64> refAddrs;
+       std::set<deUint64> checkAddrs;
+
+       // distinct, squach and sort address list
+       for (deUint32 i = 0; i < cbottoms; ++i)
+       {
+               refAddrs.insert(addresses[i+1]);
+               checkAddrs.insert(header->handleArray[i]);
+       }
+
+       return std::equal(refAddrs.begin(), refAddrs.end(), checkAddrs.begin());
+}
+
+bool RayTracingHeaderBottomAddressTestInstance::areAddressesDifferent (const std::vector<deUint64>& addresses1, const std::vector<deUint64>& addresses2)
+{
+       // the number of addresses must be equal
+       if (addresses1.size() != addresses2.size())
+               return false;
+
+       // adresses of top-level AS must differ
+       if (addresses1[0] == addresses2[0])
+               return false;
+
+       std::set<deUint64>      addrs1;
+       std::set<deUint64>      addrs2;
+       deUint32                        matches         = 0;
+       const deUint32          cbottoms        = deUint32(addresses1.size() - 1);
+
+       for (deUint32 i = 0; i < cbottoms; ++i)
+       {
+               addrs1.insert(addresses1[i+1]);
+               addrs2.insert(addresses2[i+1]);
+       }
+
+       // the first addresses set must not contain any address from the second addresses set
+       for (auto& addr1 : addrs1)
+       {
+               if (addrs2.end() != addrs2.find(addr1))
+                       ++matches;
+       }
+
+       return (matches == 0);
+}
+
 }      // anonymous
 
 void addBasicBuildingTests(tcu::TestCaseGroup* group)
@@ -3373,6 +3620,68 @@ void addGetDeviceAccelerationStructureCompabilityTests (tcu::TestCaseGroup* grou
        }
 }
 
+void addUpdateHeaderBottomAddressTests (tcu::TestCaseGroup* group)
+{
+       struct
+       {
+               vk::VkAccelerationStructureBuildTypeKHR         buildType;
+               std::string                                                                     name;
+       }
+       const buildTypes[] =
+       {
+               { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,        "cpu_built"     },
+               { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,      "gpu_built"     },
+       };
+
+       struct
+       {
+               TopTestType     type;
+               std::string     name;
+       }
+       const instTypes[] =
+       {
+               { TTT_IDENTICAL_INSTANCES,      "the_same_instances"            },
+               { TTT_DIFFERENT_INSTANCES,      "different_instances"           },
+               { TTT_MIX_INSTANCES,            "mix_same_diff_instances"       },
+       };
+
+       auto& ctx = group->getTestContext();
+
+       for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
+       {
+               de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str(), ""));
+
+               for (int instTypeIdx = 0; instTypeIdx < DE_LENGTH_OF_ARRAY(instTypes); ++instTypeIdx)
+               {
+                       TestParams testParams
+                       {
+                               buildTypes[buildTypeIdx].buildType,                                                                     // buildType
+                               VK_FORMAT_R32G32B32_SFLOAT,                                                                                     // vertexFormat
+                               false,                                                                                                                          // padVertices
+                               VK_INDEX_TYPE_NONE_KHR,                                                                                         // indexType
+                               BTT_TRIANGLES,                                                                                                          // bottomTestType
+                               InstanceCullFlags::NONE,                                                                                        // cullFlags
+                               false,                                                                                                                          // bottomUsesAOP
+                               false,                                                                                                                          // bottomGeneric
+                               instTypes[instTypeIdx].type,                                                                            // topTestType
+                               false,                                                                                                                          // topUsesAOP
+                               false,                                                                                                                          // topGeneric
+                               VkBuildAccelerationStructureFlagsKHR(0u),                                                       // buildFlags
+                               OT_TOP_ACCELERATION,                                                                                            // operationTarget
+                               OP_NONE,                                                                                                                        // operationType
+                               RTAS_DEFAULT_SIZE,                                                                                                      // width
+                               RTAS_DEFAULT_SIZE,                                                                                                      // height
+                               de::SharedPtr<TestConfiguration>(DE_NULL),                                                      // testConfiguration
+                               0u,                                                                                                                                     // workerThreadsCount
+                               EmptyAccelerationStructureCase::NOT_EMPTY,                                                      // emptyASCase
+                               InstanceCustomIndexCase::NONE,                                                                          // instanceCustomIndexCase
+                       };
+                       buildTypeGroup->addChild(new RayTracingHeaderBottomAddressTestCase(ctx, instTypes[instTypeIdx].name.c_str(), de::SharedPtr<TestParams>(new TestParams(testParams))));
+               }
+               group->addChild(buildTypeGroup.release());
+       }
+}
+
 tcu::TestCaseGroup*    createAccelerationStructuresTests(tcu::TestContext& testCtx)
 {
        de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "acceleration_structures", "Acceleration structure tests"));
@@ -3387,6 +3696,7 @@ tcu::TestCaseGroup*       createAccelerationStructuresTests(tcu::TestContext& testCtx)
        addTestGroup(group.get(), "empty", "Test building empty acceleration structures using different methods", addEmptyAccelerationStructureTests);
        addTestGroup(group.get(), "instance_index", "Test using different values for the instance index and checking them in shaders", addInstanceIndexTests);
        addTestGroup(group.get(), "device_compability_khr", "", addGetDeviceAccelerationStructureCompabilityTests);
+       addTestGroup(group.get(), "header_bottom_address", "", addUpdateHeaderBottomAddressTests);
 
        return group.release();
 }
@@ -3394,3 +3704,4 @@ tcu::TestCaseGroup*       createAccelerationStructuresTests(tcu::TestContext& testCtx)
 }      // RayTracing
 
 }      // vkt
+
index d891276..d3aac1c 100644 (file)
@@ -8063,6 +8063,12 @@ dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.cpu_
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.cpu_built.bottom
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.gpu_built.top
 dEQP-VK.ray_tracing_pipeline.acceleration_structures.device_compability_khr.gpu_built.bottom
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.the_same_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.different_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.cpu_built.mix_same_diff_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.the_same_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.different_instances
+dEQP-VK.ray_tracing_pipeline.acceleration_structures.header_bottom_address.gpu_built.mix_same_diff_instances
 dEQP-VK.ray_tracing_pipeline.procedural_geometry.object_behind_bounding_boxes
 dEQP-VK.ray_tracing_pipeline.procedural_geometry.triangle_in_between
 dEQP-VK.ray_tracing_pipeline.indirect.build_structure