Framework definitions for VK_KHR_ray_tracing
authorBoris Zanin <boris.zanin@mobica.com>
Fri, 18 Oct 2019 13:38:32 +0000 (15:38 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 9 Apr 2020 07:13:58 +0000 (03:13 -0400)
Initial commit required to build VK_KHR_ray_tracing.
Also contains framework definitions for wrappers used
to run CTS with VK_NV_ray_tracing extention.

Components: Framework, Vulkan

VK-GL-CTS issue: 2143

Change-Id: I5fa7556f72fd0155f3eadfb0eaf2c8c84c540791

13 files changed:
AndroidGen.mk
external/fetch_sources.py
external/openglcts/modules/common/glcSpirvUtils.cpp
external/vulkancts/framework/vulkan/CMakeLists.txt
external/vulkancts/framework/vulkan/vkBarrierUtil.cpp
external/vulkancts/framework/vulkan/vkBarrierUtil.hpp
external/vulkancts/framework/vulkan/vkBuilderUtil.cpp
external/vulkancts/framework/vulkan/vkBuilderUtil.hpp
external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp [new file with mode: 0644]
external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp [new file with mode: 0644]
external/vulkancts/framework/vulkan/vkRefUtil.cpp
external/vulkancts/framework/vulkan/vkRefUtil.hpp
external/vulkancts/framework/vulkan/vkShaderToSpirV.cpp

index d317943..ea11405 100644 (file)
@@ -47,6 +47,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/framework/vulkan/vkPlatform.cpp \
        external/vulkancts/framework/vulkan/vkPrograms.cpp \
        external/vulkancts/framework/vulkan/vkQueryUtil.cpp \
+       external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp \
        external/vulkancts/framework/vulkan/vkRef.cpp \
        external/vulkancts/framework/vulkan/vkRefUtil.cpp \
        external/vulkancts/framework/vulkan/vkRenderDocUtil.cpp \
index f412f7e..03b57fa 100644 (file)
@@ -316,18 +316,18 @@ PACKAGES = [
        GitRepo(
                "https://github.com/KhronosGroup/SPIRV-Tools.git",
                None,
-               "a9624b4d5d0bb1617d6e20dbaba174b07cee18ee",
+               "5a97e3a391677ff9baae8ccdf5c03c4d403d848b",
                "spirv-tools"),
        GitRepo(
                "https://github.com/KhronosGroup/glslang.git",
                None,
-               "540662253ea35e8e75122aac68f8542f993e3396",
+               "c7910056825a6791a33149fca20ee299daf6ed25",
                "glslang",
                removeTags = ["master-tot"]),
        GitRepo(
                "https://github.com/KhronosGroup/SPIRV-Headers.git",
                None,
-               "dc77030acc9c6fe7ca21fff54c5a9d7b532d7da6",
+               "f8bf11a0253a32375c32cad92c841237b96696c0",
                "spirv-headers"),
        GitRepo(
                "https://github.com/google/amber.git",
index 857b812..d30bc3b 100644 (file)
@@ -59,7 +59,7 @@ EShLanguage getGlslangStage(glu::ShaderType type)
 {
        static const EShLanguage stageMap[] = {
                EShLangVertex, EShLangFragment, EShLangGeometry, EShLangTessControl, EShLangTessEvaluation, EShLangCompute,
-               EShLangRayGenNV, EShLangAnyHitNV, EShLangClosestHitNV, EShLangMissNV, EShLangIntersectNV, EShLangCallableNV
+               EShLangRayGen, EShLangAnyHit, EShLangClosestHit, EShLangMiss, EShLangIntersect, EShLangCallable
        };
 
        return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
index c307da7..37dc216 100644 (file)
@@ -74,6 +74,8 @@ set(VKUTILNOSHADER_SRCS
        vkDeviceProperties.hpp
        vkDeviceProperties.cpp
        vkDeviceProperties.inl
+       vkRayTracingUtil.hpp
+       vkRayTracingUtil.cpp
        )
 
 set(VKUTIL_SRCS
index b0bed43..f047d14 100644 (file)
@@ -88,4 +88,49 @@ VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags       srcAccessMask,
        return barrier;
 }
 
+void cmdPipelineMemoryBarrier          (const DeviceInterface&                 vk,
+                                                                        const VkCommandBuffer                  commandBuffer,
+                                                                        const VkPipelineStageFlags             srcStageMask,
+                                                                        const VkPipelineStageFlags             dstStageMask,
+                                                                        const VkMemoryBarrier*                 pMemoryBarriers,
+                                                                        const size_t                                   memoryBarrierCount,
+                                                                        const VkDependencyFlags                dependencyFlags)
+{
+       const deUint32  memoryBarrierCount32    =static_cast<deUint32>(memoryBarrierCount);
+
+       DE_ASSERT(memoryBarrierCount == memoryBarrierCount32);
+
+       vk.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount32, pMemoryBarriers, 0u, DE_NULL, 0u, DE_NULL);
+}
+
+void cmdPipelineBufferMemoryBarrier    (const DeviceInterface&                 vk,
+                                                                        const VkCommandBuffer                  commandBuffer,
+                                                                        const VkPipelineStageFlags             srcStageMask,
+                                                                        const VkPipelineStageFlags             dstStageMask,
+                                                                        const VkBufferMemoryBarrier*   pBufferMemoryBarriers,
+                                                                        const size_t                                   bufferMemoryBarrierCount,
+                                                                        const VkDependencyFlags                dependencyFlags)
+{
+       const deUint32  bufferMemoryBarrierCount32      =static_cast<deUint32>(bufferMemoryBarrierCount);
+
+       DE_ASSERT(bufferMemoryBarrierCount == bufferMemoryBarrierCount32);
+
+       vk.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, DE_NULL, bufferMemoryBarrierCount32, pBufferMemoryBarriers, 0u, DE_NULL);
+}
+
+void cmdPipelineImageMemoryBarrier     (const DeviceInterface&                 vk,
+                                                                        const VkCommandBuffer                  commandBuffer,
+                                                                        const VkPipelineStageFlags             srcStageMask,
+                                                                        const VkPipelineStageFlags             dstStageMask,
+                                                                        const VkImageMemoryBarrier*    pImageMemoryBarriers,
+                                                                        const size_t                                   imageMemoryBarrierCount,
+                                                                        const VkDependencyFlags                dependencyFlags)
+{
+       const deUint32  imageMemoryBarrierCount32       =static_cast<deUint32>(imageMemoryBarrierCount);
+
+       DE_ASSERT(imageMemoryBarrierCount == imageMemoryBarrierCount32);
+
+       vk.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, DE_NULL, 0u, DE_NULL, imageMemoryBarrierCount32, pImageMemoryBarriers);
+}
+
 } // vkt
index a803f6d..269a099 100644 (file)
@@ -50,6 +50,30 @@ VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags                     srcAccessMask
 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags srcAccessMask,
                                                                   const VkAccessFlags  dstAccessMask);
 
+void cmdPipelineMemoryBarrier          (const DeviceInterface&                 vk,
+                                                                        const VkCommandBuffer                  commandBuffer,
+                                                                        const VkPipelineStageFlags             srcStageMask,
+                                                                        const VkPipelineStageFlags             dstStageMask,
+                                                                        const VkMemoryBarrier*                 pMemoryBarriers,
+                                                                        const size_t                                   memoryBarrierCount = 1u,
+                                                                        const VkDependencyFlags                dependencyFlags = 0);
+
+void cmdPipelineBufferMemoryBarrier    (const DeviceInterface&                 vk,
+                                                                        const VkCommandBuffer                  commandBuffer,
+                                                                        const VkPipelineStageFlags             srcStageMask,
+                                                                        const VkPipelineStageFlags             dstStageMask,
+                                                                        const VkBufferMemoryBarrier*   pBufferMemoryBarriers,
+                                                                        const size_t                                   bufferMemoryBarrierCount = 1u,
+                                                                        const VkDependencyFlags                dependencyFlags = 0);
+
+void cmdPipelineImageMemoryBarrier     (const DeviceInterface&                 vk,
+                                                                        const VkCommandBuffer                  commandBuffer,
+                                                                        const VkPipelineStageFlags             srcStageMask,
+                                                                        const VkPipelineStageFlags             dstStageMask,
+                                                                        const VkImageMemoryBarrier*    pImageMemoryBarriers,
+                                                                        const size_t                                   imageMemoryBarrierCount = 1u,
+                                                                        const VkDependencyFlags                dependencyFlags = 0);
+
 } // vk
 
 #endif // _VKBARRIERUTIL_HPP
index bbeee7e..4032289 100644 (file)
@@ -200,13 +200,14 @@ DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet
                                                                                                                           VkDescriptorType                                     descriptorType,
                                                                                                                           const VkDescriptorImageInfo*         pImageInfo,
                                                                                                                           const VkDescriptorBufferInfo*        pBufferInfo,
-                                                                                                                          const VkBufferView*                          pTexelBufferView)
+                                                                                                                          const VkBufferView*                          pTexelBufferView,
+                                                                                                                          const void*                                          pNext)
 {
        // pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
        const VkWriteDescriptorSet writeParams =
        {
                VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-               DE_NULL,
+               pNext,
                destSet,                        //!< destSet
                destBinding,            //!< destBinding
                destArrayElement,       //!< destArrayElement
index 3e13b71..24cdbc0 100644 (file)
@@ -163,7 +163,8 @@ public:
                                                                                                                                         VkDescriptorType                               descriptorType,
                                                                                                                                         const VkDescriptorImageInfo*   pImageInfo,
                                                                                                                                         const VkDescriptorBufferInfo*  pBufferInfo,
-                                                                                                                                        const VkBufferView*                    pTexelBufferView);
+                                                                                                                                        const VkBufferView*                    pTexelBufferView,
+                                                                                                                                        const void*                                    pNext = DE_NULL);
 
        DescriptorSetUpdateBuilder&                     copy                                            (VkDescriptorSet        srcSet,
                                                                                                                                         deUint32                       srcBinding,
@@ -203,6 +204,14 @@ public:
                return write(destSet, destLocation.m_binding, destLocation.m_arrayElement, 1u, descriptorType, DE_NULL, DE_NULL, pTexelBufferView);
        }
 
+       inline DescriptorSetUpdateBuilder&      writeSingle                                     (VkDescriptorSet                                                                                destSet,
+                                                                                                                                        const Location&                                                                                destLocation,
+                                                                                                                                        VkDescriptorType                                                                               descriptorType,
+                                                                                                                                        const VkWriteDescriptorSetAccelerationStructureKHR*    pAccelerationStructure)
+       {
+               return write(destSet, destLocation.m_binding, destLocation.m_arrayElement, 1u, descriptorType, DE_NULL, DE_NULL, DE_NULL, pAccelerationStructure);
+       }
+
        inline DescriptorSetUpdateBuilder&      writeArray                                      (VkDescriptorSet                                destSet,
                                                                                                                                         const Location&                                destLocation,
                                                                                                                                         VkDescriptorType                               descriptorType,
diff --git a/external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp b/external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp
new file mode 100644 (file)
index 0000000..fb90f95
--- /dev/null
@@ -0,0 +1,2143 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2020 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Utilities for creating commonly used Vulkan objects
+ *//*--------------------------------------------------------------------*/
+
+#include "vkRayTracingUtil.hpp"
+
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkBarrierUtil.hpp"
+
+#include <vector>
+#include <string>
+#include <thread>
+
+namespace vk
+{
+
+std::string getCommonRayGenerationShader (void)
+{
+       return
+               "#version 460 core\n"
+               "#extension GL_EXT_nonuniform_qualifier : enable\n"
+               "#extension GL_EXT_ray_tracing : require\n"
+               "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
+               "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
+               "\n"
+               "void main()\n"
+               "{\n"
+               "  uint  rayFlags = 0;\n"
+               "  uint  cullMask = 0xFF;\n"
+               "  float tmin     = 0.0;\n"
+               "  float tmax     = 9.0;\n"
+               "  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
+               "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
+               "  traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
+               "}\n";
+}
+
+const char* getRayTracingExtensionUsed (void)
+{
+       return "VK_KHR_ray_tracing";
+}
+
+RaytracedGeometryBase::RaytracedGeometryBase (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType)
+       : m_geometryType        (geometryType)
+       , m_vertexFormat        (vertexFormat)
+       , m_indexType           (indexType)
+       , m_geometryFlags       ((VkGeometryFlagsKHR)0u)
+{
+}
+
+RaytracedGeometryBase::~RaytracedGeometryBase ()
+{
+}
+
+de::SharedPtr<RaytracedGeometryBase> makeRaytracedGeometry (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType)
+{
+       switch (vertexFormat)
+       {
+               case VK_FORMAT_R32G32_SFLOAT:
+                       switch (indexType)
+                       {
+                               case VK_INDEX_TYPE_UINT16:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<tcu::Vec2, deUint16>(geometryType));
+                               case VK_INDEX_TYPE_UINT32:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<tcu::Vec2, deUint32>(geometryType));
+                               case VK_INDEX_TYPE_NONE_KHR:    return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<tcu::Vec2, EmptyIndex>(geometryType));
+                               default:                                                TCU_THROW(InternalError, "Wrong index type");
+                       };
+               case VK_FORMAT_R32G32B32_SFLOAT:
+                       switch (indexType)
+                       {
+                               case VK_INDEX_TYPE_UINT16:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<tcu::Vec3, deUint16>(geometryType));
+                               case VK_INDEX_TYPE_UINT32:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<tcu::Vec3, deUint32>(geometryType));
+                               case VK_INDEX_TYPE_NONE_KHR:    return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<tcu::Vec3, EmptyIndex>(geometryType));
+                               default:                                                TCU_THROW(InternalError, "Wrong index type");
+                       };
+               case VK_FORMAT_R16G16_SFLOAT:
+                       switch (indexType)
+                       {
+                               case VK_INDEX_TYPE_UINT16:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec2_16, deUint16>(geometryType));
+                               case VK_INDEX_TYPE_UINT32:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec2_16, deUint32>(geometryType));
+                               case VK_INDEX_TYPE_NONE_KHR:    return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec2_16, EmptyIndex>(geometryType));
+                               default:                                                TCU_THROW(InternalError, "Wrong index type");
+                       };
+               case VK_FORMAT_R16G16B16A16_SFLOAT:
+                       switch (indexType)
+                       {
+                               case VK_INDEX_TYPE_UINT16:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec4_16, deUint16>(geometryType));
+                               case VK_INDEX_TYPE_UINT32:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec4_16, deUint32>(geometryType));
+                               case VK_INDEX_TYPE_NONE_KHR:    return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec4_16, EmptyIndex>(geometryType));
+                               default:                                                TCU_THROW(InternalError, "Wrong index type");
+                       };
+               case VK_FORMAT_R16G16_SNORM:
+                       switch (indexType)
+                       {
+                               case VK_INDEX_TYPE_UINT16:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec2_16SNorm, deUint16>(geometryType));
+                               case VK_INDEX_TYPE_UINT32:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec2_16SNorm, deUint32>(geometryType));
+                               case VK_INDEX_TYPE_NONE_KHR:    return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec2_16SNorm, EmptyIndex>(geometryType));
+                               default:                                                TCU_THROW(InternalError, "Wrong index type");
+                       };
+               case VK_FORMAT_R16G16B16A16_SNORM:
+                       switch (indexType)
+                       {
+                               case VK_INDEX_TYPE_UINT16:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec4_16SNorm, deUint16>(geometryType));
+                               case VK_INDEX_TYPE_UINT32:              return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec4_16SNorm, deUint32>(geometryType));
+                               case VK_INDEX_TYPE_NONE_KHR:    return de::SharedPtr<RaytracedGeometryBase>(new RaytracedGeometry<Vec4_16SNorm, EmptyIndex>(geometryType));
+                               default:                                                TCU_THROW(InternalError, "Wrong index type");
+                       };
+               default:
+                       TCU_THROW(InternalError, "Wrong vertex format");
+       };
+
+}
+
+static inline VkDeviceOrHostAddressConstKHR makeDeviceOrHostAddressConstKHR (const void* hostAddress)
+{
+       // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
+       VkDeviceOrHostAddressConstKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       result.hostAddress = hostAddress;
+
+       return result;
+}
+
+static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (void* hostAddress)
+{
+       // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
+       VkDeviceOrHostAddressKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       result.hostAddress = hostAddress;
+
+       return result;
+}
+
+static inline VkDeviceOrHostAddressConstKHR makeDeviceOrHostAddressConstKHR (const DeviceInterface&    vk,
+                                                                                                                                         const VkDevice                        device,
+                                                                                                                                         VkBuffer                                      buffer,
+                                                                                                                                         VkDeviceSize                          offset)
+{
+       // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
+       VkDeviceOrHostAddressConstKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,       // VkStructureType       sType;
+               DE_NULL,                                                                                        // const void*           pNext;
+               buffer,                                                                                         // VkBuffer                     buffer
+       };
+       result.deviceAddress = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo) + offset;
+
+       return result;
+}
+
+static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (const DeviceInterface&      vk,
+                                                                                                                                  const VkDevice                       device,
+                                                                                                                                  VkBuffer                                     buffer,
+                                                                                                                                  VkDeviceSize                         offset)
+{
+       // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
+       VkDeviceOrHostAddressKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,       // VkStructureType       sType;
+               DE_NULL,                                                                                        // const void*           pNext;
+               buffer,                                                                                         // VkBuffer                     buffer
+       };
+       result.deviceAddress = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo) + offset;
+
+       return result;
+}
+
+static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryTrianglesDataKHR& triangles)
+{
+       VkAccelerationStructureGeometryDataKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       result.triangles = triangles;
+
+       return result;
+}
+
+static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryAabbsDataKHR& aabbs)
+{
+       VkAccelerationStructureGeometryDataKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       result.aabbs = aabbs;
+
+       return result;
+}
+
+static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureInstancesDataKHR (const VkAccelerationStructureGeometryInstancesDataKHR& instances)
+{
+       VkAccelerationStructureGeometryDataKHR result;
+
+       deMemset(&result, 0, sizeof(result));
+
+       result.instances = instances;
+
+       return result;
+}
+
+static inline VkAccelerationStructureInstanceKHR makeVkAccelerationStructureInstanceKHR (const VkTransformMatrixKHR&                   transform,
+                                                                                                                                                                                deUint32                                                               instanceCustomIndex,
+                                                                                                                                                                                deUint32                                                               mask,
+                                                                                                                                                                                deUint32                                                               instanceShaderBindingTableRecordOffset,
+                                                                                                                                                                                VkGeometryInstanceFlagsKHR                             flags,
+                                                                                                                                                                                deUint64                                                               accelerationStructureReference)
+{
+       VkAccelerationStructureInstanceKHR instance             = { transform, 0, 0, 0, 0, accelerationStructureReference };
+       instance.instanceCustomIndex                                    = instanceCustomIndex & 0xFFFFFF;
+       instance.mask                                                                   = mask & 0xFF;
+       instance.instanceShaderBindingTableRecordOffset = instanceShaderBindingTableRecordOffset & 0xFFFFFF;
+       instance.flags                                                                  = flags & 0xFF;
+       return instance;
+}
+
+static inline VkMemoryRequirements getAccelerationStructureMemoryRequirements (const DeviceInterface&                                                                  vk,
+                                                                                                                                                          const VkDevice                                                                                       device,
+                                                                                                                                                          const VkAccelerationStructureKHR                                                     accelerationStructure,
+                                                                                                                                                          const VkAccelerationStructureMemoryRequirementsTypeKHR       memoryRequirementsType,
+                                                                                                                                                          const VkAccelerationStructureBuildTypeKHR                            buildType                               = VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+{
+       const VkAccelerationStructureMemoryRequirementsInfoKHR  accelerationStructureMemoryRequirementsInfoKHR  =
+       {
+               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR,  //  VkStructureType                                                                             sType;
+               DE_NULL,                                                                                                                                //  const void*                                                                                 pNext;
+               memoryRequirementsType,                                                                                                 //  VkAccelerationStructureMemoryRequirementsTypeKHR    type;
+               buildType,                                                                                                                              //  VkAccelerationStructureBuildTypeKHR                                 buildType;
+               accelerationStructure                                                                                                   //  VkAccelerationStructureKHR                                                  accelerationStructure;
+       };
+       VkMemoryRequirements2                                                                   memoryRequirements2                                                             =
+       {
+               VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,        //  VkStructureType                     sType;
+               DE_NULL,                                                                        //  void*                                       pNext;
+               {0, 0, 0}                                                                       //  VkMemoryRequirements        memoryRequirements;
+       };
+
+       vk.getAccelerationStructureMemoryRequirementsKHR(device, &accelerationStructureMemoryRequirementsInfoKHR, &memoryRequirements2);
+
+       return memoryRequirements2.memoryRequirements;
+}
+
+VkResult getRayTracingShaderGroupHandlesKHR (const DeviceInterface&            vk,
+                                                                                        const VkDevice                         device,
+                                                                                        const VkPipeline                       pipeline,
+                                                                                        const deUint32                         firstGroup,
+                                                                                        const deUint32                         groupCount,
+                                                                                        const deUintptr                        dataSize,
+                                                                                        void*                                          pData)
+{
+       return vk.getRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData);
+}
+
+VkResult getRayTracingShaderGroupHandles (const DeviceInterface&               vk,
+                                                                                 const VkDevice                                device,
+                                                                                 const VkPipeline                              pipeline,
+                                                                                 const deUint32                                firstGroup,
+                                                                                 const deUint32                                groupCount,
+                                                                                 const deUintptr                               dataSize,
+                                                                                 void*                                                 pData)
+{
+       return getRayTracingShaderGroupHandlesKHR(vk, device, pipeline, firstGroup, groupCount, dataSize, pData);
+}
+
+VkResult finishDeferredOperation (const DeviceInterface&       vk,
+                                                                 VkDevice                                      device,
+                                                                 VkDeferredOperationKHR        deferredOperation)
+{
+       VkResult result = vk.deferredOperationJoinKHR(device, deferredOperation);
+
+       while (result == VK_THREAD_IDLE_KHR)
+       {
+               std::this_thread::yield();
+               result = vk.deferredOperationJoinKHR(device, deferredOperation);
+       }
+
+       switch( result )
+       {
+               case VK_SUCCESS:
+               {
+                       // Deferred operation has finished. Query its result
+                       result = vk.getDeferredOperationResultKHR(device, deferredOperation);
+
+                       break;
+               }
+
+               case VK_THREAD_DONE_KHR:
+               {
+                       // Deferred operation is being wrapped up by another thread
+                       // wait for that thread to finish
+                       do
+                       {
+                               std::this_thread::yield();
+                               result = vk.getDeferredOperationResultKHR(device, deferredOperation);
+                       } while (result == VK_NOT_READY);
+
+                       break;
+               }
+
+               default:
+               {
+                       DE_ASSERT(false);
+
+                       break;
+               }
+       }
+
+       return result;
+}
+
+SerialStorage::SerialStorage (const DeviceInterface&                                                                   vk,
+                                                         const VkDevice                                                                                        device,
+                                                         Allocator&                                                                                            allocator,
+                                                         const VkAccelerationStructureBuildTypeKHR                                     buildType,
+                                                         const VkDeviceSize                                                                            storageSize)
+       : m_buildType (buildType)
+{
+       const VkBufferCreateInfo        bufferCreateInfo        = makeBufferCreateInfo(storageSize, VK_BUFFER_USAGE_RAY_TRACING_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));
+}
+
+VkDeviceOrHostAddressKHR SerialStorage::getAddress (const DeviceInterface&                             vk,
+                                                                                                       const VkDevice                                          device)
+{
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+               return makeDeviceOrHostAddressKHR(vk, device, m_buffer->get(), 0);
+       else
+               return makeDeviceOrHostAddressKHR(m_buffer->getAllocation().getHostPtr());
+}
+
+VkDeviceOrHostAddressConstKHR SerialStorage::getAddressConst (const DeviceInterface&   vk,
+                                                                                                                         const VkDevice                        device)
+{
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+               return makeDeviceOrHostAddressConstKHR(vk, device, m_buffer->get(), 0);
+       else
+               return makeDeviceOrHostAddressConstKHR(m_buffer->getAllocation().getHostPtr());
+}
+
+
+BottomLevelAccelerationStructure::~BottomLevelAccelerationStructure ()
+{
+}
+
+BottomLevelAccelerationStructure::BottomLevelAccelerationStructure ()
+       : m_geometriesData      ()
+{
+}
+
+void BottomLevelAccelerationStructure::setGeometryData (const std::vector<tcu::Vec3>&  geometryData,
+                                                                                                               const bool                                              triangles,
+                                                                                                               const VkGeometryFlagsKHR                geometryFlags)
+{
+       if (triangles)
+               DE_ASSERT((geometryData.size() % 3) == 0);
+       else
+               DE_ASSERT((geometryData.size() % 2) == 0);
+
+       setGeometryCount(1u);
+
+       addGeometry(geometryData, triangles, geometryFlags);
+}
+
+void BottomLevelAccelerationStructure::setDefaultGeometryData (const VkShaderStageFlagBits     testStage)
+{
+       bool                                    trianglesData   = false;
+       float                                   z                               = 0.0f;
+       std::vector<tcu::Vec3>  geometryData;
+
+       switch (testStage)
+       {
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:            z = -1.0f; trianglesData = true;        break;
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:           z = -1.0f; trianglesData = true;        break;
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:       z = -1.0f; trianglesData = true;        break;
+               case VK_SHADER_STAGE_MISS_BIT_KHR:                      z = -9.9f; trianglesData = true;        break;
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:      z = -1.0f; trianglesData = false;       break;
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:          z = -1.0f; trianglesData = true;        break;
+               default:                                                                        TCU_THROW(InternalError, "Unacceptable stage");
+       }
+
+       if (trianglesData)
+       {
+               geometryData.reserve(6);
+
+               geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z));
+               geometryData.push_back(tcu::Vec3(-1.0f, +1.0f, z));
+               geometryData.push_back(tcu::Vec3(+1.0f, -1.0f, z));
+               geometryData.push_back(tcu::Vec3(-1.0f, +1.0f, z));
+               geometryData.push_back(tcu::Vec3(+1.0f, -1.0f, z));
+               geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z));
+       }
+       else
+       {
+               geometryData.reserve(2);
+
+               geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z));
+               geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z));
+       }
+
+       setGeometryCount(1u);
+
+       addGeometry(geometryData, trianglesData);
+}
+
+void BottomLevelAccelerationStructure::setGeometryCount (const size_t geometryCount)
+{
+       m_geometriesData.clear();
+
+       m_geometriesData.reserve(geometryCount);
+}
+
+void BottomLevelAccelerationStructure::addGeometry (de::SharedPtr<RaytracedGeometryBase>&              raytracedGeometry)
+{
+       m_geometriesData.push_back(raytracedGeometry);
+}
+
+void BottomLevelAccelerationStructure::addGeometry (const std::vector<tcu::Vec3>&      geometryData,
+                                                                                                       const bool                                              triangles,
+                                                                                                       const VkGeometryFlagsKHR                geometryFlags)
+{
+       DE_ASSERT(geometryData.size() > 0);
+       DE_ASSERT((triangles && geometryData.size() % 3 == 0) || (!triangles && geometryData.size() % 2 == 0));
+
+       if (!triangles)
+               for (size_t posNdx = 0; posNdx < geometryData.size() / 2; ++posNdx)
+               {
+                       DE_ASSERT(geometryData[2 * posNdx].x() <= geometryData[2 * posNdx + 1].x());
+                       DE_ASSERT(geometryData[2 * posNdx].y() <= geometryData[2 * posNdx + 1].y());
+                       DE_ASSERT(geometryData[2 * posNdx].z() <= geometryData[2 * posNdx + 1].z());
+               }
+
+       de::SharedPtr<RaytracedGeometryBase> geometry = makeRaytracedGeometry(triangles ? VK_GEOMETRY_TYPE_TRIANGLES_KHR : VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
+       for (auto it = begin(geometryData), eit = end(geometryData); it != eit; ++it)
+               geometry->addVertex(*it);
+
+       geometry->setGeometryFlags(geometryFlags);
+       addGeometry(geometry);
+}
+
+BufferWithMemory* createVertexBuffer (const DeviceInterface&                                                                   vk,
+                                                                         const VkDevice                                                                                        device,
+                                                                         Allocator&                                                                                            allocator,
+                                                                         const std::vector<de::SharedPtr<RaytracedGeometryBase>>&      geometriesData)
+{
+       DE_ASSERT(geometriesData.size() != 0);
+
+       VkDeviceSize                                    bufferSizeBytes = 0;
+       for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
+               bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getVertexByteSize(),8);
+
+       const VkBufferCreateInfo                bufferCreateInfo        = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+       return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
+}
+
+void updateVertexBuffer (const DeviceInterface&                                                                                vk,
+                                                const VkDevice                                                                                         device,
+                                                const std::vector<de::SharedPtr<RaytracedGeometryBase>>&       geometriesData,
+                                                BufferWithMemory*                                                                                      vertexBuffer)
+{
+       const Allocation&                               geometryAlloc           = vertexBuffer->getAllocation();
+       deUint8*                                                bufferStart                     = static_cast<deUint8*>(geometryAlloc.getHostPtr());
+       VkDeviceSize                                    bufferOffset            = 0;
+
+       for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
+       {
+               const void*                                     geometryPtr                     = geometriesData[geometryNdx]->getVertexPointer();
+               const size_t                            geometryPtrSize         = geometriesData[geometryNdx]->getVertexByteSize();
+
+               deMemcpy(&bufferStart[bufferOffset], geometryPtr, geometryPtrSize);
+
+               bufferOffset += deAlignSize(geometryPtrSize,8);
+       }
+
+       flushMappedMemoryRange(vk, device, geometryAlloc.getMemory(), geometryAlloc.getOffset(), VK_WHOLE_SIZE);
+}
+
+BufferWithMemory* createIndexBuffer (const DeviceInterface&                                                                            vk,
+                                                                        const VkDevice                                                                                         device,
+                                                                        Allocator&                                                                                                     allocator,
+                                                                        const std::vector<de::SharedPtr<RaytracedGeometryBase>>&       geometriesData)
+{
+       DE_ASSERT(!geometriesData.empty());
+
+       VkDeviceSize                                    bufferSizeBytes = 0;
+       for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
+               if(geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
+                       bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getIndexByteSize(),8);
+
+       if (bufferSizeBytes == 0)
+               return DE_NULL;
+
+       const VkBufferCreateInfo                bufferCreateInfo        = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+       return  new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
+}
+
+void updateIndexBuffer (const DeviceInterface&                                                                         vk,
+                                               const VkDevice                                                                                          device,
+                                               const std::vector<de::SharedPtr<RaytracedGeometryBase>>&        geometriesData,
+                                               BufferWithMemory*                                                                                       indexBuffer)
+{
+       const Allocation&                               indexAlloc                      = indexBuffer->getAllocation();
+       deUint8*                                                bufferStart                     = static_cast<deUint8*>(indexAlloc.getHostPtr());
+       VkDeviceSize                                    bufferOffset            = 0;
+
+       for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
+       {
+               if (geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
+               {
+                       const void*                                     indexPtr                = geometriesData[geometryNdx]->getIndexPointer();
+                       const size_t                            indexPtrSize    = geometriesData[geometryNdx]->getIndexByteSize();
+
+                       deMemcpy(&bufferStart[bufferOffset], indexPtr, indexPtrSize);
+
+                       bufferOffset += deAlignSize(indexPtrSize, 8);
+               }
+       }
+
+       flushMappedMemoryRange(vk, device, indexAlloc.getMemory(), indexAlloc.getOffset(), VK_WHOLE_SIZE);
+}
+
+class BottomLevelAccelerationStructureKHR : public BottomLevelAccelerationStructure
+{
+public:
+       static deUint32                                                                                 getRequiredAllocationCount                                              (void);
+
+                                                                                                                       BottomLevelAccelerationStructureKHR                             ();
+                                                                                                                       BottomLevelAccelerationStructureKHR                             (const BottomLevelAccelerationStructureKHR&     other) = delete;
+       virtual                                                                                                 ~BottomLevelAccelerationStructureKHR                    ();
+
+       void                                                                                                    setBuildType                                                                    (const VkAccelerationStructureBuildTypeKHR      buildType) override;
+       void                                                                                                    setBuildFlags                                                                   (const VkBuildAccelerationStructureFlagsKHR     flags) override;
+       void                                                                                                    setDeferredOperation                                                    (const bool                                                                     deferredOperation) override;
+       void                                                                                                    setUseArrayOfPointers                                                   (const bool                                                                     useArrayOfPointers) override;
+       void                                                                                                    setIndirectBuildParameters                                              (const VkBuffer                                                         indirectBuffer,
+                                                                                                                                                                                                                        const VkDeviceSize                                                     indirectBufferOffset,
+                                                                                                                                                                                                                        const deUint32                                                         indirectBufferStride) override;
+       VkBuildAccelerationStructureFlagsKHR                                    getBuildFlags                                                                   () const override;
+
+       void                                                                                                    create                                                                                  (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                        const VkDevice                                                         device,
+                                                                                                                                                                                                                        Allocator&                                                                     allocator,
+                                                                                                                                                                                                                        VkDeviceAddress                                                        deviceAddress,
+                                                                                                                                                                                                                        VkDeviceSize                                                           compactCopySize) override;
+       void                                                                                                    build                                                                                   (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                        const VkDevice                                                         device,
+                                                                                                                                                                                                                        const VkCommandBuffer                                          cmdBuffer) override;
+       void                                                                                                    copyFrom                                                                                (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                        const VkDevice                                                         device,
+                                                                                                                                                                                                                        const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                        BottomLevelAccelerationStructure*                      accelerationStructure,
+                                                                                                                                                                                                                        VkDeviceSize                                                           compactCopySize) override;
+
+       void                                                                                                    serialize                                                                               (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                        const VkDevice                                                         device,
+                                                                                                                                                                                                                        const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                        SerialStorage*                                                         storage) override;
+       void                                                                                                    deserialize                                                                             (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                        const VkDevice                                                         device,
+                                                                                                                                                                                                                        const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                        SerialStorage*                                                         storage) override;
+
+       const VkAccelerationStructureKHR*                                               getPtr                                                                                  (void) const override;
+
+protected:
+       VkAccelerationStructureBuildTypeKHR                                             m_buildType;
+       VkBuildAccelerationStructureFlagsKHR                                    m_buildFlags;
+       bool                                                                                                    m_deferredOperation;
+       bool                                                                                                    m_useArrayOfPointers;
+       de::MovePtr<BufferWithMemory>                                                   m_vertexBuffer;
+       de::MovePtr<BufferWithMemory>                                                   m_indexBuffer;
+       de::MovePtr<Allocation>                                                                 m_accelerationStructureAlloc;
+       de::MovePtr<BufferWithMemory>                                                   m_scratchBuffer;
+       Move<VkAccelerationStructureKHR>                                                m_accelerationStructureKHR;
+       VkBuffer                                                                                                m_indirectBuffer;
+       VkDeviceSize                                                                                    m_indirectBufferOffset;
+       deUint32                                                                                                m_indirectBufferStride;
+};
+
+deUint32 BottomLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
+{
+       /*
+               de::MovePtr<BufferWithMemory>                                                   m_geometryBuffer; // but only when m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR
+               de::MovePtr<Allocation>                                                                 m_accelerationStructureAlloc;
+               de::MovePtr<BufferWithMemory>                                                   m_scratchBuffer;
+       */
+       return 3u;
+}
+
+BottomLevelAccelerationStructureKHR::~BottomLevelAccelerationStructureKHR ()
+{
+}
+
+BottomLevelAccelerationStructureKHR::BottomLevelAccelerationStructureKHR ()
+       : BottomLevelAccelerationStructure      ()
+       , m_buildType                                           (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       , m_buildFlags                                          (0u)
+       , m_deferredOperation                           (false)
+       , m_useArrayOfPointers                          (false)
+       , m_vertexBuffer                                        ()
+       , m_indexBuffer                                         ()
+       , m_accelerationStructureAlloc          ()
+       , m_scratchBuffer                                       ()
+       , m_accelerationStructureKHR            ()
+       , m_indirectBuffer                                      (DE_NULL)
+       , m_indirectBufferOffset                        (0)
+       , m_indirectBufferStride                        (0)
+{
+}
+
+void BottomLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR      buildType)
+{
+       m_buildType = buildType;
+}
+
+void BottomLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR    flags)
+{
+       m_buildFlags = flags;
+}
+
+void BottomLevelAccelerationStructureKHR::setDeferredOperation (const bool     deferredOperation)
+{
+       m_deferredOperation = deferredOperation;
+}
+
+void BottomLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool    useArrayOfPointers)
+{
+       m_useArrayOfPointers = useArrayOfPointers;
+}
+
+void BottomLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer           indirectBuffer,
+                                                                                                                                         const VkDeviceSize    indirectBufferOffset,
+                                                                                                                                         const deUint32                indirectBufferStride)
+{
+       m_indirectBuffer                = indirectBuffer;
+       m_indirectBufferOffset  = indirectBufferOffset;
+       m_indirectBufferStride  = indirectBufferStride;
+}
+
+VkBuildAccelerationStructureFlagsKHR BottomLevelAccelerationStructureKHR::getBuildFlags () const
+{
+       return m_buildFlags;
+}
+
+void BottomLevelAccelerationStructureKHR::create (const DeviceInterface&                               vk,
+                                                                                                 const VkDevice                                                device,
+                                                                                                 Allocator&                                                    allocator,
+                                                                                                 VkDeviceAddress                                               deviceAddress,
+                                                                                                 VkDeviceSize                                                  compactCopySize)
+{
+       DE_ASSERT(!m_geometriesData.empty() !=  !(compactCopySize==0)); // logical xor
+
+       {
+               std::vector<VkAccelerationStructureCreateGeometryTypeInfoKHR>   accelerationStructureCreateGeometryTypeInfosKHR(m_geometriesData.size());
+
+               for (size_t geometryNdx = 0; geometryNdx < m_geometriesData.size(); ++geometryNdx)
+               {
+                       de::SharedPtr<RaytracedGeometryBase>&   geometryData    =       m_geometriesData[geometryNdx];
+                       const VkAccelerationStructureCreateGeometryTypeInfoKHR  accelerationStructureCreateGeometryTypeInfoKHR  =
+                       {
+                               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR, //  VkStructureType             sType;
+                               DE_NULL,                                                                                                                                //  const void*                 pNext;
+                               geometryData->getGeometryType(),                                                                                //  VkGeometryTypeKHR   geometryType;
+                               geometryData->getPrimitiveCount(),                                                                              //  deUint32                    maxPrimitiveCount;
+                               geometryData->getIndexType(),                                                                                   //  VkIndexType                 indexType;
+                               geometryData->getVertexCount(),                                                                                 //  deUint32                    maxVertexCount;
+                               geometryData->getVertexFormat(),                                                                                //  VkFormat                    vertexFormat;
+                               DE_FALSE                                                                                                                                //  VkBool32                    allowsTransforms;
+                       };
+
+                       accelerationStructureCreateGeometryTypeInfosKHR[geometryNdx] = accelerationStructureCreateGeometryTypeInfoKHR;
+               }
+
+               const VkAccelerationStructureCreateInfoKHR      accelerationStructureCreateInfoKHR      =
+               {
+                       VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR,                                               //  VkStructureType                                                                                     sType;
+                       DE_NULL,                                                                                                                                                //  const void*                                                                                         pNext;
+                       compactCopySize,                                                                                                                                //  VkDeviceSize                                                                                        compactedSize;
+                       VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,                                                                //  VkAccelerationStructureTypeKHR                                                      type;
+                       m_buildFlags,                                                                                                                                   //  VkBuildAccelerationStructureFlagsKHR                                        flags;
+                       static_cast<deUint32>(accelerationStructureCreateGeometryTypeInfosKHR.size()),  //  deUint32                                                                                            maxGeometryCount;
+                       dataOrNullPtr(accelerationStructureCreateGeometryTypeInfosKHR),                                 //  const VkAccelerationStructureCreateGeometryTypeInfoKHR*     pGeometryInfos;
+                       deviceAddress                                                                                                                                   //  VkDeviceAddress                                                                                     deviceAddress;
+               };
+
+               m_accelerationStructureKHR      = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL);
+       }
+
+       {
+               const VkMemoryRequirements      memoryRequirements      = getAccelerationStructureMemoryRequirements(vk, device, m_accelerationStructureKHR.get(), VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR, m_buildType);
+
+               m_accelerationStructureAlloc = allocator.allocate(memoryRequirements, vk::MemoryRequirement::Local);
+       }
+
+       {
+               const VkBindAccelerationStructureMemoryInfoKHR  bindAccelerationStructureMemoryInfoKHR  =
+               {
+                       VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR,  //  VkStructureType                             sType;
+                       DE_NULL,                                                                                                                //  const void*                                 pNext;
+                       m_accelerationStructureKHR.get(),                                                               //  VkAccelerationStructureKHR  accelerationStructure;
+                       m_accelerationStructureAlloc->getMemory(),                                              //  VkDeviceMemory                              memory;
+                       m_accelerationStructureAlloc->getOffset(),                                              //  VkDeviceSize                                memoryOffset;
+                       0,                                                                                                                              //  deUint32                                    deviceIndexCount;
+                       DE_NULL,                                                                                                                //  const deUint32*                             pDeviceIndices;
+               };
+
+               VK_CHECK(vk.bindAccelerationStructureMemoryKHR(device, 1, &bindAccelerationStructureMemoryInfoKHR));
+       }
+
+       {
+               const VkMemoryRequirements              memoryRequirements      = getAccelerationStructureMemoryRequirements(vk, device, m_accelerationStructureKHR.get(), VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR, m_buildType);
+               if (memoryRequirements.size > 0u)
+               {
+                       const VkBufferCreateInfo                bufferCreateInfo        = makeBufferCreateInfo(memoryRequirements.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+                       m_scratchBuffer                                                                         = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
+               }
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR && !m_geometriesData.empty())
+       {
+               m_vertexBuffer  = de::MovePtr<BufferWithMemory>(createVertexBuffer(vk, device, allocator, m_geometriesData));
+               m_indexBuffer   = de::MovePtr<BufferWithMemory>(createIndexBuffer(vk, device, allocator, m_geometriesData));
+       }
+}
+
+void BottomLevelAccelerationStructureKHR::build (const DeviceInterface&                                                vk,
+                                                                                                const VkDevice                                                         device,
+                                                                                                const VkCommandBuffer                                          cmdBuffer)
+{
+       DE_ASSERT(!m_geometriesData.empty());
+       DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               updateVertexBuffer(vk, device, m_geometriesData, m_vertexBuffer.get());
+               if(m_indexBuffer.get() != DE_NULL)
+                       updateIndexBuffer(vk, device, m_geometriesData, m_indexBuffer.get());
+       }
+
+       {
+               std::vector<VkAccelerationStructureGeometryKHR>                 accelerationStructureGeometriesKHR                      (m_geometriesData.size());
+               std::vector<VkAccelerationStructureGeometryKHR*>                accelerationStructureGeometriesKHRPointers      (m_geometriesData.size());
+               std::vector<VkAccelerationStructureBuildOffsetInfoKHR>  accelerationStructureBuildOffsetInfoKHR         (m_geometriesData.size());
+               VkDeviceSize vertexBufferOffset = 0, indexBufferOffset = 0;
+
+               for (size_t geometryNdx = 0; geometryNdx < m_geometriesData.size(); ++geometryNdx)
+               {
+                       de::SharedPtr<RaytracedGeometryBase>&                                   geometryData                                                    = m_geometriesData[geometryNdx];
+                       VkDeviceOrHostAddressConstKHR                                                   vertexData, indexData;
+                       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+                       {
+                               vertexData                      = makeDeviceOrHostAddressConstKHR(vk, device, m_vertexBuffer->get(), vertexBufferOffset);
+                               vertexBufferOffset      += deAlignSize(geometryData->getVertexByteSize(), 8);
+
+                               if (geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
+                               {
+                                       indexData                       = makeDeviceOrHostAddressConstKHR(vk, device, m_indexBuffer->get(), indexBufferOffset);
+                                       indexBufferOffset       += deAlignSize(geometryData->getIndexByteSize(), 8);
+                               }
+                               else
+                                       indexData                       = makeDeviceOrHostAddressConstKHR(DE_NULL);
+                       }
+                       else
+                       {
+                               vertexData      = makeDeviceOrHostAddressConstKHR( geometryData->getVertexPointer() );
+                               if (m_indexBuffer.get() != DE_NULL)
+                                       indexData       = makeDeviceOrHostAddressConstKHR( geometryData->getIndexPointer() );
+                               else
+                                       indexData       = makeDeviceOrHostAddressConstKHR(DE_NULL);
+                       }
+
+                       const VkAccelerationStructureGeometryTrianglesDataKHR   accelerationStructureGeometryTrianglesDataKHR   =
+                       {
+                               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,   //  VkStructureType                                     sType;
+                               DE_NULL,                                                                                                                                //  const void*                                         pNext;
+                               geometryData->getVertexFormat(),                                                                                //  VkFormat                                            vertexFormat;
+                               vertexData,                                                                                                                             //  VkDeviceOrHostAddressConstKHR       vertexData;
+                               geometryData->getVertexStride(),                                                                                //  VkDeviceSize                                        vertexStride;
+                               geometryData->getIndexType(),                                                                                   //  VkIndexType                                         indexType;
+                               indexData,                                                                                                                              //  VkDeviceOrHostAddressConstKHR       indexData;
+                               makeDeviceOrHostAddressConstKHR(DE_NULL),                                                               //  VkDeviceOrHostAddressConstKHR       transformData;
+                       };
+
+                       const VkAccelerationStructureGeometryAabbsDataKHR               accelerationStructureGeometryAabbsDataKHR               =
+                       {
+                               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR,       //  VkStructureType                                     sType;
+                               DE_NULL,                                                                                                                        //  const void*                                         pNext;
+                               vertexData,                                                                                                                     //  VkDeviceOrHostAddressConstKHR       data;
+                               geometryData->getAABBStride()                                                                           //  VkDeviceSize                                        stride;
+                       };
+                       const VkAccelerationStructureGeometryDataKHR                    geometry                                                                                = (geometryData->isTrianglesType())
+                                                                                                                                                                                                                                       ? makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryTrianglesDataKHR)
+                                                                                                                                                                                                                                       : makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryAabbsDataKHR);
+                       const VkAccelerationStructureGeometryKHR                                accelerationStructureGeometryKHR                                =
+                       {
+                               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,  //  VkStructureType                                                     sType;
+                               DE_NULL,                                                                                                //  const void*                                                         pNext;
+                               geometryData->getGeometryType(),                                                //  VkGeometryTypeKHR                                           geometryType;
+                               geometry,                                                                                               //  VkAccelerationStructureGeometryDataKHR      geometry;
+                               geometryData->getGeometryFlags()                                                //  VkGeometryFlagsKHR                                          flags;
+                       };
+
+                       const VkAccelerationStructureBuildOffsetInfoKHR                 accelerationStructureBuildOffsetInfosKHR                =
+                       {
+                               geometryData->getPrimitiveCount(),      //  deUint32    primitiveCount;
+                               0,                                                                      //  deUint32    primitiveOffset;
+                               0,                                                                      //  deUint32    firstVertex;
+                               0                                                                       //  deUint32    firstTransform;
+                       };
+
+                       accelerationStructureGeometriesKHR[geometryNdx]                         = accelerationStructureGeometryKHR;
+                       accelerationStructureGeometriesKHRPointers[geometryNdx]         = &accelerationStructureGeometriesKHR[geometryNdx];
+                       accelerationStructureBuildOffsetInfoKHR[geometryNdx]            = accelerationStructureBuildOffsetInfosKHR;
+               }
+
+               VkAccelerationStructureGeometryKHR*                     accelerationStructureGeometriesKHRPointer       = accelerationStructureGeometriesKHR.data();
+               VkAccelerationStructureGeometryKHR**            accelerationStructureGeometry                           = (m_useArrayOfPointers)
+                                                                                                                                                                                               ? accelerationStructureGeometriesKHRPointers.data()
+                                                                                                                                                                                               : &accelerationStructureGeometriesKHRPointer;
+               VkDeviceOrHostAddressKHR                                        scratchData                                                                     = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+                                                                                                                                                                                               ? makeDeviceOrHostAddressKHR(vk, device, m_scratchBuffer->get(), 0)
+                                                                                                                                                                                               : makeDeviceOrHostAddressKHR(m_scratchBuffer->getAllocation().getHostPtr());
+
+               VkAccelerationStructureBuildGeometryInfoKHR     accelerationStructureBuildGeometryInfoKHR       =
+               {
+                       VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,                       //  VkStructureType                                                             sType;
+                       DE_NULL,                                                                                                                                        //  const void*                                                                 pNext;
+                       VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,                                                        //  VkAccelerationStructureTypeKHR                              type;
+                       m_buildFlags,                                                                                                                           //  VkBuildAccelerationStructureFlagsKHR                flags;
+                       DE_FALSE,                                                                                                                                       //  VkBool32                                                                    update;
+                       DE_NULL,                                                                                                                                        //  VkAccelerationStructureKHR                                  srcAccelerationStructure;
+                       m_accelerationStructureKHR.get(),                                                                                       //  VkAccelerationStructureKHR                                  dstAccelerationStructure;
+                       (VkBool32)( m_useArrayOfPointers ? DE_TRUE : DE_FALSE ),                                        //  VkBool32                                                                    geometryArrayOfPointers;
+                       static_cast<deUint32>(accelerationStructureGeometriesKHR.size()),                       //  deUint32                                                                    geometryCount;
+                       (const VkAccelerationStructureGeometryKHR**)accelerationStructureGeometry,      //  const VkAccelerationStructureGeometryKHR**  ppGeometries;
+                       scratchData                                                                                                                                     //  VkDeviceOrHostAddressKHR                                    scratchData;
+               };
+               VkAccelerationStructureBuildOffsetInfoKHR* accelerationStructureBuildOffsetInfoKHRPtr   = accelerationStructureBuildOffsetInfoKHR.data();
+
+               if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+               {
+                       if (m_indirectBuffer == DE_NULL)
+                               vk.cmdBuildAccelerationStructureKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildOffsetInfoKHR**)&accelerationStructureBuildOffsetInfoKHRPtr);
+                       else
+                               vk.cmdBuildAccelerationStructureIndirectKHR(cmdBuffer, &accelerationStructureBuildGeometryInfoKHR, m_indirectBuffer, m_indirectBufferOffset, m_indirectBufferStride);
+               }
+               else if (!m_deferredOperation)
+               {
+                       VK_CHECK(vk.buildAccelerationStructureKHR(device, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildOffsetInfoKHR**)&accelerationStructureBuildOffsetInfoKHRPtr));
+               }
+               else
+               {
+                       VkDeferredOperationKHR deferredOperation        = DE_NULL;
+
+                       VK_CHECK(vk.createDeferredOperationKHR(device, DE_NULL, &deferredOperation));
+
+                       VkDeferredOperationInfoKHR      deferredOperationInfoKHR        =
+                       {
+                               VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR,  //  VkStructureType                     sType;
+                               DE_NULL,                                                                                //  const void*                         pNext;
+                               deferredOperation                                                               //  VkDeferredOperationKHR      operationHandle;
+                       };
+
+                       accelerationStructureBuildGeometryInfoKHR.pNext = &deferredOperationInfoKHR;
+
+                       VkResult result = vk.buildAccelerationStructureKHR(device, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildOffsetInfoKHR**)&accelerationStructureBuildOffsetInfoKHRPtr);
+
+                       DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
+                       DE_UNREF(result);
+
+                       VK_CHECK(finishDeferredOperation(vk, device, deferredOperation));
+
+                       accelerationStructureBuildGeometryInfoKHR.pNext = DE_NULL;
+               }
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               const VkAccessFlags             accessMasks     = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+               const VkMemoryBarrier   memBarrier      = makeMemoryBarrier(accessMasks, accessMasks);
+
+               cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
+       }
+}
+
+void BottomLevelAccelerationStructureKHR::copyFrom (const DeviceInterface&                                             vk,
+                                                                                                       const VkDevice                                                          device,
+                                                                                                       const VkCommandBuffer                                           cmdBuffer,
+                                                                                                       BottomLevelAccelerationStructure*                       accelerationStructure,
+                                                                                                       VkDeviceSize                                                            compactCopySize)
+{
+       VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo =
+       {
+               VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR,                                                                                                                                 // VkStructureType                                              sType;
+               DE_NULL,                                                                                                                                                                                                                                // const void*                                                  pNext;
+               *(accelerationStructure->getPtr()),                                                                                                                                                                             // VkAccelerationStructureKHR                   src;
+               *(getPtr()),                                                                                                                                                                                                                    // VkAccelerationStructureKHR                   dst;
+               compactCopySize > 0u ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR  // VkCopyAccelerationStructureModeKHR   mode;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               vk.cmdCopyAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
+       }
+       else if (!m_deferredOperation)
+       {
+               VK_CHECK(vk.copyAccelerationStructureKHR(device, &copyAccelerationStructureInfo));
+       }
+       else
+       {
+               VkDeferredOperationKHR deferredOperation        = DE_NULL;
+
+               VK_CHECK(vk.createDeferredOperationKHR(device, DE_NULL, &deferredOperation));
+
+               VkDeferredOperationInfoKHR      deferredOperationInfoKHR        =
+               {
+                       VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR,  //  VkStructureType                     sType;
+                       DE_NULL,                                                                                //  const void*                         pNext;
+                       deferredOperation                                                               //  VkDeferredOperationKHR      operationHandle;
+               };
+
+               copyAccelerationStructureInfo.pNext = &deferredOperationInfoKHR;
+
+               VkResult result = vk.copyAccelerationStructureKHR(device, &copyAccelerationStructureInfo);
+
+               DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
+               DE_UNREF(result);
+
+               VK_CHECK(finishDeferredOperation(vk, device, deferredOperation));
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               const VkAccessFlags             accessMasks     = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+               const VkMemoryBarrier   memBarrier      = makeMemoryBarrier(accessMasks, accessMasks);
+
+               cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
+       }
+}
+
+void BottomLevelAccelerationStructureKHR::serialize (const DeviceInterface&            vk,
+                                                                                                        const VkDevice                         device,
+                                                                                                        const VkCommandBuffer          cmdBuffer,
+                                                                                                        SerialStorage*                         storage)
+{
+       VkCopyAccelerationStructureToMemoryInfoKHR copyAccelerationStructureInfo =
+       {
+               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;
+               VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR                                       // VkCopyAccelerationStructureModeKHR   mode;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, &copyAccelerationStructureInfo);
+       }
+       else
+       {
+               VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, &copyAccelerationStructureInfo));
+       }
+       // There is no deferred operation for vkCopyAccelerationStructureToMemoryKHR
+}
+
+void BottomLevelAccelerationStructureKHR::deserialize (const DeviceInterface&  vk,
+                                                                                                          const VkDevice                       device,
+                                                                                                          const VkCommandBuffer        cmdBuffer,
+                                                                                                          SerialStorage*                       storage)
+{
+       VkCopyMemoryToAccelerationStructureInfoKHR copyAccelerationStructureInfo =
+       {
+               VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR,       // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                                        // const void*                                                          pNext;
+               storage->getAddressConst(vk,device),                                                            // VkDeviceOrHostAddressConstKHR                        src;
+               *(getPtr()),                                                                                                            // VkAccelerationStructureKHR                           dst;
+               VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR                                     // VkCopyAccelerationStructureModeKHR           mode;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
+       }
+       else
+       {
+               VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, &copyAccelerationStructureInfo));
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               const VkAccessFlags             accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+               const VkMemoryBarrier   memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
+
+               cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
+       }
+}
+
+const VkAccelerationStructureKHR* BottomLevelAccelerationStructureKHR::getPtr (void) const
+{
+       return &m_accelerationStructureKHR.get();
+}
+
+deUint32 BottomLevelAccelerationStructure::getRequiredAllocationCount (void)
+{
+       return BottomLevelAccelerationStructureKHR::getRequiredAllocationCount();
+}
+
+void BottomLevelAccelerationStructure::createAndBuild (const DeviceInterface&  vk,
+                                                                                                          const VkDevice                       device,
+                                                                                                          const VkCommandBuffer        cmdBuffer,
+                                                                                                          Allocator&                           allocator,
+                                                                                                          VkDeviceAddress                      deviceAddress)
+{
+       create(vk, device, allocator, deviceAddress, 0u);
+       build(vk, device, cmdBuffer);
+}
+
+void BottomLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface&                               vk,
+                                                                                                                 const VkDevice                                                device,
+                                                                                                                 const VkCommandBuffer                                 cmdBuffer,
+                                                                                                                 Allocator&                                                    allocator,
+                                                                                                                 VkDeviceAddress                                               deviceAddress,
+                                                                                                                 BottomLevelAccelerationStructure*             accelerationStructure,
+                                                                                                                 VkDeviceSize                                                  compactCopySize)
+{
+       create(vk, device, allocator, deviceAddress, compactCopySize);
+       copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize);
+}
+
+void BottomLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
+                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                VkDeviceAddress                                                        deviceAddress,
+                                                                                                                                SerialStorage*                                                         storage)
+{
+       create(vk, device, allocator, deviceAddress, 0u);
+       deserialize(vk, device, cmdBuffer, storage);
+}
+
+de::MovePtr<BottomLevelAccelerationStructure> makeBottomLevelAccelerationStructure ()
+{
+       return de::MovePtr<BottomLevelAccelerationStructure>(new BottomLevelAccelerationStructureKHR);
+}
+
+TopLevelAccelerationStructure::~TopLevelAccelerationStructure ()
+{
+}
+
+TopLevelAccelerationStructure::TopLevelAccelerationStructure ()
+       : m_bottomLevelInstances        ()
+{
+}
+
+void TopLevelAccelerationStructure::setInstanceCount (const size_t instanceCount)
+{
+       m_bottomLevelInstances.reserve(instanceCount);
+       m_instanceData.reserve(instanceCount);
+}
+
+void TopLevelAccelerationStructure::addInstance (de::SharedPtr<BottomLevelAccelerationStructure>       bottomLevelStructure,
+                                                                                                const VkTransformMatrixKHR&                                            matrix,
+                                                                                                deUint32                                                                                       instanceCustomIndex,
+                                                                                                deUint32                                                                                       mask,
+                                                                                                deUint32                                                                                       instanceShaderBindingTableRecordOffset,
+                                                                                                VkGeometryInstanceFlagsKHR                                                     flags)
+{
+       m_bottomLevelInstances.push_back(bottomLevelStructure);
+       m_instanceData.push_back(InstanceData(matrix, instanceCustomIndex, mask, instanceShaderBindingTableRecordOffset, flags));
+}
+
+void TopLevelAccelerationStructure::createAndBuild (const DeviceInterface&     vk,
+                                                                                                       const VkDevice                  device,
+                                                                                                       const VkCommandBuffer   cmdBuffer,
+                                                                                                       Allocator&                              allocator,
+                                                                                                       VkDeviceAddress                 deviceAddress)
+{
+       create(vk, device, allocator, deviceAddress, 0u);
+       build(vk, device, cmdBuffer);
+}
+
+void TopLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface&                          vk,
+                                                                                                          const VkDevice                                               device,
+                                                                                                          const VkCommandBuffer                                cmdBuffer,
+                                                                                                          Allocator&                                                   allocator,
+                                                                                                          VkDeviceAddress                                              deviceAddress,
+                                                                                                          TopLevelAccelerationStructure*               accelerationStructure,
+                                                                                                          VkDeviceSize                                                 compactCopySize)
+{
+       create(vk, device, allocator, deviceAddress, compactCopySize);
+       copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize);
+}
+
+void TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
+                                                                                                                         const VkDevice                                                        device,
+                                                                                                                         const VkCommandBuffer                                         cmdBuffer,
+                                                                                                                         Allocator&                                                            allocator,
+                                                                                                                         VkDeviceAddress                                                       deviceAddress,
+                                                                                                                         SerialStorage*                                                        storage)
+{
+       create(vk, device, allocator, deviceAddress, 0u);
+       deserialize(vk, device, cmdBuffer, storage);
+}
+
+BufferWithMemory* createInstanceBuffer (const DeviceInterface&                                                                                 vk,
+                                                                               const VkDevice                                                                                                  device,
+                                                                               Allocator&                                                                                                              allocator,
+                                                                               std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >   bottomLevelInstances,
+                                                                               std::vector<InstanceData>                                                                               instanceData)
+{
+       DE_ASSERT(bottomLevelInstances.size() != 0);
+       DE_ASSERT(bottomLevelInstances.size() == instanceData.size());
+       DE_UNREF(instanceData);
+
+       const VkDeviceSize                      bufferSizeBytes         = bottomLevelInstances.size() * sizeof(VkAccelerationStructureInstanceKHR);
+       const VkBufferCreateInfo        bufferCreateInfo        = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+       return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
+}
+
+void updateInstanceBuffer (const DeviceInterface&                                                                                      vk,
+                                                  const VkDevice                                                                                                       device,
+                                                  std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >        bottomLevelInstances,
+                                                  std::vector<InstanceData>                                                                            instanceData,
+                                                  BufferWithMemory*                                                                                            instanceBuffer,
+                                                  VkAccelerationStructureBuildTypeKHR                                                          buildType)
+{
+       DE_ASSERT(bottomLevelInstances.size() != 0);
+       DE_ASSERT(bottomLevelInstances.size() == instanceData.size());
+
+       const Allocation&                       instancesAlloc          = instanceBuffer->getAllocation();
+
+       deUint8*                                        bufferStart                     = static_cast<deUint8*>(instancesAlloc.getHostPtr());
+       VkDeviceSize                            bufferOffset            = 0;
+
+       for (size_t instanceNdx = 0; instanceNdx < bottomLevelInstances.size(); ++instanceNdx)
+       {
+               const BottomLevelAccelerationStructure&         bottomLevelAccelerationStructure        = *bottomLevelInstances[instanceNdx];
+               const VkAccelerationStructureKHR                        accelerationStructureKHR                        = *bottomLevelAccelerationStructure.getPtr();
+
+               // This part needs to be fixed once a new version of the VkAccelerationStructureInstanceKHR will be added to vkStructTypes.inl
+               VkDeviceAddress accelerationStructureAddress;
+               if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+               {
+                       VkAccelerationStructureDeviceAddressInfoKHR asDeviceAddressInfo =
+                       {
+                               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,       // VkStructureType                              sType;
+                               DE_NULL,                                                                                                                        // const void*                                  pNext;
+                               accelerationStructureKHR                                                                                        // VkAccelerationStructureKHR   accelerationStructure;
+                       };
+                       accelerationStructureAddress = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo);
+               }
+
+               const deUint64 structureReference       = (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+                                                                                       ? deUint64(accelerationStructureAddress)
+                                                                                       : deUint64(&accelerationStructureKHR);
+
+               VkAccelerationStructureInstanceKHR      accelerationStructureInstanceKHR = makeVkAccelerationStructureInstanceKHR
+               (
+                       instanceData[instanceNdx].matrix,                                                                                                       //  VkTransformMatrixKHR                transform;
+                       instanceData[instanceNdx].instanceCustomIndex,                                                                          //  deUint32                                    instanceCustomIndex:24;
+                       instanceData[instanceNdx].mask,                                                                                                         //  deUint32                                    mask:8;
+                       instanceData[instanceNdx].instanceShaderBindingTableRecordOffset,                                       //  deUint32                                    instanceShaderBindingTableRecordOffset:24;
+                       instanceData[instanceNdx].flags,                                                                                                        //  VkGeometryInstanceFlagsKHR  flags:8;
+                       structureReference                                                                                                                                      //  deUint64                                    accelerationStructureReference;
+               );
+
+               deMemcpy(&bufferStart[bufferOffset], &accelerationStructureInstanceKHR, sizeof(VkAccelerationStructureInstanceKHR));
+
+               bufferOffset += sizeof(VkAccelerationStructureInstanceKHR);
+       }
+
+       flushMappedMemoryRange(vk, device, instancesAlloc.getMemory(), instancesAlloc.getOffset(), VK_WHOLE_SIZE);
+}
+
+class TopLevelAccelerationStructureKHR : public TopLevelAccelerationStructure
+{
+public:
+       static deUint32                                                                                 getRequiredAllocationCount                                                      (void);
+
+                                                                                                                       TopLevelAccelerationStructureKHR                                        ();
+                                                                                                                       TopLevelAccelerationStructureKHR                                        (const TopLevelAccelerationStructureKHR&        other) = delete;
+       virtual                                                                                                 ~TopLevelAccelerationStructureKHR                                       ();
+
+       void                                                                                                    setBuildType                                                                            (const VkAccelerationStructureBuildTypeKHR      buildType) override;
+       void                                                                                                    setBuildFlags                                                                           (const VkBuildAccelerationStructureFlagsKHR     flags) override;
+       void                                                                                                    setDeferredOperation                                                            (const bool                                                                     deferredOperation) override;
+       void                                                                                                    setUseArrayOfPointers                                                           (const bool                                                                     useArrayOfPointers) override;
+       void                                                                                                    setIndirectBuildParameters                                                      (const VkBuffer                                                         indirectBuffer,
+                                                                                                                                                                                                                                const VkDeviceSize                                                     indirectBufferOffset,
+                                                                                                                                                                                                                                const deUint32                                                         indirectBufferStride) override;
+       VkBuildAccelerationStructureFlagsKHR                                    getBuildFlags                                                                           () const override;
+
+       void                                                                                                    create                                                                                          (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress,
+                                                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize) override;
+       void                                                                                                    build                                                                                           (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer) override;
+       void                                                                                                    copyFrom                                                                                        (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                                TopLevelAccelerationStructure*                         accelerationStructure,
+                                                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize) override;
+
+       void                                                                                                    serialize                                                                                       (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                                SerialStorage*                                                         storage) override;
+       void                                                                                                    deserialize                                                                                     (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                                SerialStorage*                                                         storage) override;
+
+       const VkAccelerationStructureKHR*                                               getPtr                                                                                          (void) const override;
+
+protected:
+       VkAccelerationStructureBuildTypeKHR                                             m_buildType;
+       VkBuildAccelerationStructureFlagsKHR                                    m_buildFlags;
+       bool                                                                                                    m_deferredOperation;
+       bool                                                                                                    m_useArrayOfPointers;
+       de::MovePtr<BufferWithMemory>                                                   m_instanceBuffer;
+       de::MovePtr<BufferWithMemory>                                                   m_instanceAddressBuffer;
+       de::MovePtr<Allocation>                                                                 m_accelerationStructureAlloc;
+       de::MovePtr<BufferWithMemory>                                                   m_scratchBuffer;
+       Move<VkAccelerationStructureKHR>                                                m_accelerationStructureKHR;
+       VkBuffer                                                                                                m_indirectBuffer;
+       VkDeviceSize                                                                                    m_indirectBufferOffset;
+       deUint32                                                                                                m_indirectBufferStride;
+};
+
+deUint32 TopLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
+{
+       /*
+               de::MovePtr<BufferWithMemory>                                                   m_instanceBuffer;
+               de::MovePtr<Allocation>                                                                 m_accelerationStructureAlloc;
+               de::MovePtr<BufferWithMemory>                                                   m_scratchBuffer;
+       */
+       return 3u;
+}
+
+TopLevelAccelerationStructureKHR::TopLevelAccelerationStructureKHR ()
+       : TopLevelAccelerationStructure ()
+       , m_buildType                                   (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       , m_buildFlags                                  (0u)
+       , m_deferredOperation                   (false)
+       , m_useArrayOfPointers                  (false)
+       , m_instanceBuffer                              ()
+       , m_instanceAddressBuffer               ()
+       , m_accelerationStructureAlloc  ()
+       , m_scratchBuffer                               ()
+       , m_accelerationStructureKHR    ()
+       , m_indirectBuffer                              (DE_NULL)
+       , m_indirectBufferOffset                (0)
+       , m_indirectBufferStride                (0)
+{
+}
+
+TopLevelAccelerationStructureKHR::~TopLevelAccelerationStructureKHR ()
+{
+}
+
+void TopLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR buildType)
+{
+       m_buildType = buildType;
+}
+
+void TopLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR       flags)
+{
+       m_buildFlags = flags;
+}
+
+void TopLevelAccelerationStructureKHR::setDeferredOperation (const bool        deferredOperation)
+{
+       m_deferredOperation = deferredOperation;
+}
+
+void TopLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool       useArrayOfPointers)
+{
+       m_useArrayOfPointers = useArrayOfPointers;
+}
+
+void TopLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer              indirectBuffer,
+                                                                                                                                  const VkDeviceSize   indirectBufferOffset,
+                                                                                                                                  const deUint32               indirectBufferStride)
+{
+       m_indirectBuffer                = indirectBuffer;
+       m_indirectBufferOffset  = indirectBufferOffset;
+       m_indirectBufferStride  = indirectBufferStride;
+}
+
+VkBuildAccelerationStructureFlagsKHR TopLevelAccelerationStructureKHR::getBuildFlags () const
+{
+       return m_buildFlags;
+}
+
+void TopLevelAccelerationStructureKHR::create (const DeviceInterface&                          vk,
+                                                                                          const VkDevice                                               device,
+                                                                                          Allocator&                                                   allocator,
+                                                                                          VkDeviceAddress                                              deviceAddress,
+                                                                                          VkDeviceSize                                                 compactCopySize)
+{
+       DE_ASSERT(!m_bottomLevelInstances.empty() != !(compactCopySize == 0)); // logical xor
+
+       {
+               const VkAccelerationStructureCreateGeometryTypeInfoKHR  accelerationStructureCreateGeometryTypeInfoKHR          =
+               {
+                       VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR, //  VkStructureType             sType;
+                       DE_NULL,                                                                                                                                //  const void*                 pNext;
+                       VK_GEOMETRY_TYPE_INSTANCES_KHR,                                                                                 //  VkGeometryTypeKHR   geometryType;
+                       static_cast<deUint32>(m_bottomLevelInstances.size()),                                   //  deUint32                    maxPrimitiveCount;
+                       VK_INDEX_TYPE_NONE_KHR,                                                                                                 //  VkIndexType                 indexType;
+                       0u,                                                                                                                                             //  deUint32                    maxVertexCount;
+                       VK_FORMAT_UNDEFINED,                                                                                                    //  VkFormat                    vertexFormat;
+                       DE_FALSE                                                                                                                                //  VkBool32                    allowsTransforms;
+               };
+               const VkAccelerationStructureCreateInfoKHR                              accelerationStructureCreateInfoKHR                                      =
+               {
+                       VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR,       //  VkStructureType                                                                                     sType;
+                       DE_NULL,                                                                                                        //  const void*                                                                                         pNext;
+                       compactCopySize,                                                                                        //  VkDeviceSize                                                                                        compactedSize;
+                       VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,                           //  VkAccelerationStructureTypeKHR                                                      type;
+                       m_buildFlags,                                                                                           //  VkBuildAccelerationStructureFlagsKHR                                        flags;
+                       1u,                                                                                                                     //  deUint32                                                                                            maxGeometryCount;
+                       &accelerationStructureCreateGeometryTypeInfoKHR,                        //  const VkAccelerationStructureCreateGeometryTypeInfoKHR*     pGeometryInfos;
+                       deviceAddress                                                                                           //  VkDeviceAddress                                                                                     deviceAddress;
+               };
+
+               m_accelerationStructureKHR      = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL);
+       }
+
+       {
+               const VkMemoryRequirements      memoryRequirements      = getAccelerationStructureMemoryRequirements(vk, device, m_accelerationStructureKHR.get(), VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR, m_buildType);
+
+               m_accelerationStructureAlloc = allocator.allocate(memoryRequirements, vk::MemoryRequirement::Local);
+       }
+
+       {
+               const VkBindAccelerationStructureMemoryInfoKHR  bindAccelerationStructureMemoryInfoKHR  =
+               {
+                       VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR,  //  VkStructureType                             sType;
+                       DE_NULL,                                                                                                                //  const void*                                 pNext;
+                       m_accelerationStructureKHR.get(),                                                               //  VkAccelerationStructureKHR  accelerationStructure;
+                       m_accelerationStructureAlloc->getMemory(),                                              //  VkDeviceMemory                              memory;
+                       m_accelerationStructureAlloc->getOffset(),                                              //  VkDeviceSize                                memoryOffset;
+                       0,                                                                                                                              //  deUint32                                    deviceIndexCount;
+                       DE_NULL,                                                                                                                //  const deUint32*                             pDeviceIndices;
+               };
+
+               VK_CHECK(vk.bindAccelerationStructureMemoryKHR(device, 1, &bindAccelerationStructureMemoryInfoKHR));
+       }
+
+       {
+               const VkMemoryRequirements      memoryRequirements              = getAccelerationStructureMemoryRequirements(vk, device, m_accelerationStructureKHR.get(), VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR, m_buildType);
+               if(memoryRequirements.size > 0u)
+               {
+                       const VkBufferCreateInfo                bufferCreateInfo        = makeBufferCreateInfo(memoryRequirements.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+                       m_scratchBuffer                                                                         = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
+               }
+       }
+
+       if (m_useArrayOfPointers)
+       {
+               const VkBufferCreateInfo        bufferCreateInfo = makeBufferCreateInfo(m_bottomLevelInstances.size() * sizeof(VkDeviceOrHostAddressConstKHR), VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
+               m_instanceAddressBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
+       }
+
+       if(!m_bottomLevelInstances.empty())
+               m_instanceBuffer = de::MovePtr<BufferWithMemory>(createInstanceBuffer(vk, device, allocator, m_bottomLevelInstances, m_instanceData));
+}
+
+void TopLevelAccelerationStructureKHR::build (const DeviceInterface&   vk,
+                                                                                         const VkDevice                        device,
+                                                                                         const VkCommandBuffer         cmdBuffer)
+{
+       DE_ASSERT(!m_bottomLevelInstances.empty());
+       DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
+
+       updateInstanceBuffer(vk, device, m_bottomLevelInstances, m_instanceData, m_instanceBuffer.get(), m_buildType);
+
+       VkDeviceOrHostAddressConstKHR                                                   instancesData;
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               if (m_useArrayOfPointers)
+               {
+                       deUint8*                                                bufferStart                     = static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr());
+                       VkDeviceSize                                    bufferOffset            = 0;
+                       VkDeviceOrHostAddressConstKHR   firstInstance           = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0);
+                       for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
+                       {
+                               VkDeviceOrHostAddressConstKHR   currentInstance;
+                               currentInstance.deviceAddress   = firstInstance.deviceAddress + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR);
+
+                               deMemcpy(&bufferStart[bufferOffset], &currentInstance, sizeof(VkDeviceOrHostAddressConstKHR));
+                               bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR);
+                       }
+                       flushMappedMemoryRange(vk, device, m_instanceAddressBuffer->getAllocation().getMemory(), m_instanceAddressBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
+
+                       instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceAddressBuffer->get(), 0);
+               }
+               else
+                       instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0);
+       }
+       else
+       {
+               if (m_useArrayOfPointers)
+               {
+                       deUint8*                                                bufferStart                     = static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr());
+                       VkDeviceSize                                    bufferOffset            = 0;
+                       for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
+                       {
+                               VkDeviceOrHostAddressConstKHR   currentInstance;
+                               currentInstance.hostAddress     = (deUint8*)m_instanceBuffer->getAllocation().getHostPtr() + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR);
+
+                               deMemcpy(&bufferStart[bufferOffset], &currentInstance, sizeof(VkDeviceOrHostAddressConstKHR));
+                               bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR);
+                       }
+                       instancesData = makeDeviceOrHostAddressConstKHR(m_instanceAddressBuffer->getAllocation().getHostPtr());
+               }
+               else
+                       instancesData = makeDeviceOrHostAddressConstKHR(m_instanceBuffer->getAllocation().getHostPtr());
+       }
+
+       VkAccelerationStructureGeometryInstancesDataKHR accelerationStructureGeometryInstancesDataKHR   =
+       {
+               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR,   //  VkStructureType                                     sType;
+               DE_NULL,                                                                                                                                //  const void*                                         pNext;
+               (VkBool32)( m_useArrayOfPointers ? DE_TRUE : DE_FALSE ),                                //  VkBool32                                            arrayOfPointers;
+               instancesData                                                                                                                   //  VkDeviceOrHostAddressConstKHR       data;
+       };
+
+       VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR                                     =
+       {
+               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,                                                                          //  VkStructureType                                                     sType;
+               DE_NULL,                                                                                                                                                                        //  const void*                                                         pNext;
+               VK_GEOMETRY_TYPE_INSTANCES_KHR,                                                                                                                         //  VkGeometryTypeKHR                                           geometryType;
+               makeVkAccelerationStructureInstancesDataKHR(accelerationStructureGeometryInstancesDataKHR),     //  VkAccelerationStructureGeometryDataKHR      geometry;
+               (VkGeometryFlagsKHR)0u                                                                                                                                          //  VkGeometryFlagsKHR                                          flags;
+       };
+       VkAccelerationStructureGeometryKHR* accelerationStructureGeometryKHRPointer                     = &accelerationStructureGeometryKHR;
+
+       VkDeviceOrHostAddressKHR                                                        scratchData;
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+               scratchData = makeDeviceOrHostAddressKHR(vk, device, m_scratchBuffer->get(), 0);
+       else
+               scratchData = makeDeviceOrHostAddressKHR(m_scratchBuffer->getAllocation().getHostPtr());
+
+       VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR           =
+       {
+               VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,                                               //  VkStructureType                                                             sType;
+               DE_NULL,                                                                                                                                                                //  const void*                                                                 pNext;
+               VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,                                                                                   //  VkAccelerationStructureTypeKHR                              type;
+               m_buildFlags,                                                                                                                                                   //  VkBuildAccelerationStructureFlagsKHR                flags;
+               DE_FALSE,                                                                                                                                                               //  VkBool32                                                                    update;
+               DE_NULL,                                                                                                                                                                //  VkAccelerationStructureKHR                                  srcAccelerationStructure;
+               m_accelerationStructureKHR.get(),                                                                                                               //  VkAccelerationStructureKHR                                  dstAccelerationStructure;
+               DE_FALSE,                                                                                                                                                               //  VkBool32                                                                    geometryArrayOfPointers;
+               1u,                                                                                                                                                                             //  deUint32                                                                    geometryCount;
+               (const VkAccelerationStructureGeometryKHR**)&accelerationStructureGeometryKHRPointer,   //  const VkAccelerationStructureGeometryKHR**  ppGeometries;
+               scratchData                                                                                                                                                             //  VkDeviceOrHostAddressKHR                                    scratchData;
+       };
+
+       VkAccelerationStructureBuildOffsetInfoKHR accelerationStructureBuildOffsetInfoKHR               =
+       {
+               (deUint32)m_bottomLevelInstances.size(),        //  deUint32    primitiveCount;
+               0,                                                                                      //  deUint32    primitiveOffset;
+               0,                                                                                      //  deUint32    firstVertex;
+               0                                                                                       //  deUint32    firstTransform;
+       };
+       VkAccelerationStructureBuildOffsetInfoKHR* accelerationStructureBuildOffsetInfoKHRPtr   = &accelerationStructureBuildOffsetInfoKHR;
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               if (m_indirectBuffer == DE_NULL)
+                       vk.cmdBuildAccelerationStructureKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildOffsetInfoKHR**)&accelerationStructureBuildOffsetInfoKHRPtr);
+               else
+                       vk.cmdBuildAccelerationStructureIndirectKHR(cmdBuffer, &accelerationStructureBuildGeometryInfoKHR, m_indirectBuffer, m_indirectBufferOffset, m_indirectBufferStride);
+       }
+       else if (!m_deferredOperation)
+       {
+               VK_CHECK(vk.buildAccelerationStructureKHR(device, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildOffsetInfoKHR**)&accelerationStructureBuildOffsetInfoKHRPtr));
+       }
+       else
+       {
+               VkDeferredOperationKHR deferredOperation        = DE_NULL;
+
+               VK_CHECK(vk.createDeferredOperationKHR(device, DE_NULL, &deferredOperation));
+
+               VkDeferredOperationInfoKHR      deferredOperationInfoKHR        =
+               {
+                       VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR,  //  VkStructureType                     sType;
+                       DE_NULL,                                                                                //  const void*                         pNext;
+                       deferredOperation                                                               //  VkDeferredOperationKHR      operationHandle;
+               };
+
+               accelerationStructureBuildGeometryInfoKHR.pNext = &deferredOperationInfoKHR;
+
+               VkResult result = vk.buildAccelerationStructureKHR(device, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildOffsetInfoKHR**)&accelerationStructureBuildOffsetInfoKHRPtr);
+
+               DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
+               DE_UNREF(result);
+
+               VK_CHECK(finishDeferredOperation(vk, device, deferredOperation));
+
+               accelerationStructureBuildGeometryInfoKHR.pNext = DE_NULL;
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               const VkAccessFlags             accessMasks     = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+               const VkMemoryBarrier   memBarrier      = makeMemoryBarrier(accessMasks, accessMasks);
+
+               cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
+       }
+}
+
+void TopLevelAccelerationStructureKHR::copyFrom (const DeviceInterface&                                vk,
+                                                                                                const VkDevice                                         device,
+                                                                                                const VkCommandBuffer                          cmdBuffer,
+                                                                                                TopLevelAccelerationStructure*         accelerationStructure,
+                                                                                                VkDeviceSize                                           compactCopySize)
+{
+       VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo =
+       {
+               VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR,                                                                                                                                 // VkStructureType                                              sType;
+               DE_NULL,                                                                                                                                                                                                                                // const void*                                                  pNext;
+               *(accelerationStructure->getPtr()),                                                                                                                                                                             // VkAccelerationStructureKHR                   src;
+               *(getPtr()),                                                                                                                                                                                                                    // VkAccelerationStructureKHR                   dst;
+               compactCopySize > 0u ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR  // VkCopyAccelerationStructureModeKHR   mode;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               vk.cmdCopyAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
+       }
+       else if (!m_deferredOperation)
+       {
+               VK_CHECK(vk.copyAccelerationStructureKHR(device, &copyAccelerationStructureInfo));
+       }
+       else
+       {
+               VkDeferredOperationKHR deferredOperation        = DE_NULL;
+
+               VK_CHECK(vk.createDeferredOperationKHR(device, DE_NULL, &deferredOperation));
+
+               VkDeferredOperationInfoKHR      deferredOperationInfoKHR        =
+               {
+                       VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR,  //  VkStructureType                     sType;
+                       DE_NULL,                                                                                //  const void*                         pNext;
+                       deferredOperation                                                               //  VkDeferredOperationKHR      operationHandle;
+               };
+
+               copyAccelerationStructureInfo.pNext = &deferredOperationInfoKHR;
+
+               VkResult result = vk.copyAccelerationStructureKHR(device, &copyAccelerationStructureInfo);
+
+               DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
+               DE_UNREF(result);
+
+               VK_CHECK(finishDeferredOperation(vk, device, deferredOperation));
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               const VkAccessFlags             accessMasks     = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+               const VkMemoryBarrier   memBarrier      = makeMemoryBarrier(accessMasks, accessMasks);
+
+               cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
+       }
+
+}
+
+void TopLevelAccelerationStructureKHR::serialize (const DeviceInterface&       vk,
+                                                                                                 const VkDevice                        device,
+                                                                                                 const VkCommandBuffer         cmdBuffer,
+                                                                                                 SerialStorage*                        storage)
+{
+       VkCopyAccelerationStructureToMemoryInfoKHR copyAccelerationStructureInfo =
+       {
+               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;
+               VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR                                       // VkCopyAccelerationStructureModeKHR   mode;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, &copyAccelerationStructureInfo);
+       }
+       else
+       {
+               VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, &copyAccelerationStructureInfo));
+       }
+       // There is no deferred operation for vkCopyAccelerationStructureToMemoryKHR
+}
+
+void TopLevelAccelerationStructureKHR::deserialize (const DeviceInterface&     vk,
+                                                                                                       const VkDevice                  device,
+                                                                                                       const VkCommandBuffer   cmdBuffer,
+                                                                                                       SerialStorage*                  storage)
+{
+       VkCopyMemoryToAccelerationStructureInfoKHR copyAccelerationStructureInfo =
+       {
+               VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR,       // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                                        // const void*                                                          pNext;
+               storage->getAddressConst(vk,device),                                                            // VkDeviceOrHostAddressConstKHR                        src;
+               *(getPtr()),                                                                                                            // VkAccelerationStructureKHR                           dst;
+               VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR                                     // VkCopyAccelerationStructureModeKHR           mode;
+       };
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
+       }
+       else
+       {
+               VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, &copyAccelerationStructureInfo));
+       }
+
+       if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               const VkAccessFlags             accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+               const VkMemoryBarrier   memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
+
+               cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
+       }
+}
+
+const VkAccelerationStructureKHR* TopLevelAccelerationStructureKHR::getPtr (void) const
+{
+       return &m_accelerationStructureKHR.get();
+}
+
+deUint32 TopLevelAccelerationStructure::getRequiredAllocationCount (void)
+{
+       return TopLevelAccelerationStructureKHR::getRequiredAllocationCount();
+}
+
+de::MovePtr<TopLevelAccelerationStructure> makeTopLevelAccelerationStructure ()
+{
+       return de::MovePtr<TopLevelAccelerationStructure>(new TopLevelAccelerationStructureKHR);
+}
+
+bool queryAccelerationStructureSizeKHR (const DeviceInterface&                                                 vk,
+                                                                               const VkDevice                                                                  device,
+                                                                               const VkCommandBuffer                                                   cmdBuffer,
+                                                                               const std::vector<VkAccelerationStructureKHR>&  accelerationStructureHandles,
+                                                                               VkAccelerationStructureBuildTypeKHR                             buildType,
+                                                                               const VkQueryPool                                                               queryPool,
+                                                                               VkQueryType                                                                             queryType,
+                                                                               deUint32                                                                                firstQuery,
+                                                                               std::vector<VkDeviceSize>&                                              results)
+{
+       DE_ASSERT(queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR || queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR);
+
+       if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
+       {
+               // queryPool must be large enough to contain at least (firstQuery + accelerationStructureHandles.size()) queries
+               vk.cmdResetQueryPool(cmdBuffer, queryPool, firstQuery, deUint32(accelerationStructureHandles.size()));
+               vk.cmdWriteAccelerationStructuresPropertiesKHR(cmdBuffer, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType, queryPool, firstQuery);
+               // results cannot be retrieved to CPU at the moment - you need to do it using getQueryPoolResults after cmdBuffer is executed. Meanwhile function returns a vector of 0s.
+               results.resize(accelerationStructureHandles.size(), 0u);
+               return false;
+       }
+       // buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR
+       results.resize(accelerationStructureHandles.size(), 0u);
+       vk.writeAccelerationStructuresPropertiesKHR(device, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType, sizeof(VkDeviceSize), results.data(), sizeof(VkDeviceSize));
+       // results will contain proper values
+       return true;
+}
+
+bool queryAccelerationStructureSize (const DeviceInterface&                                                    vk,
+                                                                        const VkDevice                                                                 device,
+                                                                        const VkCommandBuffer                                                  cmdBuffer,
+                                                                        const std::vector<VkAccelerationStructureKHR>& accelerationStructureHandles,
+                                                                        VkAccelerationStructureBuildTypeKHR                    buildType,
+                                                                        const VkQueryPool                                                              queryPool,
+                                                                        VkQueryType                                                                    queryType,
+                                                                        deUint32                                                                               firstQuery,
+                                                                        std::vector<VkDeviceSize>&                                             results)
+{
+       return queryAccelerationStructureSizeKHR(vk, device, cmdBuffer, accelerationStructureHandles, buildType, queryPool, queryType, firstQuery, results);
+}
+
+RayTracingPipeline::RayTracingPipeline ()
+       : m_shadersModules                      ()
+       , m_pipelineLibraries           ()
+       , m_shaderCreateInfos           ()
+       , m_shadersGroupCreateInfos     ()
+       , m_pipelineCreateFlags         (0U)
+       , m_maxRecursionDepth           (1U)
+       , m_maxPayloadSize                      (0U)
+       , m_maxAttributeSize            (0U)
+       , m_maxCallableSize                     (0U)
+       , m_deferredOperation           (false)
+{
+}
+
+RayTracingPipeline::~RayTracingPipeline ()
+{
+}
+
+#define CHECKED_ASSIGN_SHADER(SHADER, STAGE)                                           \
+       if (SHADER == VK_SHADER_UNUSED_KHR)                                                             \
+               SHADER = STAGE;                                                                                         \
+       else                                                                                                                    \
+               TCU_THROW(InternalError, "Attempt to reassign shader")
+
+void RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, Move<VkShaderModule> shaderModule, deUint32 group)
+{
+       if (group >= m_shadersGroupCreateInfos.size())
+       {
+               for (size_t groupNdx = m_shadersGroupCreateInfos.size(); groupNdx <= group; ++groupNdx)
+               {
+                       VkRayTracingShaderGroupCreateInfoKHR    shaderGroupCreateInfo   =
+                       {
+                               VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,     //  VkStructureType                                     sType;
+                               DE_NULL,                                                                                                        //  const void*                                         pNext;
+                               VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR,                          //  VkRayTracingShaderGroupTypeKHR      type;
+                               VK_SHADER_UNUSED_KHR,                                                                           //  deUint32                                            generalShader;
+                               VK_SHADER_UNUSED_KHR,                                                                           //  deUint32                                            closestHitShader;
+                               VK_SHADER_UNUSED_KHR,                                                                           //  deUint32                                            anyHitShader;
+                               VK_SHADER_UNUSED_KHR,                                                                           //  deUint32                                            intersectionShader;
+                               DE_NULL,                                                                                                        //  const void*                                         pShaderGroupCaptureReplayHandle;
+                       };
+
+                       m_shadersGroupCreateInfos.push_back(shaderGroupCreateInfo);
+               }
+       }
+
+       const deUint32                                                  shaderStageNdx                  = (deUint32)m_shaderCreateInfos.size();
+       VkRayTracingShaderGroupCreateInfoKHR&   shaderGroupCreateInfo   = m_shadersGroupCreateInfos[group];
+
+       switch (shaderStage)
+       {
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:            CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader,              shaderStageNdx);        break;
+               case VK_SHADER_STAGE_MISS_BIT_KHR:                      CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader,              shaderStageNdx);        break;
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:          CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader,              shaderStageNdx);        break;
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:           CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.anyHitShader,               shaderStageNdx);        break;
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:       CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.closestHitShader,   shaderStageNdx);        break;
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:      CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.intersectionShader, shaderStageNdx);        break;
+               default:                                                                        TCU_THROW(InternalError, "Unacceptable stage");
+       }
+
+       switch (shaderStage)
+       {
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
+               case VK_SHADER_STAGE_MISS_BIT_KHR:
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
+               {
+                       DE_ASSERT(shaderGroupCreateInfo.type == VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR);
+                       shaderGroupCreateInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
+               {
+                       DE_ASSERT(shaderGroupCreateInfo.type != VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR);
+                       shaderGroupCreateInfo.type      = (shaderGroupCreateInfo.intersectionShader == VK_SHADER_UNUSED_KHR)
+                                                                               ? VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR
+                                                                               : VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR;
+
+                       break;
+               }
+
+               default: TCU_THROW(InternalError, "Unacceptable stage");
+       }
+
+       {
+               const VkPipelineShaderStageCreateInfo   shaderCreateInfo        =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    //  VkStructureType                                             sType;
+                       DE_NULL,                                                                                                //  const void*                                                 pNext;
+                       (VkPipelineShaderStageCreateFlags)0,                                    //  VkPipelineShaderStageCreateFlags    flags;
+                       shaderStage,                                                                                    //  VkShaderStageFlagBits                               stage;
+                       *shaderModule,                                                                                  //  VkShaderModule                                              module;
+                       "main",                                                                                                 //  const char*                                                 pName;
+                       DE_NULL,                                                                                                //  const VkSpecializationInfo*                 pSpecializationInfo;
+               };
+
+               m_shaderCreateInfos.push_back(shaderCreateInfo);
+       }
+
+       m_shadersModules.push_back(makeVkSharedPtr(shaderModule));
+}
+
+void RayTracingPipeline::addLibrary (de::SharedPtr<de::MovePtr<RayTracingPipeline>> pipelineLibrary)
+{
+       m_pipelineLibraries.push_back(pipelineLibrary);
+}
+
+Move<VkPipeline> RayTracingPipeline::createPipelineKHR (const DeviceInterface&                                                         vk,
+                                                                                                               const VkDevice                                                                          device,
+                                                                                                               const VkPipelineLayout                                                          pipelineLayout,
+                                                                                                               const std::vector<de::SharedPtr<Move<VkPipeline>>>&     pipelineLibraries)
+{
+       for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx)
+               DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR);
+
+       DE_ASSERT(m_shaderCreateInfos.size() > 0);
+       DE_ASSERT(m_shadersGroupCreateInfos.size() > 0);
+
+       std::vector<VkPipeline>                                                         vkPipelineLibraries;
+       for (auto it = begin(pipelineLibraries), eit = end(pipelineLibraries); it != eit; ++it)
+               vkPipelineLibraries.push_back( it->get()->get() );
+       const VkPipelineLibraryCreateInfoKHR                            librariesCreateInfo     =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR,             //  VkStructureType     sType;
+               DE_NULL,                                                                                                //  const void*         pNext;
+               deUint32(vkPipelineLibraries.size()),                                   //  deUint32            libraryCount;
+               dataOrNullPtr(vkPipelineLibraries)                                              //  VkPipeline*         pLibraries;
+       };
+       const VkRayTracingPipelineInterfaceCreateInfoKHR        pipelineInterfaceCreateInfo             =
+       {
+               VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR,       //  VkStructureType     sType;
+               DE_NULL,                                                                                                                        //  const void*         pNext;
+               m_maxPayloadSize,                                                                                                       //  deUint32            maxPayloadSize;
+               m_maxAttributeSize,                                                                                                     //  deUint32            maxAttributeSize;
+               m_maxCallableSize                                                                                                       //  deUint32            maxCallableSize;
+       };
+       const bool                                                                                      addPipelineInterfaceCreateInfo  = m_maxPayloadSize != 0 || m_maxAttributeSize != 0 || m_maxCallableSize != 0;
+       const VkRayTracingPipelineInterfaceCreateInfoKHR*       pipelineInterfaceCreateInfoPtr  = addPipelineInterfaceCreateInfo ? &pipelineInterfaceCreateInfo : DE_NULL;
+       Move<VkDeferredOperationKHR>                                            deferredOperation                               = (m_deferredOperation ? createDeferredOperationKHR(vk, device) : Move<VkDeferredOperationKHR>());
+       VkDeferredOperationInfoKHR                                                      deferredOperationInfoKHR                =
+       {
+               VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR,  //  VkStructureType                     sType;
+               DE_NULL,                                                                                //  const void*                         pNext;
+               *deferredOperation                                                              //  VkDeferredOperationKHR      operationHandle;
+       };
+       const VkDeferredOperationInfoKHR*                                       deferredOperationInfoPtr                = m_deferredOperation ? &deferredOperationInfoKHR : DE_NULL;
+       const VkRayTracingPipelineCreateInfoKHR                         pipelineCreateInfo                              =
+       {
+               VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, //  VkStructureType                                                             sType;
+               deferredOperationInfoPtr,                                                               //  const void*                                                                 pNext;
+               m_pipelineCreateFlags,                                                                  //  VkPipelineCreateFlags                                               flags;
+               (deUint32)m_shaderCreateInfos.size(),                                   //  deUint32                                                                    stageCount;
+               m_shaderCreateInfos.data(),                                                             //  const VkPipelineShaderStageCreateInfo*              pStages;
+               (deUint32)m_shadersGroupCreateInfos.size(),                             //  deUint32                                                                    groupCount;
+               m_shadersGroupCreateInfos.data(),                                               //  const VkRayTracingShaderGroupCreateInfoKHR* pGroups;
+               m_maxRecursionDepth,                                                                    //  deUint32                                                                    maxRecursionDepth;
+               librariesCreateInfo,                                                                    //  VkPipelineLibraryCreateInfoKHR                              libraries;
+               pipelineInterfaceCreateInfoPtr,                                                 //  VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface;
+               pipelineLayout,                                                                                 //  VkPipelineLayout                                                    layout;
+               (VkPipeline)DE_NULL,                                                                    //  VkPipeline                                                                  basePipelineHandle;
+               0,                                                                                                              //  deInt32                                                                             basePipelineIndex;
+       };
+       VkPipeline                                                                                      object                                                  = DE_NULL;
+       VkResult                                                                                        result                                                  = vk.createRayTracingPipelinesKHR(device, DE_NULL, 1u, &pipelineCreateInfo, DE_NULL, &object);
+       Move<VkPipeline>                                                                        pipeline                                                (check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, DE_NULL));
+
+       if (m_deferredOperation)
+       {
+               DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
+               DE_UNREF(result);
+
+               VK_CHECK(finishDeferredOperation(vk, device, *deferredOperation));
+       }
+
+       return pipeline;
+}
+
+
+Move<VkPipeline> RayTracingPipeline::createPipeline (const DeviceInterface&                                                                    vk,
+                                                                                                        const VkDevice                                                                                 device,
+                                                                                                        const VkPipelineLayout                                                                 pipelineLayout,
+                                                                                                        const std::vector<de::SharedPtr<Move<VkPipeline>>>&    pipelineLibraries)
+{
+       return createPipelineKHR(vk, device, pipelineLayout, pipelineLibraries);
+}
+
+std::vector<de::SharedPtr<Move<VkPipeline>>> RayTracingPipeline::createPipelineWithLibraries (const DeviceInterface&                   vk,
+                                                                                                                                                                                               const VkDevice                                  device,
+                                                                                                                                                                                               const VkPipelineLayout                  pipelineLayout)
+{
+       for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx)
+               DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR);
+
+       DE_ASSERT(m_shaderCreateInfos.size() > 0);
+       DE_ASSERT(m_shadersGroupCreateInfos.size() > 0);
+
+       std::vector<de::SharedPtr<Move<VkPipeline>>> result, allLibraries, firstLibraries;
+       for(auto it=begin(m_pipelineLibraries), eit=end(m_pipelineLibraries); it!=eit; ++it)
+       {
+               auto childLibraries = (*it)->get()->createPipelineWithLibraries(vk, device, pipelineLayout);
+               DE_ASSERT(childLibraries.size() > 0);
+               firstLibraries.push_back(childLibraries[0]);
+               std::copy(begin(childLibraries), end(childLibraries), std::back_inserter(allLibraries));
+       }
+       result.push_back(makeVkSharedPtr(createPipeline(vk, device, pipelineLayout, firstLibraries)));
+       std::copy(begin(allLibraries), end(allLibraries), std::back_inserter(result));
+       return result;
+}
+
+de::MovePtr<BufferWithMemory> RayTracingPipeline::createShaderBindingTable (const DeviceInterface&             vk,
+                                                                                                                                                       const VkDevice                          device,
+                                                                                                                                                       const VkPipeline                        pipeline,
+                                                                                                                                                       Allocator&                                      allocator,
+                                                                                                                                                       const deUint32&                         shaderGroupHandleSize,
+                                                                                                                                                       const deUint32                          shaderGroupBaseAlignment,
+                                                                                                                                                       const deUint32&                         firstGroup,
+                                                                                                                                                       const deUint32&                         groupCount,
+                                                                                                                                                       const VkBufferCreateFlags&      additionalBufferCreateFlags,
+                                                                                                                                                       const VkBufferUsageFlags&       additionalBufferUsageFlags,
+                                                                                                                                                       const MemoryRequirement&        additionalMemoryRequirement,
+                                                                                                                                                       const VkDeviceAddress&          opaqueCaptureAddress,
+                                                                                                                                                       const deUint32                          shaderBindingTableOffset,
+                                                                                                                                                       const deUint32                          shaderRecordSize)
+{
+       DE_ASSERT(shaderGroupBaseAlignment != 0u);
+       DE_ASSERT((shaderBindingTableOffset % shaderGroupBaseAlignment) == 0);
+       DE_UNREF(shaderGroupBaseAlignment);
+
+       const deUint32                                                  sbtSize                                                 = shaderBindingTableOffset + groupCount * deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize);
+       const VkBufferUsageFlags                                sbtFlags                                                = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | additionalBufferUsageFlags;
+       VkBufferCreateInfo                                              sbtCreateInfo                                   = makeBufferCreateInfo(sbtSize, sbtFlags);
+       sbtCreateInfo.flags                                                                                                             |= additionalBufferCreateFlags;
+       VkBufferOpaqueCaptureAddressCreateInfo  sbtCaptureAddressInfo                   =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,    // VkStructureType      sType;
+               DE_NULL,                                                                                                                // const void*          pNext;
+               deUint64(opaqueCaptureAddress)                                                                  // deUint64                     opaqueCaptureAddress;
+       };
+       if (opaqueCaptureAddress != 0u)
+               sbtCreateInfo.pNext = &sbtCaptureAddressInfo;
+       const MemoryRequirement                 sbtMemRequirements                                              = MemoryRequirement::HostVisible | MemoryRequirement::Coherent | additionalMemoryRequirement;
+       de::MovePtr<BufferWithMemory>   sbtBuffer                                                               = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, sbtCreateInfo, sbtMemRequirements));
+       vk::Allocation&                                 sbtAlloc                                                                = sbtBuffer->getAllocation();
+
+       // collect shader group handles
+       std::vector<deUint8>                    shaderHandles                                                   (groupCount * shaderGroupHandleSize);
+       VK_CHECK(getRayTracingShaderGroupHandles(vk, device, pipeline, firstGroup, groupCount, groupCount * shaderGroupHandleSize, shaderHandles.data()));
+
+       // reserve place for ShaderRecordKHR after each shader handle ( ShaderRecordKHR size might be 0 ). Also take alignment into consideration
+       deUint8* shaderBegin = (deUint8*)sbtAlloc.getHostPtr() + shaderBindingTableOffset;
+       for (deUint32 idx = 0; idx < groupCount; ++idx)
+       {
+               deUint8* shaderSrcPos   = shaderHandles.data() + idx * shaderGroupHandleSize;
+               deUint8* shaderDstPos   = shaderBegin + idx * deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize);
+               deMemcpy(shaderDstPos, shaderSrcPos, shaderGroupHandleSize);
+       }
+
+       flushMappedMemoryRange(vk, device, sbtAlloc.getMemory(), sbtAlloc.getOffset(), VK_WHOLE_SIZE);
+
+       return sbtBuffer;
+}
+
+void RayTracingPipeline::setCreateFlags (const VkPipelineCreateFlags& pipelineCreateFlags)
+{
+       m_pipelineCreateFlags = pipelineCreateFlags;
+}
+
+void RayTracingPipeline::setMaxRecursionDepth (const deUint32& maxRecursionDepth)
+{
+       m_maxRecursionDepth = maxRecursionDepth;
+}
+
+void RayTracingPipeline::setMaxPayloadSize (const deUint32& maxPayloadSize)
+{
+       m_maxPayloadSize = maxPayloadSize;
+}
+
+void RayTracingPipeline::setMaxAttributeSize (const deUint32& maxAttributeSize)
+{
+       m_maxAttributeSize = maxAttributeSize;
+}
+
+void RayTracingPipeline::setMaxCallableSize (const deUint32& maxCallableSize)
+{
+       m_maxCallableSize = maxCallableSize;
+}
+
+void RayTracingPipeline::setDeferredOperation (const bool deferredOperation)
+{
+       m_deferredOperation = deferredOperation;
+}
+
+class RayTracingPropertiesKHR : public RayTracingProperties
+{
+public:
+                                                       RayTracingPropertiesKHR                                         () = delete;
+                                                       RayTracingPropertiesKHR                                         (const InstanceInterface&       vki,
+                                                                                                                                                const VkPhysicalDevice         physicalDevice);
+       virtual                                 ~RayTracingPropertiesKHR                                        ();
+
+       virtual deUint32                getShaderGroupHandleSize                                        (void)  { return m_rayTracingPropertiesKHR.shaderGroupHandleSize;                                       };
+       virtual deUint32                getMaxRecursionDepth                                            (void)  { return m_rayTracingPropertiesKHR.maxRecursionDepth;                                           };
+       virtual deUint32                getMaxShaderGroupStride                                         (void)  { return m_rayTracingPropertiesKHR.maxShaderGroupStride;                                        };
+       virtual deUint32                getShaderGroupBaseAlignment                                     (void)  { return m_rayTracingPropertiesKHR.shaderGroupBaseAlignment;                            };
+       virtual deUint64                getMaxGeometryCount                                                     (void)  { return m_rayTracingPropertiesKHR.maxGeometryCount;                                            };
+       virtual deUint64                getMaxInstanceCount                                                     (void)  { return m_rayTracingPropertiesKHR.maxInstanceCount;                                            };
+       virtual deUint64                getMaxPrimitiveCount                                            (void)  { return m_rayTracingPropertiesKHR.maxPrimitiveCount;                                           };
+       virtual deUint32                getMaxDescriptorSetAccelerationStructures       (void)  { return m_rayTracingPropertiesKHR.maxDescriptorSetAccelerationStructures;      };
+
+protected:
+       VkPhysicalDeviceRayTracingPropertiesKHR m_rayTracingPropertiesKHR;
+};
+
+RayTracingPropertiesKHR::~RayTracingPropertiesKHR ()
+{
+}
+
+RayTracingPropertiesKHR::RayTracingPropertiesKHR (const InstanceInterface&     vki,
+                                                                                                 const VkPhysicalDevice        physicalDevice)
+       : RayTracingProperties  (vki, physicalDevice)
+{
+       m_rayTracingPropertiesKHR = getPhysicalDeviceExtensionProperties(vki, physicalDevice);
+}
+
+de::MovePtr<RayTracingProperties> makeRayTracingProperties (const InstanceInterface&   vki,
+                                                                                                                       const VkPhysicalDevice          physicalDevice)
+{
+       return de::MovePtr<RayTracingProperties>(new RayTracingPropertiesKHR(vki, physicalDevice));
+}
+
+static inline void cmdTraceRaysKHR (const DeviceInterface&                             vk,
+                                                                       VkCommandBuffer                                         commandBuffer,
+                                                                       const VkStridedBufferRegionKHR*         raygenShaderBindingTableRegion,
+                                                                       const VkStridedBufferRegionKHR*         missShaderBindingTableRegion,
+                                                                       const VkStridedBufferRegionKHR*         hitShaderBindingTableRegion,
+                                                                       const VkStridedBufferRegionKHR*         callableShaderBindingTableRegion,
+                                                                       deUint32                                                        width,
+                                                                       deUint32                                                        height,
+                                                                       deUint32                                                        depth)
+{
+       return vk.cmdTraceRaysKHR(commandBuffer,
+                                                         raygenShaderBindingTableRegion,
+                                                         missShaderBindingTableRegion,
+                                                         hitShaderBindingTableRegion,
+                                                         callableShaderBindingTableRegion,
+                                                         width,
+                                                         height,
+                                                         depth);
+}
+
+
+void cmdTraceRays (const DeviceInterface&                      vk,
+                                  VkCommandBuffer                                      commandBuffer,
+                                  const VkStridedBufferRegionKHR*      raygenShaderBindingTableRegion,
+                                  const VkStridedBufferRegionKHR*      missShaderBindingTableRegion,
+                                  const VkStridedBufferRegionKHR*      hitShaderBindingTableRegion,
+                                  const VkStridedBufferRegionKHR*      callableShaderBindingTableRegion,
+                                  deUint32                                                     width,
+                                  deUint32                                                     height,
+                                  deUint32                                                     depth)
+{
+       DE_ASSERT(raygenShaderBindingTableRegion        != DE_NULL);
+       DE_ASSERT(missShaderBindingTableRegion          != DE_NULL);
+       DE_ASSERT(hitShaderBindingTableRegion           != DE_NULL);
+       DE_ASSERT(callableShaderBindingTableRegion      != DE_NULL);
+       DE_ASSERT(width > 0);
+       DE_ASSERT(height > 0);
+       DE_ASSERT(depth > 0);
+
+       return cmdTraceRaysKHR(vk,
+                                                  commandBuffer,
+                                                  raygenShaderBindingTableRegion,
+                                                  missShaderBindingTableRegion,
+                                                  hitShaderBindingTableRegion,
+                                                  callableShaderBindingTableRegion,
+                                                  width,
+                                                  height,
+                                                  depth);
+}
+
+static inline void cmdTraceRaysIndirectKHR (const DeviceInterface&                             vk,
+                                                                                       VkCommandBuffer                                         commandBuffer,
+                                                                                       const VkStridedBufferRegionKHR*         raygenShaderBindingTableRegion,
+                                                                                       const VkStridedBufferRegionKHR*         missShaderBindingTableRegion,
+                                                                                       const VkStridedBufferRegionKHR*         hitShaderBindingTableRegion,
+                                                                                       const VkStridedBufferRegionKHR*         callableShaderBindingTableRegion,
+                                                                                       VkBuffer                                                        buffer,
+                                                                                       VkDeviceSize                                            offset)
+{
+       DE_ASSERT(raygenShaderBindingTableRegion        != DE_NULL);
+       DE_ASSERT(missShaderBindingTableRegion          != DE_NULL);
+       DE_ASSERT(hitShaderBindingTableRegion           != DE_NULL);
+       DE_ASSERT(callableShaderBindingTableRegion      != DE_NULL);
+       DE_ASSERT(buffer != DE_NULL);
+
+       return vk.cmdTraceRaysIndirectKHR(commandBuffer,
+                                                                         raygenShaderBindingTableRegion,
+                                                                         missShaderBindingTableRegion,
+                                                                         hitShaderBindingTableRegion,
+                                                                         callableShaderBindingTableRegion,
+                                                                         buffer,
+                                                                         offset);
+}
+
+void cmdTraceRaysIndirect (const DeviceInterface&                      vk,
+                                                  VkCommandBuffer                                      commandBuffer,
+                                                  const VkStridedBufferRegionKHR*      raygenShaderBindingTableRegion,
+                                                  const VkStridedBufferRegionKHR*      missShaderBindingTableRegion,
+                                                  const VkStridedBufferRegionKHR*      hitShaderBindingTableRegion,
+                                                  const VkStridedBufferRegionKHR*      callableShaderBindingTableRegion,
+                                                  VkBuffer                                                     buffer,
+                                                  VkDeviceSize                                         offset)
+{
+       return cmdTraceRaysIndirectKHR(vk,
+                                                                  commandBuffer,
+                                                                  raygenShaderBindingTableRegion,
+                                                                  missShaderBindingTableRegion,
+                                                                  hitShaderBindingTableRegion,
+                                                                  callableShaderBindingTableRegion,
+                                                                  buffer,
+                                                                  offset);
+}
+
+} // vk
diff --git a/external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp b/external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp
new file mode 100644 (file)
index 0000000..8446d74
--- /dev/null
@@ -0,0 +1,595 @@
+#ifndef _VKRAYTRACINGUTIL_HPP
+#define _VKRAYTRACINGUTIL_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2020 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan ray tracing utility.
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkRef.hpp"
+#include "vkMemUtil.hpp"
+#include "vkBufferWithMemory.hpp"
+
+#include "deFloat16.h"
+
+#include "tcuVector.hpp"
+#include "tcuVectorType.hpp"
+
+#include <vector>
+
+namespace vk
+{
+const VkTransformMatrixKHR identityMatrix3x4 = { { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f } } };
+
+template<typename T>
+inline de::SharedPtr<Move<T>> makeVkSharedPtr(Move<T> move)
+{
+       return de::SharedPtr<Move<T>>(new Move<T>(move));
+}
+
+template<typename T>
+inline de::SharedPtr<de::MovePtr<T> > makeVkSharedPtr(de::MovePtr<T> movePtr)
+{
+       return de::SharedPtr<de::MovePtr<T> >(new de::MovePtr<T>(movePtr));
+}
+
+template<typename T>
+inline const T* dataOrNullPtr(const std::vector<T>& v)
+{
+       return (v.empty() ? DE_NULL : v.data());
+}
+
+template<typename T>
+inline T* dataOrNullPtr(std::vector<T>& v)
+{
+       return (v.empty() ? DE_NULL : v.data());
+}
+
+inline std::string updateRayTracingGLSL (const std::string& str)
+{
+       return str;
+}
+
+std::string getCommonRayGenerationShader (void);
+
+const char* getRayTracingExtensionUsed (void);
+
+class RaytracedGeometryBase
+{
+public:
+                                                               RaytracedGeometryBase                   ()                                                                              = delete;
+                                                               RaytracedGeometryBase                   (const RaytracedGeometryBase& geometry) = delete;
+                                                               RaytracedGeometryBase                   (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType);
+                                                               virtual ~RaytracedGeometryBase  ();
+
+       inline VkGeometryTypeKHR        getGeometryType                                 (void) const                                                            { return m_geometryType; }
+       inline bool                                     isTrianglesType                                 (void) const                                                            { return m_geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR; }
+       inline VkFormat                         getVertexFormat                                 (void) const                                                            { return m_vertexFormat; }
+       inline VkIndexType                      getIndexType                                    (void) const                                                            { return m_indexType; }
+       inline bool                                     usesIndices                                             (void) const                                                            { return m_indexType != VK_INDEX_TYPE_NONE_KHR; }
+       inline VkGeometryFlagsKHR       getGeometryFlags                                (void) const                                                            { return m_geometryFlags; }
+       inline void                                     setGeometryFlags                                (const VkGeometryFlagsKHR geometryFlags)        { m_geometryFlags = geometryFlags; }
+       virtual deUint32                        getVertexCount                                  (void) const                                                            = 0;
+       virtual const deUint8*          getVertexPointer                                (void) const                                                            = 0;
+       virtual VkDeviceSize            getVertexStride                                 (void) const                                                            = 0;
+       virtual size_t                          getVertexByteSize                               (void) const                                                            = 0;
+       virtual VkDeviceSize            getAABBStride                                   (void) const                                                            = 0;
+       virtual deUint32                        getIndexCount                                   (void) const                                                            = 0;
+       virtual const deUint8*          getIndexPointer                                 (void) const                                                            = 0;
+       virtual VkDeviceSize            getIndexStride                                  (void) const                                                            = 0;
+       virtual size_t                          getIndexByteSize                                (void) const                                                            = 0;
+       virtual deUint32                        getPrimitiveCount                               (void) const                                                            = 0;
+       virtual void                            addVertex                                               (const tcu::Vec3& vertex)                                       = 0;
+       virtual void                            addIndex                                                (const deUint32& index)                                         = 0;
+private:
+       VkGeometryTypeKHR                       m_geometryType;
+       VkFormat                                        m_vertexFormat;
+       VkIndexType                                     m_indexType;
+       VkGeometryFlagsKHR                      m_geometryFlags;
+};
+
+template <typename T>
+inline T convertSatRte (float f)
+{
+       // \note Doesn't work for 64-bit types
+       DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64));
+       DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
+
+       deInt64 minVal  = std::numeric_limits<T>::min();
+       deInt64 maxVal  = std::numeric_limits<T>::max();
+       float   q               = deFloatFrac(f);
+       deInt64 intVal  = (deInt64)(f-q);
+
+       // Rounding.
+       if (q == 0.5f)
+       {
+               if (intVal % 2 != 0)
+                       intVal++;
+       }
+       else if (q > 0.5f)
+               intVal++;
+       // else Don't add anything
+
+       // Saturate.
+       intVal = de::max(minVal, de::min(maxVal, intVal));
+
+       return (T)intVal;
+}
+
+inline deInt16 deFloat32ToSNorm16 (float src)
+{
+       const deInt16   range = (deInt32)((1u << 15) - 1u);
+       const deInt16   intVal = convertSatRte<deInt16>(src * (float)range);
+       return de::clamp<deInt16>(intVal, -range, range);
+}
+
+typedef tcu::Vector<deFloat16, 2>                      Vec2_16;
+typedef tcu::Vector<deFloat16, 4>                      Vec4_16;
+typedef tcu::Vector<deInt16, 2>                                Vec2_16SNorm;
+typedef tcu::Vector<deInt16, 4>                                Vec4_16SNorm;
+
+template<typename V>   VkFormat                        vertexFormatFromType                            ()                                                      { TCU_THROW(TestError, "Unknown VkFormat"); }
+template<>                             inline VkFormat         vertexFormatFromType<tcu::Vec2>         ()                                                      { return VK_FORMAT_R32G32_SFLOAT; }
+template<>                             inline VkFormat         vertexFormatFromType<tcu::Vec3>         ()                                                      { return VK_FORMAT_R32G32B32_SFLOAT; }
+template<>                             inline VkFormat         vertexFormatFromType<Vec2_16>           ()                                                      { return VK_FORMAT_R16G16_SFLOAT; }
+template<>                             inline VkFormat         vertexFormatFromType<Vec4_16>           ()                                                      { return VK_FORMAT_R16G16B16A16_SFLOAT; }
+template<>                             inline VkFormat         vertexFormatFromType<Vec2_16SNorm>      ()                                                      { return VK_FORMAT_R16G16_SNORM; }
+template<>                             inline VkFormat         vertexFormatFromType<Vec4_16SNorm>      ()                                                      { return VK_FORMAT_R16G16B16A16_SNORM; }
+
+struct EmptyIndex {};
+template<typename I>   VkIndexType                     indexTypeFromType                                       ()                                                      { TCU_THROW(TestError, "Unknown VkIndexType"); }
+template<>                             inline VkIndexType      indexTypeFromType<deUint16>                     ()                                                      { return VK_INDEX_TYPE_UINT16; }
+template<>                             inline VkIndexType      indexTypeFromType<deUint32>                     ()                                                      { return VK_INDEX_TYPE_UINT32; }
+template<>                             inline VkIndexType      indexTypeFromType<EmptyIndex>           ()                                                      { return VK_INDEX_TYPE_NONE_KHR; }
+
+template<typename V>   V                                       convertFloatTo                                          (const tcu::Vec3& vertex)       { DE_UNREF(vertex); TCU_THROW(TestError, "Unknown data format"); }
+template<>                             inline tcu::Vec2        convertFloatTo<tcu::Vec2>                       (const tcu::Vec3& vertex)       { return tcu::Vec2(vertex.x(), vertex.y()); }
+template<>                             inline tcu::Vec3        convertFloatTo<tcu::Vec3>                       (const tcu::Vec3& vertex)       { return vertex; }
+template<>                             inline Vec2_16          convertFloatTo<Vec2_16>                         (const tcu::Vec3& vertex)       { return Vec2_16(deFloat32To16(vertex.x()), deFloat32To16(vertex.y())); }
+template<>                             inline Vec4_16          convertFloatTo<Vec4_16>                         (const tcu::Vec3& vertex)       { return Vec4_16(deFloat32To16(vertex.x()), deFloat32To16(vertex.y()), deFloat32To16(vertex.z()), deFloat32To16(0.0f)); }
+template<>                             inline Vec2_16SNorm     convertFloatTo<Vec2_16SNorm>            (const tcu::Vec3& vertex)       { return Vec2_16SNorm(deFloat32ToSNorm16(vertex.x()), deFloat32ToSNorm16(vertex.y())); }
+template<>                             inline Vec4_16SNorm     convertFloatTo<Vec4_16SNorm>            (const tcu::Vec3& vertex)       { return Vec4_16SNorm(deFloat32ToSNorm16(vertex.x()), deFloat32ToSNorm16(vertex.y()), deFloat32ToSNorm16(vertex.z()), deFloat32ToSNorm16(0.0f)); }
+
+template<typename V>   V                                       convertIndexTo                                          (deUint32 index)                        { DE_UNREF(index); TCU_THROW(TestError, "Unknown index format"); }
+template<>                             inline EmptyIndex       convertIndexTo<EmptyIndex>                      (deUint32 index)                        { DE_UNREF(index); TCU_THROW(TestError, "Cannot add empty index"); }
+template<>                             inline deUint16         convertIndexTo<deUint16>                        (deUint32 index)                        { return static_cast<deUint16>(index); }
+template<>                             inline deUint32         convertIndexTo<deUint32>                        (deUint32 index)                        { return index; }
+
+template<typename V, typename I>
+class RaytracedGeometry : public RaytracedGeometryBase
+{
+public:
+                                               RaytracedGeometry                       ()                                                                      = delete;
+                                               RaytracedGeometry                       (const RaytracedGeometry& geometry)     = delete;
+                                               RaytracedGeometry                       (VkGeometryTypeKHR geometryType);
+                                               RaytracedGeometry                       (VkGeometryTypeKHR geometryType, const std::vector<V>& vertices, const std::vector<I>& indices = std::vector<I>());
+
+       deUint32                        getVertexCount                          (void) const override;
+       const deUint8*          getVertexPointer                        (void) const override;
+       VkDeviceSize            getVertexStride                         (void) const override;
+       size_t                          getVertexByteSize                       (void) const override;
+       VkDeviceSize            getAABBStride                           (void) const override;
+       deUint32                        getIndexCount                           (void) const override;
+       const deUint8*          getIndexPointer                         (void) const override;
+       VkDeviceSize            getIndexStride                          (void) const override;
+       size_t                          getIndexByteSize                        (void) const override;
+       deUint32                        getPrimitiveCount                       (void) const override;
+
+       void                            addVertex                                       (const tcu::Vec3& vertex) override;
+       void                            addIndex                                        (const deUint32& index) override;
+private:
+       std::vector<V>          m_vertices;
+       std::vector<I>          m_indices;
+};
+
+template<typename V, typename I>
+RaytracedGeometry<V, I>::RaytracedGeometry (VkGeometryTypeKHR geometryType)
+       : RaytracedGeometryBase(geometryType, vertexFormatFromType<V>(), indexTypeFromType<I>())
+{
+}
+
+template<typename V, typename I>
+RaytracedGeometry<V,I>::RaytracedGeometry (VkGeometryTypeKHR geometryType, const std::vector<V>& vertices, const std::vector<I>& indices)
+       : RaytracedGeometryBase(geometryType, vertexFormatFromType<V>(), indexTypeFromType<I>())
+       , m_vertices(vertices)
+       , m_indices(indices)
+{
+}
+
+template<typename V, typename I>
+deUint32 RaytracedGeometry<V,I>::getVertexCount (void) const
+{
+       return static_cast<deUint32>( isTrianglesType() ? m_vertices.size() : 0);
+}
+
+template<typename V, typename I>
+const deUint8* RaytracedGeometry<V, I>::getVertexPointer (void) const
+{
+       return reinterpret_cast<const deUint8*>(m_vertices.empty() ? DE_NULL : m_vertices.data());
+}
+
+template<typename V, typename I>
+VkDeviceSize RaytracedGeometry<V,I>::getVertexStride (void) const
+{
+       return static_cast<VkDeviceSize>(sizeof(V));
+}
+
+template<typename V, typename I>
+VkDeviceSize RaytracedGeometry<V, I>::getAABBStride (void) const
+{
+       return static_cast<VkDeviceSize>(2 * sizeof(V));
+}
+
+template<typename V, typename I>
+size_t RaytracedGeometry<V, I>::getVertexByteSize (void) const
+{
+       return static_cast<size_t>(m_vertices.size() * sizeof(V));
+}
+
+template<typename V, typename I>
+deUint32 RaytracedGeometry<V, I>::getIndexCount (void) const
+{
+       return static_cast<deUint32>(isTrianglesType() ? m_indices.size() : 0);
+}
+
+template<typename V, typename I>
+const deUint8* RaytracedGeometry<V, I>::getIndexPointer (void) const
+{
+       return reinterpret_cast<const deUint8*>(m_indices.empty() ? DE_NULL : m_indices.data());
+}
+
+template<typename V, typename I>
+VkDeviceSize RaytracedGeometry<V, I>::getIndexStride (void) const
+{
+       return static_cast<VkDeviceSize>(sizeof(I));
+}
+
+template<typename V, typename I>
+size_t RaytracedGeometry<V, I>::getIndexByteSize (void) const
+{
+       return static_cast<size_t>(m_indices.size() * sizeof(I));
+}
+
+template<typename V, typename I>
+deUint32 RaytracedGeometry<V,I>::getPrimitiveCount (void) const
+{
+       return static_cast<deUint32>(isTrianglesType() ? (usesIndices() ? m_indices.size() / 3 : m_vertices.size() / 3) : (m_vertices.size() / 2));
+}
+
+template<typename V, typename I>
+void RaytracedGeometry<V, I>::addVertex (const tcu::Vec3& vertex)
+{
+       m_vertices.push_back(convertFloatTo<V>(vertex));
+}
+
+template<typename V, typename I>
+void RaytracedGeometry<V, I>::addIndex (const deUint32& index)
+{
+       m_indices.push_back(convertIndexTo<I>(index));
+}
+
+de::SharedPtr<RaytracedGeometryBase> makeRaytracedGeometry (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType);
+
+class SerialStorage
+{
+public:
+                                                                                       SerialStorage           () = delete;
+                                                                                       SerialStorage           (const DeviceInterface&                                         vk,
+                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                const VkAccelerationStructureBuildTypeKHR      buildType,
+                                                                                                                                const VkDeviceSize                                                     storageSize);
+
+       VkDeviceOrHostAddressKHR                                getAddress                      (const DeviceInterface& vk,
+                                                                                                                                const VkDevice                 device);
+       VkDeviceOrHostAddressConstKHR                   getAddressConst         (const DeviceInterface& vk,
+                                                                                                                                const VkDevice                 device);
+protected:
+       VkAccelerationStructureBuildTypeKHR             m_buildType;
+       de::MovePtr<BufferWithMemory>                   m_buffer;
+
+};
+
+class BottomLevelAccelerationStructure
+{
+public:
+       static deUint32                                                                         getRequiredAllocationCount                              (void);
+
+                                                                                                               BottomLevelAccelerationStructure                ();
+                                                                                                               BottomLevelAccelerationStructure                (const BottomLevelAccelerationStructure&        other) = delete;
+       virtual                                                                                         ~BottomLevelAccelerationStructure               ();
+
+       virtual void                                                                            setGeometryData                                                 (const std::vector<tcu::Vec3>&                          geometryData,
+                                                                                                                                                                                                const bool                                                                     triangles,
+                                                                                                                                                                                                const VkGeometryFlagsKHR                                       geometryFlags = 0);
+       virtual void                                                                            setDefaultGeometryData                                  (const VkShaderStageFlagBits                            testStage);
+       virtual void                                                                            setGeometryCount                                                (const size_t                                                           geometryCount);
+       virtual void                                                                            addGeometry                                                             (de::SharedPtr<RaytracedGeometryBase>&          raytracedGeometry);
+       virtual void                                                                            addGeometry                                                             (const std::vector<tcu::Vec3>&                          geometryData,
+                                                                                                                                                                                                const bool                                                                     triangles,
+                                                                                                                                                                                                const VkGeometryFlagsKHR                                       geometryFlags = 0);
+
+       virtual void                                                                            setBuildType                                                    (const VkAccelerationStructureBuildTypeKHR      buildType) = DE_NULL;
+       virtual void                                                                            setBuildFlags                                                   (const VkBuildAccelerationStructureFlagsKHR     flags) = DE_NULL;
+       virtual void                                                                            setDeferredOperation                                    (const bool                                                                     deferredOperation) = DE_NULL;
+       virtual void                                                                            setUseArrayOfPointers                                   (const bool                                                                     useArrayOfPointers) = DE_NULL;
+       virtual void                                                                            setIndirectBuildParameters                              (const VkBuffer                                                         indirectBuffer,
+                                                                                                                                                                                                const VkDeviceSize                                                     indirectBufferOffset,
+                                                                                                                                                                                                const deUint32                                                         indirectBufferStride) = DE_NULL;
+       virtual VkBuildAccelerationStructureFlagsKHR            getBuildFlags                                                   () const = DE_NULL;
+
+       // methods specific for each acceleration structure
+       virtual void                                                                            create                                                                  (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress,
+                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize) = DE_NULL;
+       virtual void                                                                            build                                                                   (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer) = DE_NULL;
+       virtual void                                                                            copyFrom                                                                (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                BottomLevelAccelerationStructure*                      accelerationStructure,
+                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize) = DE_NULL;
+
+       virtual void                                                                            serialize                                                               (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                SerialStorage*                                                         storage) = DE_NULL;
+       virtual void                                                                            deserialize                                                             (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                SerialStorage*                                                         storage) = DE_NULL;
+
+       // helper methods for typical acceleration structure creation tasks
+       void                                                                                            createAndBuild                                                  (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress                   = 0u );
+       void                                                                                            createAndCopyFrom                                               (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress                   = 0u,
+                                                                                                                                                                                                BottomLevelAccelerationStructure*                      accelerationStructure   = DE_NULL,
+                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize                 = 0u);
+       void                                                                                            createAndDeserializeFrom                                (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress                   = 0u,
+                                                                                                                                                                                                SerialStorage*                                                         storage                                 = DE_NULL);
+
+       virtual const VkAccelerationStructureKHR*                       getPtr                                                                  (void) const = DE_NULL;
+protected:
+       std::vector<de::SharedPtr<RaytracedGeometryBase>>       m_geometriesData;
+};
+
+de::MovePtr<BottomLevelAccelerationStructure> makeBottomLevelAccelerationStructure ();
+
+struct InstanceData
+{
+                                                               InstanceData (VkTransformMatrixKHR                                                      matrix_,
+                                                                                         deUint32                                                                              instanceCustomIndex_,
+                                                                                         deUint32                                                                              mask_,
+                                                                                         deUint32                                                                              instanceShaderBindingTableRecordOffset_,
+                                                                                         VkGeometryInstanceFlagsKHR                                    flags_)
+                                                                       : matrix(matrix_), instanceCustomIndex(instanceCustomIndex_), mask(mask_), instanceShaderBindingTableRecordOffset(instanceShaderBindingTableRecordOffset_), flags(flags_)
+                                                               {
+                                                               }
+       VkTransformMatrixKHR            matrix;
+       deUint32                                        instanceCustomIndex;
+       deUint32                                        mask;
+       deUint32                                        instanceShaderBindingTableRecordOffset;
+       VkGeometryInstanceFlagsKHR      flags;
+};
+
+class TopLevelAccelerationStructure
+{
+public:
+       static deUint32                                                                                                 getRequiredAllocationCount                      (void);
+
+                                                                                                                                       TopLevelAccelerationStructure           ();
+                                                                                                                                       TopLevelAccelerationStructure           (const TopLevelAccelerationStructure&                           other) = delete;
+       virtual                                                                                                                 ~TopLevelAccelerationStructure          ();
+
+       virtual void                                                                                                    setInstanceCount                                        (const size_t                                                                           instanceCount);
+       virtual void                                                                                                    addInstance                                                     (de::SharedPtr<BottomLevelAccelerationStructure>        bottomLevelStructure,
+                                                                                                                                                                                                                const VkTransformMatrixKHR&                                            matrix                                                                  = identityMatrix3x4,
+                                                                                                                                                                                                                deUint32                                                                                       instanceCustomIndex                                             = 0,
+                                                                                                                                                                                                                deUint32                                                                                       mask                                                                    = 0xFF,
+                                                                                                                                                                                                                deUint32                                                                                       instanceShaderBindingTableRecordOffset  = 0,
+                                                                                                                                                                                                                VkGeometryInstanceFlagsKHR                                                     flags                                                                   = VkGeometryInstanceFlagBitsKHR(0u)     );
+
+       virtual void                                                                                                    setBuildType                                            (const VkAccelerationStructureBuildTypeKHR                      buildType) = DE_NULL;
+       virtual void                                                                                                    setBuildFlags                                           (const VkBuildAccelerationStructureFlagsKHR                     flags) = DE_NULL;
+       virtual void                                                                                                    setDeferredOperation                            (const bool                                                                                     deferredOperation) = DE_NULL;
+       virtual void                                                                                                    setUseArrayOfPointers                           (const bool                                                                                     useArrayOfPointers) = DE_NULL;
+       virtual void                                                                                                    setIndirectBuildParameters                      (const VkBuffer                                                                         indirectBuffer,
+                                                                                                                                                                                                                const VkDeviceSize                                                                     indirectBufferOffset,
+                                                                                                                                                                                                                const deUint32                                                                         indirectBufferStride) = DE_NULL;
+       virtual VkBuildAccelerationStructureFlagsKHR                                    getBuildFlags                                           () const = DE_NULL;
+
+       // methods specific for each acceleration structure
+       virtual void                                                                                                    create                                                          (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress,
+                                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize) = DE_NULL;
+       virtual void                                                                                                    build                                                           (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer) = DE_NULL;
+       virtual void                                                                                                    copyFrom                                                        (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                TopLevelAccelerationStructure*                         accelerationStructure,
+                                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize) = DE_NULL;
+
+       virtual void                                                                                                    serialize                                                       (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                SerialStorage*                                                         storage) = DE_NULL;
+       virtual void                                                                                                    deserialize                                                     (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                SerialStorage*                                                         storage) = DE_NULL;
+
+       // helper methods for typical acceleration structure creation tasks
+       void                                                                                                                    createAndBuild                                          (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress                   = 0u );
+       void                                                                                                                    createAndCopyFrom                                       (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress                   = 0u,
+                                                                                                                                                                                                                TopLevelAccelerationStructure*                         accelerationStructure   = DE_NULL,
+                                                                                                                                                                                                                VkDeviceSize                                                           compactCopySize                 = 0u);
+       void                                                                                                                    createAndDeserializeFrom                        (const DeviceInterface&                                         vk,
+                                                                                                                                                                                                                const VkDevice                                                         device,
+                                                                                                                                                                                                                const VkCommandBuffer                                          cmdBuffer,
+                                                                                                                                                                                                                Allocator&                                                                     allocator,
+                                                                                                                                                                                                                VkDeviceAddress                                                        deviceAddress                   = 0u,
+                                                                                                                                                                                                                SerialStorage*                                                         storage                                 = DE_NULL);
+
+       virtual const VkAccelerationStructureKHR*                                               getPtr                                                          (void) const = DE_NULL;
+
+protected:
+       std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >   m_bottomLevelInstances;
+       std::vector<InstanceData>                                                                               m_instanceData;
+};
+
+de::MovePtr<TopLevelAccelerationStructure> makeTopLevelAccelerationStructure ();
+
+bool queryAccelerationStructureSize (const DeviceInterface&                                                    vk,
+                                                                        const VkDevice                                                                 device,
+                                                                        const VkCommandBuffer                                                  cmdBuffer,
+                                                                        const std::vector<VkAccelerationStructureKHR>& accelerationStructureHandles,
+                                                                        VkAccelerationStructureBuildTypeKHR                    buildType,
+                                                                        const VkQueryPool                                                              queryPool,
+                                                                        VkQueryType                                                                    queryType,
+                                                                        deUint32                                                                               firstQuery,
+                                                                        std::vector<VkDeviceSize>&                                             results);
+
+class RayTracingPipeline
+{
+public:
+                                                                                                                               RayTracingPipeline                      ();
+                                                                                                                               ~RayTracingPipeline                     ();
+
+       void                                                                                                            addShader                                       (VkShaderStageFlagBits                                                                  shaderStage,
+                                                                                                                                                                                        Move<VkShaderModule>                                                                   shaderModule,
+                                                                                                                                                                                        deUint32                                                                                               group);
+       void                                                                                                            addLibrary                                      (de::SharedPtr<de::MovePtr<RayTracingPipeline>>                 pipelineLibrary);
+       Move<VkPipeline>                                                                                        createPipeline                          (const DeviceInterface&                                                                 vk,
+                                                                                                                                                                                        const VkDevice                                                                                 device,
+                                                                                                                                                                                        const VkPipelineLayout                                                                 pipelineLayout,
+                                                                                                                                                                                        const std::vector<de::SharedPtr<Move<VkPipeline>>>&    pipelineLibraries                       = std::vector<de::SharedPtr<Move<VkPipeline>>>());
+       std::vector<de::SharedPtr<Move<VkPipeline>>>                            createPipelineWithLibraries     (const DeviceInterface&                                                                 vk,
+                                                                                                                                                                                        const VkDevice                                                                                 device,
+                                                                                                                                                                                        const VkPipelineLayout                                                                 pipelineLayout);
+       de::MovePtr<BufferWithMemory>                                                           createShaderBindingTable        (const DeviceInterface&                                                                 vk,
+                                                                                                                                                                                        const VkDevice                                                                                 device,
+                                                                                                                                                                                        const VkPipeline                                                                               pipeline,
+                                                                                                                                                                                        Allocator&                                                                                             allocator,
+                                                                                                                                                                                        const deUint32&                                                                                shaderGroupHandleSize,
+                                                                                                                                                                                        const deUint32                                                                                 shaderGroupBaseAlignment,
+                                                                                                                                                                                        const deUint32&                                                                                firstGroup,
+                                                                                                                                                                                        const deUint32&                                                                                groupCount,
+                                                                                                                                                                                        const VkBufferCreateFlags&                                                             additionalBufferCreateFlags     = VkBufferCreateFlags(0u),
+                                                                                                                                                                                        const VkBufferUsageFlags&                                                              additionalBufferUsageFlags      = VkBufferUsageFlags(0u),
+                                                                                                                                                                                        const MemoryRequirement&                                                               additionalMemoryRequirement     = MemoryRequirement::Any,
+                                                                                                                                                                                        const VkDeviceAddress&                                                                 opaqueCaptureAddress            = 0u,
+                                                                                                                                                                                        const deUint32                                                                                 shaderBindingTableOffset        = 0u,
+                                                                                                                                                                                        const deUint32                                                                                 shaderRecordSize                        = 0u);
+       void                                                                                                            setCreateFlags                          (const VkPipelineCreateFlags&                                                   pipelineCreateFlags);
+       void                                                                                                            setMaxRecursionDepth            (const deUint32&                                                                                maxRecursionDepth);
+       void                                                                                                            setMaxPayloadSize                       (const deUint32&                                                                                maxPayloadSize);
+       void                                                                                                            setMaxAttributeSize                     (const deUint32&                                                                                maxAttributeSize);
+       void                                                                                                            setMaxCallableSize                      (const deUint32&                                                                                maxCallableSize);
+       void                                                                                                            setDeferredOperation            (const bool                                                                                             deferredOperation);
+
+protected:
+       Move<VkPipeline>                                                                                        createPipelineKHR                       (const DeviceInterface&                                                                 vk,
+                                                                                                                                                                                        const VkDevice                                                                                 device,
+                                                                                                                                                                                        const VkPipelineLayout                                                                 pipelineLayout,
+                                                                                                                                                                                        const std::vector<de::SharedPtr<Move<VkPipeline>>>&    pipelineLibraries);
+
+       std::vector<de::SharedPtr<Move<VkShaderModule> > >                      m_shadersModules;
+       std::vector<de::SharedPtr<de::MovePtr<RayTracingPipeline>>>     m_pipelineLibraries;
+       std::vector<VkPipelineShaderStageCreateInfo>                            m_shaderCreateInfos;
+       std::vector<VkRayTracingShaderGroupCreateInfoKHR>                       m_shadersGroupCreateInfos;
+       VkPipelineCreateFlags                                                                           m_pipelineCreateFlags;
+       deUint32                                                                                                        m_maxRecursionDepth;
+       deUint32                                                                                                        m_maxPayloadSize;
+       deUint32                                                                                                        m_maxAttributeSize;
+       deUint32                                                                                                        m_maxCallableSize;
+       bool                                                                                                            m_deferredOperation;
+};
+
+class RayTracingProperties
+{
+protected:
+                                                                       RayTracingProperties                                            () {};
+
+public:
+                                                                       RayTracingProperties                                            (const InstanceInterface&       vki,
+                                                                                                                                                                const VkPhysicalDevice         physicalDevice) { DE_UNREF(vki); DE_UNREF(physicalDevice); };
+       virtual                                                 ~RayTracingProperties                                           () {};
+
+       virtual deUint32                                getShaderGroupHandleSize                                        (void)  = DE_NULL;
+       virtual deUint32                                getMaxRecursionDepth                                            (void)  = DE_NULL;
+       virtual deUint32                                getMaxShaderGroupStride                                         (void)  = DE_NULL;
+       virtual deUint32                                getShaderGroupBaseAlignment                                     (void)  = DE_NULL;
+       virtual deUint64                                getMaxGeometryCount                                                     (void)  = DE_NULL;
+       virtual deUint64                                getMaxInstanceCount                                                     (void)  = DE_NULL;
+       virtual deUint64                                getMaxPrimitiveCount                                            (void)  = DE_NULL;
+       virtual deUint32                                getMaxDescriptorSetAccelerationStructures       (void)  = DE_NULL;
+};
+
+de::MovePtr<RayTracingProperties> makeRayTracingProperties (const InstanceInterface&   vki,
+                                                                                                                       const VkPhysicalDevice          physicalDevice);
+
+void cmdTraceRays      (const DeviceInterface&                         vk,
+                                        VkCommandBuffer                                        commandBuffer,
+                                        const VkStridedBufferRegionKHR*        raygenShaderBindingTableRegion,
+                                        const VkStridedBufferRegionKHR*        missShaderBindingTableRegion,
+                                        const VkStridedBufferRegionKHR*        hitShaderBindingTableRegion,
+                                        const VkStridedBufferRegionKHR*        callableShaderBindingTableRegion,
+                                        deUint32                                                       width,
+                                        deUint32                                                       height,
+                                        deUint32                                                       depth);
+
+void cmdTraceRaysIndirect      (const DeviceInterface&                         vk,
+                                                        VkCommandBuffer                                        commandBuffer,
+                                                        const VkStridedBufferRegionKHR*        raygenShaderBindingTableRegion,
+                                                        const VkStridedBufferRegionKHR*        missShaderBindingTableRegion,
+                                                        const VkStridedBufferRegionKHR*        hitShaderBindingTableRegion,
+                                                        const VkStridedBufferRegionKHR*        callableShaderBindingTableRegion,
+                                                        VkBuffer                                                       buffer,
+                                                        VkDeviceSize                                           offset);
+} // vk
+
+#endif // _VKRAYTRACINGUTIL_HPP
index dbe70d5..6551cbb 100644 (file)
@@ -50,17 +50,28 @@ Move<VkPipeline> createComputePipeline (const DeviceInterface&                              vk,
        return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
 }
 
-Move<VkPipeline> createRayTracingPipelineNV (const DeviceInterface&                            vk,
-                                                                               VkDevice                                                        device,
-                                                                               VkPipelineCache                                         pipelineCache,
-                                                                               const VkRayTracingPipelineCreateInfoNV* pCreateInfo,
-                                                                               const VkAllocationCallbacks*            pAllocator)
+Move<VkPipeline> createRayTracingPipelineNV (const DeviceInterface&                                            vk,
+                                                                                        VkDevice                                                                       device,
+                                                                                        VkPipelineCache                                                        pipelineCache,
+                                                                                        const VkRayTracingPipelineCreateInfoNV*        pCreateInfo,
+                                                                                        const VkAllocationCallbacks*                           pAllocator)
 {
        VkPipeline object = 0;
        VK_CHECK(vk.createRayTracingPipelinesNV(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object));
        return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
 }
 
+Move<VkPipeline> createRayTracingPipelineKHR (const DeviceInterface&                                   vk,
+                                                                                         VkDevice                                                                      device,
+                                                                                         VkPipelineCache                                                       pipelineCache,
+                                                                                         const VkRayTracingPipelineCreateInfoKHR*      pCreateInfo,
+                                                                                         const VkAllocationCallbacks*                          pAllocator)
+{
+       VkPipeline object = 0;
+       VK_CHECK(vk.createRayTracingPipelinesKHR(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object));
+       return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
+}
+
 Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface& vk, VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo)
 {
        VkCommandBuffer object = 0;
index a966b20..7032842 100644 (file)
@@ -46,6 +46,11 @@ Move<VkPipeline>             createRayTracingPipelineNV(const DeviceInterface&                                       vk,
                                                                                                 VkPipelineCache                                                pipelineCache,
                                                                                                 const VkRayTracingPipelineCreateInfoNV*        pCreateInfo,
                                                                                                 const VkAllocationCallbacks*                   pAllocator = DE_NULL);
+Move<VkPipeline>               createRayTracingPipelineKHR     (const DeviceInterface&                                 vk,
+                                                                                                VkDevice                                                                       device,
+                                                                                                VkPipelineCache                                                        pipelineCache,
+                                                                                                const VkRayTracingPipelineCreateInfoKHR*       pCreateInfo,
+                                                                                                const VkAllocationCallbacks*                           pAllocator = DE_NULL);
 Move<VkCommandBuffer>  allocateCommandBuffer   (const DeviceInterface& vk, VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo);
 Move<VkDescriptorSet>  allocateDescriptorSet   (const DeviceInterface& vk, VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo);
 
index 9916c59..031b69b 100644 (file)
@@ -56,12 +56,12 @@ EShLanguage getGlslangStage (glu::ShaderType type)
                EShLangTessControl,
                EShLangTessEvaluation,
                EShLangCompute,
-               EShLangRayGenNV,
-               EShLangAnyHitNV,
-               EShLangClosestHitNV,
-               EShLangMissNV,
-               EShLangIntersectNV,
-               EShLangCallableNV,
+               EShLangRayGen,
+               EShLangAnyHit,
+               EShLangClosestHit,
+               EShLangMiss,
+               EShLangIntersect,
+               EShLangCallable,
        };
        return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
 }