1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan CTS Framework 3e5c31af7Sopenharmony_ci * -------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2020 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Utilities for creating commonly used Vulkan objects 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 27e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 33e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include <vector> 36e5c31af7Sopenharmony_ci#include <string> 37e5c31af7Sopenharmony_ci#include <thread> 38e5c31af7Sopenharmony_ci#include <limits> 39e5c31af7Sopenharmony_ci#include <type_traits> 40e5c31af7Sopenharmony_ci#include <map> 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_cinamespace vk 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_cistatic const deUint32 WATCHDOG_INTERVAL = 16384; // Touch watchDog every N iterations. 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cistruct DeferredThreadParams 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci const DeviceInterface& vk; 52e5c31af7Sopenharmony_ci VkDevice device; 53e5c31af7Sopenharmony_ci VkDeferredOperationKHR deferredOperation; 54e5c31af7Sopenharmony_ci VkResult result; 55e5c31af7Sopenharmony_ci}; 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_cistd::string getFormatSimpleName (vk::VkFormat format) 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_ci constexpr size_t kPrefixLen = 10; // strlen("VK_FORMAT_") 60e5c31af7Sopenharmony_ci return de::toLower(de::toString(format).substr(kPrefixLen)); 61e5c31af7Sopenharmony_ci} 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_cibool pointInTriangle2D(const tcu::Vec3& p, const tcu::Vec3& p0, const tcu::Vec3& p1, const tcu::Vec3& p2) 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci float s = p0.y() * p2.x() - p0.x() * p2.y() + (p2.y() - p0.y()) * p.x() + (p0.x() - p2.x()) * p.y(); 66e5c31af7Sopenharmony_ci float t = p0.x() * p1.y() - p0.y() * p1.x() + (p0.y() - p1.y()) * p.x() + (p1.x() - p0.x()) * p.y(); 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ci if ((s < 0) != (t < 0)) 69e5c31af7Sopenharmony_ci return false; 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci float a = -p1.y() * p2.x() + p0.y() * (p2.x() - p1.x()) + p0.x() * (p1.y() - p2.y()) + p1.x() * p2.y(); 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ci return a < 0 ? 74e5c31af7Sopenharmony_ci (s <= 0 && s + t >= a) : 75e5c31af7Sopenharmony_ci (s >= 0 && s + t <= a); 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci// Returns true if VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR needs to be supported for the given format. 79e5c31af7Sopenharmony_cistatic bool isMandatoryAccelerationStructureVertexBufferFormat (vk::VkFormat format) 80e5c31af7Sopenharmony_ci{ 81e5c31af7Sopenharmony_ci bool mandatory = false; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci switch (format) 84e5c31af7Sopenharmony_ci { 85e5c31af7Sopenharmony_ci case VK_FORMAT_R32G32_SFLOAT: 86e5c31af7Sopenharmony_ci case VK_FORMAT_R32G32B32_SFLOAT: 87e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16_SFLOAT: 88e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SFLOAT: 89e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16_SNORM: 90e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SNORM: 91e5c31af7Sopenharmony_ci mandatory = true; 92e5c31af7Sopenharmony_ci break; 93e5c31af7Sopenharmony_ci default: 94e5c31af7Sopenharmony_ci break; 95e5c31af7Sopenharmony_ci } 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci return mandatory; 98e5c31af7Sopenharmony_ci} 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_civoid checkAccelerationStructureVertexBufferFormat (const vk::InstanceInterface &vki, vk::VkPhysicalDevice physicalDevice, vk::VkFormat format) 101e5c31af7Sopenharmony_ci{ 102e5c31af7Sopenharmony_ci const vk::VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci if ((formatProperties.bufferFeatures & vk::VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR) == 0u) 105e5c31af7Sopenharmony_ci { 106e5c31af7Sopenharmony_ci const std::string errorMsg = "Format not supported for acceleration structure vertex buffers"; 107e5c31af7Sopenharmony_ci if (isMandatoryAccelerationStructureVertexBufferFormat(format)) 108e5c31af7Sopenharmony_ci TCU_FAIL(errorMsg); 109e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, errorMsg); 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci} 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_cistd::string getCommonRayGenerationShader (void) 114e5c31af7Sopenharmony_ci{ 115e5c31af7Sopenharmony_ci return 116e5c31af7Sopenharmony_ci "#version 460 core\n" 117e5c31af7Sopenharmony_ci "#extension GL_EXT_ray_tracing : require\n" 118e5c31af7Sopenharmony_ci "layout(location = 0) rayPayloadEXT vec3 hitValue;\n" 119e5c31af7Sopenharmony_ci "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n" 120e5c31af7Sopenharmony_ci "\n" 121e5c31af7Sopenharmony_ci "void main()\n" 122e5c31af7Sopenharmony_ci "{\n" 123e5c31af7Sopenharmony_ci " uint rayFlags = 0;\n" 124e5c31af7Sopenharmony_ci " uint cullMask = 0xFF;\n" 125e5c31af7Sopenharmony_ci " float tmin = 0.0;\n" 126e5c31af7Sopenharmony_ci " float tmax = 9.0;\n" 127e5c31af7Sopenharmony_ci " 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" 128e5c31af7Sopenharmony_ci " vec3 direct = vec3(0.0, 0.0, -1.0);\n" 129e5c31af7Sopenharmony_ci " traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n" 130e5c31af7Sopenharmony_ci "}\n"; 131e5c31af7Sopenharmony_ci} 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ciRaytracedGeometryBase::RaytracedGeometryBase (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType) 134e5c31af7Sopenharmony_ci : m_geometryType (geometryType) 135e5c31af7Sopenharmony_ci , m_vertexFormat (vertexFormat) 136e5c31af7Sopenharmony_ci , m_indexType (indexType) 137e5c31af7Sopenharmony_ci , m_geometryFlags ((VkGeometryFlagsKHR)0u) 138e5c31af7Sopenharmony_ci , m_hasOpacityMicromap (false) 139e5c31af7Sopenharmony_ci{ 140e5c31af7Sopenharmony_ci if (m_geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) 141e5c31af7Sopenharmony_ci DE_ASSERT(m_vertexFormat == VK_FORMAT_R32G32B32_SFLOAT); 142e5c31af7Sopenharmony_ci} 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ciRaytracedGeometryBase::~RaytracedGeometryBase () 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci} 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_cistruct GeometryBuilderParams 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci VkGeometryTypeKHR geometryType; 151e5c31af7Sopenharmony_ci bool usePadding; 152e5c31af7Sopenharmony_ci}; 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_citemplate <typename V, typename I> 155e5c31af7Sopenharmony_ciRaytracedGeometryBase* buildRaytracedGeometry (const GeometryBuilderParams& params) 156e5c31af7Sopenharmony_ci{ 157e5c31af7Sopenharmony_ci return new RaytracedGeometry<V, I>(params.geometryType, (params.usePadding ? 1u : 0u)); 158e5c31af7Sopenharmony_ci} 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_cide::SharedPtr<RaytracedGeometryBase> makeRaytracedGeometry (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType, bool padVertices) 161e5c31af7Sopenharmony_ci{ 162e5c31af7Sopenharmony_ci const GeometryBuilderParams builderParams { geometryType, padVertices }; 163e5c31af7Sopenharmony_ci 164e5c31af7Sopenharmony_ci switch (vertexFormat) 165e5c31af7Sopenharmony_ci { 166e5c31af7Sopenharmony_ci case VK_FORMAT_R32G32_SFLOAT: 167e5c31af7Sopenharmony_ci switch (indexType) 168e5c31af7Sopenharmony_ci { 169e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec2, deUint16>(builderParams)); 170e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec2, deUint32>(builderParams)); 171e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec2, EmptyIndex>(builderParams)); 172e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 173e5c31af7Sopenharmony_ci } 174e5c31af7Sopenharmony_ci case VK_FORMAT_R32G32B32_SFLOAT: 175e5c31af7Sopenharmony_ci switch (indexType) 176e5c31af7Sopenharmony_ci { 177e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec3, deUint16>(builderParams)); 178e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec3, deUint32>(builderParams)); 179e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec3, EmptyIndex>(builderParams)); 180e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 181e5c31af7Sopenharmony_ci } 182e5c31af7Sopenharmony_ci case VK_FORMAT_R32G32B32A32_SFLOAT: 183e5c31af7Sopenharmony_ci switch (indexType) 184e5c31af7Sopenharmony_ci { 185e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec4, deUint16>(builderParams)); 186e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec4, deUint32>(builderParams)); 187e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec4, EmptyIndex>(builderParams)); 188e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 189e5c31af7Sopenharmony_ci } 190e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16_SFLOAT: 191e5c31af7Sopenharmony_ci switch (indexType) 192e5c31af7Sopenharmony_ci { 193e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16, deUint16>(builderParams)); 194e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16, deUint32>(builderParams)); 195e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16, EmptyIndex>(builderParams)); 196e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 197e5c31af7Sopenharmony_ci } 198e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16B16_SFLOAT: 199e5c31af7Sopenharmony_ci switch (indexType) 200e5c31af7Sopenharmony_ci { 201e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16, deUint16>(builderParams)); 202e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16, deUint32>(builderParams)); 203e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16, EmptyIndex>(builderParams)); 204e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 205e5c31af7Sopenharmony_ci } 206e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SFLOAT: 207e5c31af7Sopenharmony_ci switch (indexType) 208e5c31af7Sopenharmony_ci { 209e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16, deUint16>(builderParams)); 210e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16, deUint32>(builderParams)); 211e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16, EmptyIndex>(builderParams)); 212e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 213e5c31af7Sopenharmony_ci } 214e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16_SNORM: 215e5c31af7Sopenharmony_ci switch (indexType) 216e5c31af7Sopenharmony_ci { 217e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16SNorm, deUint16>(builderParams)); 218e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16SNorm, deUint32>(builderParams)); 219e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16SNorm, EmptyIndex>(builderParams)); 220e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 221e5c31af7Sopenharmony_ci } 222e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16B16_SNORM: 223e5c31af7Sopenharmony_ci switch (indexType) 224e5c31af7Sopenharmony_ci { 225e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16SNorm, deUint16>(builderParams)); 226e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16SNorm, deUint32>(builderParams)); 227e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16SNorm, EmptyIndex>(builderParams)); 228e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 229e5c31af7Sopenharmony_ci } 230e5c31af7Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SNORM: 231e5c31af7Sopenharmony_ci switch (indexType) 232e5c31af7Sopenharmony_ci { 233e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16SNorm, deUint16>(builderParams)); 234e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16SNorm, deUint32>(builderParams)); 235e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16SNorm, EmptyIndex>(builderParams)); 236e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 237e5c31af7Sopenharmony_ci } 238e5c31af7Sopenharmony_ci case VK_FORMAT_R64G64_SFLOAT: 239e5c31af7Sopenharmony_ci switch (indexType) 240e5c31af7Sopenharmony_ci { 241e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec2, deUint16>(builderParams)); 242e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec2, deUint32>(builderParams)); 243e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec2, EmptyIndex>(builderParams)); 244e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 245e5c31af7Sopenharmony_ci } 246e5c31af7Sopenharmony_ci case VK_FORMAT_R64G64B64_SFLOAT: 247e5c31af7Sopenharmony_ci switch (indexType) 248e5c31af7Sopenharmony_ci { 249e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec3, deUint16>(builderParams)); 250e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec3, deUint32>(builderParams)); 251e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec3, EmptyIndex>(builderParams)); 252e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 253e5c31af7Sopenharmony_ci } 254e5c31af7Sopenharmony_ci case VK_FORMAT_R64G64B64A64_SFLOAT: 255e5c31af7Sopenharmony_ci switch (indexType) 256e5c31af7Sopenharmony_ci { 257e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec4, deUint16>(builderParams)); 258e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec4, deUint32>(builderParams)); 259e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec4, EmptyIndex>(builderParams)); 260e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 261e5c31af7Sopenharmony_ci } 262e5c31af7Sopenharmony_ci case VK_FORMAT_R8G8_SNORM: 263e5c31af7Sopenharmony_ci switch (indexType) 264e5c31af7Sopenharmony_ci { 265e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_8SNorm, deUint16>(builderParams)); 266e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_8SNorm, deUint32>(builderParams)); 267e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_8SNorm, EmptyIndex>(builderParams)); 268e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 269e5c31af7Sopenharmony_ci } 270e5c31af7Sopenharmony_ci case VK_FORMAT_R8G8B8_SNORM: 271e5c31af7Sopenharmony_ci switch (indexType) 272e5c31af7Sopenharmony_ci { 273e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_8SNorm, deUint16>(builderParams)); 274e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_8SNorm, deUint32>(builderParams)); 275e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_8SNorm, EmptyIndex>(builderParams)); 276e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 277e5c31af7Sopenharmony_ci } 278e5c31af7Sopenharmony_ci case VK_FORMAT_R8G8B8A8_SNORM: 279e5c31af7Sopenharmony_ci switch (indexType) 280e5c31af7Sopenharmony_ci { 281e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_8SNorm, deUint16>(builderParams)); 282e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_8SNorm, deUint32>(builderParams)); 283e5c31af7Sopenharmony_ci case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_8SNorm, EmptyIndex>(builderParams)); 284e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Wrong index type"); 285e5c31af7Sopenharmony_ci } 286e5c31af7Sopenharmony_ci default: 287e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Wrong vertex format"); 288e5c31af7Sopenharmony_ci } 289e5c31af7Sopenharmony_ci 290e5c31af7Sopenharmony_ci} 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ciVkDeviceAddress getBufferDeviceAddress ( const DeviceInterface& vk, 293e5c31af7Sopenharmony_ci const VkDevice device, 294e5c31af7Sopenharmony_ci const VkBuffer buffer, 295e5c31af7Sopenharmony_ci VkDeviceSize offset ) 296e5c31af7Sopenharmony_ci{ 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci if (buffer == DE_NULL) 299e5c31af7Sopenharmony_ci return 0; 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci VkBufferDeviceAddressInfo deviceAddressInfo 302e5c31af7Sopenharmony_ci { 303e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, // VkStructureType sType 304e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext 305e5c31af7Sopenharmony_ci buffer // VkBuffer buffer; 306e5c31af7Sopenharmony_ci }; 307e5c31af7Sopenharmony_ci return vk.getBufferDeviceAddress(device, &deviceAddressInfo) + offset; 308e5c31af7Sopenharmony_ci} 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ci 311e5c31af7Sopenharmony_cistatic inline Move<VkQueryPool> makeQueryPool (const DeviceInterface& vk, 312e5c31af7Sopenharmony_ci const VkDevice device, 313e5c31af7Sopenharmony_ci const VkQueryType queryType, 314e5c31af7Sopenharmony_ci deUint32 queryCount) 315e5c31af7Sopenharmony_ci{ 316e5c31af7Sopenharmony_ci const VkQueryPoolCreateInfo queryPoolCreateInfo = 317e5c31af7Sopenharmony_ci { 318e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType 319e5c31af7Sopenharmony_ci DE_NULL, // pNext 320e5c31af7Sopenharmony_ci (VkQueryPoolCreateFlags)0, // flags 321e5c31af7Sopenharmony_ci queryType, // queryType 322e5c31af7Sopenharmony_ci queryCount, // queryCount 323e5c31af7Sopenharmony_ci 0u, // pipelineStatistics 324e5c31af7Sopenharmony_ci }; 325e5c31af7Sopenharmony_ci return createQueryPool(vk, device, &queryPoolCreateInfo); 326e5c31af7Sopenharmony_ci} 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_cistatic inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryTrianglesDataKHR& triangles) 329e5c31af7Sopenharmony_ci{ 330e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryDataKHR result; 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci deMemset(&result, 0, sizeof(result)); 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci result.triangles = triangles; 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci return result; 337e5c31af7Sopenharmony_ci} 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_cistatic inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryAabbsDataKHR& aabbs) 340e5c31af7Sopenharmony_ci{ 341e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryDataKHR result; 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci deMemset(&result, 0, sizeof(result)); 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci result.aabbs = aabbs; 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci return result; 348e5c31af7Sopenharmony_ci} 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_cistatic inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureInstancesDataKHR (const VkAccelerationStructureGeometryInstancesDataKHR& instances) 351e5c31af7Sopenharmony_ci{ 352e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryDataKHR result; 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ci deMemset(&result, 0, sizeof(result)); 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci result.instances = instances; 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci return result; 359e5c31af7Sopenharmony_ci} 360e5c31af7Sopenharmony_ci 361e5c31af7Sopenharmony_cistatic inline VkAccelerationStructureInstanceKHR makeVkAccelerationStructureInstanceKHR (const VkTransformMatrixKHR& transform, 362e5c31af7Sopenharmony_ci deUint32 instanceCustomIndex, 363e5c31af7Sopenharmony_ci deUint32 mask, 364e5c31af7Sopenharmony_ci deUint32 instanceShaderBindingTableRecordOffset, 365e5c31af7Sopenharmony_ci VkGeometryInstanceFlagsKHR flags, 366e5c31af7Sopenharmony_ci deUint64 accelerationStructureReference) 367e5c31af7Sopenharmony_ci{ 368e5c31af7Sopenharmony_ci VkAccelerationStructureInstanceKHR instance = { transform, 0, 0, 0, 0, accelerationStructureReference }; 369e5c31af7Sopenharmony_ci instance.instanceCustomIndex = instanceCustomIndex & 0xFFFFFF; 370e5c31af7Sopenharmony_ci instance.mask = mask & 0xFF; 371e5c31af7Sopenharmony_ci instance.instanceShaderBindingTableRecordOffset = instanceShaderBindingTableRecordOffset & 0xFFFFFF; 372e5c31af7Sopenharmony_ci instance.flags = flags & 0xFF; 373e5c31af7Sopenharmony_ci return instance; 374e5c31af7Sopenharmony_ci} 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ciVkResult getRayTracingShaderGroupHandlesKHR (const DeviceInterface& vk, 377e5c31af7Sopenharmony_ci const VkDevice device, 378e5c31af7Sopenharmony_ci const VkPipeline pipeline, 379e5c31af7Sopenharmony_ci const deUint32 firstGroup, 380e5c31af7Sopenharmony_ci const deUint32 groupCount, 381e5c31af7Sopenharmony_ci const deUintptr dataSize, 382e5c31af7Sopenharmony_ci void* pData) 383e5c31af7Sopenharmony_ci{ 384e5c31af7Sopenharmony_ci return vk.getRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData); 385e5c31af7Sopenharmony_ci} 386e5c31af7Sopenharmony_ci 387e5c31af7Sopenharmony_ciVkResult getRayTracingShaderGroupHandles (const DeviceInterface& vk, 388e5c31af7Sopenharmony_ci const VkDevice device, 389e5c31af7Sopenharmony_ci const VkPipeline pipeline, 390e5c31af7Sopenharmony_ci const deUint32 firstGroup, 391e5c31af7Sopenharmony_ci const deUint32 groupCount, 392e5c31af7Sopenharmony_ci const deUintptr dataSize, 393e5c31af7Sopenharmony_ci void* pData) 394e5c31af7Sopenharmony_ci{ 395e5c31af7Sopenharmony_ci return getRayTracingShaderGroupHandlesKHR(vk, device, pipeline, firstGroup, groupCount, dataSize, pData); 396e5c31af7Sopenharmony_ci} 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ciVkResult getRayTracingCaptureReplayShaderGroupHandles (const DeviceInterface& vk, 399e5c31af7Sopenharmony_ci const VkDevice device, 400e5c31af7Sopenharmony_ci const VkPipeline pipeline, 401e5c31af7Sopenharmony_ci const deUint32 firstGroup, 402e5c31af7Sopenharmony_ci const deUint32 groupCount, 403e5c31af7Sopenharmony_ci const deUintptr dataSize, 404e5c31af7Sopenharmony_ci void* pData) 405e5c31af7Sopenharmony_ci{ 406e5c31af7Sopenharmony_ci return vk.getRayTracingCaptureReplayShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData); 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ciVkResult finishDeferredOperation (const DeviceInterface& vk, 410e5c31af7Sopenharmony_ci VkDevice device, 411e5c31af7Sopenharmony_ci VkDeferredOperationKHR deferredOperation) 412e5c31af7Sopenharmony_ci{ 413e5c31af7Sopenharmony_ci VkResult result = vk.deferredOperationJoinKHR(device, deferredOperation); 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci while (result == VK_THREAD_IDLE_KHR) 416e5c31af7Sopenharmony_ci { 417e5c31af7Sopenharmony_ci std::this_thread::yield(); 418e5c31af7Sopenharmony_ci result = vk.deferredOperationJoinKHR(device, deferredOperation); 419e5c31af7Sopenharmony_ci } 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci switch( result ) 422e5c31af7Sopenharmony_ci { 423e5c31af7Sopenharmony_ci case VK_SUCCESS: 424e5c31af7Sopenharmony_ci { 425e5c31af7Sopenharmony_ci // Deferred operation has finished. Query its result 426e5c31af7Sopenharmony_ci result = vk.getDeferredOperationResultKHR(device, deferredOperation); 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci break; 429e5c31af7Sopenharmony_ci } 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci case VK_THREAD_DONE_KHR: 432e5c31af7Sopenharmony_ci { 433e5c31af7Sopenharmony_ci // Deferred operation is being wrapped up by another thread 434e5c31af7Sopenharmony_ci // wait for that thread to finish 435e5c31af7Sopenharmony_ci do 436e5c31af7Sopenharmony_ci { 437e5c31af7Sopenharmony_ci std::this_thread::yield(); 438e5c31af7Sopenharmony_ci result = vk.getDeferredOperationResultKHR(device, deferredOperation); 439e5c31af7Sopenharmony_ci } while (result == VK_NOT_READY); 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci break; 442e5c31af7Sopenharmony_ci } 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci default: 445e5c31af7Sopenharmony_ci { 446e5c31af7Sopenharmony_ci DE_ASSERT(false); 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci break; 449e5c31af7Sopenharmony_ci } 450e5c31af7Sopenharmony_ci } 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci return result; 453e5c31af7Sopenharmony_ci} 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_civoid finishDeferredOperationThreaded (DeferredThreadParams* deferredThreadParams) 456e5c31af7Sopenharmony_ci{ 457e5c31af7Sopenharmony_ci deferredThreadParams->result = finishDeferredOperation(deferredThreadParams->vk, deferredThreadParams->device, deferredThreadParams->deferredOperation); 458e5c31af7Sopenharmony_ci} 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_civoid finishDeferredOperation (const DeviceInterface& vk, 461e5c31af7Sopenharmony_ci VkDevice device, 462e5c31af7Sopenharmony_ci VkDeferredOperationKHR deferredOperation, 463e5c31af7Sopenharmony_ci const deUint32 workerThreadCount, 464e5c31af7Sopenharmony_ci const bool operationNotDeferred) 465e5c31af7Sopenharmony_ci{ 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci if (operationNotDeferred) 468e5c31af7Sopenharmony_ci { 469e5c31af7Sopenharmony_ci // when the operation deferral returns VK_OPERATION_NOT_DEFERRED_KHR, 470e5c31af7Sopenharmony_ci // the deferred operation should act as if no command was deferred 471e5c31af7Sopenharmony_ci VK_CHECK(vk.getDeferredOperationResultKHR(device, deferredOperation)); 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci // there is not need to join any threads to the deferred operation, 475e5c31af7Sopenharmony_ci // so below can be skipped. 476e5c31af7Sopenharmony_ci return; 477e5c31af7Sopenharmony_ci } 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci if (workerThreadCount == 0) 480e5c31af7Sopenharmony_ci { 481e5c31af7Sopenharmony_ci VK_CHECK(finishDeferredOperation(vk, device, deferredOperation)); 482e5c31af7Sopenharmony_ci } 483e5c31af7Sopenharmony_ci else 484e5c31af7Sopenharmony_ci { 485e5c31af7Sopenharmony_ci const deUint32 maxThreadCountSupported = deMinu32(256u, vk.getDeferredOperationMaxConcurrencyKHR(device, deferredOperation)); 486e5c31af7Sopenharmony_ci const deUint32 requestedThreadCount = workerThreadCount; 487e5c31af7Sopenharmony_ci const deUint32 testThreadCount = requestedThreadCount == std::numeric_limits<deUint32>::max() ? maxThreadCountSupported : requestedThreadCount; 488e5c31af7Sopenharmony_ci 489e5c31af7Sopenharmony_ci if (maxThreadCountSupported == 0) 490e5c31af7Sopenharmony_ci TCU_FAIL("vkGetDeferredOperationMaxConcurrencyKHR must not return 0"); 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ci const DeferredThreadParams deferredThreadParams = 493e5c31af7Sopenharmony_ci { 494e5c31af7Sopenharmony_ci vk, // const DeviceInterface& vk; 495e5c31af7Sopenharmony_ci device, // VkDevice device; 496e5c31af7Sopenharmony_ci deferredOperation, // VkDeferredOperationKHR deferredOperation; 497e5c31af7Sopenharmony_ci VK_RESULT_MAX_ENUM, // VResult result; 498e5c31af7Sopenharmony_ci }; 499e5c31af7Sopenharmony_ci std::vector<DeferredThreadParams> threadParams (testThreadCount, deferredThreadParams); 500e5c31af7Sopenharmony_ci std::vector<de::MovePtr<std::thread> > threads (testThreadCount); 501e5c31af7Sopenharmony_ci bool executionResult = false; 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci DE_ASSERT(threads.size() > 0 && threads.size() == testThreadCount); 504e5c31af7Sopenharmony_ci 505e5c31af7Sopenharmony_ci for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx) 506e5c31af7Sopenharmony_ci threads[threadNdx] = de::MovePtr<std::thread>(new std::thread(finishDeferredOperationThreaded, &threadParams[threadNdx])); 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_ci for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx) 509e5c31af7Sopenharmony_ci threads[threadNdx]->join(); 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx) 512e5c31af7Sopenharmony_ci if (threadParams[threadNdx].result == VK_SUCCESS) 513e5c31af7Sopenharmony_ci executionResult = true; 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci if (!executionResult) 516e5c31af7Sopenharmony_ci TCU_FAIL("Neither reported VK_SUCCESS"); 517e5c31af7Sopenharmony_ci } 518e5c31af7Sopenharmony_ci} 519e5c31af7Sopenharmony_ci 520e5c31af7Sopenharmony_ciSerialStorage::SerialStorage (const DeviceInterface& vk, 521e5c31af7Sopenharmony_ci const VkDevice device, 522e5c31af7Sopenharmony_ci Allocator& allocator, 523e5c31af7Sopenharmony_ci const VkAccelerationStructureBuildTypeKHR buildType, 524e5c31af7Sopenharmony_ci const VkDeviceSize storageSize) 525e5c31af7Sopenharmony_ci : m_buildType (buildType) 526e5c31af7Sopenharmony_ci , m_storageSize (storageSize) 527e5c31af7Sopenharmony_ci , m_serialInfo () 528e5c31af7Sopenharmony_ci{ 529e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(storageSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 530e5c31af7Sopenharmony_ci try 531e5c31af7Sopenharmony_ci { 532e5c31af7Sopenharmony_ci m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 533e5c31af7Sopenharmony_ci } 534e5c31af7Sopenharmony_ci catch (const tcu::NotSupportedError&) 535e5c31af7Sopenharmony_ci { 536e5c31af7Sopenharmony_ci // retry without Cached flag 537e5c31af7Sopenharmony_ci m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 538e5c31af7Sopenharmony_ci } 539e5c31af7Sopenharmony_ci} 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ciSerialStorage::SerialStorage (const DeviceInterface& vk, 542e5c31af7Sopenharmony_ci const VkDevice device, 543e5c31af7Sopenharmony_ci Allocator& allocator, 544e5c31af7Sopenharmony_ci const VkAccelerationStructureBuildTypeKHR buildType, 545e5c31af7Sopenharmony_ci const SerialInfo& serialInfo) 546e5c31af7Sopenharmony_ci : m_buildType (buildType) 547e5c31af7Sopenharmony_ci , m_storageSize (serialInfo.sizes()[0]) // raise assertion if serialInfo is empty 548e5c31af7Sopenharmony_ci , m_serialInfo (serialInfo) 549e5c31af7Sopenharmony_ci{ 550e5c31af7Sopenharmony_ci DE_ASSERT(serialInfo.sizes().size() >= 2u); 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci // create buffer for top-level acceleration structure 553e5c31af7Sopenharmony_ci { 554e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_storageSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 555e5c31af7Sopenharmony_ci m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 556e5c31af7Sopenharmony_ci } 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci // create buffers for bottom-level acceleration structures 559e5c31af7Sopenharmony_ci { 560e5c31af7Sopenharmony_ci std::vector<deUint64> addrs; 561e5c31af7Sopenharmony_ci 562e5c31af7Sopenharmony_ci for (std::size_t i = 1; i < serialInfo.addresses().size(); ++i) 563e5c31af7Sopenharmony_ci { 564e5c31af7Sopenharmony_ci const deUint64& lookAddr = serialInfo.addresses()[i]; 565e5c31af7Sopenharmony_ci auto end = addrs.end(); 566e5c31af7Sopenharmony_ci auto match = std::find_if(addrs.begin(), end, [&](const deUint64& item){ return item == lookAddr; }); 567e5c31af7Sopenharmony_ci if (match == end) 568e5c31af7Sopenharmony_ci { 569e5c31af7Sopenharmony_ci addrs.emplace_back(lookAddr); 570e5c31af7Sopenharmony_ci m_bottoms.emplace_back(de::SharedPtr<SerialStorage>(new SerialStorage(vk, device, allocator, buildType, serialInfo.sizes()[i]))); 571e5c31af7Sopenharmony_ci } 572e5c31af7Sopenharmony_ci } 573e5c31af7Sopenharmony_ci } 574e5c31af7Sopenharmony_ci} 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ciVkDeviceOrHostAddressKHR SerialStorage::getAddress (const DeviceInterface& vk, 577e5c31af7Sopenharmony_ci const VkDevice device, 578e5c31af7Sopenharmony_ci const VkAccelerationStructureBuildTypeKHR buildType) 579e5c31af7Sopenharmony_ci{ 580e5c31af7Sopenharmony_ci if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 581e5c31af7Sopenharmony_ci return makeDeviceOrHostAddressKHR(vk, device, m_buffer->get(), 0); 582e5c31af7Sopenharmony_ci else 583e5c31af7Sopenharmony_ci return makeDeviceOrHostAddressKHR(m_buffer->getAllocation().getHostPtr()); 584e5c31af7Sopenharmony_ci} 585e5c31af7Sopenharmony_ci 586e5c31af7Sopenharmony_ciSerialStorage::AccelerationStructureHeader* SerialStorage::getASHeader () 587e5c31af7Sopenharmony_ci{ 588e5c31af7Sopenharmony_ci return reinterpret_cast<AccelerationStructureHeader*>(getHostAddress().hostAddress); 589e5c31af7Sopenharmony_ci} 590e5c31af7Sopenharmony_ci 591e5c31af7Sopenharmony_cibool SerialStorage::hasDeepFormat () const 592e5c31af7Sopenharmony_ci{ 593e5c31af7Sopenharmony_ci return (m_serialInfo.sizes().size() >= 2u); 594e5c31af7Sopenharmony_ci} 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_cide::SharedPtr<SerialStorage> SerialStorage::getBottomStorage (deUint32 index) const 597e5c31af7Sopenharmony_ci{ 598e5c31af7Sopenharmony_ci return m_bottoms[index]; 599e5c31af7Sopenharmony_ci} 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ciVkDeviceOrHostAddressKHR SerialStorage::getHostAddress (VkDeviceSize offset) 602e5c31af7Sopenharmony_ci{ 603e5c31af7Sopenharmony_ci DE_ASSERT(offset < m_storageSize); 604e5c31af7Sopenharmony_ci return makeDeviceOrHostAddressKHR(static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr()) + offset); 605e5c31af7Sopenharmony_ci} 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ciVkDeviceOrHostAddressConstKHR SerialStorage::getHostAddressConst (VkDeviceSize offset) 608e5c31af7Sopenharmony_ci{ 609e5c31af7Sopenharmony_ci return makeDeviceOrHostAddressConstKHR(static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr()) + offset); 610e5c31af7Sopenharmony_ci} 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ciVkDeviceOrHostAddressConstKHR SerialStorage::getAddressConst (const DeviceInterface& vk, 613e5c31af7Sopenharmony_ci const VkDevice device, 614e5c31af7Sopenharmony_ci const VkAccelerationStructureBuildTypeKHR buildType) 615e5c31af7Sopenharmony_ci{ 616e5c31af7Sopenharmony_ci if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 617e5c31af7Sopenharmony_ci return makeDeviceOrHostAddressConstKHR(vk, device, m_buffer->get(), 0); 618e5c31af7Sopenharmony_ci else 619e5c31af7Sopenharmony_ci return getHostAddressConst(); 620e5c31af7Sopenharmony_ci} 621e5c31af7Sopenharmony_ci 622e5c31af7Sopenharmony_ciinline VkDeviceSize SerialStorage::getStorageSize () const 623e5c31af7Sopenharmony_ci{ 624e5c31af7Sopenharmony_ci return m_storageSize; 625e5c31af7Sopenharmony_ci} 626e5c31af7Sopenharmony_ci 627e5c31af7Sopenharmony_ciinline const SerialInfo& SerialStorage::getSerialInfo () const 628e5c31af7Sopenharmony_ci{ 629e5c31af7Sopenharmony_ci return m_serialInfo; 630e5c31af7Sopenharmony_ci} 631e5c31af7Sopenharmony_ci 632e5c31af7Sopenharmony_cideUint64 SerialStorage::getDeserializedSize () 633e5c31af7Sopenharmony_ci{ 634e5c31af7Sopenharmony_ci deUint64 result = 0; 635e5c31af7Sopenharmony_ci const deUint8* startPtr = static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr()); 636e5c31af7Sopenharmony_ci 637e5c31af7Sopenharmony_ci DE_ASSERT(sizeof(result) == DESERIALIZED_SIZE_SIZE); 638e5c31af7Sopenharmony_ci 639e5c31af7Sopenharmony_ci deMemcpy(&result, startPtr + DESERIALIZED_SIZE_OFFSET, sizeof(result)); 640e5c31af7Sopenharmony_ci 641e5c31af7Sopenharmony_ci return result; 642e5c31af7Sopenharmony_ci} 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ciBottomLevelAccelerationStructure::~BottomLevelAccelerationStructure () 645e5c31af7Sopenharmony_ci{ 646e5c31af7Sopenharmony_ci} 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ciBottomLevelAccelerationStructure::BottomLevelAccelerationStructure () 649e5c31af7Sopenharmony_ci : m_structureSize (0u) 650e5c31af7Sopenharmony_ci , m_updateScratchSize (0u) 651e5c31af7Sopenharmony_ci , m_buildScratchSize (0u) 652e5c31af7Sopenharmony_ci{ 653e5c31af7Sopenharmony_ci} 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::setGeometryData (const std::vector<tcu::Vec3>& geometryData, 656e5c31af7Sopenharmony_ci const bool triangles, 657e5c31af7Sopenharmony_ci const VkGeometryFlagsKHR geometryFlags) 658e5c31af7Sopenharmony_ci{ 659e5c31af7Sopenharmony_ci if (triangles) 660e5c31af7Sopenharmony_ci DE_ASSERT((geometryData.size() % 3) == 0); 661e5c31af7Sopenharmony_ci else 662e5c31af7Sopenharmony_ci DE_ASSERT((geometryData.size() % 2) == 0); 663e5c31af7Sopenharmony_ci 664e5c31af7Sopenharmony_ci setGeometryCount(1u); 665e5c31af7Sopenharmony_ci 666e5c31af7Sopenharmony_ci addGeometry(geometryData, triangles, geometryFlags); 667e5c31af7Sopenharmony_ci} 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::setDefaultGeometryData (const VkShaderStageFlagBits testStage, 670e5c31af7Sopenharmony_ci const VkGeometryFlagsKHR geometryFlags) 671e5c31af7Sopenharmony_ci{ 672e5c31af7Sopenharmony_ci bool trianglesData = false; 673e5c31af7Sopenharmony_ci float z = 0.0f; 674e5c31af7Sopenharmony_ci std::vector<tcu::Vec3> geometryData; 675e5c31af7Sopenharmony_ci 676e5c31af7Sopenharmony_ci switch (testStage) 677e5c31af7Sopenharmony_ci { 678e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_RAYGEN_BIT_KHR: z = -1.0f; trianglesData = true; break; 679e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: z = -1.0f; trianglesData = true; break; 680e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: z = -1.0f; trianglesData = true; break; 681e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_MISS_BIT_KHR: z = -9.9f; trianglesData = true; break; 682e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: z = -1.0f; trianglesData = false; break; 683e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_CALLABLE_BIT_KHR: z = -1.0f; trianglesData = true; break; 684e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unacceptable stage"); 685e5c31af7Sopenharmony_ci } 686e5c31af7Sopenharmony_ci 687e5c31af7Sopenharmony_ci if (trianglesData) 688e5c31af7Sopenharmony_ci { 689e5c31af7Sopenharmony_ci geometryData.reserve(6); 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z)); 692e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(-1.0f, +1.0f, z)); 693e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(+1.0f, -1.0f, z)); 694e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(+1.0f, -1.0f, z)); 695e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(-1.0f, +1.0f, z)); 696e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z)); 697e5c31af7Sopenharmony_ci } 698e5c31af7Sopenharmony_ci else 699e5c31af7Sopenharmony_ci { 700e5c31af7Sopenharmony_ci geometryData.reserve(2); 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z)); 703e5c31af7Sopenharmony_ci geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z)); 704e5c31af7Sopenharmony_ci } 705e5c31af7Sopenharmony_ci 706e5c31af7Sopenharmony_ci setGeometryCount(1u); 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci addGeometry(geometryData, trianglesData, geometryFlags); 709e5c31af7Sopenharmony_ci} 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::setGeometryCount (const size_t geometryCount) 712e5c31af7Sopenharmony_ci{ 713e5c31af7Sopenharmony_ci m_geometriesData.clear(); 714e5c31af7Sopenharmony_ci 715e5c31af7Sopenharmony_ci m_geometriesData.reserve(geometryCount); 716e5c31af7Sopenharmony_ci} 717e5c31af7Sopenharmony_ci 718e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::addGeometry (de::SharedPtr<RaytracedGeometryBase>& raytracedGeometry) 719e5c31af7Sopenharmony_ci{ 720e5c31af7Sopenharmony_ci m_geometriesData.push_back(raytracedGeometry); 721e5c31af7Sopenharmony_ci} 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::addGeometry (const std::vector<tcu::Vec3>& geometryData, 724e5c31af7Sopenharmony_ci const bool triangles, 725e5c31af7Sopenharmony_ci const VkGeometryFlagsKHR geometryFlags, 726e5c31af7Sopenharmony_ci const VkAccelerationStructureTrianglesOpacityMicromapEXT* opacityGeometryMicromap) 727e5c31af7Sopenharmony_ci{ 728e5c31af7Sopenharmony_ci DE_ASSERT(geometryData.size() > 0); 729e5c31af7Sopenharmony_ci DE_ASSERT((triangles && geometryData.size() % 3 == 0) || (!triangles && geometryData.size() % 2 == 0)); 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci if (!triangles) 732e5c31af7Sopenharmony_ci for (size_t posNdx = 0; posNdx < geometryData.size() / 2; ++posNdx) 733e5c31af7Sopenharmony_ci { 734e5c31af7Sopenharmony_ci DE_ASSERT(geometryData[2 * posNdx].x() <= geometryData[2 * posNdx + 1].x()); 735e5c31af7Sopenharmony_ci DE_ASSERT(geometryData[2 * posNdx].y() <= geometryData[2 * posNdx + 1].y()); 736e5c31af7Sopenharmony_ci DE_ASSERT(geometryData[2 * posNdx].z() <= geometryData[2 * posNdx + 1].z()); 737e5c31af7Sopenharmony_ci } 738e5c31af7Sopenharmony_ci 739e5c31af7Sopenharmony_ci 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); 740e5c31af7Sopenharmony_ci for (auto it = begin(geometryData), eit = end(geometryData); it != eit; ++it) 741e5c31af7Sopenharmony_ci geometry->addVertex(*it); 742e5c31af7Sopenharmony_ci 743e5c31af7Sopenharmony_ci geometry->setGeometryFlags(geometryFlags); 744e5c31af7Sopenharmony_ci if (opacityGeometryMicromap) 745e5c31af7Sopenharmony_ci geometry->setOpacityMicromap(opacityGeometryMicromap); 746e5c31af7Sopenharmony_ci addGeometry(geometry); 747e5c31af7Sopenharmony_ci} 748e5c31af7Sopenharmony_ci 749e5c31af7Sopenharmony_ciVkAccelerationStructureBuildSizesInfoKHR BottomLevelAccelerationStructure::getStructureBuildSizes () const 750e5c31af7Sopenharmony_ci{ 751e5c31af7Sopenharmony_ci return 752e5c31af7Sopenharmony_ci { 753e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; 754e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 755e5c31af7Sopenharmony_ci m_structureSize, // VkDeviceSize accelerationStructureSize; 756e5c31af7Sopenharmony_ci m_updateScratchSize, // VkDeviceSize updateScratchSize; 757e5c31af7Sopenharmony_ci m_buildScratchSize // VkDeviceSize buildScratchSize; 758e5c31af7Sopenharmony_ci }; 759e5c31af7Sopenharmony_ci}; 760e5c31af7Sopenharmony_ci 761e5c31af7Sopenharmony_ciVkDeviceSize getVertexBufferSize (const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData) 762e5c31af7Sopenharmony_ci{ 763e5c31af7Sopenharmony_ci DE_ASSERT(geometriesData.size() != 0); 764e5c31af7Sopenharmony_ci VkDeviceSize bufferSizeBytes = 0; 765e5c31af7Sopenharmony_ci for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) 766e5c31af7Sopenharmony_ci bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getVertexByteSize(),8); 767e5c31af7Sopenharmony_ci return bufferSizeBytes; 768e5c31af7Sopenharmony_ci} 769e5c31af7Sopenharmony_ci 770e5c31af7Sopenharmony_ciBufferWithMemory* createVertexBuffer (const DeviceInterface& vk, 771e5c31af7Sopenharmony_ci const VkDevice device, 772e5c31af7Sopenharmony_ci Allocator& allocator, 773e5c31af7Sopenharmony_ci const VkDeviceSize bufferSizeBytes) 774e5c31af7Sopenharmony_ci{ 775e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 776e5c31af7Sopenharmony_ci return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); 777e5c31af7Sopenharmony_ci} 778e5c31af7Sopenharmony_ci 779e5c31af7Sopenharmony_ciBufferWithMemory* createVertexBuffer (const DeviceInterface& vk, 780e5c31af7Sopenharmony_ci const VkDevice device, 781e5c31af7Sopenharmony_ci Allocator& allocator, 782e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData) 783e5c31af7Sopenharmony_ci{ 784e5c31af7Sopenharmony_ci return createVertexBuffer(vk, device, allocator, getVertexBufferSize(geometriesData)); 785e5c31af7Sopenharmony_ci} 786e5c31af7Sopenharmony_ci 787e5c31af7Sopenharmony_civoid updateVertexBuffer (const DeviceInterface& vk, 788e5c31af7Sopenharmony_ci const VkDevice device, 789e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData, 790e5c31af7Sopenharmony_ci BufferWithMemory* vertexBuffer, 791e5c31af7Sopenharmony_ci VkDeviceSize geometriesOffset = 0) 792e5c31af7Sopenharmony_ci{ 793e5c31af7Sopenharmony_ci const Allocation& geometryAlloc = vertexBuffer->getAllocation(); 794e5c31af7Sopenharmony_ci deUint8* bufferStart = static_cast<deUint8*>(geometryAlloc.getHostPtr()); 795e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = geometriesOffset; 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_ci for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) 798e5c31af7Sopenharmony_ci { 799e5c31af7Sopenharmony_ci const void* geometryPtr = geometriesData[geometryNdx]->getVertexPointer(); 800e5c31af7Sopenharmony_ci const size_t geometryPtrSize = geometriesData[geometryNdx]->getVertexByteSize(); 801e5c31af7Sopenharmony_ci 802e5c31af7Sopenharmony_ci deMemcpy(&bufferStart[bufferOffset], geometryPtr, geometryPtrSize); 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci bufferOffset += deAlignSize(geometryPtrSize,8); 805e5c31af7Sopenharmony_ci } 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci // Flush the whole allocation. We could flush only the interesting range, but we'd need to be sure both the offset and size 808e5c31af7Sopenharmony_ci // align to VkPhysicalDeviceLimits::nonCoherentAtomSize, which we are not considering. Also note most code uses Coherent memory 809e5c31af7Sopenharmony_ci // for the vertex and index buffers, so flushing is actually not needed. 810e5c31af7Sopenharmony_ci flushAlloc(vk, device, geometryAlloc); 811e5c31af7Sopenharmony_ci} 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_ciVkDeviceSize getIndexBufferSize (const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData) 814e5c31af7Sopenharmony_ci{ 815e5c31af7Sopenharmony_ci DE_ASSERT(!geometriesData.empty()); 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci VkDeviceSize bufferSizeBytes = 0; 818e5c31af7Sopenharmony_ci for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) 819e5c31af7Sopenharmony_ci if(geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR) 820e5c31af7Sopenharmony_ci bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getIndexByteSize(),8); 821e5c31af7Sopenharmony_ci return bufferSizeBytes; 822e5c31af7Sopenharmony_ci} 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ciBufferWithMemory* createIndexBuffer (const DeviceInterface& vk, 825e5c31af7Sopenharmony_ci const VkDevice device, 826e5c31af7Sopenharmony_ci Allocator& allocator, 827e5c31af7Sopenharmony_ci const VkDeviceSize bufferSizeBytes) 828e5c31af7Sopenharmony_ci{ 829e5c31af7Sopenharmony_ci DE_ASSERT(bufferSizeBytes); 830e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 831e5c31af7Sopenharmony_ci return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); 832e5c31af7Sopenharmony_ci} 833e5c31af7Sopenharmony_ci 834e5c31af7Sopenharmony_ciBufferWithMemory* createIndexBuffer (const DeviceInterface& vk, 835e5c31af7Sopenharmony_ci const VkDevice device, 836e5c31af7Sopenharmony_ci Allocator& allocator, 837e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData) 838e5c31af7Sopenharmony_ci{ 839e5c31af7Sopenharmony_ci const VkDeviceSize bufferSizeBytes = getIndexBufferSize(geometriesData); 840e5c31af7Sopenharmony_ci return bufferSizeBytes ? createIndexBuffer(vk, device, allocator, bufferSizeBytes) : nullptr; 841e5c31af7Sopenharmony_ci} 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_civoid updateIndexBuffer (const DeviceInterface& vk, 844e5c31af7Sopenharmony_ci const VkDevice device, 845e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData, 846e5c31af7Sopenharmony_ci BufferWithMemory* indexBuffer, 847e5c31af7Sopenharmony_ci VkDeviceSize geometriesOffset) 848e5c31af7Sopenharmony_ci{ 849e5c31af7Sopenharmony_ci const Allocation& indexAlloc = indexBuffer->getAllocation(); 850e5c31af7Sopenharmony_ci deUint8* bufferStart = static_cast<deUint8*>(indexAlloc.getHostPtr()); 851e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = geometriesOffset; 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ci for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) 854e5c31af7Sopenharmony_ci { 855e5c31af7Sopenharmony_ci if (geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR) 856e5c31af7Sopenharmony_ci { 857e5c31af7Sopenharmony_ci const void* indexPtr = geometriesData[geometryNdx]->getIndexPointer(); 858e5c31af7Sopenharmony_ci const size_t indexPtrSize = geometriesData[geometryNdx]->getIndexByteSize(); 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_ci deMemcpy(&bufferStart[bufferOffset], indexPtr, indexPtrSize); 861e5c31af7Sopenharmony_ci 862e5c31af7Sopenharmony_ci bufferOffset += deAlignSize(indexPtrSize, 8); 863e5c31af7Sopenharmony_ci } 864e5c31af7Sopenharmony_ci } 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci // Flush the whole allocation. We could flush only the interesting range, but we'd need to be sure both the offset and size 867e5c31af7Sopenharmony_ci // align to VkPhysicalDeviceLimits::nonCoherentAtomSize, which we are not considering. Also note most code uses Coherent memory 868e5c31af7Sopenharmony_ci // for the vertex and index buffers, so flushing is actually not needed. 869e5c31af7Sopenharmony_ci flushAlloc(vk, device, indexAlloc); 870e5c31af7Sopenharmony_ci} 871e5c31af7Sopenharmony_ci 872e5c31af7Sopenharmony_ciclass BottomLevelAccelerationStructureKHR : public BottomLevelAccelerationStructure 873e5c31af7Sopenharmony_ci{ 874e5c31af7Sopenharmony_cipublic: 875e5c31af7Sopenharmony_ci static deUint32 getRequiredAllocationCount (void); 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci BottomLevelAccelerationStructureKHR (); 878e5c31af7Sopenharmony_ci BottomLevelAccelerationStructureKHR (const BottomLevelAccelerationStructureKHR& other) = delete; 879e5c31af7Sopenharmony_ci virtual ~BottomLevelAccelerationStructureKHR (); 880e5c31af7Sopenharmony_ci 881e5c31af7Sopenharmony_ci void setBuildType (const VkAccelerationStructureBuildTypeKHR buildType) override; 882e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR getBuildType () const override; 883e5c31af7Sopenharmony_ci void setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags) override; 884e5c31af7Sopenharmony_ci void setCreateGeneric (bool createGeneric) override; 885e5c31af7Sopenharmony_ci void setCreationBufferUnbounded (bool creationBufferUnbounded) override; 886e5c31af7Sopenharmony_ci void setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags) override; 887e5c31af7Sopenharmony_ci void setBuildWithoutGeometries (bool buildWithoutGeometries) override; 888e5c31af7Sopenharmony_ci void setBuildWithoutPrimitives (bool buildWithoutPrimitives) override; 889e5c31af7Sopenharmony_ci void setDeferredOperation (const bool deferredOperation, 890e5c31af7Sopenharmony_ci const deUint32 workerThreadCount) override; 891e5c31af7Sopenharmony_ci void setUseArrayOfPointers (const bool useArrayOfPointers) override; 892e5c31af7Sopenharmony_ci void setUseMaintenance5 (const bool useMaintenance5) override; 893e5c31af7Sopenharmony_ci void setIndirectBuildParameters (const VkBuffer indirectBuffer, 894e5c31af7Sopenharmony_ci const VkDeviceSize indirectBufferOffset, 895e5c31af7Sopenharmony_ci const deUint32 indirectBufferStride) override; 896e5c31af7Sopenharmony_ci VkBuildAccelerationStructureFlagsKHR getBuildFlags () const override; 897e5c31af7Sopenharmony_ci 898e5c31af7Sopenharmony_ci void create (const DeviceInterface& vk, 899e5c31af7Sopenharmony_ci const VkDevice device, 900e5c31af7Sopenharmony_ci Allocator& allocator, 901e5c31af7Sopenharmony_ci VkDeviceSize structureSize, 902e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress = 0u, 903e5c31af7Sopenharmony_ci const void* pNext = DE_NULL, 904e5c31af7Sopenharmony_ci const MemoryRequirement& addMemoryRequirement = MemoryRequirement::Any, 905e5c31af7Sopenharmony_ci const VkBuffer creationBuffer = VK_NULL_HANDLE, 906e5c31af7Sopenharmony_ci const VkDeviceSize creationBufferSize = 0u) override; 907e5c31af7Sopenharmony_ci void build (const DeviceInterface& vk, 908e5c31af7Sopenharmony_ci const VkDevice device, 909e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 910e5c31af7Sopenharmony_ci BottomLevelAccelerationStructure* srcAccelerationStructure = DE_NULL) override; 911e5c31af7Sopenharmony_ci void copyFrom (const DeviceInterface& vk, 912e5c31af7Sopenharmony_ci const VkDevice device, 913e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 914e5c31af7Sopenharmony_ci BottomLevelAccelerationStructure* accelerationStructure, 915e5c31af7Sopenharmony_ci bool compactCopy) override; 916e5c31af7Sopenharmony_ci 917e5c31af7Sopenharmony_ci void serialize (const DeviceInterface& vk, 918e5c31af7Sopenharmony_ci const VkDevice device, 919e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 920e5c31af7Sopenharmony_ci SerialStorage* storage) override; 921e5c31af7Sopenharmony_ci void deserialize (const DeviceInterface& vk, 922e5c31af7Sopenharmony_ci const VkDevice device, 923e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 924e5c31af7Sopenharmony_ci SerialStorage* storage) override; 925e5c31af7Sopenharmony_ci 926e5c31af7Sopenharmony_ci const VkAccelerationStructureKHR* getPtr (void) const override; 927e5c31af7Sopenharmony_ci void updateGeometry (size_t geometryIndex, 928e5c31af7Sopenharmony_ci de::SharedPtr<RaytracedGeometryBase>& raytracedGeometry) override; 929e5c31af7Sopenharmony_ci 930e5c31af7Sopenharmony_ciprotected: 931e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR m_buildType; 932e5c31af7Sopenharmony_ci VkAccelerationStructureCreateFlagsKHR m_createFlags; 933e5c31af7Sopenharmony_ci bool m_createGeneric; 934e5c31af7Sopenharmony_ci bool m_creationBufferUnbounded; 935e5c31af7Sopenharmony_ci VkBuildAccelerationStructureFlagsKHR m_buildFlags; 936e5c31af7Sopenharmony_ci bool m_buildWithoutGeometries; 937e5c31af7Sopenharmony_ci bool m_buildWithoutPrimitives; 938e5c31af7Sopenharmony_ci bool m_deferredOperation; 939e5c31af7Sopenharmony_ci deUint32 m_workerThreadCount; 940e5c31af7Sopenharmony_ci bool m_useArrayOfPointers; 941e5c31af7Sopenharmony_ci bool m_useMaintenance5; 942e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_accelerationStructureBuffer; 943e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_vertexBuffer; 944e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_indexBuffer; 945e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_deviceScratchBuffer; 946e5c31af7Sopenharmony_ci de::UniquePtr<std::vector<deUint8>> m_hostScratchBuffer; 947e5c31af7Sopenharmony_ci Move<VkAccelerationStructureKHR> m_accelerationStructureKHR; 948e5c31af7Sopenharmony_ci VkBuffer m_indirectBuffer; 949e5c31af7Sopenharmony_ci VkDeviceSize m_indirectBufferOffset; 950e5c31af7Sopenharmony_ci deUint32 m_indirectBufferStride; 951e5c31af7Sopenharmony_ci 952e5c31af7Sopenharmony_ci void prepareGeometries (const DeviceInterface& vk, 953e5c31af7Sopenharmony_ci const VkDevice device, 954e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR>& accelerationStructureGeometriesKHR, 955e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR*>& accelerationStructureGeometriesKHRPointers, 956e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureBuildRangeInfoKHR>& accelerationStructureBuildRangeInfoKHR, 957e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureTrianglesOpacityMicromapEXT>& accelerationStructureGeometryMicromapsEXT, 958e5c31af7Sopenharmony_ci std::vector<deUint32>& maxPrimitiveCounts, 959e5c31af7Sopenharmony_ci VkDeviceSize vertexBufferOffset = 0, 960e5c31af7Sopenharmony_ci VkDeviceSize indexBufferOffset = 0) const; 961e5c31af7Sopenharmony_ci 962e5c31af7Sopenharmony_ci virtual BufferWithMemory* getAccelerationStructureBuffer () const { return m_accelerationStructureBuffer.get(); } 963e5c31af7Sopenharmony_ci virtual BufferWithMemory* getDeviceScratchBuffer () const { return m_deviceScratchBuffer.get(); } 964e5c31af7Sopenharmony_ci virtual std::vector<deUint8>* getHostScratchBuffer () const { return m_hostScratchBuffer.get(); } 965e5c31af7Sopenharmony_ci virtual BufferWithMemory* getVertexBuffer () const { return m_vertexBuffer.get(); } 966e5c31af7Sopenharmony_ci virtual BufferWithMemory* getIndexBuffer () const { return m_indexBuffer.get(); } 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ci virtual VkDeviceSize getAccelerationStructureBufferOffset () const { return 0; } 969e5c31af7Sopenharmony_ci virtual VkDeviceSize getDeviceScratchBufferOffset () const { return 0; } 970e5c31af7Sopenharmony_ci virtual VkDeviceSize getVertexBufferOffset () const { return 0; } 971e5c31af7Sopenharmony_ci virtual VkDeviceSize getIndexBufferOffset () const { return 0; } 972e5c31af7Sopenharmony_ci}; 973e5c31af7Sopenharmony_ci 974e5c31af7Sopenharmony_cideUint32 BottomLevelAccelerationStructureKHR::getRequiredAllocationCount (void) 975e5c31af7Sopenharmony_ci{ 976e5c31af7Sopenharmony_ci /* 977e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_geometryBuffer; // but only when m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR 978e5c31af7Sopenharmony_ci de::MovePtr<Allocation> m_accelerationStructureAlloc; 979e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_deviceScratchBuffer; 980e5c31af7Sopenharmony_ci */ 981e5c31af7Sopenharmony_ci return 3u; 982e5c31af7Sopenharmony_ci} 983e5c31af7Sopenharmony_ci 984e5c31af7Sopenharmony_ciBottomLevelAccelerationStructureKHR::~BottomLevelAccelerationStructureKHR () 985e5c31af7Sopenharmony_ci{ 986e5c31af7Sopenharmony_ci} 987e5c31af7Sopenharmony_ci 988e5c31af7Sopenharmony_ciBottomLevelAccelerationStructureKHR::BottomLevelAccelerationStructureKHR () 989e5c31af7Sopenharmony_ci : BottomLevelAccelerationStructure () 990e5c31af7Sopenharmony_ci , m_buildType (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 991e5c31af7Sopenharmony_ci , m_createFlags (0u) 992e5c31af7Sopenharmony_ci , m_createGeneric (false) 993e5c31af7Sopenharmony_ci , m_creationBufferUnbounded (false) 994e5c31af7Sopenharmony_ci , m_buildFlags (0u) 995e5c31af7Sopenharmony_ci , m_buildWithoutGeometries (false) 996e5c31af7Sopenharmony_ci , m_buildWithoutPrimitives (false) 997e5c31af7Sopenharmony_ci , m_deferredOperation (false) 998e5c31af7Sopenharmony_ci , m_workerThreadCount (0) 999e5c31af7Sopenharmony_ci , m_useArrayOfPointers (false) 1000e5c31af7Sopenharmony_ci , m_accelerationStructureBuffer (DE_NULL) 1001e5c31af7Sopenharmony_ci , m_vertexBuffer (DE_NULL) 1002e5c31af7Sopenharmony_ci , m_indexBuffer (DE_NULL) 1003e5c31af7Sopenharmony_ci , m_deviceScratchBuffer (DE_NULL) 1004e5c31af7Sopenharmony_ci , m_hostScratchBuffer (new std::vector<deUint8>) 1005e5c31af7Sopenharmony_ci , m_accelerationStructureKHR () 1006e5c31af7Sopenharmony_ci , m_indirectBuffer (DE_NULL) 1007e5c31af7Sopenharmony_ci , m_indirectBufferOffset (0) 1008e5c31af7Sopenharmony_ci , m_indirectBufferStride (0) 1009e5c31af7Sopenharmony_ci{ 1010e5c31af7Sopenharmony_ci} 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR buildType) 1013e5c31af7Sopenharmony_ci{ 1014e5c31af7Sopenharmony_ci m_buildType = buildType; 1015e5c31af7Sopenharmony_ci} 1016e5c31af7Sopenharmony_ci 1017e5c31af7Sopenharmony_ciVkAccelerationStructureBuildTypeKHR BottomLevelAccelerationStructureKHR::getBuildType () const 1018e5c31af7Sopenharmony_ci{ 1019e5c31af7Sopenharmony_ci return m_buildType; 1020e5c31af7Sopenharmony_ci} 1021e5c31af7Sopenharmony_ci 1022e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags) 1023e5c31af7Sopenharmony_ci{ 1024e5c31af7Sopenharmony_ci m_createFlags = createFlags; 1025e5c31af7Sopenharmony_ci} 1026e5c31af7Sopenharmony_ci 1027e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setCreateGeneric (bool createGeneric) 1028e5c31af7Sopenharmony_ci{ 1029e5c31af7Sopenharmony_ci m_createGeneric = createGeneric; 1030e5c31af7Sopenharmony_ci} 1031e5c31af7Sopenharmony_ci 1032e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setCreationBufferUnbounded (bool creationBufferUnbounded) 1033e5c31af7Sopenharmony_ci{ 1034e5c31af7Sopenharmony_ci m_creationBufferUnbounded = creationBufferUnbounded; 1035e5c31af7Sopenharmony_ci} 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags) 1038e5c31af7Sopenharmony_ci{ 1039e5c31af7Sopenharmony_ci m_buildFlags = buildFlags; 1040e5c31af7Sopenharmony_ci} 1041e5c31af7Sopenharmony_ci 1042e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setBuildWithoutGeometries (bool buildWithoutGeometries) 1043e5c31af7Sopenharmony_ci{ 1044e5c31af7Sopenharmony_ci m_buildWithoutGeometries = buildWithoutGeometries; 1045e5c31af7Sopenharmony_ci} 1046e5c31af7Sopenharmony_ci 1047e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setBuildWithoutPrimitives (bool buildWithoutPrimitives) 1048e5c31af7Sopenharmony_ci{ 1049e5c31af7Sopenharmony_ci m_buildWithoutPrimitives = buildWithoutPrimitives; 1050e5c31af7Sopenharmony_ci} 1051e5c31af7Sopenharmony_ci 1052e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setDeferredOperation (const bool deferredOperation, 1053e5c31af7Sopenharmony_ci const deUint32 workerThreadCount) 1054e5c31af7Sopenharmony_ci{ 1055e5c31af7Sopenharmony_ci m_deferredOperation = deferredOperation; 1056e5c31af7Sopenharmony_ci m_workerThreadCount = workerThreadCount; 1057e5c31af7Sopenharmony_ci} 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool useArrayOfPointers) 1060e5c31af7Sopenharmony_ci{ 1061e5c31af7Sopenharmony_ci m_useArrayOfPointers = useArrayOfPointers; 1062e5c31af7Sopenharmony_ci} 1063e5c31af7Sopenharmony_ci 1064e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setUseMaintenance5(const bool useMaintenance5) 1065e5c31af7Sopenharmony_ci{ 1066e5c31af7Sopenharmony_ci m_useMaintenance5 = useMaintenance5; 1067e5c31af7Sopenharmony_ci} 1068e5c31af7Sopenharmony_ci 1069e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer indirectBuffer, 1070e5c31af7Sopenharmony_ci const VkDeviceSize indirectBufferOffset, 1071e5c31af7Sopenharmony_ci const deUint32 indirectBufferStride) 1072e5c31af7Sopenharmony_ci{ 1073e5c31af7Sopenharmony_ci m_indirectBuffer = indirectBuffer; 1074e5c31af7Sopenharmony_ci m_indirectBufferOffset = indirectBufferOffset; 1075e5c31af7Sopenharmony_ci m_indirectBufferStride = indirectBufferStride; 1076e5c31af7Sopenharmony_ci} 1077e5c31af7Sopenharmony_ci 1078e5c31af7Sopenharmony_ciVkBuildAccelerationStructureFlagsKHR BottomLevelAccelerationStructureKHR::getBuildFlags () const 1079e5c31af7Sopenharmony_ci{ 1080e5c31af7Sopenharmony_ci return m_buildFlags; 1081e5c31af7Sopenharmony_ci} 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::create (const DeviceInterface& vk, 1084e5c31af7Sopenharmony_ci const VkDevice device, 1085e5c31af7Sopenharmony_ci Allocator& allocator, 1086e5c31af7Sopenharmony_ci VkDeviceSize structureSize, 1087e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress, 1088e5c31af7Sopenharmony_ci const void* pNext, 1089e5c31af7Sopenharmony_ci const MemoryRequirement& addMemoryRequirement, 1090e5c31af7Sopenharmony_ci const VkBuffer creationBuffer, 1091e5c31af7Sopenharmony_ci const VkDeviceSize creationBufferSize) 1092e5c31af7Sopenharmony_ci{ 1093e5c31af7Sopenharmony_ci // AS may be built from geometries using vkCmdBuildAccelerationStructuresKHR / vkBuildAccelerationStructuresKHR 1094e5c31af7Sopenharmony_ci // or may be copied/compacted/deserialized from other AS ( in this case AS does not need geometries, but it needs to know its size before creation ). 1095e5c31af7Sopenharmony_ci DE_ASSERT(!m_geometriesData.empty() != !(structureSize == 0)); // logical xor 1096e5c31af7Sopenharmony_ci 1097e5c31af7Sopenharmony_ci if (structureSize == 0) 1098e5c31af7Sopenharmony_ci { 1099e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR> accelerationStructureGeometriesKHR; 1100e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR*> accelerationStructureGeometriesKHRPointers; 1101e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureBuildRangeInfoKHR> accelerationStructureBuildRangeInfoKHR; 1102e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureTrianglesOpacityMicromapEXT> accelerationStructureGeometryMicromapsEXT; 1103e5c31af7Sopenharmony_ci std::vector<deUint32> maxPrimitiveCounts; 1104e5c31af7Sopenharmony_ci prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, accelerationStructureGeometryMicromapsEXT, maxPrimitiveCounts); 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data(); 1107e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data(); 1108e5c31af7Sopenharmony_ci 1109e5c31af7Sopenharmony_ci const deUint32 geometryCount = (m_buildWithoutGeometries 1110e5c31af7Sopenharmony_ci ? 0u 1111e5c31af7Sopenharmony_ci : static_cast<deUint32>(accelerationStructureGeometriesKHR.size())); 1112e5c31af7Sopenharmony_ci VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = 1113e5c31af7Sopenharmony_ci { 1114e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; 1115e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1116e5c31af7Sopenharmony_ci VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; 1117e5c31af7Sopenharmony_ci m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; 1118e5c31af7Sopenharmony_ci VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode; 1119e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure; 1120e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure; 1121e5c31af7Sopenharmony_ci geometryCount, // deUint32 geometryCount; 1122e5c31af7Sopenharmony_ci m_useArrayOfPointers ? DE_NULL : accelerationStructureGeometriesKHRPointer, // const VkAccelerationStructureGeometryKHR* pGeometries; 1123e5c31af7Sopenharmony_ci m_useArrayOfPointers ? accelerationStructureGeometry : DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries; 1124e5c31af7Sopenharmony_ci makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData; 1125e5c31af7Sopenharmony_ci }; 1126e5c31af7Sopenharmony_ci VkAccelerationStructureBuildSizesInfoKHR sizeInfo = 1127e5c31af7Sopenharmony_ci { 1128e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; 1129e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1130e5c31af7Sopenharmony_ci 0, // VkDeviceSize accelerationStructureSize; 1131e5c31af7Sopenharmony_ci 0, // VkDeviceSize updateScratchSize; 1132e5c31af7Sopenharmony_ci 0 // VkDeviceSize buildScratchSize; 1133e5c31af7Sopenharmony_ci }; 1134e5c31af7Sopenharmony_ci 1135e5c31af7Sopenharmony_ci vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo); 1136e5c31af7Sopenharmony_ci 1137e5c31af7Sopenharmony_ci m_structureSize = sizeInfo.accelerationStructureSize; 1138e5c31af7Sopenharmony_ci m_updateScratchSize = sizeInfo.updateScratchSize; 1139e5c31af7Sopenharmony_ci m_buildScratchSize = sizeInfo.buildScratchSize; 1140e5c31af7Sopenharmony_ci } 1141e5c31af7Sopenharmony_ci else 1142e5c31af7Sopenharmony_ci { 1143e5c31af7Sopenharmony_ci m_structureSize = structureSize; 1144e5c31af7Sopenharmony_ci m_updateScratchSize = 0u; 1145e5c31af7Sopenharmony_ci m_buildScratchSize = 0u; 1146e5c31af7Sopenharmony_ci } 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci const bool externalCreationBuffer = (creationBuffer != VK_NULL_HANDLE); 1149e5c31af7Sopenharmony_ci 1150e5c31af7Sopenharmony_ci if (externalCreationBuffer) 1151e5c31af7Sopenharmony_ci { 1152e5c31af7Sopenharmony_ci DE_UNREF(creationBufferSize); // For release builds. 1153e5c31af7Sopenharmony_ci DE_ASSERT(creationBufferSize >= m_structureSize); 1154e5c31af7Sopenharmony_ci } 1155e5c31af7Sopenharmony_ci 1156e5c31af7Sopenharmony_ci if (!externalCreationBuffer) 1157e5c31af7Sopenharmony_ci { 1158e5c31af7Sopenharmony_ci VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_structureSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 1159e5c31af7Sopenharmony_ci VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = vk::initVulkanStructure(); 1160e5c31af7Sopenharmony_ci 1161e5c31af7Sopenharmony_ci if (m_useMaintenance5) 1162e5c31af7Sopenharmony_ci { 1163e5c31af7Sopenharmony_ci bufferUsageFlags2.usage = VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR; 1164e5c31af7Sopenharmony_ci bufferCreateInfo.pNext = &bufferUsageFlags2; 1165e5c31af7Sopenharmony_ci bufferCreateInfo.usage = 0; 1166e5c31af7Sopenharmony_ci } 1167e5c31af7Sopenharmony_ci 1168e5c31af7Sopenharmony_ci const MemoryRequirement memoryRequirement = addMemoryRequirement | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress; 1169e5c31af7Sopenharmony_ci const bool bindMemOnCreation = (!m_creationBufferUnbounded); 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ci try 1172e5c31af7Sopenharmony_ci { 1173e5c31af7Sopenharmony_ci m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, (MemoryRequirement::Cached | memoryRequirement), bindMemOnCreation)); 1174e5c31af7Sopenharmony_ci } 1175e5c31af7Sopenharmony_ci catch (const tcu::NotSupportedError&) 1176e5c31af7Sopenharmony_ci { 1177e5c31af7Sopenharmony_ci // retry without Cached flag 1178e5c31af7Sopenharmony_ci m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, memoryRequirement, bindMemOnCreation)); 1179e5c31af7Sopenharmony_ci } 1180e5c31af7Sopenharmony_ci } 1181e5c31af7Sopenharmony_ci 1182e5c31af7Sopenharmony_ci const auto createInfoBuffer = (externalCreationBuffer ? creationBuffer : getAccelerationStructureBuffer()->get()); 1183e5c31af7Sopenharmony_ci const auto createInfoOffset = (externalCreationBuffer ? static_cast<VkDeviceSize>(0) : getAccelerationStructureBufferOffset()); 1184e5c31af7Sopenharmony_ci { 1185e5c31af7Sopenharmony_ci const VkAccelerationStructureTypeKHR structureType = (m_createGeneric 1186e5c31af7Sopenharmony_ci ? VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 1187e5c31af7Sopenharmony_ci : VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR); 1188e5c31af7Sopenharmony_ci const VkAccelerationStructureCreateInfoKHR accelerationStructureCreateInfoKHR 1189e5c31af7Sopenharmony_ci { 1190e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType; 1191e5c31af7Sopenharmony_ci pNext, // const void* pNext; 1192e5c31af7Sopenharmony_ci m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags; 1193e5c31af7Sopenharmony_ci createInfoBuffer, // VkBuffer buffer; 1194e5c31af7Sopenharmony_ci createInfoOffset, // VkDeviceSize offset; 1195e5c31af7Sopenharmony_ci m_structureSize, // VkDeviceSize size; 1196e5c31af7Sopenharmony_ci structureType, // VkAccelerationStructureTypeKHR type; 1197e5c31af7Sopenharmony_ci deviceAddress // VkDeviceAddress deviceAddress; 1198e5c31af7Sopenharmony_ci }; 1199e5c31af7Sopenharmony_ci 1200e5c31af7Sopenharmony_ci m_accelerationStructureKHR = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL); 1201e5c31af7Sopenharmony_ci 1202e5c31af7Sopenharmony_ci // Make sure buffer memory is always bound after creation. 1203e5c31af7Sopenharmony_ci if (!externalCreationBuffer) 1204e5c31af7Sopenharmony_ci m_accelerationStructureBuffer->bindMemory(); 1205e5c31af7Sopenharmony_ci } 1206e5c31af7Sopenharmony_ci 1207e5c31af7Sopenharmony_ci if (m_buildScratchSize > 0u) 1208e5c31af7Sopenharmony_ci { 1209e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1210e5c31af7Sopenharmony_ci { 1211e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_buildScratchSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 1212e5c31af7Sopenharmony_ci m_deviceScratchBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 1213e5c31af7Sopenharmony_ci } 1214e5c31af7Sopenharmony_ci else 1215e5c31af7Sopenharmony_ci { 1216e5c31af7Sopenharmony_ci m_hostScratchBuffer->resize(static_cast<size_t>(m_buildScratchSize)); 1217e5c31af7Sopenharmony_ci } 1218e5c31af7Sopenharmony_ci } 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR && !m_geometriesData.empty()) 1221e5c31af7Sopenharmony_ci { 1222e5c31af7Sopenharmony_ci VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(getVertexBufferSize(m_geometriesData), VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 1223e5c31af7Sopenharmony_ci VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = vk::initVulkanStructure(); 1224e5c31af7Sopenharmony_ci 1225e5c31af7Sopenharmony_ci if (m_useMaintenance5) 1226e5c31af7Sopenharmony_ci { 1227e5c31af7Sopenharmony_ci bufferUsageFlags2.usage = vk::VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR; 1228e5c31af7Sopenharmony_ci bufferCreateInfo.pNext = &bufferUsageFlags2; 1229e5c31af7Sopenharmony_ci bufferCreateInfo.usage = 0; 1230e5c31af7Sopenharmony_ci } 1231e5c31af7Sopenharmony_ci 1232e5c31af7Sopenharmony_ci const vk::MemoryRequirement memoryRequirement = MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress; 1233e5c31af7Sopenharmony_ci m_vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, memoryRequirement)); 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci bufferCreateInfo.size = getIndexBufferSize(m_geometriesData); 1236e5c31af7Sopenharmony_ci if (bufferCreateInfo.size) 1237e5c31af7Sopenharmony_ci m_indexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, memoryRequirement)); 1238e5c31af7Sopenharmony_ci else 1239e5c31af7Sopenharmony_ci m_indexBuffer = de::MovePtr<BufferWithMemory>(nullptr); 1240e5c31af7Sopenharmony_ci } 1241e5c31af7Sopenharmony_ci} 1242e5c31af7Sopenharmony_ci 1243e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::build (const DeviceInterface& vk, 1244e5c31af7Sopenharmony_ci const VkDevice device, 1245e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1246e5c31af7Sopenharmony_ci BottomLevelAccelerationStructure* srcAccelerationStructure) 1247e5c31af7Sopenharmony_ci{ 1248e5c31af7Sopenharmony_ci DE_ASSERT(!m_geometriesData.empty()); 1249e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 1250e5c31af7Sopenharmony_ci DE_ASSERT(m_buildScratchSize != 0); 1251e5c31af7Sopenharmony_ci 1252e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1253e5c31af7Sopenharmony_ci { 1254e5c31af7Sopenharmony_ci updateVertexBuffer(vk, device, m_geometriesData, getVertexBuffer(), getVertexBufferOffset()); 1255e5c31af7Sopenharmony_ci if(getIndexBuffer() != DE_NULL) 1256e5c31af7Sopenharmony_ci updateIndexBuffer(vk, device, m_geometriesData, getIndexBuffer(), getIndexBufferOffset()); 1257e5c31af7Sopenharmony_ci } 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci { 1260e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR> accelerationStructureGeometriesKHR; 1261e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR*> accelerationStructureGeometriesKHRPointers; 1262e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureBuildRangeInfoKHR> accelerationStructureBuildRangeInfoKHR; 1263e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureTrianglesOpacityMicromapEXT> accelerationStructureGeometryMicromapsEXT; 1264e5c31af7Sopenharmony_ci std::vector<deUint32> maxPrimitiveCounts; 1265e5c31af7Sopenharmony_ci 1266e5c31af7Sopenharmony_ci prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, 1267e5c31af7Sopenharmony_ci accelerationStructureBuildRangeInfoKHR, accelerationStructureGeometryMicromapsEXT, maxPrimitiveCounts, getVertexBufferOffset(), getIndexBufferOffset()); 1268e5c31af7Sopenharmony_ci 1269e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data(); 1270e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data(); 1271e5c31af7Sopenharmony_ci VkDeviceOrHostAddressKHR scratchData = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1272e5c31af7Sopenharmony_ci ? makeDeviceOrHostAddressKHR(vk, device, getDeviceScratchBuffer()->get(), getDeviceScratchBufferOffset()) 1273e5c31af7Sopenharmony_ci : makeDeviceOrHostAddressKHR(getHostScratchBuffer()->data()); 1274e5c31af7Sopenharmony_ci const deUint32 geometryCount = (m_buildWithoutGeometries 1275e5c31af7Sopenharmony_ci ? 0u 1276e5c31af7Sopenharmony_ci : static_cast<deUint32>(accelerationStructureGeometriesKHR.size())); 1277e5c31af7Sopenharmony_ci 1278e5c31af7Sopenharmony_ci VkAccelerationStructureKHR srcStructure = (srcAccelerationStructure != DE_NULL) ? *(srcAccelerationStructure->getPtr()) : DE_NULL; 1279e5c31af7Sopenharmony_ci VkBuildAccelerationStructureModeKHR mode = (srcAccelerationStructure != DE_NULL) ? VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR : VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; 1280e5c31af7Sopenharmony_ci 1281e5c31af7Sopenharmony_ci VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = 1282e5c31af7Sopenharmony_ci { 1283e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; 1284e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1285e5c31af7Sopenharmony_ci VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; 1286e5c31af7Sopenharmony_ci m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; 1287e5c31af7Sopenharmony_ci mode, // VkBuildAccelerationStructureModeKHR mode; 1288e5c31af7Sopenharmony_ci srcStructure, // VkAccelerationStructureKHR srcAccelerationStructure; 1289e5c31af7Sopenharmony_ci m_accelerationStructureKHR.get(), // VkAccelerationStructureKHR dstAccelerationStructure; 1290e5c31af7Sopenharmony_ci geometryCount, // deUint32 geometryCount; 1291e5c31af7Sopenharmony_ci m_useArrayOfPointers ? DE_NULL : accelerationStructureGeometriesKHRPointer, // const VkAccelerationStructureGeometryKHR* pGeometries; 1292e5c31af7Sopenharmony_ci m_useArrayOfPointers ? accelerationStructureGeometry : DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries; 1293e5c31af7Sopenharmony_ci scratchData // VkDeviceOrHostAddressKHR scratchData; 1294e5c31af7Sopenharmony_ci }; 1295e5c31af7Sopenharmony_ci 1296e5c31af7Sopenharmony_ci VkAccelerationStructureBuildRangeInfoKHR* accelerationStructureBuildRangeInfoKHRPtr = accelerationStructureBuildRangeInfoKHR.data(); 1297e5c31af7Sopenharmony_ci 1298e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1299e5c31af7Sopenharmony_ci { 1300e5c31af7Sopenharmony_ci if (m_indirectBuffer == DE_NULL) 1301e5c31af7Sopenharmony_ci vk.cmdBuildAccelerationStructuresKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr); 1302e5c31af7Sopenharmony_ci else 1303e5c31af7Sopenharmony_ci { 1304e5c31af7Sopenharmony_ci VkDeviceAddress indirectDeviceAddress = getBufferDeviceAddress(vk, device, m_indirectBuffer, m_indirectBufferOffset); 1305e5c31af7Sopenharmony_ci deUint32* pMaxPrimitiveCounts = maxPrimitiveCounts.data(); 1306e5c31af7Sopenharmony_ci vk.cmdBuildAccelerationStructuresIndirectKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, &indirectDeviceAddress, &m_indirectBufferStride, &pMaxPrimitiveCounts); 1307e5c31af7Sopenharmony_ci } 1308e5c31af7Sopenharmony_ci } 1309e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 1310e5c31af7Sopenharmony_ci { 1311e5c31af7Sopenharmony_ci VK_CHECK(vk.buildAccelerationStructuresKHR(device, DE_NULL, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr)); 1312e5c31af7Sopenharmony_ci } 1313e5c31af7Sopenharmony_ci else 1314e5c31af7Sopenharmony_ci { 1315e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 1316e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 1317e5c31af7Sopenharmony_ci 1318e5c31af7Sopenharmony_ci VkResult result = vk.buildAccelerationStructuresKHR(device, deferredOperation, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr); 1319e5c31af7Sopenharmony_ci 1320e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 1321e5c31af7Sopenharmony_ci 1322e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 1323e5c31af7Sopenharmony_ci } 1324e5c31af7Sopenharmony_ci } 1325e5c31af7Sopenharmony_ci 1326e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1327e5c31af7Sopenharmony_ci { 1328e5c31af7Sopenharmony_ci const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; 1329e5c31af7Sopenharmony_ci const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks); 1330e5c31af7Sopenharmony_ci 1331e5c31af7Sopenharmony_ci cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier); 1332e5c31af7Sopenharmony_ci } 1333e5c31af7Sopenharmony_ci} 1334e5c31af7Sopenharmony_ci 1335e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::copyFrom (const DeviceInterface& vk, 1336e5c31af7Sopenharmony_ci const VkDevice device, 1337e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1338e5c31af7Sopenharmony_ci BottomLevelAccelerationStructure* accelerationStructure, 1339e5c31af7Sopenharmony_ci bool compactCopy) 1340e5c31af7Sopenharmony_ci{ 1341e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 1342e5c31af7Sopenharmony_ci DE_ASSERT(accelerationStructure != DE_NULL); 1343e5c31af7Sopenharmony_ci 1344e5c31af7Sopenharmony_ci VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo = 1345e5c31af7Sopenharmony_ci { 1346e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType; 1347e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1348e5c31af7Sopenharmony_ci *(accelerationStructure->getPtr()), // VkAccelerationStructureKHR src; 1349e5c31af7Sopenharmony_ci *(getPtr()), // VkAccelerationStructureKHR dst; 1350e5c31af7Sopenharmony_ci compactCopy ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR // VkCopyAccelerationStructureModeKHR mode; 1351e5c31af7Sopenharmony_ci }; 1352e5c31af7Sopenharmony_ci 1353e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1354e5c31af7Sopenharmony_ci { 1355e5c31af7Sopenharmony_ci vk.cmdCopyAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo); 1356e5c31af7Sopenharmony_ci } 1357e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 1358e5c31af7Sopenharmony_ci { 1359e5c31af7Sopenharmony_ci VK_CHECK(vk.copyAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo)); 1360e5c31af7Sopenharmony_ci } 1361e5c31af7Sopenharmony_ci else 1362e5c31af7Sopenharmony_ci { 1363e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 1364e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 1365e5c31af7Sopenharmony_ci 1366e5c31af7Sopenharmony_ci VkResult result = vk.copyAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo); 1367e5c31af7Sopenharmony_ci 1368e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 1369e5c31af7Sopenharmony_ci 1370e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 1371e5c31af7Sopenharmony_ci } 1372e5c31af7Sopenharmony_ci 1373e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1374e5c31af7Sopenharmony_ci { 1375e5c31af7Sopenharmony_ci const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; 1376e5c31af7Sopenharmony_ci const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks); 1377e5c31af7Sopenharmony_ci 1378e5c31af7Sopenharmony_ci cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier); 1379e5c31af7Sopenharmony_ci } 1380e5c31af7Sopenharmony_ci} 1381e5c31af7Sopenharmony_ci 1382e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::serialize (const DeviceInterface& vk, 1383e5c31af7Sopenharmony_ci const VkDevice device, 1384e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1385e5c31af7Sopenharmony_ci SerialStorage* storage) 1386e5c31af7Sopenharmony_ci{ 1387e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 1388e5c31af7Sopenharmony_ci DE_ASSERT(storage != DE_NULL); 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_ci const VkCopyAccelerationStructureToMemoryInfoKHR copyAccelerationStructureInfo = 1391e5c31af7Sopenharmony_ci { 1392e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR, // VkStructureType sType; 1393e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1394e5c31af7Sopenharmony_ci *(getPtr()), // VkAccelerationStructureKHR src; 1395e5c31af7Sopenharmony_ci storage->getAddress(vk, device, m_buildType), // VkDeviceOrHostAddressKHR dst; 1396e5c31af7Sopenharmony_ci VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode; 1397e5c31af7Sopenharmony_ci }; 1398e5c31af7Sopenharmony_ci 1399e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1400e5c31af7Sopenharmony_ci { 1401e5c31af7Sopenharmony_ci vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, ©AccelerationStructureInfo); 1402e5c31af7Sopenharmony_ci } 1403e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 1404e5c31af7Sopenharmony_ci { 1405e5c31af7Sopenharmony_ci VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, ©AccelerationStructureInfo)); 1406e5c31af7Sopenharmony_ci } 1407e5c31af7Sopenharmony_ci else 1408e5c31af7Sopenharmony_ci { 1409e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 1410e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 1411e5c31af7Sopenharmony_ci 1412e5c31af7Sopenharmony_ci const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, ©AccelerationStructureInfo); 1413e5c31af7Sopenharmony_ci 1414e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 1415e5c31af7Sopenharmony_ci 1416e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 1417e5c31af7Sopenharmony_ci } 1418e5c31af7Sopenharmony_ci} 1419e5c31af7Sopenharmony_ci 1420e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::deserialize (const DeviceInterface& vk, 1421e5c31af7Sopenharmony_ci const VkDevice device, 1422e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1423e5c31af7Sopenharmony_ci SerialStorage* storage) 1424e5c31af7Sopenharmony_ci{ 1425e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 1426e5c31af7Sopenharmony_ci DE_ASSERT(storage != DE_NULL); 1427e5c31af7Sopenharmony_ci 1428e5c31af7Sopenharmony_ci const VkCopyMemoryToAccelerationStructureInfoKHR copyAccelerationStructureInfo = 1429e5c31af7Sopenharmony_ci { 1430e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType; 1431e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1432e5c31af7Sopenharmony_ci storage->getAddressConst(vk, device, m_buildType), // VkDeviceOrHostAddressConstKHR src; 1433e5c31af7Sopenharmony_ci *(getPtr()), // VkAccelerationStructureKHR dst; 1434e5c31af7Sopenharmony_ci VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode; 1435e5c31af7Sopenharmony_ci }; 1436e5c31af7Sopenharmony_ci 1437e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1438e5c31af7Sopenharmony_ci { 1439e5c31af7Sopenharmony_ci vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo); 1440e5c31af7Sopenharmony_ci } 1441e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 1442e5c31af7Sopenharmony_ci { 1443e5c31af7Sopenharmony_ci VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo)); 1444e5c31af7Sopenharmony_ci } 1445e5c31af7Sopenharmony_ci else 1446e5c31af7Sopenharmony_ci { 1447e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 1448e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 1449e5c31af7Sopenharmony_ci 1450e5c31af7Sopenharmony_ci const VkResult result = vk.copyMemoryToAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo); 1451e5c31af7Sopenharmony_ci 1452e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 1453e5c31af7Sopenharmony_ci 1454e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 1455e5c31af7Sopenharmony_ci } 1456e5c31af7Sopenharmony_ci 1457e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1458e5c31af7Sopenharmony_ci { 1459e5c31af7Sopenharmony_ci const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; 1460e5c31af7Sopenharmony_ci const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks); 1461e5c31af7Sopenharmony_ci 1462e5c31af7Sopenharmony_ci cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier); 1463e5c31af7Sopenharmony_ci } 1464e5c31af7Sopenharmony_ci} 1465e5c31af7Sopenharmony_ci 1466e5c31af7Sopenharmony_ciconst VkAccelerationStructureKHR* BottomLevelAccelerationStructureKHR::getPtr (void) const 1467e5c31af7Sopenharmony_ci{ 1468e5c31af7Sopenharmony_ci return &m_accelerationStructureKHR.get(); 1469e5c31af7Sopenharmony_ci} 1470e5c31af7Sopenharmony_ci 1471e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::prepareGeometries (const DeviceInterface& vk, 1472e5c31af7Sopenharmony_ci const VkDevice device, 1473e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR>& accelerationStructureGeometriesKHR, 1474e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR*>& accelerationStructureGeometriesKHRPointers, 1475e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureBuildRangeInfoKHR>& accelerationStructureBuildRangeInfoKHR, 1476e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureTrianglesOpacityMicromapEXT>& accelerationStructureGeometryMicromapsEXT, 1477e5c31af7Sopenharmony_ci std::vector<deUint32>& maxPrimitiveCounts, 1478e5c31af7Sopenharmony_ci VkDeviceSize vertexBufferOffset, 1479e5c31af7Sopenharmony_ci VkDeviceSize indexBufferOffset) const 1480e5c31af7Sopenharmony_ci{ 1481e5c31af7Sopenharmony_ci accelerationStructureGeometriesKHR.resize(m_geometriesData.size()); 1482e5c31af7Sopenharmony_ci accelerationStructureGeometriesKHRPointers.resize(m_geometriesData.size()); 1483e5c31af7Sopenharmony_ci accelerationStructureBuildRangeInfoKHR.resize(m_geometriesData.size()); 1484e5c31af7Sopenharmony_ci accelerationStructureGeometryMicromapsEXT.resize(m_geometriesData.size()); 1485e5c31af7Sopenharmony_ci maxPrimitiveCounts.resize(m_geometriesData.size()); 1486e5c31af7Sopenharmony_ci 1487e5c31af7Sopenharmony_ci for (size_t geometryNdx = 0; geometryNdx < m_geometriesData.size(); ++geometryNdx) 1488e5c31af7Sopenharmony_ci { 1489e5c31af7Sopenharmony_ci const de::SharedPtr<RaytracedGeometryBase>& geometryData = m_geometriesData[geometryNdx]; 1490e5c31af7Sopenharmony_ci VkDeviceOrHostAddressConstKHR vertexData, indexData; 1491e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 1492e5c31af7Sopenharmony_ci { 1493e5c31af7Sopenharmony_ci if (getVertexBuffer() != DE_NULL) 1494e5c31af7Sopenharmony_ci { 1495e5c31af7Sopenharmony_ci vertexData = makeDeviceOrHostAddressConstKHR(vk, device, getVertexBuffer()->get(), vertexBufferOffset); 1496e5c31af7Sopenharmony_ci if (m_indirectBuffer == DE_NULL ) 1497e5c31af7Sopenharmony_ci { 1498e5c31af7Sopenharmony_ci vertexBufferOffset += deAlignSize(geometryData->getVertexByteSize(), 8); 1499e5c31af7Sopenharmony_ci } 1500e5c31af7Sopenharmony_ci } 1501e5c31af7Sopenharmony_ci else 1502e5c31af7Sopenharmony_ci vertexData = makeDeviceOrHostAddressConstKHR(DE_NULL); 1503e5c31af7Sopenharmony_ci 1504e5c31af7Sopenharmony_ci if (getIndexBuffer() != DE_NULL && geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR) 1505e5c31af7Sopenharmony_ci { 1506e5c31af7Sopenharmony_ci indexData = makeDeviceOrHostAddressConstKHR(vk, device, getIndexBuffer()->get(), indexBufferOffset); 1507e5c31af7Sopenharmony_ci indexBufferOffset += deAlignSize(geometryData->getIndexByteSize(), 8); 1508e5c31af7Sopenharmony_ci } 1509e5c31af7Sopenharmony_ci else 1510e5c31af7Sopenharmony_ci indexData = makeDeviceOrHostAddressConstKHR(DE_NULL); 1511e5c31af7Sopenharmony_ci } 1512e5c31af7Sopenharmony_ci else 1513e5c31af7Sopenharmony_ci { 1514e5c31af7Sopenharmony_ci vertexData = makeDeviceOrHostAddressConstKHR(geometryData->getVertexPointer()); 1515e5c31af7Sopenharmony_ci if (geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR) 1516e5c31af7Sopenharmony_ci indexData = makeDeviceOrHostAddressConstKHR(geometryData->getIndexPointer()); 1517e5c31af7Sopenharmony_ci else 1518e5c31af7Sopenharmony_ci indexData = makeDeviceOrHostAddressConstKHR(DE_NULL); 1519e5c31af7Sopenharmony_ci } 1520e5c31af7Sopenharmony_ci 1521e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryTrianglesDataKHR accelerationStructureGeometryTrianglesDataKHR = 1522e5c31af7Sopenharmony_ci { 1523e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR, // VkStructureType sType; 1524e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1525e5c31af7Sopenharmony_ci geometryData->getVertexFormat(), // VkFormat vertexFormat; 1526e5c31af7Sopenharmony_ci vertexData, // VkDeviceOrHostAddressConstKHR vertexData; 1527e5c31af7Sopenharmony_ci geometryData->getVertexStride(), // VkDeviceSize vertexStride; 1528e5c31af7Sopenharmony_ci static_cast<deUint32>(geometryData->getVertexCount()), // uint32_t maxVertex; 1529e5c31af7Sopenharmony_ci geometryData->getIndexType(), // VkIndexType indexType; 1530e5c31af7Sopenharmony_ci indexData, // VkDeviceOrHostAddressConstKHR indexData; 1531e5c31af7Sopenharmony_ci makeDeviceOrHostAddressConstKHR(DE_NULL), // VkDeviceOrHostAddressConstKHR transformData; 1532e5c31af7Sopenharmony_ci }; 1533e5c31af7Sopenharmony_ci 1534e5c31af7Sopenharmony_ci if (geometryData->getHasOpacityMicromap()) 1535e5c31af7Sopenharmony_ci accelerationStructureGeometryTrianglesDataKHR.pNext = &geometryData->getOpacityMicromap(); 1536e5c31af7Sopenharmony_ci 1537e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryAabbsDataKHR accelerationStructureGeometryAabbsDataKHR = 1538e5c31af7Sopenharmony_ci { 1539e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR, // VkStructureType sType; 1540e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1541e5c31af7Sopenharmony_ci vertexData, // VkDeviceOrHostAddressConstKHR data; 1542e5c31af7Sopenharmony_ci geometryData->getAABBStride() // VkDeviceSize stride; 1543e5c31af7Sopenharmony_ci }; 1544e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryDataKHR geometry = (geometryData->isTrianglesType()) 1545e5c31af7Sopenharmony_ci ? makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryTrianglesDataKHR) 1546e5c31af7Sopenharmony_ci : makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryAabbsDataKHR); 1547e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR = 1548e5c31af7Sopenharmony_ci { 1549e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // VkStructureType sType; 1550e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1551e5c31af7Sopenharmony_ci geometryData->getGeometryType(), // VkGeometryTypeKHR geometryType; 1552e5c31af7Sopenharmony_ci geometry, // VkAccelerationStructureGeometryDataKHR geometry; 1553e5c31af7Sopenharmony_ci geometryData->getGeometryFlags() // VkGeometryFlagsKHR flags; 1554e5c31af7Sopenharmony_ci }; 1555e5c31af7Sopenharmony_ci 1556e5c31af7Sopenharmony_ci const deUint32 primitiveCount = (m_buildWithoutPrimitives ? 0u : geometryData->getPrimitiveCount()); 1557e5c31af7Sopenharmony_ci 1558e5c31af7Sopenharmony_ci const VkAccelerationStructureBuildRangeInfoKHR accelerationStructureBuildRangeInfosKHR = 1559e5c31af7Sopenharmony_ci { 1560e5c31af7Sopenharmony_ci primitiveCount, // deUint32 primitiveCount; 1561e5c31af7Sopenharmony_ci 0, // deUint32 primitiveOffset; 1562e5c31af7Sopenharmony_ci 0, // deUint32 firstVertex; 1563e5c31af7Sopenharmony_ci 0 // deUint32 firstTransform; 1564e5c31af7Sopenharmony_ci }; 1565e5c31af7Sopenharmony_ci 1566e5c31af7Sopenharmony_ci accelerationStructureGeometriesKHR[geometryNdx] = accelerationStructureGeometryKHR; 1567e5c31af7Sopenharmony_ci accelerationStructureGeometriesKHRPointers[geometryNdx] = &accelerationStructureGeometriesKHR[geometryNdx]; 1568e5c31af7Sopenharmony_ci accelerationStructureBuildRangeInfoKHR[geometryNdx] = accelerationStructureBuildRangeInfosKHR; 1569e5c31af7Sopenharmony_ci maxPrimitiveCounts[geometryNdx] = geometryData->getPrimitiveCount(); 1570e5c31af7Sopenharmony_ci } 1571e5c31af7Sopenharmony_ci} 1572e5c31af7Sopenharmony_ci 1573e5c31af7Sopenharmony_cideUint32 BottomLevelAccelerationStructure::getRequiredAllocationCount (void) 1574e5c31af7Sopenharmony_ci{ 1575e5c31af7Sopenharmony_ci return BottomLevelAccelerationStructureKHR::getRequiredAllocationCount(); 1576e5c31af7Sopenharmony_ci} 1577e5c31af7Sopenharmony_ci 1578e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::createAndBuild (const DeviceInterface& vk, 1579e5c31af7Sopenharmony_ci const VkDevice device, 1580e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1581e5c31af7Sopenharmony_ci Allocator& allocator, 1582e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) 1583e5c31af7Sopenharmony_ci{ 1584e5c31af7Sopenharmony_ci create(vk, device, allocator, 0u, deviceAddress); 1585e5c31af7Sopenharmony_ci build(vk, device, cmdBuffer); 1586e5c31af7Sopenharmony_ci} 1587e5c31af7Sopenharmony_ci 1588e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface& vk, 1589e5c31af7Sopenharmony_ci const VkDevice device, 1590e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1591e5c31af7Sopenharmony_ci Allocator& allocator, 1592e5c31af7Sopenharmony_ci BottomLevelAccelerationStructure* accelerationStructure, 1593e5c31af7Sopenharmony_ci VkDeviceSize compactCopySize, 1594e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) 1595e5c31af7Sopenharmony_ci{ 1596e5c31af7Sopenharmony_ci DE_ASSERT(accelerationStructure != NULL); 1597e5c31af7Sopenharmony_ci VkDeviceSize copiedSize = compactCopySize > 0u ? compactCopySize : accelerationStructure->getStructureBuildSizes().accelerationStructureSize; 1598e5c31af7Sopenharmony_ci DE_ASSERT(copiedSize != 0u); 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci create(vk, device, allocator, copiedSize, deviceAddress); 1601e5c31af7Sopenharmony_ci copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u); 1602e5c31af7Sopenharmony_ci} 1603e5c31af7Sopenharmony_ci 1604e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk, 1605e5c31af7Sopenharmony_ci const VkDevice device, 1606e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 1607e5c31af7Sopenharmony_ci Allocator& allocator, 1608e5c31af7Sopenharmony_ci SerialStorage* storage, 1609e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress ) 1610e5c31af7Sopenharmony_ci{ 1611e5c31af7Sopenharmony_ci DE_ASSERT(storage != NULL); 1612e5c31af7Sopenharmony_ci DE_ASSERT(storage->getStorageSize() >= SerialStorage::SERIAL_STORAGE_SIZE_MIN); 1613e5c31af7Sopenharmony_ci create(vk, device, allocator, storage->getDeserializedSize(), deviceAddress); 1614e5c31af7Sopenharmony_ci deserialize(vk, device, cmdBuffer, storage); 1615e5c31af7Sopenharmony_ci} 1616e5c31af7Sopenharmony_ci 1617e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructureKHR::updateGeometry (size_t geometryIndex, 1618e5c31af7Sopenharmony_ci de::SharedPtr<RaytracedGeometryBase>& raytracedGeometry) 1619e5c31af7Sopenharmony_ci{ 1620e5c31af7Sopenharmony_ci DE_ASSERT(geometryIndex < m_geometriesData.size()); 1621e5c31af7Sopenharmony_ci m_geometriesData[geometryIndex] = raytracedGeometry; 1622e5c31af7Sopenharmony_ci} 1623e5c31af7Sopenharmony_ci 1624e5c31af7Sopenharmony_cide::MovePtr<BottomLevelAccelerationStructure> makeBottomLevelAccelerationStructure () 1625e5c31af7Sopenharmony_ci{ 1626e5c31af7Sopenharmony_ci return de::MovePtr<BottomLevelAccelerationStructure>(new BottomLevelAccelerationStructureKHR); 1627e5c31af7Sopenharmony_ci} 1628e5c31af7Sopenharmony_ci 1629e5c31af7Sopenharmony_ci// Forward declaration 1630e5c31af7Sopenharmony_cistruct BottomLevelAccelerationStructurePoolImpl; 1631e5c31af7Sopenharmony_ci 1632e5c31af7Sopenharmony_ciclass BottomLevelAccelerationStructurePoolMember : public BottomLevelAccelerationStructureKHR 1633e5c31af7Sopenharmony_ci{ 1634e5c31af7Sopenharmony_cipublic: 1635e5c31af7Sopenharmony_ci friend class BottomLevelAccelerationStructurePool; 1636e5c31af7Sopenharmony_ci 1637e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolMember (BottomLevelAccelerationStructurePoolImpl& pool); 1638e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolMember (const BottomLevelAccelerationStructurePoolMember&) = delete; 1639e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolMember (BottomLevelAccelerationStructurePoolMember&&) = delete; 1640e5c31af7Sopenharmony_ci virtual ~BottomLevelAccelerationStructurePoolMember () = default; 1641e5c31af7Sopenharmony_ci 1642e5c31af7Sopenharmony_ci virtual void create (const DeviceInterface&, 1643e5c31af7Sopenharmony_ci const VkDevice, 1644e5c31af7Sopenharmony_ci Allocator&, 1645e5c31af7Sopenharmony_ci VkDeviceSize, 1646e5c31af7Sopenharmony_ci VkDeviceAddress, 1647e5c31af7Sopenharmony_ci const void*, 1648e5c31af7Sopenharmony_ci const MemoryRequirement&, 1649e5c31af7Sopenharmony_ci const VkBuffer, 1650e5c31af7Sopenharmony_ci const VkDeviceSize) override 1651e5c31af7Sopenharmony_ci { 1652e5c31af7Sopenharmony_ci DE_ASSERT(0); // Silent this method 1653e5c31af7Sopenharmony_ci } 1654e5c31af7Sopenharmony_ci virtual auto computeBuildSize (const DeviceInterface& vk, 1655e5c31af7Sopenharmony_ci const VkDevice device, 1656e5c31af7Sopenharmony_ci const VkDeviceSize strSize) const 1657e5c31af7Sopenharmony_ci // accStrSize,updateScratch, buildScratch, vertexSize, indexSize 1658e5c31af7Sopenharmony_ci -> std::tuple<VkDeviceSize, VkDeviceSize, VkDeviceSize, VkDeviceSize, VkDeviceSize>; 1659e5c31af7Sopenharmony_ciprotected: 1660e5c31af7Sopenharmony_ci struct Info; 1661e5c31af7Sopenharmony_ci virtual void preCreateSetSizesAndOffsets (const Info& info, 1662e5c31af7Sopenharmony_ci const VkDeviceSize accStrSize, 1663e5c31af7Sopenharmony_ci const VkDeviceSize updateScratchSize, 1664e5c31af7Sopenharmony_ci const VkDeviceSize buildScratchSize); 1665e5c31af7Sopenharmony_ci virtual void createAccellerationStructure (const DeviceInterface& vk, 1666e5c31af7Sopenharmony_ci const VkDevice device, 1667e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress); 1668e5c31af7Sopenharmony_ci 1669e5c31af7Sopenharmony_ci virtual BufferWithMemory* getAccelerationStructureBuffer () const override; 1670e5c31af7Sopenharmony_ci virtual BufferWithMemory* getDeviceScratchBuffer () const override; 1671e5c31af7Sopenharmony_ci virtual std::vector<deUint8>* getHostScratchBuffer () const override; 1672e5c31af7Sopenharmony_ci virtual BufferWithMemory* getVertexBuffer () const override; 1673e5c31af7Sopenharmony_ci virtual BufferWithMemory* getIndexBuffer () const override; 1674e5c31af7Sopenharmony_ci 1675e5c31af7Sopenharmony_ci virtual VkDeviceSize getAccelerationStructureBufferOffset () const override { return m_info.accStrOffset; } 1676e5c31af7Sopenharmony_ci virtual VkDeviceSize getDeviceScratchBufferOffset () const override { return m_info.buildScratchBuffOffset; } 1677e5c31af7Sopenharmony_ci virtual VkDeviceSize getVertexBufferOffset () const override { return m_info.vertBuffOffset; } 1678e5c31af7Sopenharmony_ci virtual VkDeviceSize getIndexBufferOffset () const override { return m_info.indexBuffOffset; } 1679e5c31af7Sopenharmony_ci 1680e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolImpl& m_pool; 1681e5c31af7Sopenharmony_ci 1682e5c31af7Sopenharmony_ci struct Info 1683e5c31af7Sopenharmony_ci { 1684e5c31af7Sopenharmony_ci deUint32 accStrIndex; 1685e5c31af7Sopenharmony_ci VkDeviceSize accStrOffset; 1686e5c31af7Sopenharmony_ci deUint32 vertBuffIndex; 1687e5c31af7Sopenharmony_ci VkDeviceSize vertBuffOffset; 1688e5c31af7Sopenharmony_ci deUint32 indexBuffIndex; 1689e5c31af7Sopenharmony_ci VkDeviceSize indexBuffOffset; 1690e5c31af7Sopenharmony_ci deUint32 buildScratchBuffIndex; 1691e5c31af7Sopenharmony_ci VkDeviceSize buildScratchBuffOffset; 1692e5c31af7Sopenharmony_ci } m_info; 1693e5c31af7Sopenharmony_ci}; 1694e5c31af7Sopenharmony_ci 1695e5c31af7Sopenharmony_citemplate<class X> inline X negz (const X&) 1696e5c31af7Sopenharmony_ci{ 1697e5c31af7Sopenharmony_ci return (~static_cast<X>(0)); 1698e5c31af7Sopenharmony_ci} 1699e5c31af7Sopenharmony_citemplate<class X> inline bool isnegz (const X& x) 1700e5c31af7Sopenharmony_ci{ 1701e5c31af7Sopenharmony_ci return x == negz(x); 1702e5c31af7Sopenharmony_ci} 1703e5c31af7Sopenharmony_citemplate<class Y> inline auto make_unsigned(const Y& y) -> typename std::make_unsigned<Y>::type 1704e5c31af7Sopenharmony_ci{ 1705e5c31af7Sopenharmony_ci return static_cast<typename std::make_unsigned<Y>::type>(y); 1706e5c31af7Sopenharmony_ci} 1707e5c31af7Sopenharmony_ci 1708e5c31af7Sopenharmony_ciBottomLevelAccelerationStructurePoolMember::BottomLevelAccelerationStructurePoolMember (BottomLevelAccelerationStructurePoolImpl& pool) 1709e5c31af7Sopenharmony_ci : m_pool (pool) 1710e5c31af7Sopenharmony_ci , m_info {} 1711e5c31af7Sopenharmony_ci{ 1712e5c31af7Sopenharmony_ci} 1713e5c31af7Sopenharmony_ci 1714e5c31af7Sopenharmony_cistruct BottomLevelAccelerationStructurePoolImpl 1715e5c31af7Sopenharmony_ci{ 1716e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolImpl (BottomLevelAccelerationStructurePoolImpl&&) = delete; 1717e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolImpl (const BottomLevelAccelerationStructurePoolImpl&) = delete; 1718e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolImpl (BottomLevelAccelerationStructurePool& pool); 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePool& m_pool; 1721e5c31af7Sopenharmony_ci std::vector<de::SharedPtr<BufferWithMemory>> m_accellerationStructureBuffers; 1722e5c31af7Sopenharmony_ci de::SharedPtr<BufferWithMemory> m_deviceScratchBuffer; 1723e5c31af7Sopenharmony_ci de::UniquePtr<std::vector<deUint8>> m_hostScratchBuffer; 1724e5c31af7Sopenharmony_ci std::vector<de::SharedPtr<BufferWithMemory>> m_vertexBuffers; 1725e5c31af7Sopenharmony_ci std::vector<de::SharedPtr<BufferWithMemory>> m_indexBuffers; 1726e5c31af7Sopenharmony_ci}; 1727e5c31af7Sopenharmony_ciBottomLevelAccelerationStructurePoolImpl::BottomLevelAccelerationStructurePoolImpl (BottomLevelAccelerationStructurePool& pool) 1728e5c31af7Sopenharmony_ci : m_pool (pool) 1729e5c31af7Sopenharmony_ci , m_accellerationStructureBuffers () 1730e5c31af7Sopenharmony_ci , m_deviceScratchBuffer () 1731e5c31af7Sopenharmony_ci , m_hostScratchBuffer (new std::vector<deUint8>) 1732e5c31af7Sopenharmony_ci , m_vertexBuffers () 1733e5c31af7Sopenharmony_ci , m_indexBuffers () 1734e5c31af7Sopenharmony_ci{ 1735e5c31af7Sopenharmony_ci} 1736e5c31af7Sopenharmony_ciBufferWithMemory* BottomLevelAccelerationStructurePoolMember::getAccelerationStructureBuffer () const 1737e5c31af7Sopenharmony_ci{ 1738e5c31af7Sopenharmony_ci BufferWithMemory* result = nullptr; 1739e5c31af7Sopenharmony_ci if (m_pool.m_accellerationStructureBuffers.size()) 1740e5c31af7Sopenharmony_ci { 1741e5c31af7Sopenharmony_ci DE_ASSERT(!isnegz(m_info.accStrIndex)); 1742e5c31af7Sopenharmony_ci result = m_pool.m_accellerationStructureBuffers[m_info.accStrIndex].get(); 1743e5c31af7Sopenharmony_ci } 1744e5c31af7Sopenharmony_ci return result; 1745e5c31af7Sopenharmony_ci} 1746e5c31af7Sopenharmony_ciBufferWithMemory* BottomLevelAccelerationStructurePoolMember::getDeviceScratchBuffer () const 1747e5c31af7Sopenharmony_ci{ 1748e5c31af7Sopenharmony_ci DE_ASSERT(m_info.buildScratchBuffIndex == 0); 1749e5c31af7Sopenharmony_ci return m_pool.m_deviceScratchBuffer.get(); 1750e5c31af7Sopenharmony_ci} 1751e5c31af7Sopenharmony_cistd::vector<deUint8>* BottomLevelAccelerationStructurePoolMember::getHostScratchBuffer () const 1752e5c31af7Sopenharmony_ci{ 1753e5c31af7Sopenharmony_ci return this->m_buildScratchSize ? m_pool.m_hostScratchBuffer.get() : nullptr; 1754e5c31af7Sopenharmony_ci} 1755e5c31af7Sopenharmony_ci 1756e5c31af7Sopenharmony_ciBufferWithMemory* BottomLevelAccelerationStructurePoolMember::getVertexBuffer () const 1757e5c31af7Sopenharmony_ci{ 1758e5c31af7Sopenharmony_ci BufferWithMemory* result = nullptr; 1759e5c31af7Sopenharmony_ci if (m_pool.m_vertexBuffers.size()) 1760e5c31af7Sopenharmony_ci { 1761e5c31af7Sopenharmony_ci DE_ASSERT(!isnegz(m_info.vertBuffIndex)); 1762e5c31af7Sopenharmony_ci result = m_pool.m_vertexBuffers[m_info.vertBuffIndex].get(); 1763e5c31af7Sopenharmony_ci } 1764e5c31af7Sopenharmony_ci return result; 1765e5c31af7Sopenharmony_ci} 1766e5c31af7Sopenharmony_ciBufferWithMemory* BottomLevelAccelerationStructurePoolMember::getIndexBuffer () const 1767e5c31af7Sopenharmony_ci{ 1768e5c31af7Sopenharmony_ci BufferWithMemory* result = nullptr; 1769e5c31af7Sopenharmony_ci if (m_pool.m_indexBuffers.size()) 1770e5c31af7Sopenharmony_ci { 1771e5c31af7Sopenharmony_ci DE_ASSERT(!isnegz(m_info.indexBuffIndex)); 1772e5c31af7Sopenharmony_ci result = m_pool.m_indexBuffers[m_info.indexBuffIndex].get(); 1773e5c31af7Sopenharmony_ci } 1774e5c31af7Sopenharmony_ci return result; 1775e5c31af7Sopenharmony_ci} 1776e5c31af7Sopenharmony_ci 1777e5c31af7Sopenharmony_cistruct BottomLevelAccelerationStructurePool::Impl : BottomLevelAccelerationStructurePoolImpl 1778e5c31af7Sopenharmony_ci{ 1779e5c31af7Sopenharmony_ci friend class BottomLevelAccelerationStructurePool; 1780e5c31af7Sopenharmony_ci friend class BottomLevelAccelerationStructurePoolMember; 1781e5c31af7Sopenharmony_ci 1782e5c31af7Sopenharmony_ci Impl (BottomLevelAccelerationStructurePool& pool) 1783e5c31af7Sopenharmony_ci : BottomLevelAccelerationStructurePoolImpl(pool) { } 1784e5c31af7Sopenharmony_ci}; 1785e5c31af7Sopenharmony_ci 1786e5c31af7Sopenharmony_ciBottomLevelAccelerationStructurePool::BottomLevelAccelerationStructurePool () 1787e5c31af7Sopenharmony_ci : m_batchStructCount (4) 1788e5c31af7Sopenharmony_ci , m_batchGeomCount (0) 1789e5c31af7Sopenharmony_ci , m_infos () 1790e5c31af7Sopenharmony_ci , m_structs () 1791e5c31af7Sopenharmony_ci , m_createOnce (false) 1792e5c31af7Sopenharmony_ci , m_tryCachedMemory (true) 1793e5c31af7Sopenharmony_ci , m_structsBuffSize (0) 1794e5c31af7Sopenharmony_ci , m_updatesScratchSize (0) 1795e5c31af7Sopenharmony_ci , m_buildsScratchSize (0) 1796e5c31af7Sopenharmony_ci , m_verticesSize (0) 1797e5c31af7Sopenharmony_ci , m_indicesSize (0) 1798e5c31af7Sopenharmony_ci , m_impl (new Impl(*this)) 1799e5c31af7Sopenharmony_ci{ 1800e5c31af7Sopenharmony_ci} 1801e5c31af7Sopenharmony_ci 1802e5c31af7Sopenharmony_ciBottomLevelAccelerationStructurePool::~BottomLevelAccelerationStructurePool() 1803e5c31af7Sopenharmony_ci{ 1804e5c31af7Sopenharmony_ci delete m_impl; 1805e5c31af7Sopenharmony_ci} 1806e5c31af7Sopenharmony_ci 1807e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePool::batchStructCount (const deUint32& value) 1808e5c31af7Sopenharmony_ci{ 1809e5c31af7Sopenharmony_ci DE_ASSERT(value >= 1); m_batchStructCount = value; 1810e5c31af7Sopenharmony_ci} 1811e5c31af7Sopenharmony_ci 1812e5c31af7Sopenharmony_ciauto BottomLevelAccelerationStructurePool::add (VkDeviceSize structureSize, 1813e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) -> BottomLevelAccelerationStructurePool::BlasPtr 1814e5c31af7Sopenharmony_ci{ 1815e5c31af7Sopenharmony_ci // Prevent a programmer from calling this method after batchCreate(...) method has been called. 1816e5c31af7Sopenharmony_ci if (m_createOnce) DE_ASSERT(0); 1817e5c31af7Sopenharmony_ci 1818e5c31af7Sopenharmony_ci auto blas = new BottomLevelAccelerationStructurePoolMember(*m_impl); 1819e5c31af7Sopenharmony_ci m_infos.push_back({structureSize, deviceAddress}); 1820e5c31af7Sopenharmony_ci m_structs.emplace_back(blas); 1821e5c31af7Sopenharmony_ci return m_structs.back(); 1822e5c31af7Sopenharmony_ci} 1823e5c31af7Sopenharmony_ci 1824e5c31af7Sopenharmony_civoid adjustBatchCount (const DeviceInterface& vkd, 1825e5c31af7Sopenharmony_ci const VkDevice device, 1826e5c31af7Sopenharmony_ci const std::vector<BottomLevelAccelerationStructurePool::BlasPtr>& structs, 1827e5c31af7Sopenharmony_ci const std::vector<BottomLevelAccelerationStructurePool::BlasInfo>& infos, 1828e5c31af7Sopenharmony_ci const VkDeviceSize maxBufferSize, 1829e5c31af7Sopenharmony_ci deUint32 (&result)[4]) 1830e5c31af7Sopenharmony_ci{ 1831e5c31af7Sopenharmony_ci tcu::Vector<VkDeviceSize, 4> sizes(0); 1832e5c31af7Sopenharmony_ci tcu::Vector<VkDeviceSize, 4> sums(0); 1833e5c31af7Sopenharmony_ci tcu::Vector<deUint32, 4> tmps(0); 1834e5c31af7Sopenharmony_ci tcu::Vector<deUint32, 4> batches(0); 1835e5c31af7Sopenharmony_ci 1836e5c31af7Sopenharmony_ci VkDeviceSize updateScratchSize = 0; static_cast<void>(updateScratchSize); // not used yet, disabled for future implementation 1837e5c31af7Sopenharmony_ci 1838e5c31af7Sopenharmony_ci auto updateIf = [&](deUint32 c) 1839e5c31af7Sopenharmony_ci { 1840e5c31af7Sopenharmony_ci if (sums[c] + sizes[c] <= maxBufferSize) 1841e5c31af7Sopenharmony_ci { 1842e5c31af7Sopenharmony_ci sums[c] += sizes[c]; 1843e5c31af7Sopenharmony_ci tmps[c] += 1; 1844e5c31af7Sopenharmony_ci 1845e5c31af7Sopenharmony_ci batches[c] = std::max(tmps[c], batches[c]); 1846e5c31af7Sopenharmony_ci } 1847e5c31af7Sopenharmony_ci else 1848e5c31af7Sopenharmony_ci { 1849e5c31af7Sopenharmony_ci sums[c] = 0; 1850e5c31af7Sopenharmony_ci tmps[c] = 0; 1851e5c31af7Sopenharmony_ci } 1852e5c31af7Sopenharmony_ci }; 1853e5c31af7Sopenharmony_ci 1854e5c31af7Sopenharmony_ci const deUint32 maxIter = static_cast<deUint32>(structs.size()); 1855e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < maxIter; ++i) 1856e5c31af7Sopenharmony_ci { 1857e5c31af7Sopenharmony_ci auto& str = *dynamic_cast<BottomLevelAccelerationStructurePoolMember*>(structs[i].get()); 1858e5c31af7Sopenharmony_ci std::tie(sizes[0], updateScratchSize, sizes[1], sizes[2], sizes[3]) = str.computeBuildSize(vkd, device, infos[i].structureSize); 1859e5c31af7Sopenharmony_ci 1860e5c31af7Sopenharmony_ci updateIf(0); 1861e5c31af7Sopenharmony_ci updateIf(1); 1862e5c31af7Sopenharmony_ci updateIf(2); 1863e5c31af7Sopenharmony_ci updateIf(3); 1864e5c31af7Sopenharmony_ci } 1865e5c31af7Sopenharmony_ci 1866e5c31af7Sopenharmony_ci result[0] = std::max(batches[0], 1u); 1867e5c31af7Sopenharmony_ci result[1] = std::max(batches[1], 1u); 1868e5c31af7Sopenharmony_ci result[2] = std::max(batches[2], 1u); 1869e5c31af7Sopenharmony_ci result[3] = std::max(batches[3], 1u); 1870e5c31af7Sopenharmony_ci} 1871e5c31af7Sopenharmony_ci 1872e5c31af7Sopenharmony_cisize_t BottomLevelAccelerationStructurePool::getAllocationCount () const 1873e5c31af7Sopenharmony_ci{ 1874e5c31af7Sopenharmony_ci return m_impl->m_accellerationStructureBuffers.size() 1875e5c31af7Sopenharmony_ci + m_impl->m_vertexBuffers.size() 1876e5c31af7Sopenharmony_ci + m_impl->m_indexBuffers.size() 1877e5c31af7Sopenharmony_ci + 1 /* for scratch buffer */; 1878e5c31af7Sopenharmony_ci} 1879e5c31af7Sopenharmony_ci 1880e5c31af7Sopenharmony_cisize_t BottomLevelAccelerationStructurePool::getAllocationCount (const DeviceInterface& vk, 1881e5c31af7Sopenharmony_ci const VkDevice device, 1882e5c31af7Sopenharmony_ci const VkDeviceSize maxBufferSize) const 1883e5c31af7Sopenharmony_ci{ 1884e5c31af7Sopenharmony_ci DE_ASSERT(m_structs.size() != 0); 1885e5c31af7Sopenharmony_ci 1886e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> accStrSizes; 1887e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> vertBuffSizes; 1888e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> indexBuffSizes; 1889e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> scratchBuffSizes; 1890e5c31af7Sopenharmony_ci 1891e5c31af7Sopenharmony_ci const deUint32 allStructsCount = structCount(); 1892e5c31af7Sopenharmony_ci 1893e5c31af7Sopenharmony_ci deUint32 batchStructCount = m_batchStructCount; 1894e5c31af7Sopenharmony_ci deUint32 batchScratchCount = m_batchStructCount; 1895e5c31af7Sopenharmony_ci deUint32 batchVertexCount = m_batchGeomCount ? m_batchGeomCount : m_batchStructCount; 1896e5c31af7Sopenharmony_ci deUint32 batchIndexCount = batchVertexCount; 1897e5c31af7Sopenharmony_ci 1898e5c31af7Sopenharmony_ci if (!isnegz(maxBufferSize)) 1899e5c31af7Sopenharmony_ci { 1900e5c31af7Sopenharmony_ci deUint32 batches[4]; 1901e5c31af7Sopenharmony_ci adjustBatchCount(vk, device, m_structs, m_infos, maxBufferSize, batches); 1902e5c31af7Sopenharmony_ci batchStructCount = batches[0]; 1903e5c31af7Sopenharmony_ci batchScratchCount = batches[1]; 1904e5c31af7Sopenharmony_ci batchVertexCount = batches[2]; 1905e5c31af7Sopenharmony_ci batchIndexCount = batches[3]; 1906e5c31af7Sopenharmony_ci } 1907e5c31af7Sopenharmony_ci 1908e5c31af7Sopenharmony_ci deUint32 iStr = 0; 1909e5c31af7Sopenharmony_ci deUint32 iScratch = 0; 1910e5c31af7Sopenharmony_ci deUint32 iVertex = 0; 1911e5c31af7Sopenharmony_ci deUint32 iIndex = 0; 1912e5c31af7Sopenharmony_ci 1913e5c31af7Sopenharmony_ci VkDeviceSize strSize = 0; 1914e5c31af7Sopenharmony_ci VkDeviceSize updateScratchSize = 0; 1915e5c31af7Sopenharmony_ci VkDeviceSize buildScratchSize = 0; 1916e5c31af7Sopenharmony_ci VkDeviceSize vertexSize = 0; 1917e5c31af7Sopenharmony_ci VkDeviceSize indexSize = 0; 1918e5c31af7Sopenharmony_ci 1919e5c31af7Sopenharmony_ci for (; iStr < allStructsCount; ++iStr) 1920e5c31af7Sopenharmony_ci { 1921e5c31af7Sopenharmony_ci auto& str = *dynamic_cast<BottomLevelAccelerationStructurePoolMember*>(m_structs[iStr].get()); 1922e5c31af7Sopenharmony_ci std::tie(strSize, updateScratchSize, buildScratchSize, vertexSize, indexSize) = str.computeBuildSize(vk, device, m_infos[iStr].structureSize); 1923e5c31af7Sopenharmony_ci 1924e5c31af7Sopenharmony_ci { 1925e5c31af7Sopenharmony_ci const VkDeviceSize alignedStrSize = deAlign64(strSize, 256); 1926e5c31af7Sopenharmony_ci const deUint32 accStrIndex = (iStr / batchStructCount); 1927e5c31af7Sopenharmony_ci accStrSizes[accStrIndex] += alignedStrSize; 1928e5c31af7Sopenharmony_ci } 1929e5c31af7Sopenharmony_ci 1930e5c31af7Sopenharmony_ci if (buildScratchSize != 0) 1931e5c31af7Sopenharmony_ci { 1932e5c31af7Sopenharmony_ci const VkDeviceSize alignedBuilsScratchSize = deAlign64(buildScratchSize, 256); 1933e5c31af7Sopenharmony_ci const deUint32 scratchBuffIndex = (iScratch/ batchScratchCount); 1934e5c31af7Sopenharmony_ci scratchBuffSizes[scratchBuffIndex] += alignedBuilsScratchSize; 1935e5c31af7Sopenharmony_ci iScratch += 1; 1936e5c31af7Sopenharmony_ci } 1937e5c31af7Sopenharmony_ci 1938e5c31af7Sopenharmony_ci if (vertexSize != 0) 1939e5c31af7Sopenharmony_ci { 1940e5c31af7Sopenharmony_ci const VkDeviceSize alignedVertBuffSize = deAlign64(vertexSize, 8); 1941e5c31af7Sopenharmony_ci const deUint32 vertBuffIndex = (iVertex / batchVertexCount); 1942e5c31af7Sopenharmony_ci vertBuffSizes[vertBuffIndex] += alignedVertBuffSize; 1943e5c31af7Sopenharmony_ci iVertex += 1; 1944e5c31af7Sopenharmony_ci } 1945e5c31af7Sopenharmony_ci 1946e5c31af7Sopenharmony_ci if (indexSize != 0) 1947e5c31af7Sopenharmony_ci { 1948e5c31af7Sopenharmony_ci const VkDeviceSize alignedIndexBuffSize = deAlign64(indexSize, 8); 1949e5c31af7Sopenharmony_ci const deUint32 indexBuffIndex = (iIndex / batchIndexCount); 1950e5c31af7Sopenharmony_ci indexBuffSizes[indexBuffIndex] += alignedIndexBuffSize; 1951e5c31af7Sopenharmony_ci iIndex += 1; 1952e5c31af7Sopenharmony_ci } 1953e5c31af7Sopenharmony_ci } 1954e5c31af7Sopenharmony_ci 1955e5c31af7Sopenharmony_ci return accStrSizes.size() 1956e5c31af7Sopenharmony_ci + vertBuffSizes.size() 1957e5c31af7Sopenharmony_ci + indexBuffSizes.size() 1958e5c31af7Sopenharmony_ci + scratchBuffSizes.size(); 1959e5c31af7Sopenharmony_ci} 1960e5c31af7Sopenharmony_ci 1961e5c31af7Sopenharmony_citcu::Vector<VkDeviceSize, 4> BottomLevelAccelerationStructurePool::getAllocationSizes (const DeviceInterface& vk, 1962e5c31af7Sopenharmony_ci const VkDevice device) const 1963e5c31af7Sopenharmony_ci{ 1964e5c31af7Sopenharmony_ci if (m_structsBuffSize) 1965e5c31af7Sopenharmony_ci { 1966e5c31af7Sopenharmony_ci return tcu::Vector<VkDeviceSize, 4>(m_structsBuffSize, m_buildsScratchSize, m_verticesSize, m_indicesSize); 1967e5c31af7Sopenharmony_ci } 1968e5c31af7Sopenharmony_ci 1969e5c31af7Sopenharmony_ci VkDeviceSize strSize = 0; 1970e5c31af7Sopenharmony_ci VkDeviceSize updateScratchSize = 0; static_cast<void>(updateScratchSize); // not used yet, disabled for future implementation 1971e5c31af7Sopenharmony_ci VkDeviceSize buildScratchSize = 0; 1972e5c31af7Sopenharmony_ci VkDeviceSize vertexSize = 0; 1973e5c31af7Sopenharmony_ci VkDeviceSize indexSize = 0; 1974e5c31af7Sopenharmony_ci VkDeviceSize sumStrSize = 0; 1975e5c31af7Sopenharmony_ci VkDeviceSize sumUpdateScratchSize = 0; static_cast<void>(sumUpdateScratchSize); // not used yet, disabled for future implementation 1976e5c31af7Sopenharmony_ci VkDeviceSize sumBuildScratchSize = 0; 1977e5c31af7Sopenharmony_ci VkDeviceSize sumVertexSize = 0; 1978e5c31af7Sopenharmony_ci VkDeviceSize sumIndexSize = 0; 1979e5c31af7Sopenharmony_ci for (size_t i = 0; i < structCount(); ++i) 1980e5c31af7Sopenharmony_ci { 1981e5c31af7Sopenharmony_ci auto& str = *dynamic_cast<BottomLevelAccelerationStructurePoolMember*>(m_structs[i].get()); 1982e5c31af7Sopenharmony_ci std::tie(strSize, updateScratchSize, buildScratchSize, vertexSize, indexSize) = str.computeBuildSize(vk, device, m_infos[i].structureSize); 1983e5c31af7Sopenharmony_ci sumStrSize += deAlign64(strSize, 256); 1984e5c31af7Sopenharmony_ci //sumUpdateScratchSize += deAlign64(updateScratchSize, 256); not used yet, disabled for future implementation 1985e5c31af7Sopenharmony_ci sumBuildScratchSize += deAlign64(buildScratchSize, 256); 1986e5c31af7Sopenharmony_ci sumVertexSize += deAlign64(vertexSize, 8); 1987e5c31af7Sopenharmony_ci sumIndexSize += deAlign64(indexSize, 8); 1988e5c31af7Sopenharmony_ci } 1989e5c31af7Sopenharmony_ci return tcu::Vector<VkDeviceSize, 4>(sumStrSize, sumBuildScratchSize, sumVertexSize, sumIndexSize); 1990e5c31af7Sopenharmony_ci} 1991e5c31af7Sopenharmony_ci 1992e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePool::batchCreate (const DeviceInterface& vkd, 1993e5c31af7Sopenharmony_ci const VkDevice device, 1994e5c31af7Sopenharmony_ci Allocator& allocator) 1995e5c31af7Sopenharmony_ci{ 1996e5c31af7Sopenharmony_ci batchCreateAdjust(vkd, device, allocator, negz<VkDeviceSize>(0)); 1997e5c31af7Sopenharmony_ci} 1998e5c31af7Sopenharmony_ci 1999e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePool::batchCreateAdjust (const DeviceInterface& vkd, 2000e5c31af7Sopenharmony_ci const VkDevice device, 2001e5c31af7Sopenharmony_ci Allocator& allocator, 2002e5c31af7Sopenharmony_ci const VkDeviceSize maxBufferSize) 2003e5c31af7Sopenharmony_ci{ 2004e5c31af7Sopenharmony_ci // Prevent a programmer from calling this method more than once. 2005e5c31af7Sopenharmony_ci if (m_createOnce) DE_ASSERT(0); 2006e5c31af7Sopenharmony_ci 2007e5c31af7Sopenharmony_ci m_createOnce = true; 2008e5c31af7Sopenharmony_ci DE_ASSERT(m_structs.size() != 0); 2009e5c31af7Sopenharmony_ci 2010e5c31af7Sopenharmony_ci auto createAccellerationStructureBuffer = [&](VkDeviceSize bufferSize) -> typename std::add_pointer<BufferWithMemory>::type 2011e5c31af7Sopenharmony_ci { 2012e5c31af7Sopenharmony_ci BufferWithMemory* res = nullptr; 2013e5c31af7Sopenharmony_ci const VkBufferCreateInfo bci = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2014e5c31af7Sopenharmony_ci 2015e5c31af7Sopenharmony_ci if (m_tryCachedMemory) try 2016e5c31af7Sopenharmony_ci { 2017e5c31af7Sopenharmony_ci res = new BufferWithMemory(vkd, device, allocator, bci, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); 2018e5c31af7Sopenharmony_ci } 2019e5c31af7Sopenharmony_ci catch (const tcu::NotSupportedError&) 2020e5c31af7Sopenharmony_ci { 2021e5c31af7Sopenharmony_ci res = nullptr; 2022e5c31af7Sopenharmony_ci } 2023e5c31af7Sopenharmony_ci 2024e5c31af7Sopenharmony_ci return (nullptr != res) 2025e5c31af7Sopenharmony_ci ? res 2026e5c31af7Sopenharmony_ci : (new BufferWithMemory(vkd, device, allocator, bci, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 2027e5c31af7Sopenharmony_ci }; 2028e5c31af7Sopenharmony_ci 2029e5c31af7Sopenharmony_ci auto createDeviceScratchBuffer = [&](VkDeviceSize bufferSize) -> de::SharedPtr<BufferWithMemory> 2030e5c31af7Sopenharmony_ci { 2031e5c31af7Sopenharmony_ci const VkBufferCreateInfo bci = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2032e5c31af7Sopenharmony_ci BufferWithMemory* p = new BufferWithMemory(vkd, device, allocator, bci, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); 2033e5c31af7Sopenharmony_ci return de::SharedPtr<BufferWithMemory>(p); 2034e5c31af7Sopenharmony_ci }; 2035e5c31af7Sopenharmony_ci 2036e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> accStrSizes; 2037e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> vertBuffSizes; 2038e5c31af7Sopenharmony_ci std::map<deUint32, VkDeviceSize> indexBuffSizes; 2039e5c31af7Sopenharmony_ci 2040e5c31af7Sopenharmony_ci const deUint32 allStructsCount = structCount(); 2041e5c31af7Sopenharmony_ci deUint32 iterKey = 0; 2042e5c31af7Sopenharmony_ci 2043e5c31af7Sopenharmony_ci deUint32 batchStructCount = m_batchStructCount; 2044e5c31af7Sopenharmony_ci deUint32 batchVertexCount = m_batchGeomCount ? m_batchGeomCount : m_batchStructCount; 2045e5c31af7Sopenharmony_ci deUint32 batchIndexCount = batchVertexCount; 2046e5c31af7Sopenharmony_ci 2047e5c31af7Sopenharmony_ci if (!isnegz(maxBufferSize)) 2048e5c31af7Sopenharmony_ci { 2049e5c31af7Sopenharmony_ci deUint32 batches[4]; 2050e5c31af7Sopenharmony_ci adjustBatchCount(vkd, device, m_structs, m_infos, maxBufferSize, batches); 2051e5c31af7Sopenharmony_ci batchStructCount = batches[0]; 2052e5c31af7Sopenharmony_ci // batches[1]: batchScratchCount 2053e5c31af7Sopenharmony_ci batchVertexCount = batches[2]; 2054e5c31af7Sopenharmony_ci batchIndexCount = batches[3]; 2055e5c31af7Sopenharmony_ci } 2056e5c31af7Sopenharmony_ci 2057e5c31af7Sopenharmony_ci deUint32 iStr = 0; 2058e5c31af7Sopenharmony_ci deUint32 iVertex = 0; 2059e5c31af7Sopenharmony_ci deUint32 iIndex = 0; 2060e5c31af7Sopenharmony_ci 2061e5c31af7Sopenharmony_ci VkDeviceSize strSize = 0; 2062e5c31af7Sopenharmony_ci VkDeviceSize updateScratchSize = 0; 2063e5c31af7Sopenharmony_ci VkDeviceSize buildScratchSize = 0; 2064e5c31af7Sopenharmony_ci VkDeviceSize maxBuildScratchSize = 0; 2065e5c31af7Sopenharmony_ci VkDeviceSize vertexSize = 0; 2066e5c31af7Sopenharmony_ci VkDeviceSize indexSize = 0; 2067e5c31af7Sopenharmony_ci 2068e5c31af7Sopenharmony_ci VkDeviceSize strOffset = 0; 2069e5c31af7Sopenharmony_ci VkDeviceSize vertexOffset = 0; 2070e5c31af7Sopenharmony_ci VkDeviceSize indexOffset = 0; 2071e5c31af7Sopenharmony_ci 2072e5c31af7Sopenharmony_ci deUint32 hostStructCount = 0; 2073e5c31af7Sopenharmony_ci deUint32 deviceStructCount = 0; 2074e5c31af7Sopenharmony_ci 2075e5c31af7Sopenharmony_ci for (; iStr < allStructsCount; ++iStr) 2076e5c31af7Sopenharmony_ci { 2077e5c31af7Sopenharmony_ci BottomLevelAccelerationStructurePoolMember::Info info{}; 2078e5c31af7Sopenharmony_ci auto& str = *dynamic_cast<BottomLevelAccelerationStructurePoolMember*>(m_structs[iStr].get()); 2079e5c31af7Sopenharmony_ci std::tie(strSize, updateScratchSize, buildScratchSize, vertexSize, indexSize) = str.computeBuildSize(vkd, device, m_infos[iStr].structureSize); 2080e5c31af7Sopenharmony_ci 2081e5c31af7Sopenharmony_ci ++(str.getBuildType() == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR ? hostStructCount : deviceStructCount); 2082e5c31af7Sopenharmony_ci 2083e5c31af7Sopenharmony_ci { 2084e5c31af7Sopenharmony_ci const VkDeviceSize alignedStrSize = deAlign64(strSize, 256); 2085e5c31af7Sopenharmony_ci const deUint32 accStrIndex = (iStr / batchStructCount); 2086e5c31af7Sopenharmony_ci if (iStr != 0 && (iStr % batchStructCount) == 0) 2087e5c31af7Sopenharmony_ci { 2088e5c31af7Sopenharmony_ci strOffset = 0; 2089e5c31af7Sopenharmony_ci } 2090e5c31af7Sopenharmony_ci 2091e5c31af7Sopenharmony_ci info.accStrIndex = accStrIndex; 2092e5c31af7Sopenharmony_ci info.accStrOffset = strOffset; 2093e5c31af7Sopenharmony_ci accStrSizes[accStrIndex] += alignedStrSize; 2094e5c31af7Sopenharmony_ci strOffset += alignedStrSize; 2095e5c31af7Sopenharmony_ci m_structsBuffSize += alignedStrSize; 2096e5c31af7Sopenharmony_ci } 2097e5c31af7Sopenharmony_ci 2098e5c31af7Sopenharmony_ci if (buildScratchSize != 0) 2099e5c31af7Sopenharmony_ci { 2100e5c31af7Sopenharmony_ci maxBuildScratchSize = std::max(maxBuildScratchSize, make_unsigned(deAlign64(buildScratchSize, 256u))); 2101e5c31af7Sopenharmony_ci 2102e5c31af7Sopenharmony_ci info.buildScratchBuffIndex = 0; 2103e5c31af7Sopenharmony_ci info.buildScratchBuffOffset = 0; 2104e5c31af7Sopenharmony_ci } 2105e5c31af7Sopenharmony_ci 2106e5c31af7Sopenharmony_ci if (vertexSize != 0) 2107e5c31af7Sopenharmony_ci { 2108e5c31af7Sopenharmony_ci const VkDeviceSize alignedVertBuffSize = deAlign64(vertexSize, 8); 2109e5c31af7Sopenharmony_ci const deUint32 vertBuffIndex = (iVertex / batchVertexCount); 2110e5c31af7Sopenharmony_ci if (iVertex != 0 && (iVertex % batchVertexCount) == 0) 2111e5c31af7Sopenharmony_ci { 2112e5c31af7Sopenharmony_ci vertexOffset = 0; 2113e5c31af7Sopenharmony_ci } 2114e5c31af7Sopenharmony_ci 2115e5c31af7Sopenharmony_ci info.vertBuffIndex = vertBuffIndex; 2116e5c31af7Sopenharmony_ci info.vertBuffOffset = vertexOffset; 2117e5c31af7Sopenharmony_ci vertBuffSizes[vertBuffIndex] += alignedVertBuffSize; 2118e5c31af7Sopenharmony_ci vertexOffset += alignedVertBuffSize; 2119e5c31af7Sopenharmony_ci m_verticesSize += alignedVertBuffSize; 2120e5c31af7Sopenharmony_ci iVertex += 1; 2121e5c31af7Sopenharmony_ci } 2122e5c31af7Sopenharmony_ci 2123e5c31af7Sopenharmony_ci if (indexSize != 0) 2124e5c31af7Sopenharmony_ci { 2125e5c31af7Sopenharmony_ci const VkDeviceSize alignedIndexBuffSize = deAlign64(indexSize, 8); 2126e5c31af7Sopenharmony_ci const deUint32 indexBuffIndex = (iIndex / batchIndexCount); 2127e5c31af7Sopenharmony_ci if (iIndex != 0 && (iIndex % batchIndexCount) == 0) 2128e5c31af7Sopenharmony_ci { 2129e5c31af7Sopenharmony_ci indexOffset = 0; 2130e5c31af7Sopenharmony_ci } 2131e5c31af7Sopenharmony_ci 2132e5c31af7Sopenharmony_ci info.indexBuffIndex = indexBuffIndex; 2133e5c31af7Sopenharmony_ci info.indexBuffOffset = indexOffset; 2134e5c31af7Sopenharmony_ci indexBuffSizes[indexBuffIndex] += alignedIndexBuffSize; 2135e5c31af7Sopenharmony_ci indexOffset += alignedIndexBuffSize; 2136e5c31af7Sopenharmony_ci m_indicesSize += alignedIndexBuffSize; 2137e5c31af7Sopenharmony_ci iIndex += 1; 2138e5c31af7Sopenharmony_ci } 2139e5c31af7Sopenharmony_ci 2140e5c31af7Sopenharmony_ci str.preCreateSetSizesAndOffsets(info, strSize, updateScratchSize, buildScratchSize); 2141e5c31af7Sopenharmony_ci } 2142e5c31af7Sopenharmony_ci 2143e5c31af7Sopenharmony_ci for (iterKey = 0; iterKey < static_cast<deUint32>(accStrSizes.size()); ++iterKey) 2144e5c31af7Sopenharmony_ci { 2145e5c31af7Sopenharmony_ci m_impl->m_accellerationStructureBuffers.emplace_back(createAccellerationStructureBuffer(accStrSizes.at(iterKey))); 2146e5c31af7Sopenharmony_ci } 2147e5c31af7Sopenharmony_ci for (iterKey = 0; iterKey < static_cast<deUint32>(vertBuffSizes.size()); ++iterKey) 2148e5c31af7Sopenharmony_ci { 2149e5c31af7Sopenharmony_ci m_impl->m_vertexBuffers.emplace_back(createVertexBuffer(vkd, device, allocator, vertBuffSizes.at(iterKey))); 2150e5c31af7Sopenharmony_ci } 2151e5c31af7Sopenharmony_ci for (iterKey = 0; iterKey < static_cast<deUint32>(indexBuffSizes.size()); ++iterKey) 2152e5c31af7Sopenharmony_ci { 2153e5c31af7Sopenharmony_ci m_impl->m_indexBuffers.emplace_back(createIndexBuffer(vkd, device, allocator, indexBuffSizes.at(iterKey))); 2154e5c31af7Sopenharmony_ci } 2155e5c31af7Sopenharmony_ci 2156e5c31af7Sopenharmony_ci if (maxBuildScratchSize) 2157e5c31af7Sopenharmony_ci { 2158e5c31af7Sopenharmony_ci if (hostStructCount) m_impl->m_hostScratchBuffer->resize(static_cast<size_t>(maxBuildScratchSize)); 2159e5c31af7Sopenharmony_ci if (deviceStructCount) m_impl->m_deviceScratchBuffer = createDeviceScratchBuffer(maxBuildScratchSize); 2160e5c31af7Sopenharmony_ci 2161e5c31af7Sopenharmony_ci m_buildsScratchSize = maxBuildScratchSize; 2162e5c31af7Sopenharmony_ci } 2163e5c31af7Sopenharmony_ci 2164e5c31af7Sopenharmony_ci for (iterKey = 0; iterKey < allStructsCount; ++iterKey) 2165e5c31af7Sopenharmony_ci { 2166e5c31af7Sopenharmony_ci auto& str = *dynamic_cast<BottomLevelAccelerationStructurePoolMember*>(m_structs[iterKey].get()); 2167e5c31af7Sopenharmony_ci str.createAccellerationStructure(vkd, device, m_infos[iterKey].deviceAddress); 2168e5c31af7Sopenharmony_ci } 2169e5c31af7Sopenharmony_ci} 2170e5c31af7Sopenharmony_ci 2171e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePool::batchBuild (const DeviceInterface& vk, 2172e5c31af7Sopenharmony_ci const VkDevice device, 2173e5c31af7Sopenharmony_ci VkCommandBuffer cmdBuffer) 2174e5c31af7Sopenharmony_ci{ 2175e5c31af7Sopenharmony_ci for (const auto& str : m_structs) 2176e5c31af7Sopenharmony_ci { 2177e5c31af7Sopenharmony_ci str->build(vk, device, cmdBuffer); 2178e5c31af7Sopenharmony_ci } 2179e5c31af7Sopenharmony_ci} 2180e5c31af7Sopenharmony_ci 2181e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePool::batchBuild (const DeviceInterface& vk, 2182e5c31af7Sopenharmony_ci const VkDevice device, 2183e5c31af7Sopenharmony_ci VkCommandPool cmdPool, 2184e5c31af7Sopenharmony_ci VkQueue queue, 2185e5c31af7Sopenharmony_ci qpWatchDog* watchDog) 2186e5c31af7Sopenharmony_ci{ 2187e5c31af7Sopenharmony_ci const deUint32 limit = 10000u; 2188e5c31af7Sopenharmony_ci const deUint32 count = structCount(); 2189e5c31af7Sopenharmony_ci std::vector<BlasPtr> buildingOnDevice; 2190e5c31af7Sopenharmony_ci 2191e5c31af7Sopenharmony_ci auto buildOnDevice = [&]() -> void 2192e5c31af7Sopenharmony_ci { 2193e5c31af7Sopenharmony_ci Move<VkCommandBuffer> cmd = allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2194e5c31af7Sopenharmony_ci 2195e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmd, 0u); 2196e5c31af7Sopenharmony_ci for (const auto& str : buildingOnDevice) 2197e5c31af7Sopenharmony_ci str->build(vk, device, *cmd); 2198e5c31af7Sopenharmony_ci endCommandBuffer(vk, *cmd); 2199e5c31af7Sopenharmony_ci 2200e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, queue, *cmd); 2201e5c31af7Sopenharmony_ci vk.resetCommandPool(device, cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); 2202e5c31af7Sopenharmony_ci }; 2203e5c31af7Sopenharmony_ci 2204e5c31af7Sopenharmony_ci buildingOnDevice.reserve(limit); 2205e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < count; ++i) 2206e5c31af7Sopenharmony_ci { 2207e5c31af7Sopenharmony_ci auto str = m_structs[i]; 2208e5c31af7Sopenharmony_ci 2209e5c31af7Sopenharmony_ci if (str->getBuildType() == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR) 2210e5c31af7Sopenharmony_ci str->build(vk, device, DE_NULL); 2211e5c31af7Sopenharmony_ci else 2212e5c31af7Sopenharmony_ci buildingOnDevice.emplace_back(str); 2213e5c31af7Sopenharmony_ci 2214e5c31af7Sopenharmony_ci if ( buildingOnDevice.size() == limit || (count - 1) == i) 2215e5c31af7Sopenharmony_ci { 2216e5c31af7Sopenharmony_ci buildOnDevice(); 2217e5c31af7Sopenharmony_ci buildingOnDevice.clear(); 2218e5c31af7Sopenharmony_ci } 2219e5c31af7Sopenharmony_ci 2220e5c31af7Sopenharmony_ci if ((i % WATCHDOG_INTERVAL) == 0 && watchDog) 2221e5c31af7Sopenharmony_ci qpWatchDog_touch(watchDog); 2222e5c31af7Sopenharmony_ci } 2223e5c31af7Sopenharmony_ci} 2224e5c31af7Sopenharmony_ci 2225e5c31af7Sopenharmony_ciauto BottomLevelAccelerationStructurePoolMember::computeBuildSize (const DeviceInterface& vk, 2226e5c31af7Sopenharmony_ci const VkDevice device, 2227e5c31af7Sopenharmony_ci const VkDeviceSize strSize) const 2228e5c31af7Sopenharmony_ci // accStrSize,updateScratch,buildScratch, vertexSize, indexSize 2229e5c31af7Sopenharmony_ci -> std::tuple<VkDeviceSize, VkDeviceSize,VkDeviceSize,VkDeviceSize,VkDeviceSize> 2230e5c31af7Sopenharmony_ci{ 2231e5c31af7Sopenharmony_ci DE_ASSERT(!m_geometriesData.empty() != !(strSize == 0)); // logical xor 2232e5c31af7Sopenharmony_ci 2233e5c31af7Sopenharmony_ci std::tuple<VkDeviceSize,VkDeviceSize,VkDeviceSize,VkDeviceSize,VkDeviceSize> result(deAlign64(strSize, 256), 0, 0, 0, 0); 2234e5c31af7Sopenharmony_ci 2235e5c31af7Sopenharmony_ci if (!m_geometriesData.empty()) 2236e5c31af7Sopenharmony_ci { 2237e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR> accelerationStructureGeometriesKHR; 2238e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureGeometryKHR*> accelerationStructureGeometriesKHRPointers; 2239e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureBuildRangeInfoKHR> accelerationStructureBuildRangeInfoKHR; 2240e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureTrianglesOpacityMicromapEXT> accelerationStructureGeometryMicromapsEXT; 2241e5c31af7Sopenharmony_ci std::vector<deUint32> maxPrimitiveCounts; 2242e5c31af7Sopenharmony_ci prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, accelerationStructureGeometryMicromapsEXT, maxPrimitiveCounts); 2243e5c31af7Sopenharmony_ci 2244e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data(); 2245e5c31af7Sopenharmony_ci const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data(); 2246e5c31af7Sopenharmony_ci 2247e5c31af7Sopenharmony_ci VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = 2248e5c31af7Sopenharmony_ci { 2249e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; 2250e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2251e5c31af7Sopenharmony_ci VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; 2252e5c31af7Sopenharmony_ci m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; 2253e5c31af7Sopenharmony_ci VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode; 2254e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure; 2255e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure; 2256e5c31af7Sopenharmony_ci static_cast<deUint32>(accelerationStructureGeometriesKHR.size()), // deUint32 geometryCount; 2257e5c31af7Sopenharmony_ci m_useArrayOfPointers ? DE_NULL : accelerationStructureGeometriesKHRPointer, // const VkAccelerationStructureGeometryKHR* pGeometries; 2258e5c31af7Sopenharmony_ci m_useArrayOfPointers ? accelerationStructureGeometry : DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries; 2259e5c31af7Sopenharmony_ci makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData; 2260e5c31af7Sopenharmony_ci }; 2261e5c31af7Sopenharmony_ci 2262e5c31af7Sopenharmony_ci VkAccelerationStructureBuildSizesInfoKHR sizeInfo = 2263e5c31af7Sopenharmony_ci { 2264e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; 2265e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2266e5c31af7Sopenharmony_ci 0, // VkDeviceSize accelerationStructureSize; 2267e5c31af7Sopenharmony_ci 0, // VkDeviceSize updateScratchSize; 2268e5c31af7Sopenharmony_ci 0 // VkDeviceSize buildScratchSize; 2269e5c31af7Sopenharmony_ci }; 2270e5c31af7Sopenharmony_ci 2271e5c31af7Sopenharmony_ci vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo); 2272e5c31af7Sopenharmony_ci 2273e5c31af7Sopenharmony_ci std::get<0>(result) = sizeInfo.accelerationStructureSize; 2274e5c31af7Sopenharmony_ci std::get<1>(result) = sizeInfo.updateScratchSize; 2275e5c31af7Sopenharmony_ci std::get<2>(result) = sizeInfo.buildScratchSize; 2276e5c31af7Sopenharmony_ci std::get<3>(result) = getVertexBufferSize(m_geometriesData); 2277e5c31af7Sopenharmony_ci std::get<4>(result) = getIndexBufferSize(m_geometriesData); 2278e5c31af7Sopenharmony_ci } 2279e5c31af7Sopenharmony_ci 2280e5c31af7Sopenharmony_ci return result; 2281e5c31af7Sopenharmony_ci} 2282e5c31af7Sopenharmony_ci 2283e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePoolMember::preCreateSetSizesAndOffsets (const Info& info, 2284e5c31af7Sopenharmony_ci const VkDeviceSize accStrSize, 2285e5c31af7Sopenharmony_ci const VkDeviceSize updateScratchSize, 2286e5c31af7Sopenharmony_ci const VkDeviceSize buildScratchSize) 2287e5c31af7Sopenharmony_ci{ 2288e5c31af7Sopenharmony_ci m_info = info; 2289e5c31af7Sopenharmony_ci m_structureSize = accStrSize; 2290e5c31af7Sopenharmony_ci m_updateScratchSize = updateScratchSize; 2291e5c31af7Sopenharmony_ci m_buildScratchSize = buildScratchSize; 2292e5c31af7Sopenharmony_ci} 2293e5c31af7Sopenharmony_ci 2294e5c31af7Sopenharmony_civoid BottomLevelAccelerationStructurePoolMember::createAccellerationStructure (const DeviceInterface& vk, 2295e5c31af7Sopenharmony_ci const VkDevice device, 2296e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) 2297e5c31af7Sopenharmony_ci{ 2298e5c31af7Sopenharmony_ci const VkAccelerationStructureTypeKHR structureType = (m_createGeneric 2299e5c31af7Sopenharmony_ci ? VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 2300e5c31af7Sopenharmony_ci : VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR); 2301e5c31af7Sopenharmony_ci const VkAccelerationStructureCreateInfoKHR accelerationStructureCreateInfoKHR 2302e5c31af7Sopenharmony_ci { 2303e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType; 2304e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2305e5c31af7Sopenharmony_ci m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags; 2306e5c31af7Sopenharmony_ci getAccelerationStructureBuffer()->get(), // VkBuffer buffer; 2307e5c31af7Sopenharmony_ci getAccelerationStructureBufferOffset(), // VkDeviceSize offset; 2308e5c31af7Sopenharmony_ci m_structureSize, // VkDeviceSize size; 2309e5c31af7Sopenharmony_ci structureType, // VkAccelerationStructureTypeKHR type; 2310e5c31af7Sopenharmony_ci deviceAddress // VkDeviceAddress deviceAddress; 2311e5c31af7Sopenharmony_ci }; 2312e5c31af7Sopenharmony_ci 2313e5c31af7Sopenharmony_ci m_accelerationStructureKHR = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL); 2314e5c31af7Sopenharmony_ci} 2315e5c31af7Sopenharmony_ci 2316e5c31af7Sopenharmony_ciTopLevelAccelerationStructure::~TopLevelAccelerationStructure () 2317e5c31af7Sopenharmony_ci{ 2318e5c31af7Sopenharmony_ci} 2319e5c31af7Sopenharmony_ci 2320e5c31af7Sopenharmony_ciTopLevelAccelerationStructure::TopLevelAccelerationStructure () 2321e5c31af7Sopenharmony_ci : m_structureSize (0u) 2322e5c31af7Sopenharmony_ci , m_updateScratchSize (0u) 2323e5c31af7Sopenharmony_ci , m_buildScratchSize (0u) 2324e5c31af7Sopenharmony_ci{ 2325e5c31af7Sopenharmony_ci} 2326e5c31af7Sopenharmony_ci 2327e5c31af7Sopenharmony_civoid TopLevelAccelerationStructure::setInstanceCount (const size_t instanceCount) 2328e5c31af7Sopenharmony_ci{ 2329e5c31af7Sopenharmony_ci m_bottomLevelInstances.reserve(instanceCount); 2330e5c31af7Sopenharmony_ci m_instanceData.reserve(instanceCount); 2331e5c31af7Sopenharmony_ci} 2332e5c31af7Sopenharmony_ci 2333e5c31af7Sopenharmony_civoid TopLevelAccelerationStructure::addInstance (de::SharedPtr<BottomLevelAccelerationStructure> bottomLevelStructure, 2334e5c31af7Sopenharmony_ci const VkTransformMatrixKHR& matrix, 2335e5c31af7Sopenharmony_ci deUint32 instanceCustomIndex, 2336e5c31af7Sopenharmony_ci deUint32 mask, 2337e5c31af7Sopenharmony_ci deUint32 instanceShaderBindingTableRecordOffset, 2338e5c31af7Sopenharmony_ci VkGeometryInstanceFlagsKHR flags) 2339e5c31af7Sopenharmony_ci{ 2340e5c31af7Sopenharmony_ci m_bottomLevelInstances.push_back(bottomLevelStructure); 2341e5c31af7Sopenharmony_ci m_instanceData.push_back(InstanceData(matrix, instanceCustomIndex, mask, instanceShaderBindingTableRecordOffset, flags)); 2342e5c31af7Sopenharmony_ci} 2343e5c31af7Sopenharmony_ci 2344e5c31af7Sopenharmony_ciVkAccelerationStructureBuildSizesInfoKHR TopLevelAccelerationStructure::getStructureBuildSizes () const 2345e5c31af7Sopenharmony_ci{ 2346e5c31af7Sopenharmony_ci return 2347e5c31af7Sopenharmony_ci { 2348e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; 2349e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2350e5c31af7Sopenharmony_ci m_structureSize, // VkDeviceSize accelerationStructureSize; 2351e5c31af7Sopenharmony_ci m_updateScratchSize, // VkDeviceSize updateScratchSize; 2352e5c31af7Sopenharmony_ci m_buildScratchSize // VkDeviceSize buildScratchSize; 2353e5c31af7Sopenharmony_ci }; 2354e5c31af7Sopenharmony_ci} 2355e5c31af7Sopenharmony_ci 2356e5c31af7Sopenharmony_civoid TopLevelAccelerationStructure::createAndBuild (const DeviceInterface& vk, 2357e5c31af7Sopenharmony_ci const VkDevice device, 2358e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2359e5c31af7Sopenharmony_ci Allocator& allocator, 2360e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) 2361e5c31af7Sopenharmony_ci{ 2362e5c31af7Sopenharmony_ci create(vk, device, allocator, 0u, deviceAddress); 2363e5c31af7Sopenharmony_ci build(vk, device, cmdBuffer); 2364e5c31af7Sopenharmony_ci} 2365e5c31af7Sopenharmony_ci 2366e5c31af7Sopenharmony_civoid TopLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface& vk, 2367e5c31af7Sopenharmony_ci const VkDevice device, 2368e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2369e5c31af7Sopenharmony_ci Allocator& allocator, 2370e5c31af7Sopenharmony_ci TopLevelAccelerationStructure* accelerationStructure, 2371e5c31af7Sopenharmony_ci VkDeviceSize compactCopySize, 2372e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) 2373e5c31af7Sopenharmony_ci{ 2374e5c31af7Sopenharmony_ci DE_ASSERT(accelerationStructure != NULL); 2375e5c31af7Sopenharmony_ci VkDeviceSize copiedSize = compactCopySize > 0u ? compactCopySize : accelerationStructure->getStructureBuildSizes().accelerationStructureSize; 2376e5c31af7Sopenharmony_ci DE_ASSERT(copiedSize != 0u); 2377e5c31af7Sopenharmony_ci 2378e5c31af7Sopenharmony_ci create(vk, device, allocator, copiedSize, deviceAddress); 2379e5c31af7Sopenharmony_ci copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u); 2380e5c31af7Sopenharmony_ci} 2381e5c31af7Sopenharmony_ci 2382e5c31af7Sopenharmony_civoid TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk, 2383e5c31af7Sopenharmony_ci const VkDevice device, 2384e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2385e5c31af7Sopenharmony_ci Allocator& allocator, 2386e5c31af7Sopenharmony_ci SerialStorage* storage, 2387e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress) 2388e5c31af7Sopenharmony_ci{ 2389e5c31af7Sopenharmony_ci DE_ASSERT(storage != NULL); 2390e5c31af7Sopenharmony_ci DE_ASSERT(storage->getStorageSize() >= SerialStorage::SERIAL_STORAGE_SIZE_MIN); 2391e5c31af7Sopenharmony_ci create(vk, device, allocator, storage->getDeserializedSize(), deviceAddress); 2392e5c31af7Sopenharmony_ci if (storage->hasDeepFormat()) createAndDeserializeBottoms(vk, device, cmdBuffer, allocator, storage); 2393e5c31af7Sopenharmony_ci deserialize(vk, device, cmdBuffer, storage); 2394e5c31af7Sopenharmony_ci} 2395e5c31af7Sopenharmony_ci 2396e5c31af7Sopenharmony_ciBufferWithMemory* createInstanceBuffer (const DeviceInterface& vk, 2397e5c31af7Sopenharmony_ci const VkDevice device, 2398e5c31af7Sopenharmony_ci Allocator& allocator, 2399e5c31af7Sopenharmony_ci std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelInstances, 2400e5c31af7Sopenharmony_ci std::vector<InstanceData> instanceData, 2401e5c31af7Sopenharmony_ci const bool tryCachedMemory) 2402e5c31af7Sopenharmony_ci{ 2403e5c31af7Sopenharmony_ci DE_ASSERT(bottomLevelInstances.size() != 0); 2404e5c31af7Sopenharmony_ci DE_ASSERT(bottomLevelInstances.size() == instanceData.size()); 2405e5c31af7Sopenharmony_ci DE_UNREF(instanceData); 2406e5c31af7Sopenharmony_ci 2407e5c31af7Sopenharmony_ci BufferWithMemory* result = nullptr; 2408e5c31af7Sopenharmony_ci const VkDeviceSize bufferSizeBytes = bottomLevelInstances.size() * sizeof(VkAccelerationStructureInstanceKHR); 2409e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2410e5c31af7Sopenharmony_ci if (tryCachedMemory) try 2411e5c31af7Sopenharmony_ci { 2412e5c31af7Sopenharmony_ci result = new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); 2413e5c31af7Sopenharmony_ci } 2414e5c31af7Sopenharmony_ci catch (const tcu::NotSupportedError&) 2415e5c31af7Sopenharmony_ci { 2416e5c31af7Sopenharmony_ci result = nullptr; 2417e5c31af7Sopenharmony_ci } 2418e5c31af7Sopenharmony_ci return result 2419e5c31af7Sopenharmony_ci ? result 2420e5c31af7Sopenharmony_ci : new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); 2421e5c31af7Sopenharmony_ci} 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_civoid updateSingleInstance (const DeviceInterface& vk, 2424e5c31af7Sopenharmony_ci const VkDevice device, 2425e5c31af7Sopenharmony_ci const BottomLevelAccelerationStructure& bottomLevelAccelerationStructure, 2426e5c31af7Sopenharmony_ci const InstanceData& instanceData, 2427e5c31af7Sopenharmony_ci deUint8* bufferLocation, 2428e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR buildType, 2429e5c31af7Sopenharmony_ci bool inactiveInstances) 2430e5c31af7Sopenharmony_ci{ 2431e5c31af7Sopenharmony_ci const VkAccelerationStructureKHR accelerationStructureKHR = *bottomLevelAccelerationStructure.getPtr(); 2432e5c31af7Sopenharmony_ci 2433e5c31af7Sopenharmony_ci // This part needs to be fixed once a new version of the VkAccelerationStructureInstanceKHR will be added to vkStructTypes.inl 2434e5c31af7Sopenharmony_ci VkDeviceAddress accelerationStructureAddress; 2435e5c31af7Sopenharmony_ci if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2436e5c31af7Sopenharmony_ci { 2437e5c31af7Sopenharmony_ci VkAccelerationStructureDeviceAddressInfoKHR asDeviceAddressInfo = 2438e5c31af7Sopenharmony_ci { 2439e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType; 2440e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2441e5c31af7Sopenharmony_ci accelerationStructureKHR // VkAccelerationStructureKHR accelerationStructure; 2442e5c31af7Sopenharmony_ci }; 2443e5c31af7Sopenharmony_ci accelerationStructureAddress = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo); 2444e5c31af7Sopenharmony_ci } 2445e5c31af7Sopenharmony_ci 2446e5c31af7Sopenharmony_ci deUint64 structureReference; 2447e5c31af7Sopenharmony_ci if (inactiveInstances) 2448e5c31af7Sopenharmony_ci { 2449e5c31af7Sopenharmony_ci // Instances will be marked inactive by making their references VK_NULL_HANDLE or having address zero. 2450e5c31af7Sopenharmony_ci structureReference = 0ull; 2451e5c31af7Sopenharmony_ci } 2452e5c31af7Sopenharmony_ci else 2453e5c31af7Sopenharmony_ci { 2454e5c31af7Sopenharmony_ci structureReference = (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2455e5c31af7Sopenharmony_ci ? deUint64(accelerationStructureAddress) 2456e5c31af7Sopenharmony_ci : deUint64(accelerationStructureKHR.getInternal()); 2457e5c31af7Sopenharmony_ci } 2458e5c31af7Sopenharmony_ci 2459e5c31af7Sopenharmony_ci VkAccelerationStructureInstanceKHR accelerationStructureInstanceKHR = makeVkAccelerationStructureInstanceKHR 2460e5c31af7Sopenharmony_ci ( 2461e5c31af7Sopenharmony_ci instanceData.matrix, // VkTransformMatrixKHR transform; 2462e5c31af7Sopenharmony_ci instanceData.instanceCustomIndex, // deUint32 instanceCustomIndex:24; 2463e5c31af7Sopenharmony_ci instanceData.mask, // deUint32 mask:8; 2464e5c31af7Sopenharmony_ci instanceData.instanceShaderBindingTableRecordOffset, // deUint32 instanceShaderBindingTableRecordOffset:24; 2465e5c31af7Sopenharmony_ci instanceData.flags, // VkGeometryInstanceFlagsKHR flags:8; 2466e5c31af7Sopenharmony_ci structureReference // deUint64 accelerationStructureReference; 2467e5c31af7Sopenharmony_ci ); 2468e5c31af7Sopenharmony_ci 2469e5c31af7Sopenharmony_ci deMemcpy(bufferLocation, &accelerationStructureInstanceKHR, sizeof(VkAccelerationStructureInstanceKHR)); 2470e5c31af7Sopenharmony_ci} 2471e5c31af7Sopenharmony_ci 2472e5c31af7Sopenharmony_civoid updateInstanceBuffer (const DeviceInterface& vk, 2473e5c31af7Sopenharmony_ci const VkDevice device, 2474e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>& bottomLevelInstances, 2475e5c31af7Sopenharmony_ci const std::vector<InstanceData>& instanceData, 2476e5c31af7Sopenharmony_ci const BufferWithMemory* instanceBuffer, 2477e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR buildType, 2478e5c31af7Sopenharmony_ci bool inactiveInstances) 2479e5c31af7Sopenharmony_ci{ 2480e5c31af7Sopenharmony_ci DE_ASSERT(bottomLevelInstances.size() != 0); 2481e5c31af7Sopenharmony_ci DE_ASSERT(bottomLevelInstances.size() == instanceData.size()); 2482e5c31af7Sopenharmony_ci 2483e5c31af7Sopenharmony_ci auto& instancesAlloc = instanceBuffer->getAllocation(); 2484e5c31af7Sopenharmony_ci auto bufferStart = reinterpret_cast<deUint8*>(instancesAlloc.getHostPtr()); 2485e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0ull; 2486e5c31af7Sopenharmony_ci 2487e5c31af7Sopenharmony_ci for (size_t instanceNdx = 0; instanceNdx < bottomLevelInstances.size(); ++instanceNdx) 2488e5c31af7Sopenharmony_ci { 2489e5c31af7Sopenharmony_ci const auto& blas = *bottomLevelInstances[instanceNdx]; 2490e5c31af7Sopenharmony_ci updateSingleInstance(vk, device, blas, instanceData[instanceNdx], bufferStart + bufferOffset, buildType, inactiveInstances); 2491e5c31af7Sopenharmony_ci bufferOffset += sizeof(VkAccelerationStructureInstanceKHR); 2492e5c31af7Sopenharmony_ci } 2493e5c31af7Sopenharmony_ci 2494e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, instancesAlloc.getMemory(), instancesAlloc.getOffset(), VK_WHOLE_SIZE); 2495e5c31af7Sopenharmony_ci} 2496e5c31af7Sopenharmony_ci 2497e5c31af7Sopenharmony_ciclass TopLevelAccelerationStructureKHR : public TopLevelAccelerationStructure 2498e5c31af7Sopenharmony_ci{ 2499e5c31af7Sopenharmony_cipublic: 2500e5c31af7Sopenharmony_ci static deUint32 getRequiredAllocationCount (void); 2501e5c31af7Sopenharmony_ci 2502e5c31af7Sopenharmony_ci TopLevelAccelerationStructureKHR (); 2503e5c31af7Sopenharmony_ci TopLevelAccelerationStructureKHR (const TopLevelAccelerationStructureKHR& other) = delete; 2504e5c31af7Sopenharmony_ci virtual ~TopLevelAccelerationStructureKHR (); 2505e5c31af7Sopenharmony_ci 2506e5c31af7Sopenharmony_ci void setBuildType (const VkAccelerationStructureBuildTypeKHR buildType) override; 2507e5c31af7Sopenharmony_ci void setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags) override; 2508e5c31af7Sopenharmony_ci void setCreateGeneric (bool createGeneric) override; 2509e5c31af7Sopenharmony_ci void setCreationBufferUnbounded (bool creationBufferUnbounded) override; 2510e5c31af7Sopenharmony_ci void setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags) override; 2511e5c31af7Sopenharmony_ci void setBuildWithoutPrimitives (bool buildWithoutPrimitives) override; 2512e5c31af7Sopenharmony_ci void setInactiveInstances (bool inactiveInstances) override; 2513e5c31af7Sopenharmony_ci void setDeferredOperation (const bool deferredOperation, 2514e5c31af7Sopenharmony_ci const deUint32 workerThreadCount) override; 2515e5c31af7Sopenharmony_ci void setUseArrayOfPointers (const bool useArrayOfPointers) override; 2516e5c31af7Sopenharmony_ci void setIndirectBuildParameters (const VkBuffer indirectBuffer, 2517e5c31af7Sopenharmony_ci const VkDeviceSize indirectBufferOffset, 2518e5c31af7Sopenharmony_ci const deUint32 indirectBufferStride) override; 2519e5c31af7Sopenharmony_ci void setUsePPGeometries (const bool usePPGeometries) override; 2520e5c31af7Sopenharmony_ci void setTryCachedMemory (const bool tryCachedMemory) override; 2521e5c31af7Sopenharmony_ci VkBuildAccelerationStructureFlagsKHR getBuildFlags () const override; 2522e5c31af7Sopenharmony_ci 2523e5c31af7Sopenharmony_ci void getCreationSizes (const DeviceInterface& vk, 2524e5c31af7Sopenharmony_ci const VkDevice device, 2525e5c31af7Sopenharmony_ci const VkDeviceSize structureSize, 2526e5c31af7Sopenharmony_ci CreationSizes& sizes) override; 2527e5c31af7Sopenharmony_ci void create (const DeviceInterface& vk, 2528e5c31af7Sopenharmony_ci const VkDevice device, 2529e5c31af7Sopenharmony_ci Allocator& allocator, 2530e5c31af7Sopenharmony_ci VkDeviceSize structureSize, 2531e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress = 0u, 2532e5c31af7Sopenharmony_ci const void* pNext = DE_NULL, 2533e5c31af7Sopenharmony_ci const MemoryRequirement& addMemoryRequirement = MemoryRequirement::Any, 2534e5c31af7Sopenharmony_ci const VkBuffer creationBuffer = VK_NULL_HANDLE, 2535e5c31af7Sopenharmony_ci const VkDeviceSize creationBufferSize = 0u) override; 2536e5c31af7Sopenharmony_ci void build (const DeviceInterface& vk, 2537e5c31af7Sopenharmony_ci const VkDevice device, 2538e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2539e5c31af7Sopenharmony_ci TopLevelAccelerationStructure* srcAccelerationStructure = DE_NULL) override; 2540e5c31af7Sopenharmony_ci void copyFrom (const DeviceInterface& vk, 2541e5c31af7Sopenharmony_ci const VkDevice device, 2542e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2543e5c31af7Sopenharmony_ci TopLevelAccelerationStructure* accelerationStructure, 2544e5c31af7Sopenharmony_ci bool compactCopy) override; 2545e5c31af7Sopenharmony_ci void serialize (const DeviceInterface& vk, 2546e5c31af7Sopenharmony_ci const VkDevice device, 2547e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2548e5c31af7Sopenharmony_ci SerialStorage* storage) override; 2549e5c31af7Sopenharmony_ci void deserialize (const DeviceInterface& vk, 2550e5c31af7Sopenharmony_ci const VkDevice device, 2551e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2552e5c31af7Sopenharmony_ci SerialStorage* storage) override; 2553e5c31af7Sopenharmony_ci 2554e5c31af7Sopenharmony_ci std::vector<VkDeviceSize> getSerializingSizes (const DeviceInterface& vk, 2555e5c31af7Sopenharmony_ci const VkDevice device, 2556e5c31af7Sopenharmony_ci const VkQueue queue, 2557e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex) override; 2558e5c31af7Sopenharmony_ci 2559e5c31af7Sopenharmony_ci std::vector<deUint64> getSerializingAddresses (const DeviceInterface& vk, 2560e5c31af7Sopenharmony_ci const VkDevice device) const override; 2561e5c31af7Sopenharmony_ci 2562e5c31af7Sopenharmony_ci 2563e5c31af7Sopenharmony_ci const VkAccelerationStructureKHR* getPtr (void) const override; 2564e5c31af7Sopenharmony_ci 2565e5c31af7Sopenharmony_ci void updateInstanceMatrix (const DeviceInterface& vk, 2566e5c31af7Sopenharmony_ci const VkDevice device, 2567e5c31af7Sopenharmony_ci size_t instanceIndex, 2568e5c31af7Sopenharmony_ci const VkTransformMatrixKHR& matrix) override; 2569e5c31af7Sopenharmony_ci 2570e5c31af7Sopenharmony_ciprotected: 2571e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR m_buildType; 2572e5c31af7Sopenharmony_ci VkAccelerationStructureCreateFlagsKHR m_createFlags; 2573e5c31af7Sopenharmony_ci bool m_createGeneric; 2574e5c31af7Sopenharmony_ci bool m_creationBufferUnbounded; 2575e5c31af7Sopenharmony_ci VkBuildAccelerationStructureFlagsKHR m_buildFlags; 2576e5c31af7Sopenharmony_ci bool m_buildWithoutPrimitives; 2577e5c31af7Sopenharmony_ci bool m_inactiveInstances; 2578e5c31af7Sopenharmony_ci bool m_deferredOperation; 2579e5c31af7Sopenharmony_ci deUint32 m_workerThreadCount; 2580e5c31af7Sopenharmony_ci bool m_useArrayOfPointers; 2581e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_accelerationStructureBuffer; 2582e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_instanceBuffer; 2583e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_instanceAddressBuffer; 2584e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_deviceScratchBuffer; 2585e5c31af7Sopenharmony_ci std::vector<deUint8> m_hostScratchBuffer; 2586e5c31af7Sopenharmony_ci Move<VkAccelerationStructureKHR> m_accelerationStructureKHR; 2587e5c31af7Sopenharmony_ci VkBuffer m_indirectBuffer; 2588e5c31af7Sopenharmony_ci VkDeviceSize m_indirectBufferOffset; 2589e5c31af7Sopenharmony_ci deUint32 m_indirectBufferStride; 2590e5c31af7Sopenharmony_ci bool m_usePPGeometries; 2591e5c31af7Sopenharmony_ci bool m_tryCachedMemory; 2592e5c31af7Sopenharmony_ci 2593e5c31af7Sopenharmony_ci 2594e5c31af7Sopenharmony_ci void prepareInstances (const DeviceInterface& vk, 2595e5c31af7Sopenharmony_ci const VkDevice device, 2596e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryKHR& accelerationStructureGeometryKHR, 2597e5c31af7Sopenharmony_ci std::vector<deUint32>& maxPrimitiveCounts); 2598e5c31af7Sopenharmony_ci 2599e5c31af7Sopenharmony_ci void serializeBottoms (const DeviceInterface& vk, 2600e5c31af7Sopenharmony_ci const VkDevice device, 2601e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2602e5c31af7Sopenharmony_ci SerialStorage* storage, 2603e5c31af7Sopenharmony_ci VkDeferredOperationKHR deferredOperation); 2604e5c31af7Sopenharmony_ci 2605e5c31af7Sopenharmony_ci void createAndDeserializeBottoms (const DeviceInterface& vk, 2606e5c31af7Sopenharmony_ci const VkDevice device, 2607e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2608e5c31af7Sopenharmony_ci Allocator& allocator, 2609e5c31af7Sopenharmony_ci SerialStorage* storage) override; 2610e5c31af7Sopenharmony_ci}; 2611e5c31af7Sopenharmony_ci 2612e5c31af7Sopenharmony_cideUint32 TopLevelAccelerationStructureKHR::getRequiredAllocationCount (void) 2613e5c31af7Sopenharmony_ci{ 2614e5c31af7Sopenharmony_ci /* 2615e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_instanceBuffer; 2616e5c31af7Sopenharmony_ci de::MovePtr<Allocation> m_accelerationStructureAlloc; 2617e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_deviceScratchBuffer; 2618e5c31af7Sopenharmony_ci */ 2619e5c31af7Sopenharmony_ci return 3u; 2620e5c31af7Sopenharmony_ci} 2621e5c31af7Sopenharmony_ci 2622e5c31af7Sopenharmony_ciTopLevelAccelerationStructureKHR::TopLevelAccelerationStructureKHR () 2623e5c31af7Sopenharmony_ci : TopLevelAccelerationStructure () 2624e5c31af7Sopenharmony_ci , m_buildType (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2625e5c31af7Sopenharmony_ci , m_createFlags (0u) 2626e5c31af7Sopenharmony_ci , m_createGeneric (false) 2627e5c31af7Sopenharmony_ci , m_creationBufferUnbounded (false) 2628e5c31af7Sopenharmony_ci , m_buildFlags (0u) 2629e5c31af7Sopenharmony_ci , m_buildWithoutPrimitives (false) 2630e5c31af7Sopenharmony_ci , m_inactiveInstances (false) 2631e5c31af7Sopenharmony_ci , m_deferredOperation (false) 2632e5c31af7Sopenharmony_ci , m_workerThreadCount (0) 2633e5c31af7Sopenharmony_ci , m_useArrayOfPointers (false) 2634e5c31af7Sopenharmony_ci , m_accelerationStructureBuffer (DE_NULL) 2635e5c31af7Sopenharmony_ci , m_instanceBuffer (DE_NULL) 2636e5c31af7Sopenharmony_ci , m_instanceAddressBuffer (DE_NULL) 2637e5c31af7Sopenharmony_ci , m_deviceScratchBuffer (DE_NULL) 2638e5c31af7Sopenharmony_ci , m_accelerationStructureKHR () 2639e5c31af7Sopenharmony_ci , m_indirectBuffer (DE_NULL) 2640e5c31af7Sopenharmony_ci , m_indirectBufferOffset (0) 2641e5c31af7Sopenharmony_ci , m_indirectBufferStride (0) 2642e5c31af7Sopenharmony_ci , m_usePPGeometries (false) 2643e5c31af7Sopenharmony_ci , m_tryCachedMemory (true) 2644e5c31af7Sopenharmony_ci{ 2645e5c31af7Sopenharmony_ci} 2646e5c31af7Sopenharmony_ci 2647e5c31af7Sopenharmony_ciTopLevelAccelerationStructureKHR::~TopLevelAccelerationStructureKHR () 2648e5c31af7Sopenharmony_ci{ 2649e5c31af7Sopenharmony_ci} 2650e5c31af7Sopenharmony_ci 2651e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR buildType) 2652e5c31af7Sopenharmony_ci{ 2653e5c31af7Sopenharmony_ci m_buildType = buildType; 2654e5c31af7Sopenharmony_ci} 2655e5c31af7Sopenharmony_ci 2656e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags) 2657e5c31af7Sopenharmony_ci{ 2658e5c31af7Sopenharmony_ci m_createFlags = createFlags; 2659e5c31af7Sopenharmony_ci} 2660e5c31af7Sopenharmony_ci 2661e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setCreateGeneric (bool createGeneric) 2662e5c31af7Sopenharmony_ci{ 2663e5c31af7Sopenharmony_ci m_createGeneric = createGeneric; 2664e5c31af7Sopenharmony_ci} 2665e5c31af7Sopenharmony_ci 2666e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setCreationBufferUnbounded (bool creationBufferUnbounded) 2667e5c31af7Sopenharmony_ci{ 2668e5c31af7Sopenharmony_ci m_creationBufferUnbounded = creationBufferUnbounded; 2669e5c31af7Sopenharmony_ci} 2670e5c31af7Sopenharmony_ci 2671e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setInactiveInstances (bool inactiveInstances) 2672e5c31af7Sopenharmony_ci{ 2673e5c31af7Sopenharmony_ci m_inactiveInstances = inactiveInstances; 2674e5c31af7Sopenharmony_ci} 2675e5c31af7Sopenharmony_ci 2676e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags) 2677e5c31af7Sopenharmony_ci{ 2678e5c31af7Sopenharmony_ci m_buildFlags = buildFlags; 2679e5c31af7Sopenharmony_ci} 2680e5c31af7Sopenharmony_ci 2681e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setBuildWithoutPrimitives (bool buildWithoutPrimitives) 2682e5c31af7Sopenharmony_ci{ 2683e5c31af7Sopenharmony_ci m_buildWithoutPrimitives = buildWithoutPrimitives; 2684e5c31af7Sopenharmony_ci} 2685e5c31af7Sopenharmony_ci 2686e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setDeferredOperation (const bool deferredOperation, 2687e5c31af7Sopenharmony_ci const deUint32 workerThreadCount) 2688e5c31af7Sopenharmony_ci{ 2689e5c31af7Sopenharmony_ci m_deferredOperation = deferredOperation; 2690e5c31af7Sopenharmony_ci m_workerThreadCount = workerThreadCount; 2691e5c31af7Sopenharmony_ci} 2692e5c31af7Sopenharmony_ci 2693e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool useArrayOfPointers) 2694e5c31af7Sopenharmony_ci{ 2695e5c31af7Sopenharmony_ci m_useArrayOfPointers = useArrayOfPointers; 2696e5c31af7Sopenharmony_ci} 2697e5c31af7Sopenharmony_ci 2698e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setUsePPGeometries (const bool usePPGeometries) 2699e5c31af7Sopenharmony_ci{ 2700e5c31af7Sopenharmony_ci m_usePPGeometries = usePPGeometries; 2701e5c31af7Sopenharmony_ci} 2702e5c31af7Sopenharmony_ci 2703e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setTryCachedMemory (const bool tryCachedMemory) 2704e5c31af7Sopenharmony_ci{ 2705e5c31af7Sopenharmony_ci m_tryCachedMemory = tryCachedMemory; 2706e5c31af7Sopenharmony_ci} 2707e5c31af7Sopenharmony_ci 2708e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer indirectBuffer, 2709e5c31af7Sopenharmony_ci const VkDeviceSize indirectBufferOffset, 2710e5c31af7Sopenharmony_ci const deUint32 indirectBufferStride) 2711e5c31af7Sopenharmony_ci{ 2712e5c31af7Sopenharmony_ci m_indirectBuffer = indirectBuffer; 2713e5c31af7Sopenharmony_ci m_indirectBufferOffset = indirectBufferOffset; 2714e5c31af7Sopenharmony_ci m_indirectBufferStride = indirectBufferStride; 2715e5c31af7Sopenharmony_ci} 2716e5c31af7Sopenharmony_ci 2717e5c31af7Sopenharmony_ciVkBuildAccelerationStructureFlagsKHR TopLevelAccelerationStructureKHR::getBuildFlags () const 2718e5c31af7Sopenharmony_ci{ 2719e5c31af7Sopenharmony_ci return m_buildFlags; 2720e5c31af7Sopenharmony_ci} 2721e5c31af7Sopenharmony_ci 2722e5c31af7Sopenharmony_ciVkDeviceSize TopLevelAccelerationStructure::CreationSizes::sum () const 2723e5c31af7Sopenharmony_ci{ 2724e5c31af7Sopenharmony_ci return structure + updateScratch + buildScratch + instancePointers + instancesBuffer; 2725e5c31af7Sopenharmony_ci} 2726e5c31af7Sopenharmony_ci 2727e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::getCreationSizes (const DeviceInterface& vk, 2728e5c31af7Sopenharmony_ci const VkDevice device, 2729e5c31af7Sopenharmony_ci const VkDeviceSize structureSize, 2730e5c31af7Sopenharmony_ci CreationSizes& sizes) 2731e5c31af7Sopenharmony_ci{ 2732e5c31af7Sopenharmony_ci // AS may be built from geometries using vkCmdBuildAccelerationStructureKHR / vkBuildAccelerationStructureKHR 2733e5c31af7Sopenharmony_ci // or may be copied/compacted/deserialized from other AS ( in this case AS does not need geometries, but it needs to know its size before creation ). 2734e5c31af7Sopenharmony_ci DE_ASSERT(!m_bottomLevelInstances.empty() != !(structureSize == 0)); // logical xor 2735e5c31af7Sopenharmony_ci 2736e5c31af7Sopenharmony_ci if (structureSize == 0) 2737e5c31af7Sopenharmony_ci { 2738e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR; 2739e5c31af7Sopenharmony_ci const auto accelerationStructureGeometryKHRPtr = &accelerationStructureGeometryKHR; 2740e5c31af7Sopenharmony_ci std::vector<deUint32> maxPrimitiveCounts; 2741e5c31af7Sopenharmony_ci prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts); 2742e5c31af7Sopenharmony_ci 2743e5c31af7Sopenharmony_ci VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = 2744e5c31af7Sopenharmony_ci { 2745e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; 2746e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2747e5c31af7Sopenharmony_ci VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; 2748e5c31af7Sopenharmony_ci m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; 2749e5c31af7Sopenharmony_ci VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode; 2750e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure; 2751e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure; 2752e5c31af7Sopenharmony_ci 1u, // deUint32 geometryCount; 2753e5c31af7Sopenharmony_ci (m_usePPGeometries ? nullptr : &accelerationStructureGeometryKHR), // const VkAccelerationStructureGeometryKHR* pGeometries; 2754e5c31af7Sopenharmony_ci (m_usePPGeometries ? &accelerationStructureGeometryKHRPtr : nullptr), // const VkAccelerationStructureGeometryKHR* const* ppGeometries; 2755e5c31af7Sopenharmony_ci makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData; 2756e5c31af7Sopenharmony_ci }; 2757e5c31af7Sopenharmony_ci 2758e5c31af7Sopenharmony_ci VkAccelerationStructureBuildSizesInfoKHR sizeInfo = 2759e5c31af7Sopenharmony_ci { 2760e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; 2761e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2762e5c31af7Sopenharmony_ci 0, // VkDeviceSize accelerationStructureSize; 2763e5c31af7Sopenharmony_ci 0, // VkDeviceSize updateScratchSize; 2764e5c31af7Sopenharmony_ci 0 // VkDeviceSize buildScratchSize; 2765e5c31af7Sopenharmony_ci }; 2766e5c31af7Sopenharmony_ci 2767e5c31af7Sopenharmony_ci vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo); 2768e5c31af7Sopenharmony_ci 2769e5c31af7Sopenharmony_ci sizes.structure = sizeInfo.accelerationStructureSize; 2770e5c31af7Sopenharmony_ci sizes.updateScratch = sizeInfo.updateScratchSize; 2771e5c31af7Sopenharmony_ci sizes.buildScratch = sizeInfo.buildScratchSize; 2772e5c31af7Sopenharmony_ci } 2773e5c31af7Sopenharmony_ci else 2774e5c31af7Sopenharmony_ci { 2775e5c31af7Sopenharmony_ci sizes.structure = structureSize; 2776e5c31af7Sopenharmony_ci sizes.updateScratch = 0u; 2777e5c31af7Sopenharmony_ci sizes.buildScratch = 0u; 2778e5c31af7Sopenharmony_ci } 2779e5c31af7Sopenharmony_ci 2780e5c31af7Sopenharmony_ci sizes.instancePointers = 0u; 2781e5c31af7Sopenharmony_ci if (m_useArrayOfPointers) 2782e5c31af7Sopenharmony_ci { 2783e5c31af7Sopenharmony_ci const size_t pointerSize = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) ? sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress) : sizeof(VkDeviceOrHostAddressConstKHR::hostAddress); 2784e5c31af7Sopenharmony_ci sizes.instancePointers = static_cast<VkDeviceSize>(m_bottomLevelInstances.size() * pointerSize); 2785e5c31af7Sopenharmony_ci } 2786e5c31af7Sopenharmony_ci 2787e5c31af7Sopenharmony_ci sizes.instancesBuffer = m_bottomLevelInstances.empty() ? 0u : m_bottomLevelInstances.size() * sizeof(VkAccelerationStructureInstanceKHR); 2788e5c31af7Sopenharmony_ci} 2789e5c31af7Sopenharmony_ci 2790e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::create (const DeviceInterface& vk, 2791e5c31af7Sopenharmony_ci const VkDevice device, 2792e5c31af7Sopenharmony_ci Allocator& allocator, 2793e5c31af7Sopenharmony_ci VkDeviceSize structureSize, 2794e5c31af7Sopenharmony_ci VkDeviceAddress deviceAddress, 2795e5c31af7Sopenharmony_ci const void* pNext, 2796e5c31af7Sopenharmony_ci const MemoryRequirement& addMemoryRequirement, 2797e5c31af7Sopenharmony_ci const VkBuffer creationBuffer, 2798e5c31af7Sopenharmony_ci const VkDeviceSize creationBufferSize) 2799e5c31af7Sopenharmony_ci{ 2800e5c31af7Sopenharmony_ci // AS may be built from geometries using vkCmdBuildAccelerationStructureKHR / vkBuildAccelerationStructureKHR 2801e5c31af7Sopenharmony_ci // or may be copied/compacted/deserialized from other AS ( in this case AS does not need geometries, but it needs to know its size before creation ). 2802e5c31af7Sopenharmony_ci DE_ASSERT(!m_bottomLevelInstances.empty() != !(structureSize == 0)); // logical xor 2803e5c31af7Sopenharmony_ci 2804e5c31af7Sopenharmony_ci if (structureSize == 0) 2805e5c31af7Sopenharmony_ci { 2806e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR; 2807e5c31af7Sopenharmony_ci const auto accelerationStructureGeometryKHRPtr = &accelerationStructureGeometryKHR; 2808e5c31af7Sopenharmony_ci std::vector<deUint32> maxPrimitiveCounts; 2809e5c31af7Sopenharmony_ci prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts); 2810e5c31af7Sopenharmony_ci 2811e5c31af7Sopenharmony_ci VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = 2812e5c31af7Sopenharmony_ci { 2813e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; 2814e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2815e5c31af7Sopenharmony_ci VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; 2816e5c31af7Sopenharmony_ci m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; 2817e5c31af7Sopenharmony_ci VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode; 2818e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure; 2819e5c31af7Sopenharmony_ci DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure; 2820e5c31af7Sopenharmony_ci 1u, // deUint32 geometryCount; 2821e5c31af7Sopenharmony_ci (m_usePPGeometries ? nullptr : &accelerationStructureGeometryKHR), // const VkAccelerationStructureGeometryKHR* pGeometries; 2822e5c31af7Sopenharmony_ci (m_usePPGeometries ? &accelerationStructureGeometryKHRPtr : nullptr), // const VkAccelerationStructureGeometryKHR* const* ppGeometries; 2823e5c31af7Sopenharmony_ci makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData; 2824e5c31af7Sopenharmony_ci }; 2825e5c31af7Sopenharmony_ci 2826e5c31af7Sopenharmony_ci VkAccelerationStructureBuildSizesInfoKHR sizeInfo = 2827e5c31af7Sopenharmony_ci { 2828e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; 2829e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2830e5c31af7Sopenharmony_ci 0, // VkDeviceSize accelerationStructureSize; 2831e5c31af7Sopenharmony_ci 0, // VkDeviceSize updateScratchSize; 2832e5c31af7Sopenharmony_ci 0 // VkDeviceSize buildScratchSize; 2833e5c31af7Sopenharmony_ci }; 2834e5c31af7Sopenharmony_ci 2835e5c31af7Sopenharmony_ci vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo); 2836e5c31af7Sopenharmony_ci 2837e5c31af7Sopenharmony_ci m_structureSize = sizeInfo.accelerationStructureSize; 2838e5c31af7Sopenharmony_ci m_updateScratchSize = sizeInfo.updateScratchSize; 2839e5c31af7Sopenharmony_ci m_buildScratchSize = sizeInfo.buildScratchSize; 2840e5c31af7Sopenharmony_ci } 2841e5c31af7Sopenharmony_ci else 2842e5c31af7Sopenharmony_ci { 2843e5c31af7Sopenharmony_ci m_structureSize = structureSize; 2844e5c31af7Sopenharmony_ci m_updateScratchSize = 0u; 2845e5c31af7Sopenharmony_ci m_buildScratchSize = 0u; 2846e5c31af7Sopenharmony_ci } 2847e5c31af7Sopenharmony_ci 2848e5c31af7Sopenharmony_ci const bool externalCreationBuffer = (creationBuffer != VK_NULL_HANDLE); 2849e5c31af7Sopenharmony_ci 2850e5c31af7Sopenharmony_ci if (externalCreationBuffer) 2851e5c31af7Sopenharmony_ci { 2852e5c31af7Sopenharmony_ci DE_UNREF(creationBufferSize); // For release builds. 2853e5c31af7Sopenharmony_ci DE_ASSERT(creationBufferSize >= m_structureSize); 2854e5c31af7Sopenharmony_ci } 2855e5c31af7Sopenharmony_ci 2856e5c31af7Sopenharmony_ci if (!externalCreationBuffer) 2857e5c31af7Sopenharmony_ci { 2858e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_structureSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2859e5c31af7Sopenharmony_ci const MemoryRequirement memoryRequirement = addMemoryRequirement | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress; 2860e5c31af7Sopenharmony_ci const bool bindMemOnCreation = (!m_creationBufferUnbounded); 2861e5c31af7Sopenharmony_ci 2862e5c31af7Sopenharmony_ci try 2863e5c31af7Sopenharmony_ci { 2864e5c31af7Sopenharmony_ci m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, (MemoryRequirement::Cached | memoryRequirement), bindMemOnCreation)); 2865e5c31af7Sopenharmony_ci } 2866e5c31af7Sopenharmony_ci catch (const tcu::NotSupportedError&) 2867e5c31af7Sopenharmony_ci { 2868e5c31af7Sopenharmony_ci // retry without Cached flag 2869e5c31af7Sopenharmony_ci m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, memoryRequirement, bindMemOnCreation)); 2870e5c31af7Sopenharmony_ci } 2871e5c31af7Sopenharmony_ci } 2872e5c31af7Sopenharmony_ci 2873e5c31af7Sopenharmony_ci const auto createInfoBuffer = (externalCreationBuffer ? creationBuffer : m_accelerationStructureBuffer->get()); 2874e5c31af7Sopenharmony_ci { 2875e5c31af7Sopenharmony_ci const VkAccelerationStructureTypeKHR structureType = (m_createGeneric 2876e5c31af7Sopenharmony_ci ? VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR 2877e5c31af7Sopenharmony_ci : VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR); 2878e5c31af7Sopenharmony_ci const VkAccelerationStructureCreateInfoKHR accelerationStructureCreateInfoKHR = 2879e5c31af7Sopenharmony_ci { 2880e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType; 2881e5c31af7Sopenharmony_ci pNext, // const void* pNext; 2882e5c31af7Sopenharmony_ci m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags; 2883e5c31af7Sopenharmony_ci createInfoBuffer, // VkBuffer buffer; 2884e5c31af7Sopenharmony_ci 0u, // VkDeviceSize offset; 2885e5c31af7Sopenharmony_ci m_structureSize, // VkDeviceSize size; 2886e5c31af7Sopenharmony_ci structureType, // VkAccelerationStructureTypeKHR type; 2887e5c31af7Sopenharmony_ci deviceAddress // VkDeviceAddress deviceAddress; 2888e5c31af7Sopenharmony_ci }; 2889e5c31af7Sopenharmony_ci 2890e5c31af7Sopenharmony_ci m_accelerationStructureKHR = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL); 2891e5c31af7Sopenharmony_ci 2892e5c31af7Sopenharmony_ci // Make sure buffer memory is always bound after creation. 2893e5c31af7Sopenharmony_ci if (!externalCreationBuffer) 2894e5c31af7Sopenharmony_ci m_accelerationStructureBuffer->bindMemory(); 2895e5c31af7Sopenharmony_ci } 2896e5c31af7Sopenharmony_ci 2897e5c31af7Sopenharmony_ci if (m_buildScratchSize > 0u) 2898e5c31af7Sopenharmony_ci { 2899e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2900e5c31af7Sopenharmony_ci { 2901e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_buildScratchSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2902e5c31af7Sopenharmony_ci m_deviceScratchBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 2903e5c31af7Sopenharmony_ci } 2904e5c31af7Sopenharmony_ci else 2905e5c31af7Sopenharmony_ci { 2906e5c31af7Sopenharmony_ci m_hostScratchBuffer.resize(static_cast<size_t>(m_buildScratchSize)); 2907e5c31af7Sopenharmony_ci } 2908e5c31af7Sopenharmony_ci } 2909e5c31af7Sopenharmony_ci 2910e5c31af7Sopenharmony_ci if (m_useArrayOfPointers) 2911e5c31af7Sopenharmony_ci { 2912e5c31af7Sopenharmony_ci const size_t pointerSize = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) ? sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress) : sizeof(VkDeviceOrHostAddressConstKHR::hostAddress); 2913e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(static_cast<VkDeviceSize>(m_bottomLevelInstances.size() * pointerSize), VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2914e5c31af7Sopenharmony_ci m_instanceAddressBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress)); 2915e5c31af7Sopenharmony_ci } 2916e5c31af7Sopenharmony_ci 2917e5c31af7Sopenharmony_ci if(!m_bottomLevelInstances.empty()) 2918e5c31af7Sopenharmony_ci m_instanceBuffer = de::MovePtr<BufferWithMemory>(createInstanceBuffer(vk, device, allocator, m_bottomLevelInstances, m_instanceData, m_tryCachedMemory)); 2919e5c31af7Sopenharmony_ci} 2920e5c31af7Sopenharmony_ci 2921e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::updateInstanceMatrix (const DeviceInterface& vk, const VkDevice device, size_t instanceIndex, const VkTransformMatrixKHR& matrix) 2922e5c31af7Sopenharmony_ci{ 2923e5c31af7Sopenharmony_ci DE_ASSERT(instanceIndex < m_bottomLevelInstances.size()); 2924e5c31af7Sopenharmony_ci DE_ASSERT(instanceIndex < m_instanceData.size()); 2925e5c31af7Sopenharmony_ci 2926e5c31af7Sopenharmony_ci const auto& blas = *m_bottomLevelInstances[instanceIndex]; 2927e5c31af7Sopenharmony_ci auto& instanceData = m_instanceData[instanceIndex]; 2928e5c31af7Sopenharmony_ci auto& instancesAlloc = m_instanceBuffer->getAllocation(); 2929e5c31af7Sopenharmony_ci auto bufferStart = reinterpret_cast<deUint8*>(instancesAlloc.getHostPtr()); 2930e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = sizeof(VkAccelerationStructureInstanceKHR) * instanceIndex; 2931e5c31af7Sopenharmony_ci 2932e5c31af7Sopenharmony_ci instanceData.matrix = matrix; 2933e5c31af7Sopenharmony_ci updateSingleInstance(vk, device, blas, instanceData, bufferStart + bufferOffset, m_buildType, m_inactiveInstances); 2934e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, instancesAlloc.getMemory(), instancesAlloc.getOffset(), VK_WHOLE_SIZE); 2935e5c31af7Sopenharmony_ci} 2936e5c31af7Sopenharmony_ci 2937e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::build (const DeviceInterface& vk, 2938e5c31af7Sopenharmony_ci const VkDevice device, 2939e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 2940e5c31af7Sopenharmony_ci TopLevelAccelerationStructure* srcAccelerationStructure) 2941e5c31af7Sopenharmony_ci{ 2942e5c31af7Sopenharmony_ci DE_ASSERT(!m_bottomLevelInstances.empty()); 2943e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 2944e5c31af7Sopenharmony_ci DE_ASSERT(m_buildScratchSize != 0); 2945e5c31af7Sopenharmony_ci 2946e5c31af7Sopenharmony_ci updateInstanceBuffer(vk, device, m_bottomLevelInstances, m_instanceData, m_instanceBuffer.get(), m_buildType, m_inactiveInstances); 2947e5c31af7Sopenharmony_ci 2948e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR; 2949e5c31af7Sopenharmony_ci const auto accelerationStructureGeometryKHRPtr = &accelerationStructureGeometryKHR; 2950e5c31af7Sopenharmony_ci std::vector<deUint32> maxPrimitiveCounts; 2951e5c31af7Sopenharmony_ci prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts); 2952e5c31af7Sopenharmony_ci 2953e5c31af7Sopenharmony_ci VkDeviceOrHostAddressKHR scratchData = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2954e5c31af7Sopenharmony_ci ? makeDeviceOrHostAddressKHR(vk, device, m_deviceScratchBuffer->get(), 0) 2955e5c31af7Sopenharmony_ci : makeDeviceOrHostAddressKHR(m_hostScratchBuffer.data()); 2956e5c31af7Sopenharmony_ci 2957e5c31af7Sopenharmony_ci VkAccelerationStructureKHR srcStructure = (srcAccelerationStructure != DE_NULL) ? *(srcAccelerationStructure->getPtr()) : DE_NULL; 2958e5c31af7Sopenharmony_ci VkBuildAccelerationStructureModeKHR mode = (srcAccelerationStructure != DE_NULL) ? VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR : VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; 2959e5c31af7Sopenharmony_ci 2960e5c31af7Sopenharmony_ci VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = 2961e5c31af7Sopenharmony_ci { 2962e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; 2963e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2964e5c31af7Sopenharmony_ci VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; 2965e5c31af7Sopenharmony_ci m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; 2966e5c31af7Sopenharmony_ci mode, // VkBuildAccelerationStructureModeKHR mode; 2967e5c31af7Sopenharmony_ci srcStructure, // VkAccelerationStructureKHR srcAccelerationStructure; 2968e5c31af7Sopenharmony_ci m_accelerationStructureKHR.get(), // VkAccelerationStructureKHR dstAccelerationStructure; 2969e5c31af7Sopenharmony_ci 1u, // deUint32 geometryCount; 2970e5c31af7Sopenharmony_ci (m_usePPGeometries ? nullptr : &accelerationStructureGeometryKHR), // const VkAccelerationStructureGeometryKHR* pGeometries; 2971e5c31af7Sopenharmony_ci (m_usePPGeometries ? &accelerationStructureGeometryKHRPtr : nullptr), // const VkAccelerationStructureGeometryKHR* const* ppGeometries; 2972e5c31af7Sopenharmony_ci scratchData // VkDeviceOrHostAddressKHR scratchData; 2973e5c31af7Sopenharmony_ci }; 2974e5c31af7Sopenharmony_ci 2975e5c31af7Sopenharmony_ci const deUint32 primitiveCount = (m_buildWithoutPrimitives ? 0u : static_cast<deUint32>(m_bottomLevelInstances.size())); 2976e5c31af7Sopenharmony_ci 2977e5c31af7Sopenharmony_ci VkAccelerationStructureBuildRangeInfoKHR accelerationStructureBuildRangeInfoKHR = 2978e5c31af7Sopenharmony_ci { 2979e5c31af7Sopenharmony_ci primitiveCount, // deUint32 primitiveCount; 2980e5c31af7Sopenharmony_ci 0, // deUint32 primitiveOffset; 2981e5c31af7Sopenharmony_ci 0, // deUint32 firstVertex; 2982e5c31af7Sopenharmony_ci 0 // deUint32 transformOffset; 2983e5c31af7Sopenharmony_ci }; 2984e5c31af7Sopenharmony_ci VkAccelerationStructureBuildRangeInfoKHR* accelerationStructureBuildRangeInfoKHRPtr = &accelerationStructureBuildRangeInfoKHR; 2985e5c31af7Sopenharmony_ci 2986e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2987e5c31af7Sopenharmony_ci { 2988e5c31af7Sopenharmony_ci if (m_indirectBuffer == DE_NULL) 2989e5c31af7Sopenharmony_ci vk.cmdBuildAccelerationStructuresKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr); 2990e5c31af7Sopenharmony_ci else 2991e5c31af7Sopenharmony_ci { 2992e5c31af7Sopenharmony_ci VkDeviceAddress indirectDeviceAddress = getBufferDeviceAddress(vk, device, m_indirectBuffer, m_indirectBufferOffset); 2993e5c31af7Sopenharmony_ci deUint32* pMaxPrimitiveCounts = maxPrimitiveCounts.data(); 2994e5c31af7Sopenharmony_ci vk.cmdBuildAccelerationStructuresIndirectKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, &indirectDeviceAddress, &m_indirectBufferStride, &pMaxPrimitiveCounts); 2995e5c31af7Sopenharmony_ci } 2996e5c31af7Sopenharmony_ci } 2997e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 2998e5c31af7Sopenharmony_ci { 2999e5c31af7Sopenharmony_ci VK_CHECK(vk.buildAccelerationStructuresKHR(device, DE_NULL, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr)); 3000e5c31af7Sopenharmony_ci } 3001e5c31af7Sopenharmony_ci else 3002e5c31af7Sopenharmony_ci { 3003e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 3004e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 3005e5c31af7Sopenharmony_ci 3006e5c31af7Sopenharmony_ci VkResult result = vk.buildAccelerationStructuresKHR(device, deferredOperation, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr); 3007e5c31af7Sopenharmony_ci 3008e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 3009e5c31af7Sopenharmony_ci 3010e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 3011e5c31af7Sopenharmony_ci 3012e5c31af7Sopenharmony_ci accelerationStructureBuildGeometryInfoKHR.pNext = DE_NULL; 3013e5c31af7Sopenharmony_ci } 3014e5c31af7Sopenharmony_ci 3015e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3016e5c31af7Sopenharmony_ci { 3017e5c31af7Sopenharmony_ci const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; 3018e5c31af7Sopenharmony_ci const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks); 3019e5c31af7Sopenharmony_ci 3020e5c31af7Sopenharmony_ci cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier); 3021e5c31af7Sopenharmony_ci } 3022e5c31af7Sopenharmony_ci} 3023e5c31af7Sopenharmony_ci 3024e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::copyFrom (const DeviceInterface& vk, 3025e5c31af7Sopenharmony_ci const VkDevice device, 3026e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3027e5c31af7Sopenharmony_ci TopLevelAccelerationStructure* accelerationStructure, 3028e5c31af7Sopenharmony_ci bool compactCopy) 3029e5c31af7Sopenharmony_ci{ 3030e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 3031e5c31af7Sopenharmony_ci DE_ASSERT(accelerationStructure != DE_NULL); 3032e5c31af7Sopenharmony_ci 3033e5c31af7Sopenharmony_ci VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo = 3034e5c31af7Sopenharmony_ci { 3035e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType; 3036e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3037e5c31af7Sopenharmony_ci *(accelerationStructure->getPtr()), // VkAccelerationStructureKHR src; 3038e5c31af7Sopenharmony_ci *(getPtr()), // VkAccelerationStructureKHR dst; 3039e5c31af7Sopenharmony_ci compactCopy ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR // VkCopyAccelerationStructureModeKHR mode; 3040e5c31af7Sopenharmony_ci }; 3041e5c31af7Sopenharmony_ci 3042e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3043e5c31af7Sopenharmony_ci { 3044e5c31af7Sopenharmony_ci vk.cmdCopyAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo); 3045e5c31af7Sopenharmony_ci } 3046e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 3047e5c31af7Sopenharmony_ci { 3048e5c31af7Sopenharmony_ci VK_CHECK(vk.copyAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo)); 3049e5c31af7Sopenharmony_ci } 3050e5c31af7Sopenharmony_ci else 3051e5c31af7Sopenharmony_ci { 3052e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 3053e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 3054e5c31af7Sopenharmony_ci 3055e5c31af7Sopenharmony_ci VkResult result = vk.copyAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo); 3056e5c31af7Sopenharmony_ci 3057e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 3058e5c31af7Sopenharmony_ci 3059e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 3060e5c31af7Sopenharmony_ci } 3061e5c31af7Sopenharmony_ci 3062e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3063e5c31af7Sopenharmony_ci { 3064e5c31af7Sopenharmony_ci const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; 3065e5c31af7Sopenharmony_ci const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks); 3066e5c31af7Sopenharmony_ci 3067e5c31af7Sopenharmony_ci cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier); 3068e5c31af7Sopenharmony_ci } 3069e5c31af7Sopenharmony_ci 3070e5c31af7Sopenharmony_ci} 3071e5c31af7Sopenharmony_ci 3072e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::serialize (const DeviceInterface& vk, 3073e5c31af7Sopenharmony_ci const VkDevice device, 3074e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3075e5c31af7Sopenharmony_ci SerialStorage* storage) 3076e5c31af7Sopenharmony_ci{ 3077e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 3078e5c31af7Sopenharmony_ci DE_ASSERT(storage != DE_NULL); 3079e5c31af7Sopenharmony_ci 3080e5c31af7Sopenharmony_ci const VkCopyAccelerationStructureToMemoryInfoKHR copyAccelerationStructureInfo = 3081e5c31af7Sopenharmony_ci { 3082e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR, // VkStructureType sType; 3083e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3084e5c31af7Sopenharmony_ci *(getPtr()), // VkAccelerationStructureKHR src; 3085e5c31af7Sopenharmony_ci storage->getAddress(vk, device, m_buildType), // VkDeviceOrHostAddressKHR dst; 3086e5c31af7Sopenharmony_ci VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode; 3087e5c31af7Sopenharmony_ci }; 3088e5c31af7Sopenharmony_ci 3089e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3090e5c31af7Sopenharmony_ci { 3091e5c31af7Sopenharmony_ci vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, ©AccelerationStructureInfo); 3092e5c31af7Sopenharmony_ci if (storage->hasDeepFormat()) serializeBottoms(vk, device, cmdBuffer, storage, DE_NULL); 3093e5c31af7Sopenharmony_ci } 3094e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 3095e5c31af7Sopenharmony_ci { 3096e5c31af7Sopenharmony_ci VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, ©AccelerationStructureInfo)); 3097e5c31af7Sopenharmony_ci if (storage->hasDeepFormat()) serializeBottoms(vk, device, cmdBuffer, storage, DE_NULL); 3098e5c31af7Sopenharmony_ci } 3099e5c31af7Sopenharmony_ci else 3100e5c31af7Sopenharmony_ci { 3101e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 3102e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 3103e5c31af7Sopenharmony_ci 3104e5c31af7Sopenharmony_ci const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, ©AccelerationStructureInfo); 3105e5c31af7Sopenharmony_ci 3106e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 3107e5c31af7Sopenharmony_ci if (storage->hasDeepFormat()) serializeBottoms(vk, device, cmdBuffer, storage, deferredOperation); 3108e5c31af7Sopenharmony_ci 3109e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 3110e5c31af7Sopenharmony_ci } 3111e5c31af7Sopenharmony_ci} 3112e5c31af7Sopenharmony_ci 3113e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::deserialize (const DeviceInterface& vk, 3114e5c31af7Sopenharmony_ci const VkDevice device, 3115e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3116e5c31af7Sopenharmony_ci SerialStorage* storage) 3117e5c31af7Sopenharmony_ci{ 3118e5c31af7Sopenharmony_ci DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL); 3119e5c31af7Sopenharmony_ci DE_ASSERT(storage != DE_NULL); 3120e5c31af7Sopenharmony_ci 3121e5c31af7Sopenharmony_ci const VkCopyMemoryToAccelerationStructureInfoKHR copyAccelerationStructureInfo = 3122e5c31af7Sopenharmony_ci { 3123e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType; 3124e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3125e5c31af7Sopenharmony_ci storage->getAddressConst(vk, device, m_buildType), // VkDeviceOrHostAddressConstKHR src; 3126e5c31af7Sopenharmony_ci *(getPtr()), // VkAccelerationStructureKHR dst; 3127e5c31af7Sopenharmony_ci VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode; 3128e5c31af7Sopenharmony_ci }; 3129e5c31af7Sopenharmony_ci 3130e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3131e5c31af7Sopenharmony_ci { 3132e5c31af7Sopenharmony_ci vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo); 3133e5c31af7Sopenharmony_ci } 3134e5c31af7Sopenharmony_ci else if (!m_deferredOperation) 3135e5c31af7Sopenharmony_ci { 3136e5c31af7Sopenharmony_ci VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo)); 3137e5c31af7Sopenharmony_ci } 3138e5c31af7Sopenharmony_ci else 3139e5c31af7Sopenharmony_ci { 3140e5c31af7Sopenharmony_ci const auto deferredOperationPtr = createDeferredOperationKHR(vk, device); 3141e5c31af7Sopenharmony_ci const auto deferredOperation = deferredOperationPtr.get(); 3142e5c31af7Sopenharmony_ci 3143e5c31af7Sopenharmony_ci const VkResult result = vk.copyMemoryToAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo); 3144e5c31af7Sopenharmony_ci 3145e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS); 3146e5c31af7Sopenharmony_ci 3147e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 3148e5c31af7Sopenharmony_ci } 3149e5c31af7Sopenharmony_ci 3150e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3151e5c31af7Sopenharmony_ci { 3152e5c31af7Sopenharmony_ci const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; 3153e5c31af7Sopenharmony_ci const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks); 3154e5c31af7Sopenharmony_ci 3155e5c31af7Sopenharmony_ci cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier); 3156e5c31af7Sopenharmony_ci } 3157e5c31af7Sopenharmony_ci} 3158e5c31af7Sopenharmony_ci 3159e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::serializeBottoms (const DeviceInterface& vk, 3160e5c31af7Sopenharmony_ci const VkDevice device, 3161e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3162e5c31af7Sopenharmony_ci SerialStorage* storage, 3163e5c31af7Sopenharmony_ci VkDeferredOperationKHR deferredOperation) 3164e5c31af7Sopenharmony_ci{ 3165e5c31af7Sopenharmony_ci DE_UNREF(deferredOperation); 3166e5c31af7Sopenharmony_ci DE_ASSERT(storage->hasDeepFormat()); 3167e5c31af7Sopenharmony_ci 3168e5c31af7Sopenharmony_ci const std::vector<deUint64>& addresses = storage->getSerialInfo().addresses(); 3169e5c31af7Sopenharmony_ci const std::size_t cbottoms = m_bottomLevelInstances.size(); 3170e5c31af7Sopenharmony_ci 3171e5c31af7Sopenharmony_ci deUint32 storageIndex = 0; 3172e5c31af7Sopenharmony_ci std::vector<deUint64> matches; 3173e5c31af7Sopenharmony_ci 3174e5c31af7Sopenharmony_ci for (std::size_t i = 0; i < cbottoms; ++i) 3175e5c31af7Sopenharmony_ci { 3176e5c31af7Sopenharmony_ci const deUint64& lookAddr = addresses[i+1]; 3177e5c31af7Sopenharmony_ci auto end = matches.end(); 3178e5c31af7Sopenharmony_ci auto match = std::find_if(matches.begin(), end, [&](const deUint64& item){ return item == lookAddr; }); 3179e5c31af7Sopenharmony_ci if (match == end) 3180e5c31af7Sopenharmony_ci { 3181e5c31af7Sopenharmony_ci matches.emplace_back(lookAddr); 3182e5c31af7Sopenharmony_ci m_bottomLevelInstances[i].get()->serialize(vk, device, cmdBuffer, storage->getBottomStorage(storageIndex).get()); 3183e5c31af7Sopenharmony_ci storageIndex += 1; 3184e5c31af7Sopenharmony_ci } 3185e5c31af7Sopenharmony_ci } 3186e5c31af7Sopenharmony_ci} 3187e5c31af7Sopenharmony_ci 3188e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::createAndDeserializeBottoms (const DeviceInterface& vk, 3189e5c31af7Sopenharmony_ci const VkDevice device, 3190e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3191e5c31af7Sopenharmony_ci Allocator& allocator, 3192e5c31af7Sopenharmony_ci SerialStorage* storage) 3193e5c31af7Sopenharmony_ci{ 3194e5c31af7Sopenharmony_ci DE_ASSERT(storage->hasDeepFormat()); 3195e5c31af7Sopenharmony_ci DE_ASSERT(m_bottomLevelInstances.size() == 0); 3196e5c31af7Sopenharmony_ci 3197e5c31af7Sopenharmony_ci const std::vector<deUint64>& addresses = storage->getSerialInfo().addresses(); 3198e5c31af7Sopenharmony_ci const std::size_t cbottoms = addresses.size() - 1; 3199e5c31af7Sopenharmony_ci deUint32 storageIndex = 0; 3200e5c31af7Sopenharmony_ci std::vector<std::pair<deUint64, std::size_t>> matches; 3201e5c31af7Sopenharmony_ci 3202e5c31af7Sopenharmony_ci for (std::size_t i = 0; i < cbottoms; ++i) 3203e5c31af7Sopenharmony_ci { 3204e5c31af7Sopenharmony_ci const deUint64& lookAddr = addresses[i+1]; 3205e5c31af7Sopenharmony_ci auto end = matches.end(); 3206e5c31af7Sopenharmony_ci auto match = std::find_if(matches.begin(), end, [&](const std::pair<deUint64, std::size_t>& item){ return item.first == lookAddr; }); 3207e5c31af7Sopenharmony_ci if (match != end) 3208e5c31af7Sopenharmony_ci { 3209e5c31af7Sopenharmony_ci m_bottomLevelInstances .emplace_back(m_bottomLevelInstances[match->second]); 3210e5c31af7Sopenharmony_ci } 3211e5c31af7Sopenharmony_ci else 3212e5c31af7Sopenharmony_ci { 3213e5c31af7Sopenharmony_ci de::MovePtr<BottomLevelAccelerationStructure> blas = makeBottomLevelAccelerationStructure(); 3214e5c31af7Sopenharmony_ci blas->createAndDeserializeFrom(vk, device, cmdBuffer, allocator, storage->getBottomStorage(storageIndex).get()); 3215e5c31af7Sopenharmony_ci m_bottomLevelInstances.emplace_back(de::SharedPtr<BottomLevelAccelerationStructure>(blas.release())); 3216e5c31af7Sopenharmony_ci matches.emplace_back(lookAddr, i); 3217e5c31af7Sopenharmony_ci storageIndex += 1; 3218e5c31af7Sopenharmony_ci } 3219e5c31af7Sopenharmony_ci } 3220e5c31af7Sopenharmony_ci 3221e5c31af7Sopenharmony_ci std::vector<deUint64> newAddresses = getSerializingAddresses(vk, device); 3222e5c31af7Sopenharmony_ci DE_ASSERT(addresses.size() == newAddresses.size()); 3223e5c31af7Sopenharmony_ci 3224e5c31af7Sopenharmony_ci SerialStorage::AccelerationStructureHeader* header = storage->getASHeader(); 3225e5c31af7Sopenharmony_ci DE_ASSERT(cbottoms ==header->handleCount); 3226e5c31af7Sopenharmony_ci 3227e5c31af7Sopenharmony_ci // finally update bottom-level AS addresses before top-level AS deserialization 3228e5c31af7Sopenharmony_ci for (std::size_t i = 0; i < cbottoms; ++i) 3229e5c31af7Sopenharmony_ci { 3230e5c31af7Sopenharmony_ci header->handleArray[i] = newAddresses[i+1]; 3231e5c31af7Sopenharmony_ci } 3232e5c31af7Sopenharmony_ci} 3233e5c31af7Sopenharmony_ci 3234e5c31af7Sopenharmony_cistd::vector<VkDeviceSize> TopLevelAccelerationStructureKHR::getSerializingSizes (const DeviceInterface& vk, 3235e5c31af7Sopenharmony_ci const VkDevice device, 3236e5c31af7Sopenharmony_ci const VkQueue queue, 3237e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex) 3238e5c31af7Sopenharmony_ci{ 3239e5c31af7Sopenharmony_ci const deUint32 queryCount(deUint32(m_bottomLevelInstances.size()) + 1); 3240e5c31af7Sopenharmony_ci std::vector<VkAccelerationStructureKHR> handles(queryCount); 3241e5c31af7Sopenharmony_ci std::vector<VkDeviceSize> sizes(queryCount); 3242e5c31af7Sopenharmony_ci 3243e5c31af7Sopenharmony_ci handles[0] = m_accelerationStructureKHR.get(); 3244e5c31af7Sopenharmony_ci 3245e5c31af7Sopenharmony_ci for (deUint32 h = 1; h < queryCount; ++h) 3246e5c31af7Sopenharmony_ci handles[h] = *m_bottomLevelInstances[h-1].get()->getPtr(); 3247e5c31af7Sopenharmony_ci 3248e5c31af7Sopenharmony_ci if (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR == m_buildType) 3249e5c31af7Sopenharmony_ci queryAccelerationStructureSize(vk, device, DE_NULL, handles, m_buildType, DE_NULL, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, sizes); 3250e5c31af7Sopenharmony_ci else 3251e5c31af7Sopenharmony_ci { 3252e5c31af7Sopenharmony_ci const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, queueFamilyIndex); 3253e5c31af7Sopenharmony_ci const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 3254e5c31af7Sopenharmony_ci const Move<VkQueryPool> queryPool = makeQueryPool(vk, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount); 3255e5c31af7Sopenharmony_ci 3256e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmdBuffer); 3257e5c31af7Sopenharmony_ci queryAccelerationStructureSize(vk, device, *cmdBuffer, handles, m_buildType, *queryPool, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, sizes); 3258e5c31af7Sopenharmony_ci endCommandBuffer(vk, *cmdBuffer); 3259e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, queue, cmdBuffer.get()); 3260e5c31af7Sopenharmony_ci 3261e5c31af7Sopenharmony_ci VK_CHECK(vk.getQueryPoolResults(device, *queryPool, 0u, queryCount, queryCount * sizeof(VkDeviceSize), sizes.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)); 3262e5c31af7Sopenharmony_ci } 3263e5c31af7Sopenharmony_ci 3264e5c31af7Sopenharmony_ci return sizes; 3265e5c31af7Sopenharmony_ci} 3266e5c31af7Sopenharmony_ci 3267e5c31af7Sopenharmony_cistd::vector<deUint64> TopLevelAccelerationStructureKHR::getSerializingAddresses (const DeviceInterface& vk, const VkDevice device) const 3268e5c31af7Sopenharmony_ci{ 3269e5c31af7Sopenharmony_ci std::vector<deUint64> result(m_bottomLevelInstances.size() + 1); 3270e5c31af7Sopenharmony_ci 3271e5c31af7Sopenharmony_ci VkAccelerationStructureDeviceAddressInfoKHR asDeviceAddressInfo = 3272e5c31af7Sopenharmony_ci { 3273e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType; 3274e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3275e5c31af7Sopenharmony_ci DE_NULL // VkAccelerationStructureKHR accelerationStructure; 3276e5c31af7Sopenharmony_ci }; 3277e5c31af7Sopenharmony_ci 3278e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3279e5c31af7Sopenharmony_ci { 3280e5c31af7Sopenharmony_ci asDeviceAddressInfo.accelerationStructure = m_accelerationStructureKHR.get(); 3281e5c31af7Sopenharmony_ci result[0] = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo); 3282e5c31af7Sopenharmony_ci } 3283e5c31af7Sopenharmony_ci else 3284e5c31af7Sopenharmony_ci { 3285e5c31af7Sopenharmony_ci result[0] = deUint64(getPtr()->getInternal()); 3286e5c31af7Sopenharmony_ci } 3287e5c31af7Sopenharmony_ci 3288e5c31af7Sopenharmony_ci for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx) 3289e5c31af7Sopenharmony_ci { 3290e5c31af7Sopenharmony_ci const BottomLevelAccelerationStructure& bottomLevelAccelerationStructure = *m_bottomLevelInstances[instanceNdx]; 3291e5c31af7Sopenharmony_ci const VkAccelerationStructureKHR accelerationStructureKHR = *bottomLevelAccelerationStructure.getPtr(); 3292e5c31af7Sopenharmony_ci 3293e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3294e5c31af7Sopenharmony_ci { 3295e5c31af7Sopenharmony_ci asDeviceAddressInfo.accelerationStructure = accelerationStructureKHR; 3296e5c31af7Sopenharmony_ci result[instanceNdx+1] = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo); 3297e5c31af7Sopenharmony_ci } 3298e5c31af7Sopenharmony_ci else 3299e5c31af7Sopenharmony_ci { 3300e5c31af7Sopenharmony_ci result[instanceNdx+1] = deUint64(accelerationStructureKHR.getInternal()); 3301e5c31af7Sopenharmony_ci } 3302e5c31af7Sopenharmony_ci } 3303e5c31af7Sopenharmony_ci 3304e5c31af7Sopenharmony_ci return result; 3305e5c31af7Sopenharmony_ci} 3306e5c31af7Sopenharmony_ci 3307e5c31af7Sopenharmony_ciconst VkAccelerationStructureKHR* TopLevelAccelerationStructureKHR::getPtr (void) const 3308e5c31af7Sopenharmony_ci{ 3309e5c31af7Sopenharmony_ci return &m_accelerationStructureKHR.get(); 3310e5c31af7Sopenharmony_ci} 3311e5c31af7Sopenharmony_ci 3312e5c31af7Sopenharmony_civoid TopLevelAccelerationStructureKHR::prepareInstances (const DeviceInterface& vk, 3313e5c31af7Sopenharmony_ci const VkDevice device, 3314e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryKHR& accelerationStructureGeometryKHR, 3315e5c31af7Sopenharmony_ci std::vector<deUint32>& maxPrimitiveCounts) 3316e5c31af7Sopenharmony_ci{ 3317e5c31af7Sopenharmony_ci maxPrimitiveCounts.resize(1); 3318e5c31af7Sopenharmony_ci maxPrimitiveCounts[0] = static_cast<deUint32>(m_bottomLevelInstances.size()); 3319e5c31af7Sopenharmony_ci 3320e5c31af7Sopenharmony_ci VkDeviceOrHostAddressConstKHR instancesData; 3321e5c31af7Sopenharmony_ci if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3322e5c31af7Sopenharmony_ci { 3323e5c31af7Sopenharmony_ci if(m_instanceBuffer.get() != DE_NULL) 3324e5c31af7Sopenharmony_ci { 3325e5c31af7Sopenharmony_ci if (m_useArrayOfPointers) 3326e5c31af7Sopenharmony_ci { 3327e5c31af7Sopenharmony_ci deUint8* bufferStart = static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr()); 3328e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0; 3329e5c31af7Sopenharmony_ci VkDeviceOrHostAddressConstKHR firstInstance = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0); 3330e5c31af7Sopenharmony_ci for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx) 3331e5c31af7Sopenharmony_ci { 3332e5c31af7Sopenharmony_ci VkDeviceOrHostAddressConstKHR currentInstance; 3333e5c31af7Sopenharmony_ci currentInstance.deviceAddress = firstInstance.deviceAddress + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR); 3334e5c31af7Sopenharmony_ci 3335e5c31af7Sopenharmony_ci deMemcpy(&bufferStart[bufferOffset], ¤tInstance, sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress)); 3336e5c31af7Sopenharmony_ci bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress); 3337e5c31af7Sopenharmony_ci } 3338e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, m_instanceAddressBuffer->getAllocation().getMemory(), m_instanceAddressBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE); 3339e5c31af7Sopenharmony_ci 3340e5c31af7Sopenharmony_ci instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceAddressBuffer->get(), 0); 3341e5c31af7Sopenharmony_ci } 3342e5c31af7Sopenharmony_ci else 3343e5c31af7Sopenharmony_ci instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0); 3344e5c31af7Sopenharmony_ci } 3345e5c31af7Sopenharmony_ci else 3346e5c31af7Sopenharmony_ci instancesData = makeDeviceOrHostAddressConstKHR(DE_NULL); 3347e5c31af7Sopenharmony_ci } 3348e5c31af7Sopenharmony_ci else 3349e5c31af7Sopenharmony_ci { 3350e5c31af7Sopenharmony_ci if (m_instanceBuffer.get() != DE_NULL) 3351e5c31af7Sopenharmony_ci { 3352e5c31af7Sopenharmony_ci if (m_useArrayOfPointers) 3353e5c31af7Sopenharmony_ci { 3354e5c31af7Sopenharmony_ci deUint8* bufferStart = static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr()); 3355e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0; 3356e5c31af7Sopenharmony_ci for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx) 3357e5c31af7Sopenharmony_ci { 3358e5c31af7Sopenharmony_ci VkDeviceOrHostAddressConstKHR currentInstance; 3359e5c31af7Sopenharmony_ci currentInstance.hostAddress = (deUint8*)m_instanceBuffer->getAllocation().getHostPtr() + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR); 3360e5c31af7Sopenharmony_ci 3361e5c31af7Sopenharmony_ci deMemcpy(&bufferStart[bufferOffset], ¤tInstance, sizeof(VkDeviceOrHostAddressConstKHR::hostAddress)); 3362e5c31af7Sopenharmony_ci bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR::hostAddress); 3363e5c31af7Sopenharmony_ci } 3364e5c31af7Sopenharmony_ci instancesData = makeDeviceOrHostAddressConstKHR(m_instanceAddressBuffer->getAllocation().getHostPtr()); 3365e5c31af7Sopenharmony_ci } 3366e5c31af7Sopenharmony_ci else 3367e5c31af7Sopenharmony_ci instancesData = makeDeviceOrHostAddressConstKHR(m_instanceBuffer->getAllocation().getHostPtr()); 3368e5c31af7Sopenharmony_ci } 3369e5c31af7Sopenharmony_ci else 3370e5c31af7Sopenharmony_ci instancesData = makeDeviceOrHostAddressConstKHR(DE_NULL); 3371e5c31af7Sopenharmony_ci } 3372e5c31af7Sopenharmony_ci 3373e5c31af7Sopenharmony_ci VkAccelerationStructureGeometryInstancesDataKHR accelerationStructureGeometryInstancesDataKHR = 3374e5c31af7Sopenharmony_ci { 3375e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR, // VkStructureType sType; 3376e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3377e5c31af7Sopenharmony_ci (VkBool32)( m_useArrayOfPointers ? DE_TRUE : DE_FALSE ), // VkBool32 arrayOfPointers; 3378e5c31af7Sopenharmony_ci instancesData // VkDeviceOrHostAddressConstKHR data; 3379e5c31af7Sopenharmony_ci }; 3380e5c31af7Sopenharmony_ci 3381e5c31af7Sopenharmony_ci accelerationStructureGeometryKHR = 3382e5c31af7Sopenharmony_ci { 3383e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // VkStructureType sType; 3384e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3385e5c31af7Sopenharmony_ci VK_GEOMETRY_TYPE_INSTANCES_KHR, // VkGeometryTypeKHR geometryType; 3386e5c31af7Sopenharmony_ci makeVkAccelerationStructureInstancesDataKHR(accelerationStructureGeometryInstancesDataKHR), // VkAccelerationStructureGeometryDataKHR geometry; 3387e5c31af7Sopenharmony_ci (VkGeometryFlagsKHR)0u // VkGeometryFlagsKHR flags; 3388e5c31af7Sopenharmony_ci }; 3389e5c31af7Sopenharmony_ci} 3390e5c31af7Sopenharmony_ci 3391e5c31af7Sopenharmony_cideUint32 TopLevelAccelerationStructure::getRequiredAllocationCount (void) 3392e5c31af7Sopenharmony_ci{ 3393e5c31af7Sopenharmony_ci return TopLevelAccelerationStructureKHR::getRequiredAllocationCount(); 3394e5c31af7Sopenharmony_ci} 3395e5c31af7Sopenharmony_ci 3396e5c31af7Sopenharmony_cide::MovePtr<TopLevelAccelerationStructure> makeTopLevelAccelerationStructure () 3397e5c31af7Sopenharmony_ci{ 3398e5c31af7Sopenharmony_ci return de::MovePtr<TopLevelAccelerationStructure>(new TopLevelAccelerationStructureKHR); 3399e5c31af7Sopenharmony_ci} 3400e5c31af7Sopenharmony_ci 3401e5c31af7Sopenharmony_cibool queryAccelerationStructureSizeKHR (const DeviceInterface& vk, 3402e5c31af7Sopenharmony_ci const VkDevice device, 3403e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3404e5c31af7Sopenharmony_ci const std::vector<VkAccelerationStructureKHR>& accelerationStructureHandles, 3405e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR buildType, 3406e5c31af7Sopenharmony_ci const VkQueryPool queryPool, 3407e5c31af7Sopenharmony_ci VkQueryType queryType, 3408e5c31af7Sopenharmony_ci deUint32 firstQuery, 3409e5c31af7Sopenharmony_ci std::vector<VkDeviceSize>& results) 3410e5c31af7Sopenharmony_ci{ 3411e5c31af7Sopenharmony_ci DE_ASSERT(queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR || queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR); 3412e5c31af7Sopenharmony_ci 3413e5c31af7Sopenharmony_ci if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 3414e5c31af7Sopenharmony_ci { 3415e5c31af7Sopenharmony_ci // queryPool must be large enough to contain at least (firstQuery + accelerationStructureHandles.size()) queries 3416e5c31af7Sopenharmony_ci vk.cmdResetQueryPool(cmdBuffer, queryPool, firstQuery, deUint32(accelerationStructureHandles.size())); 3417e5c31af7Sopenharmony_ci vk.cmdWriteAccelerationStructuresPropertiesKHR(cmdBuffer, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType, queryPool, firstQuery); 3418e5c31af7Sopenharmony_ci // 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. 3419e5c31af7Sopenharmony_ci results.resize(accelerationStructureHandles.size(), 0u); 3420e5c31af7Sopenharmony_ci return false; 3421e5c31af7Sopenharmony_ci } 3422e5c31af7Sopenharmony_ci // buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR 3423e5c31af7Sopenharmony_ci results.resize(accelerationStructureHandles.size(), 0u); 3424e5c31af7Sopenharmony_ci vk.writeAccelerationStructuresPropertiesKHR(device, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType, 3425e5c31af7Sopenharmony_ci sizeof(VkDeviceSize) * accelerationStructureHandles.size(), results.data(), sizeof(VkDeviceSize)); 3426e5c31af7Sopenharmony_ci // results will contain proper values 3427e5c31af7Sopenharmony_ci return true; 3428e5c31af7Sopenharmony_ci} 3429e5c31af7Sopenharmony_ci 3430e5c31af7Sopenharmony_cibool queryAccelerationStructureSize (const DeviceInterface& vk, 3431e5c31af7Sopenharmony_ci const VkDevice device, 3432e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 3433e5c31af7Sopenharmony_ci const std::vector<VkAccelerationStructureKHR>& accelerationStructureHandles, 3434e5c31af7Sopenharmony_ci VkAccelerationStructureBuildTypeKHR buildType, 3435e5c31af7Sopenharmony_ci const VkQueryPool queryPool, 3436e5c31af7Sopenharmony_ci VkQueryType queryType, 3437e5c31af7Sopenharmony_ci deUint32 firstQuery, 3438e5c31af7Sopenharmony_ci std::vector<VkDeviceSize>& results) 3439e5c31af7Sopenharmony_ci{ 3440e5c31af7Sopenharmony_ci return queryAccelerationStructureSizeKHR(vk, device, cmdBuffer, accelerationStructureHandles, buildType, queryPool, queryType, firstQuery, results); 3441e5c31af7Sopenharmony_ci} 3442e5c31af7Sopenharmony_ci 3443e5c31af7Sopenharmony_ciRayTracingPipeline::RayTracingPipeline () 3444e5c31af7Sopenharmony_ci : m_shadersModules () 3445e5c31af7Sopenharmony_ci , m_pipelineLibraries () 3446e5c31af7Sopenharmony_ci , m_shaderCreateInfos () 3447e5c31af7Sopenharmony_ci , m_shadersGroupCreateInfos () 3448e5c31af7Sopenharmony_ci , m_pipelineCreateFlags (0U) 3449e5c31af7Sopenharmony_ci , m_pipelineCreateFlags2 (0U) 3450e5c31af7Sopenharmony_ci , m_maxRecursionDepth (1U) 3451e5c31af7Sopenharmony_ci , m_maxPayloadSize (0U) 3452e5c31af7Sopenharmony_ci , m_maxAttributeSize (0U) 3453e5c31af7Sopenharmony_ci , m_deferredOperation (false) 3454e5c31af7Sopenharmony_ci , m_workerThreadCount (0) 3455e5c31af7Sopenharmony_ci{ 3456e5c31af7Sopenharmony_ci} 3457e5c31af7Sopenharmony_ci 3458e5c31af7Sopenharmony_ciRayTracingPipeline::~RayTracingPipeline () 3459e5c31af7Sopenharmony_ci{ 3460e5c31af7Sopenharmony_ci} 3461e5c31af7Sopenharmony_ci 3462e5c31af7Sopenharmony_ci#define CHECKED_ASSIGN_SHADER(SHADER, STAGE) \ 3463e5c31af7Sopenharmony_ci if (SHADER == VK_SHADER_UNUSED_KHR) \ 3464e5c31af7Sopenharmony_ci SHADER = STAGE; \ 3465e5c31af7Sopenharmony_ci else \ 3466e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Attempt to reassign shader") 3467e5c31af7Sopenharmony_ci 3468e5c31af7Sopenharmony_civoid RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, 3469e5c31af7Sopenharmony_ci Move<VkShaderModule> shaderModule, 3470e5c31af7Sopenharmony_ci deUint32 group, 3471e5c31af7Sopenharmony_ci const VkSpecializationInfo* specializationInfo, 3472e5c31af7Sopenharmony_ci const VkPipelineShaderStageCreateFlags pipelineShaderStageCreateFlags, 3473e5c31af7Sopenharmony_ci const void* pipelineShaderStageCreateInfopNext) 3474e5c31af7Sopenharmony_ci{ 3475e5c31af7Sopenharmony_ci addShader(shaderStage, makeVkSharedPtr(shaderModule), group, specializationInfo, pipelineShaderStageCreateFlags, pipelineShaderStageCreateInfopNext); 3476e5c31af7Sopenharmony_ci} 3477e5c31af7Sopenharmony_ci 3478e5c31af7Sopenharmony_civoid RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, 3479e5c31af7Sopenharmony_ci de::SharedPtr<Move<VkShaderModule>> shaderModule, 3480e5c31af7Sopenharmony_ci deUint32 group, 3481e5c31af7Sopenharmony_ci const VkSpecializationInfo* specializationInfoPtr, 3482e5c31af7Sopenharmony_ci const VkPipelineShaderStageCreateFlags pipelineShaderStageCreateFlags, 3483e5c31af7Sopenharmony_ci const void* pipelineShaderStageCreateInfopNext) 3484e5c31af7Sopenharmony_ci{ 3485e5c31af7Sopenharmony_ci addShader(shaderStage, **shaderModule, group, specializationInfoPtr, pipelineShaderStageCreateFlags, pipelineShaderStageCreateInfopNext); 3486e5c31af7Sopenharmony_ci m_shadersModules.push_back(shaderModule); 3487e5c31af7Sopenharmony_ci} 3488e5c31af7Sopenharmony_ci 3489e5c31af7Sopenharmony_civoid RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, 3490e5c31af7Sopenharmony_ci VkShaderModule shaderModule, 3491e5c31af7Sopenharmony_ci deUint32 group, 3492e5c31af7Sopenharmony_ci const VkSpecializationInfo* specializationInfoPtr, 3493e5c31af7Sopenharmony_ci const VkPipelineShaderStageCreateFlags pipelineShaderStageCreateFlags, 3494e5c31af7Sopenharmony_ci const void* pipelineShaderStageCreateInfopNext) 3495e5c31af7Sopenharmony_ci{ 3496e5c31af7Sopenharmony_ci if (group >= m_shadersGroupCreateInfos.size()) 3497e5c31af7Sopenharmony_ci { 3498e5c31af7Sopenharmony_ci for (size_t groupNdx = m_shadersGroupCreateInfos.size(); groupNdx <= group; ++groupNdx) 3499e5c31af7Sopenharmony_ci { 3500e5c31af7Sopenharmony_ci VkRayTracingShaderGroupCreateInfoKHR shaderGroupCreateInfo = 3501e5c31af7Sopenharmony_ci { 3502e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, // VkStructureType sType; 3503e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3504e5c31af7Sopenharmony_ci VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR, // VkRayTracingShaderGroupTypeKHR type; 3505e5c31af7Sopenharmony_ci VK_SHADER_UNUSED_KHR, // deUint32 generalShader; 3506e5c31af7Sopenharmony_ci VK_SHADER_UNUSED_KHR, // deUint32 closestHitShader; 3507e5c31af7Sopenharmony_ci VK_SHADER_UNUSED_KHR, // deUint32 anyHitShader; 3508e5c31af7Sopenharmony_ci VK_SHADER_UNUSED_KHR, // deUint32 intersectionShader; 3509e5c31af7Sopenharmony_ci DE_NULL, // const void* pShaderGroupCaptureReplayHandle; 3510e5c31af7Sopenharmony_ci }; 3511e5c31af7Sopenharmony_ci 3512e5c31af7Sopenharmony_ci m_shadersGroupCreateInfos.push_back(shaderGroupCreateInfo); 3513e5c31af7Sopenharmony_ci } 3514e5c31af7Sopenharmony_ci } 3515e5c31af7Sopenharmony_ci 3516e5c31af7Sopenharmony_ci const deUint32 shaderStageNdx = (deUint32)m_shaderCreateInfos.size(); 3517e5c31af7Sopenharmony_ci VkRayTracingShaderGroupCreateInfoKHR& shaderGroupCreateInfo = m_shadersGroupCreateInfos[group]; 3518e5c31af7Sopenharmony_ci 3519e5c31af7Sopenharmony_ci switch (shaderStage) 3520e5c31af7Sopenharmony_ci { 3521e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_RAYGEN_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader, shaderStageNdx); break; 3522e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_MISS_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader, shaderStageNdx); break; 3523e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_CALLABLE_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader, shaderStageNdx); break; 3524e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.anyHitShader, shaderStageNdx); break; 3525e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.closestHitShader, shaderStageNdx); break; 3526e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.intersectionShader, shaderStageNdx); break; 3527e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unacceptable stage"); 3528e5c31af7Sopenharmony_ci } 3529e5c31af7Sopenharmony_ci 3530e5c31af7Sopenharmony_ci switch (shaderStage) 3531e5c31af7Sopenharmony_ci { 3532e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_RAYGEN_BIT_KHR: 3533e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_MISS_BIT_KHR: 3534e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_CALLABLE_BIT_KHR: 3535e5c31af7Sopenharmony_ci { 3536e5c31af7Sopenharmony_ci DE_ASSERT(shaderGroupCreateInfo.type == VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR); 3537e5c31af7Sopenharmony_ci shaderGroupCreateInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; 3538e5c31af7Sopenharmony_ci 3539e5c31af7Sopenharmony_ci break; 3540e5c31af7Sopenharmony_ci } 3541e5c31af7Sopenharmony_ci 3542e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: 3543e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: 3544e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: 3545e5c31af7Sopenharmony_ci { 3546e5c31af7Sopenharmony_ci DE_ASSERT(shaderGroupCreateInfo.type != VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR); 3547e5c31af7Sopenharmony_ci shaderGroupCreateInfo.type = (shaderGroupCreateInfo.intersectionShader == VK_SHADER_UNUSED_KHR) 3548e5c31af7Sopenharmony_ci ? VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR 3549e5c31af7Sopenharmony_ci : VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR; 3550e5c31af7Sopenharmony_ci 3551e5c31af7Sopenharmony_ci break; 3552e5c31af7Sopenharmony_ci } 3553e5c31af7Sopenharmony_ci 3554e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unacceptable stage"); 3555e5c31af7Sopenharmony_ci } 3556e5c31af7Sopenharmony_ci 3557e5c31af7Sopenharmony_ci { 3558e5c31af7Sopenharmony_ci const VkPipelineShaderStageCreateInfo shaderCreateInfo = 3559e5c31af7Sopenharmony_ci { 3560e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 3561e5c31af7Sopenharmony_ci pipelineShaderStageCreateInfopNext, // const void* pNext; 3562e5c31af7Sopenharmony_ci pipelineShaderStageCreateFlags, // VkPipelineShaderStageCreateFlags flags; 3563e5c31af7Sopenharmony_ci shaderStage, // VkShaderStageFlagBits stage; 3564e5c31af7Sopenharmony_ci shaderModule, // VkShaderModule module; 3565e5c31af7Sopenharmony_ci "main", // const char* pName; 3566e5c31af7Sopenharmony_ci specializationInfoPtr, // const VkSpecializationInfo* pSpecializationInfo; 3567e5c31af7Sopenharmony_ci }; 3568e5c31af7Sopenharmony_ci 3569e5c31af7Sopenharmony_ci m_shaderCreateInfos.push_back(shaderCreateInfo); 3570e5c31af7Sopenharmony_ci } 3571e5c31af7Sopenharmony_ci} 3572e5c31af7Sopenharmony_ci 3573e5c31af7Sopenharmony_civoid RayTracingPipeline::setGroupCaptureReplayHandle (uint32_t group, const void* pShaderGroupCaptureReplayHandle) 3574e5c31af7Sopenharmony_ci{ 3575e5c31af7Sopenharmony_ci DE_ASSERT(static_cast<size_t>(group) < m_shadersGroupCreateInfos.size()); 3576e5c31af7Sopenharmony_ci m_shadersGroupCreateInfos[group].pShaderGroupCaptureReplayHandle = pShaderGroupCaptureReplayHandle; 3577e5c31af7Sopenharmony_ci} 3578e5c31af7Sopenharmony_ci 3579e5c31af7Sopenharmony_civoid RayTracingPipeline::addLibrary (de::SharedPtr<de::MovePtr<RayTracingPipeline>> pipelineLibrary) 3580e5c31af7Sopenharmony_ci{ 3581e5c31af7Sopenharmony_ci m_pipelineLibraries.push_back(pipelineLibrary); 3582e5c31af7Sopenharmony_ci} 3583e5c31af7Sopenharmony_ci 3584e5c31af7Sopenharmony_ciuint32_t RayTracingPipeline::getShaderGroupCount (void) 3585e5c31af7Sopenharmony_ci{ 3586e5c31af7Sopenharmony_ci return de::sizeU32(m_shadersGroupCreateInfos); 3587e5c31af7Sopenharmony_ci} 3588e5c31af7Sopenharmony_ci 3589e5c31af7Sopenharmony_ciuint32_t RayTracingPipeline::getFullShaderGroupCount (void) 3590e5c31af7Sopenharmony_ci{ 3591e5c31af7Sopenharmony_ci uint32_t totalCount = getShaderGroupCount(); 3592e5c31af7Sopenharmony_ci 3593e5c31af7Sopenharmony_ci for (const auto& lib : m_pipelineLibraries) 3594e5c31af7Sopenharmony_ci totalCount += lib->get()->getFullShaderGroupCount(); 3595e5c31af7Sopenharmony_ci 3596e5c31af7Sopenharmony_ci return totalCount; 3597e5c31af7Sopenharmony_ci} 3598e5c31af7Sopenharmony_ci 3599e5c31af7Sopenharmony_ciMove<VkPipeline> RayTracingPipeline::createPipelineKHR (const DeviceInterface& vk, 3600e5c31af7Sopenharmony_ci const VkDevice device, 3601e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 3602e5c31af7Sopenharmony_ci const std::vector<VkPipeline>& pipelineLibraries, 3603e5c31af7Sopenharmony_ci const VkPipelineCache pipelineCache) 3604e5c31af7Sopenharmony_ci{ 3605e5c31af7Sopenharmony_ci for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx) 3606e5c31af7Sopenharmony_ci DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR); 3607e5c31af7Sopenharmony_ci 3608e5c31af7Sopenharmony_ci VkPipelineLibraryCreateInfoKHR librariesCreateInfo = 3609e5c31af7Sopenharmony_ci { 3610e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType; 3611e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3612e5c31af7Sopenharmony_ci de::sizeU32(pipelineLibraries), // deUint32 libraryCount; 3613e5c31af7Sopenharmony_ci de::dataOrNull(pipelineLibraries) // VkPipeline* pLibraries; 3614e5c31af7Sopenharmony_ci }; 3615e5c31af7Sopenharmony_ci const VkRayTracingPipelineInterfaceCreateInfoKHR pipelineInterfaceCreateInfo = 3616e5c31af7Sopenharmony_ci { 3617e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR, // VkStructureType sType; 3618e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3619e5c31af7Sopenharmony_ci m_maxPayloadSize, // deUint32 maxPayloadSize; 3620e5c31af7Sopenharmony_ci m_maxAttributeSize // deUint32 maxAttributeSize; 3621e5c31af7Sopenharmony_ci }; 3622e5c31af7Sopenharmony_ci const bool addPipelineInterfaceCreateInfo = m_maxPayloadSize != 0 || m_maxAttributeSize != 0; 3623e5c31af7Sopenharmony_ci const VkRayTracingPipelineInterfaceCreateInfoKHR* pipelineInterfaceCreateInfoPtr = addPipelineInterfaceCreateInfo ? &pipelineInterfaceCreateInfo : DE_NULL; 3624e5c31af7Sopenharmony_ci const VkPipelineLibraryCreateInfoKHR* librariesCreateInfoPtr = (pipelineLibraries.empty() ? nullptr : &librariesCreateInfo); 3625e5c31af7Sopenharmony_ci 3626e5c31af7Sopenharmony_ci Move<VkDeferredOperationKHR> deferredOperation; 3627e5c31af7Sopenharmony_ci if (m_deferredOperation) 3628e5c31af7Sopenharmony_ci deferredOperation = createDeferredOperationKHR(vk, device); 3629e5c31af7Sopenharmony_ci 3630e5c31af7Sopenharmony_ci VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = 3631e5c31af7Sopenharmony_ci { 3632e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 3633e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3634e5c31af7Sopenharmony_ci 0, // VkPipelineDynamicStateCreateFlags flags; 3635e5c31af7Sopenharmony_ci static_cast<deUint32>(m_dynamicStates.size() ), // deUint32 dynamicStateCount; 3636e5c31af7Sopenharmony_ci m_dynamicStates.data(), // const VkDynamicState* pDynamicStates; 3637e5c31af7Sopenharmony_ci }; 3638e5c31af7Sopenharmony_ci 3639e5c31af7Sopenharmony_ci VkRayTracingPipelineCreateInfoKHR pipelineCreateInfo 3640e5c31af7Sopenharmony_ci { 3641e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, // VkStructureType sType; 3642e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3643e5c31af7Sopenharmony_ci m_pipelineCreateFlags, // VkPipelineCreateFlags flags; 3644e5c31af7Sopenharmony_ci de::sizeU32(m_shaderCreateInfos), // deUint32 stageCount; 3645e5c31af7Sopenharmony_ci de::dataOrNull(m_shaderCreateInfos), // const VkPipelineShaderStageCreateInfo* pStages; 3646e5c31af7Sopenharmony_ci de::sizeU32(m_shadersGroupCreateInfos), // deUint32 groupCount; 3647e5c31af7Sopenharmony_ci de::dataOrNull(m_shadersGroupCreateInfos), // const VkRayTracingShaderGroupCreateInfoKHR* pGroups; 3648e5c31af7Sopenharmony_ci m_maxRecursionDepth, // deUint32 maxRecursionDepth; 3649e5c31af7Sopenharmony_ci librariesCreateInfoPtr, // VkPipelineLibraryCreateInfoKHR* pLibraryInfo; 3650e5c31af7Sopenharmony_ci pipelineInterfaceCreateInfoPtr, // VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; 3651e5c31af7Sopenharmony_ci &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 3652e5c31af7Sopenharmony_ci pipelineLayout, // VkPipelineLayout layout; 3653e5c31af7Sopenharmony_ci (VkPipeline)DE_NULL, // VkPipeline basePipelineHandle; 3654e5c31af7Sopenharmony_ci 0, // deInt32 basePipelineIndex; 3655e5c31af7Sopenharmony_ci }; 3656e5c31af7Sopenharmony_ci VkPipeline object = DE_NULL; 3657e5c31af7Sopenharmony_ci VkResult result = vk.createRayTracingPipelinesKHR(device, deferredOperation.get(), pipelineCache, 1u, &pipelineCreateInfo, DE_NULL, &object); 3658e5c31af7Sopenharmony_ci const bool allowCompileRequired = ((m_pipelineCreateFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT) != 0); 3659e5c31af7Sopenharmony_ci 3660e5c31af7Sopenharmony_ci VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure(); 3661e5c31af7Sopenharmony_ci if (m_pipelineCreateFlags2) 3662e5c31af7Sopenharmony_ci { 3663e5c31af7Sopenharmony_ci pipelineFlags2CreateInfo.flags = m_pipelineCreateFlags2; 3664e5c31af7Sopenharmony_ci pipelineCreateInfo.pNext = &pipelineFlags2CreateInfo; 3665e5c31af7Sopenharmony_ci pipelineCreateInfo.flags = 0; 3666e5c31af7Sopenharmony_ci } 3667e5c31af7Sopenharmony_ci 3668e5c31af7Sopenharmony_ci if (m_deferredOperation) 3669e5c31af7Sopenharmony_ci { 3670e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS || (allowCompileRequired && result == VK_PIPELINE_COMPILE_REQUIRED)); 3671e5c31af7Sopenharmony_ci finishDeferredOperation(vk, device, deferredOperation.get(), m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR); 3672e5c31af7Sopenharmony_ci } 3673e5c31af7Sopenharmony_ci 3674e5c31af7Sopenharmony_ci if (allowCompileRequired && result == VK_PIPELINE_COMPILE_REQUIRED) 3675e5c31af7Sopenharmony_ci throw CompileRequiredError("createRayTracingPipelinesKHR returned VK_PIPELINE_COMPILE_REQUIRED"); 3676e5c31af7Sopenharmony_ci 3677e5c31af7Sopenharmony_ci Move<VkPipeline> pipeline (check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, DE_NULL)); 3678e5c31af7Sopenharmony_ci return pipeline; 3679e5c31af7Sopenharmony_ci} 3680e5c31af7Sopenharmony_ci 3681e5c31af7Sopenharmony_ci 3682e5c31af7Sopenharmony_ciMove<VkPipeline> RayTracingPipeline::createPipeline (const DeviceInterface& vk, 3683e5c31af7Sopenharmony_ci const VkDevice device, 3684e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 3685e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<Move<VkPipeline>>>& pipelineLibraries) 3686e5c31af7Sopenharmony_ci{ 3687e5c31af7Sopenharmony_ci std::vector<VkPipeline> rawPipelines; 3688e5c31af7Sopenharmony_ci rawPipelines.reserve(pipelineLibraries.size()); 3689e5c31af7Sopenharmony_ci for (const auto& lib : pipelineLibraries) 3690e5c31af7Sopenharmony_ci rawPipelines.push_back(lib.get()->get()); 3691e5c31af7Sopenharmony_ci 3692e5c31af7Sopenharmony_ci return createPipelineKHR(vk, device, pipelineLayout, rawPipelines); 3693e5c31af7Sopenharmony_ci} 3694e5c31af7Sopenharmony_ci 3695e5c31af7Sopenharmony_ciMove<VkPipeline> RayTracingPipeline::createPipeline (const DeviceInterface& vk, 3696e5c31af7Sopenharmony_ci const VkDevice device, 3697e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 3698e5c31af7Sopenharmony_ci const std::vector<VkPipeline>& pipelineLibraries, 3699e5c31af7Sopenharmony_ci const VkPipelineCache pipelineCache) 3700e5c31af7Sopenharmony_ci{ 3701e5c31af7Sopenharmony_ci return createPipelineKHR(vk, device, pipelineLayout, pipelineLibraries, pipelineCache); 3702e5c31af7Sopenharmony_ci} 3703e5c31af7Sopenharmony_ci 3704e5c31af7Sopenharmony_cistd::vector<de::SharedPtr<Move<VkPipeline>>> RayTracingPipeline::createPipelineWithLibraries (const DeviceInterface& vk, 3705e5c31af7Sopenharmony_ci const VkDevice device, 3706e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout) 3707e5c31af7Sopenharmony_ci{ 3708e5c31af7Sopenharmony_ci for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx) 3709e5c31af7Sopenharmony_ci DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR); 3710e5c31af7Sopenharmony_ci 3711e5c31af7Sopenharmony_ci DE_ASSERT(m_shaderCreateInfos.size() > 0); 3712e5c31af7Sopenharmony_ci DE_ASSERT(m_shadersGroupCreateInfos.size() > 0); 3713e5c31af7Sopenharmony_ci 3714e5c31af7Sopenharmony_ci std::vector<de::SharedPtr<Move<VkPipeline>>> result, allLibraries, firstLibraries; 3715e5c31af7Sopenharmony_ci for(auto it=begin(m_pipelineLibraries), eit=end(m_pipelineLibraries); it!=eit; ++it) 3716e5c31af7Sopenharmony_ci { 3717e5c31af7Sopenharmony_ci auto childLibraries = (*it)->get()->createPipelineWithLibraries(vk, device, pipelineLayout); 3718e5c31af7Sopenharmony_ci DE_ASSERT(childLibraries.size() > 0); 3719e5c31af7Sopenharmony_ci firstLibraries.push_back(childLibraries[0]); 3720e5c31af7Sopenharmony_ci std::copy(begin(childLibraries), end(childLibraries), std::back_inserter(allLibraries)); 3721e5c31af7Sopenharmony_ci } 3722e5c31af7Sopenharmony_ci result.push_back(makeVkSharedPtr(createPipeline(vk, device, pipelineLayout, firstLibraries))); 3723e5c31af7Sopenharmony_ci std::copy(begin(allLibraries), end(allLibraries), std::back_inserter(result)); 3724e5c31af7Sopenharmony_ci return result; 3725e5c31af7Sopenharmony_ci} 3726e5c31af7Sopenharmony_ci 3727e5c31af7Sopenharmony_cistd::vector<uint8_t> RayTracingPipeline::getShaderGroupHandles (const DeviceInterface& vk, 3728e5c31af7Sopenharmony_ci const VkDevice device, 3729e5c31af7Sopenharmony_ci const VkPipeline pipeline, 3730e5c31af7Sopenharmony_ci const deUint32 shaderGroupHandleSize, 3731e5c31af7Sopenharmony_ci const deUint32 firstGroup, 3732e5c31af7Sopenharmony_ci const deUint32 groupCount) const 3733e5c31af7Sopenharmony_ci{ 3734e5c31af7Sopenharmony_ci const auto handleArraySizeBytes = groupCount * shaderGroupHandleSize; 3735e5c31af7Sopenharmony_ci std::vector<uint8_t> shaderHandles (handleArraySizeBytes); 3736e5c31af7Sopenharmony_ci 3737e5c31af7Sopenharmony_ci VK_CHECK(getRayTracingShaderGroupHandles(vk, device, pipeline, 3738e5c31af7Sopenharmony_ci firstGroup, groupCount, 3739e5c31af7Sopenharmony_ci static_cast<uintptr_t>(shaderHandles.size()), de::dataOrNull(shaderHandles))); 3740e5c31af7Sopenharmony_ci 3741e5c31af7Sopenharmony_ci return shaderHandles; 3742e5c31af7Sopenharmony_ci} 3743e5c31af7Sopenharmony_ci 3744e5c31af7Sopenharmony_cistd::vector<uint8_t> RayTracingPipeline::getShaderGroupReplayHandles (const DeviceInterface &vk, 3745e5c31af7Sopenharmony_ci const VkDevice device, 3746e5c31af7Sopenharmony_ci const VkPipeline pipeline, 3747e5c31af7Sopenharmony_ci const deUint32 shaderGroupHandleReplaySize, 3748e5c31af7Sopenharmony_ci const deUint32 firstGroup, 3749e5c31af7Sopenharmony_ci const deUint32 groupCount) const 3750e5c31af7Sopenharmony_ci{ 3751e5c31af7Sopenharmony_ci const auto handleArraySizeBytes = groupCount * shaderGroupHandleReplaySize; 3752e5c31af7Sopenharmony_ci std::vector<uint8_t> shaderHandles (handleArraySizeBytes); 3753e5c31af7Sopenharmony_ci 3754e5c31af7Sopenharmony_ci VK_CHECK(getRayTracingCaptureReplayShaderGroupHandles(vk, device, pipeline, 3755e5c31af7Sopenharmony_ci firstGroup, groupCount, 3756e5c31af7Sopenharmony_ci static_cast<uintptr_t>(shaderHandles.size()), de::dataOrNull(shaderHandles))); 3757e5c31af7Sopenharmony_ci 3758e5c31af7Sopenharmony_ci return shaderHandles; 3759e5c31af7Sopenharmony_ci} 3760e5c31af7Sopenharmony_ci 3761e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> RayTracingPipeline::createShaderBindingTable (const DeviceInterface& vk, 3762e5c31af7Sopenharmony_ci const VkDevice device, 3763e5c31af7Sopenharmony_ci const VkPipeline pipeline, 3764e5c31af7Sopenharmony_ci Allocator& allocator, 3765e5c31af7Sopenharmony_ci const deUint32& shaderGroupHandleSize, 3766e5c31af7Sopenharmony_ci const deUint32 shaderGroupBaseAlignment, 3767e5c31af7Sopenharmony_ci const deUint32& firstGroup, 3768e5c31af7Sopenharmony_ci const deUint32& groupCount, 3769e5c31af7Sopenharmony_ci const VkBufferCreateFlags& additionalBufferCreateFlags, 3770e5c31af7Sopenharmony_ci const VkBufferUsageFlags& additionalBufferUsageFlags, 3771e5c31af7Sopenharmony_ci const MemoryRequirement& additionalMemoryRequirement, 3772e5c31af7Sopenharmony_ci const VkDeviceAddress& opaqueCaptureAddress, 3773e5c31af7Sopenharmony_ci const deUint32 shaderBindingTableOffset, 3774e5c31af7Sopenharmony_ci const deUint32 shaderRecordSize, 3775e5c31af7Sopenharmony_ci const void** shaderGroupDataPtrPerGroup, 3776e5c31af7Sopenharmony_ci const bool autoAlignRecords) 3777e5c31af7Sopenharmony_ci{ 3778e5c31af7Sopenharmony_ci const auto shaderHandles = getShaderGroupHandles(vk, device, pipeline, shaderGroupHandleSize, firstGroup, groupCount); 3779e5c31af7Sopenharmony_ci return createShaderBindingTable(vk, device, allocator, 3780e5c31af7Sopenharmony_ci shaderGroupHandleSize, shaderGroupBaseAlignment, shaderHandles, 3781e5c31af7Sopenharmony_ci additionalBufferCreateFlags, additionalBufferUsageFlags, additionalMemoryRequirement, 3782e5c31af7Sopenharmony_ci opaqueCaptureAddress, 3783e5c31af7Sopenharmony_ci shaderBindingTableOffset, shaderRecordSize, shaderGroupDataPtrPerGroup, 3784e5c31af7Sopenharmony_ci autoAlignRecords); 3785e5c31af7Sopenharmony_ci} 3786e5c31af7Sopenharmony_ci 3787e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> RayTracingPipeline::createShaderBindingTable (const DeviceInterface& vk, 3788e5c31af7Sopenharmony_ci const VkDevice device, 3789e5c31af7Sopenharmony_ci Allocator& allocator, 3790e5c31af7Sopenharmony_ci const deUint32 shaderGroupHandleSize, 3791e5c31af7Sopenharmony_ci const deUint32 shaderGroupBaseAlignment, 3792e5c31af7Sopenharmony_ci const std::vector<uint8_t>& shaderHandles, 3793e5c31af7Sopenharmony_ci const VkBufferCreateFlags additionalBufferCreateFlags, 3794e5c31af7Sopenharmony_ci const VkBufferUsageFlags additionalBufferUsageFlags, 3795e5c31af7Sopenharmony_ci const MemoryRequirement& additionalMemoryRequirement, 3796e5c31af7Sopenharmony_ci const VkDeviceAddress opaqueCaptureAddress, 3797e5c31af7Sopenharmony_ci const deUint32 shaderBindingTableOffset, 3798e5c31af7Sopenharmony_ci const deUint32 shaderRecordSize, 3799e5c31af7Sopenharmony_ci const void** shaderGroupDataPtrPerGroup, 3800e5c31af7Sopenharmony_ci const bool autoAlignRecords) 3801e5c31af7Sopenharmony_ci{ 3802e5c31af7Sopenharmony_ci DE_ASSERT(shaderGroupBaseAlignment != 0u); 3803e5c31af7Sopenharmony_ci DE_ASSERT((shaderBindingTableOffset % shaderGroupBaseAlignment) == 0); 3804e5c31af7Sopenharmony_ci DE_UNREF(shaderGroupBaseAlignment); 3805e5c31af7Sopenharmony_ci 3806e5c31af7Sopenharmony_ci const auto groupCount = de::sizeU32(shaderHandles) / shaderGroupHandleSize; 3807e5c31af7Sopenharmony_ci const auto totalEntrySize = (autoAlignRecords ? (deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize)) : (shaderGroupHandleSize + shaderRecordSize)); 3808e5c31af7Sopenharmony_ci const deUint32 sbtSize = shaderBindingTableOffset + groupCount * totalEntrySize; 3809e5c31af7Sopenharmony_ci const VkBufferUsageFlags sbtFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | additionalBufferUsageFlags; 3810e5c31af7Sopenharmony_ci VkBufferCreateInfo sbtCreateInfo = makeBufferCreateInfo(sbtSize, sbtFlags); 3811e5c31af7Sopenharmony_ci sbtCreateInfo.flags |= additionalBufferCreateFlags; 3812e5c31af7Sopenharmony_ci VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = vk::initVulkanStructure(); 3813e5c31af7Sopenharmony_ci VkBufferOpaqueCaptureAddressCreateInfo sbtCaptureAddressInfo = 3814e5c31af7Sopenharmony_ci { 3815e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, // VkStructureType sType; 3816e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3817e5c31af7Sopenharmony_ci deUint64(opaqueCaptureAddress) // deUint64 opaqueCaptureAddress; 3818e5c31af7Sopenharmony_ci }; 3819e5c31af7Sopenharmony_ci 3820e5c31af7Sopenharmony_ci // when maintenance5 is tested then m_pipelineCreateFlags2 is non-zero 3821e5c31af7Sopenharmony_ci if (m_pipelineCreateFlags2) 3822e5c31af7Sopenharmony_ci { 3823e5c31af7Sopenharmony_ci bufferUsageFlags2.usage = (VkBufferUsageFlags2KHR)sbtFlags; 3824e5c31af7Sopenharmony_ci sbtCreateInfo.pNext = &bufferUsageFlags2; 3825e5c31af7Sopenharmony_ci sbtCreateInfo.usage = 0; 3826e5c31af7Sopenharmony_ci } 3827e5c31af7Sopenharmony_ci 3828e5c31af7Sopenharmony_ci if (opaqueCaptureAddress != 0u) 3829e5c31af7Sopenharmony_ci { 3830e5c31af7Sopenharmony_ci sbtCreateInfo.pNext = &sbtCaptureAddressInfo; 3831e5c31af7Sopenharmony_ci sbtCreateInfo.flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; 3832e5c31af7Sopenharmony_ci } 3833e5c31af7Sopenharmony_ci const MemoryRequirement sbtMemRequirements = MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress | additionalMemoryRequirement; 3834e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> sbtBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, sbtCreateInfo, sbtMemRequirements)); 3835e5c31af7Sopenharmony_ci vk::Allocation& sbtAlloc = sbtBuffer->getAllocation(); 3836e5c31af7Sopenharmony_ci 3837e5c31af7Sopenharmony_ci // Copy handles to table, leaving space for ShaderRecordKHR after each handle. 3838e5c31af7Sopenharmony_ci deUint8* shaderBegin = (deUint8*)sbtAlloc.getHostPtr() + shaderBindingTableOffset; 3839e5c31af7Sopenharmony_ci for (deUint32 idx = 0; idx < groupCount; ++idx) 3840e5c31af7Sopenharmony_ci { 3841e5c31af7Sopenharmony_ci const deUint8* shaderSrcPos = shaderHandles.data() + idx * shaderGroupHandleSize; 3842e5c31af7Sopenharmony_ci deUint8* shaderDstPos = shaderBegin + idx * totalEntrySize; 3843e5c31af7Sopenharmony_ci deMemcpy(shaderDstPos, shaderSrcPos, shaderGroupHandleSize); 3844e5c31af7Sopenharmony_ci 3845e5c31af7Sopenharmony_ci if (shaderGroupDataPtrPerGroup != nullptr && 3846e5c31af7Sopenharmony_ci shaderGroupDataPtrPerGroup[idx] != nullptr) 3847e5c31af7Sopenharmony_ci { 3848e5c31af7Sopenharmony_ci DE_ASSERT(sbtSize >= static_cast<deUint32>(shaderDstPos - shaderBegin) + shaderGroupHandleSize); 3849e5c31af7Sopenharmony_ci 3850e5c31af7Sopenharmony_ci deMemcpy( shaderDstPos + shaderGroupHandleSize, 3851e5c31af7Sopenharmony_ci shaderGroupDataPtrPerGroup[idx], 3852e5c31af7Sopenharmony_ci shaderRecordSize); 3853e5c31af7Sopenharmony_ci } 3854e5c31af7Sopenharmony_ci } 3855e5c31af7Sopenharmony_ci 3856e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, sbtAlloc.getMemory(), sbtAlloc.getOffset(), VK_WHOLE_SIZE); 3857e5c31af7Sopenharmony_ci 3858e5c31af7Sopenharmony_ci return sbtBuffer; 3859e5c31af7Sopenharmony_ci} 3860e5c31af7Sopenharmony_ci 3861e5c31af7Sopenharmony_civoid RayTracingPipeline::setCreateFlags (const VkPipelineCreateFlags& pipelineCreateFlags) 3862e5c31af7Sopenharmony_ci{ 3863e5c31af7Sopenharmony_ci m_pipelineCreateFlags = pipelineCreateFlags; 3864e5c31af7Sopenharmony_ci} 3865e5c31af7Sopenharmony_ci 3866e5c31af7Sopenharmony_civoid RayTracingPipeline::setCreateFlags2 (const VkPipelineCreateFlags2KHR& pipelineCreateFlags2) 3867e5c31af7Sopenharmony_ci{ 3868e5c31af7Sopenharmony_ci m_pipelineCreateFlags2 = pipelineCreateFlags2; 3869e5c31af7Sopenharmony_ci} 3870e5c31af7Sopenharmony_ci 3871e5c31af7Sopenharmony_civoid RayTracingPipeline::setMaxRecursionDepth (const deUint32& maxRecursionDepth) 3872e5c31af7Sopenharmony_ci{ 3873e5c31af7Sopenharmony_ci m_maxRecursionDepth = maxRecursionDepth; 3874e5c31af7Sopenharmony_ci} 3875e5c31af7Sopenharmony_ci 3876e5c31af7Sopenharmony_civoid RayTracingPipeline::setMaxPayloadSize (const deUint32& maxPayloadSize) 3877e5c31af7Sopenharmony_ci{ 3878e5c31af7Sopenharmony_ci m_maxPayloadSize = maxPayloadSize; 3879e5c31af7Sopenharmony_ci} 3880e5c31af7Sopenharmony_ci 3881e5c31af7Sopenharmony_civoid RayTracingPipeline::setMaxAttributeSize (const deUint32& maxAttributeSize) 3882e5c31af7Sopenharmony_ci{ 3883e5c31af7Sopenharmony_ci m_maxAttributeSize = maxAttributeSize; 3884e5c31af7Sopenharmony_ci} 3885e5c31af7Sopenharmony_ci 3886e5c31af7Sopenharmony_civoid RayTracingPipeline::setDeferredOperation (const bool deferredOperation, 3887e5c31af7Sopenharmony_ci const deUint32 workerThreadCount) 3888e5c31af7Sopenharmony_ci{ 3889e5c31af7Sopenharmony_ci m_deferredOperation = deferredOperation; 3890e5c31af7Sopenharmony_ci m_workerThreadCount = workerThreadCount; 3891e5c31af7Sopenharmony_ci} 3892e5c31af7Sopenharmony_ci 3893e5c31af7Sopenharmony_civoid RayTracingPipeline::addDynamicState(const VkDynamicState& dynamicState) 3894e5c31af7Sopenharmony_ci{ 3895e5c31af7Sopenharmony_ci m_dynamicStates.push_back(dynamicState); 3896e5c31af7Sopenharmony_ci} 3897e5c31af7Sopenharmony_ci 3898e5c31af7Sopenharmony_ciclass RayTracingPropertiesKHR : public RayTracingProperties 3899e5c31af7Sopenharmony_ci{ 3900e5c31af7Sopenharmony_cipublic: 3901e5c31af7Sopenharmony_ci RayTracingPropertiesKHR () = delete; 3902e5c31af7Sopenharmony_ci RayTracingPropertiesKHR (const InstanceInterface& vki, 3903e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice); 3904e5c31af7Sopenharmony_ci virtual ~RayTracingPropertiesKHR (); 3905e5c31af7Sopenharmony_ci 3906e5c31af7Sopenharmony_ci uint32_t getShaderGroupHandleSize (void) override { return m_rayTracingPipelineProperties.shaderGroupHandleSize; } 3907e5c31af7Sopenharmony_ci uint32_t getShaderGroupHandleAlignment (void) override { return m_rayTracingPipelineProperties.shaderGroupHandleAlignment; } 3908e5c31af7Sopenharmony_ci deUint32 getShaderGroupHandleCaptureReplaySize (void) override { return m_rayTracingPipelineProperties.shaderGroupHandleCaptureReplaySize; } 3909e5c31af7Sopenharmony_ci uint32_t getMaxRecursionDepth (void) override { return m_rayTracingPipelineProperties.maxRayRecursionDepth; } 3910e5c31af7Sopenharmony_ci uint32_t getMaxShaderGroupStride (void) override { return m_rayTracingPipelineProperties.maxShaderGroupStride; } 3911e5c31af7Sopenharmony_ci uint32_t getShaderGroupBaseAlignment (void) override { return m_rayTracingPipelineProperties.shaderGroupBaseAlignment; } 3912e5c31af7Sopenharmony_ci uint64_t getMaxGeometryCount (void) override { return m_accelerationStructureProperties.maxGeometryCount; } 3913e5c31af7Sopenharmony_ci uint64_t getMaxInstanceCount (void) override { return m_accelerationStructureProperties.maxInstanceCount; } 3914e5c31af7Sopenharmony_ci uint64_t getMaxPrimitiveCount (void) override { return m_accelerationStructureProperties.maxPrimitiveCount; } 3915e5c31af7Sopenharmony_ci uint32_t getMaxDescriptorSetAccelerationStructures (void) override { return m_accelerationStructureProperties.maxDescriptorSetAccelerationStructures; } 3916e5c31af7Sopenharmony_ci uint32_t getMaxRayDispatchInvocationCount (void) override { return m_rayTracingPipelineProperties.maxRayDispatchInvocationCount; } 3917e5c31af7Sopenharmony_ci uint32_t getMaxRayHitAttributeSize (void) override { return m_rayTracingPipelineProperties.maxRayHitAttributeSize; } 3918e5c31af7Sopenharmony_ci uint32_t getMaxMemoryAllocationCount (void) override { return m_maxMemoryAllocationCount; } 3919e5c31af7Sopenharmony_ci 3920e5c31af7Sopenharmony_ciprotected: 3921e5c31af7Sopenharmony_ci VkPhysicalDeviceAccelerationStructurePropertiesKHR m_accelerationStructureProperties; 3922e5c31af7Sopenharmony_ci VkPhysicalDeviceRayTracingPipelinePropertiesKHR m_rayTracingPipelineProperties; 3923e5c31af7Sopenharmony_ci deUint32 m_maxMemoryAllocationCount; 3924e5c31af7Sopenharmony_ci}; 3925e5c31af7Sopenharmony_ci 3926e5c31af7Sopenharmony_ciRayTracingPropertiesKHR::~RayTracingPropertiesKHR () 3927e5c31af7Sopenharmony_ci{ 3928e5c31af7Sopenharmony_ci} 3929e5c31af7Sopenharmony_ci 3930e5c31af7Sopenharmony_ciRayTracingPropertiesKHR::RayTracingPropertiesKHR (const InstanceInterface& vki, 3931e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice) 3932e5c31af7Sopenharmony_ci : RayTracingProperties (vki, physicalDevice) 3933e5c31af7Sopenharmony_ci{ 3934e5c31af7Sopenharmony_ci m_accelerationStructureProperties = getPhysicalDeviceExtensionProperties(vki, physicalDevice); 3935e5c31af7Sopenharmony_ci m_rayTracingPipelineProperties = getPhysicalDeviceExtensionProperties(vki, physicalDevice); 3936e5c31af7Sopenharmony_ci m_maxMemoryAllocationCount = getPhysicalDeviceProperties(vki, physicalDevice).limits.maxMemoryAllocationCount; 3937e5c31af7Sopenharmony_ci} 3938e5c31af7Sopenharmony_ci 3939e5c31af7Sopenharmony_cide::MovePtr<RayTracingProperties> makeRayTracingProperties (const InstanceInterface& vki, 3940e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice) 3941e5c31af7Sopenharmony_ci{ 3942e5c31af7Sopenharmony_ci return de::MovePtr<RayTracingProperties>(new RayTracingPropertiesKHR(vki, physicalDevice)); 3943e5c31af7Sopenharmony_ci} 3944e5c31af7Sopenharmony_ci 3945e5c31af7Sopenharmony_cistatic inline void cmdTraceRaysKHR (const DeviceInterface& vk, 3946e5c31af7Sopenharmony_ci VkCommandBuffer commandBuffer, 3947e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion, 3948e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion, 3949e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion, 3950e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion, 3951e5c31af7Sopenharmony_ci deUint32 width, 3952e5c31af7Sopenharmony_ci deUint32 height, 3953e5c31af7Sopenharmony_ci deUint32 depth) 3954e5c31af7Sopenharmony_ci{ 3955e5c31af7Sopenharmony_ci return vk.cmdTraceRaysKHR(commandBuffer, 3956e5c31af7Sopenharmony_ci raygenShaderBindingTableRegion, 3957e5c31af7Sopenharmony_ci missShaderBindingTableRegion, 3958e5c31af7Sopenharmony_ci hitShaderBindingTableRegion, 3959e5c31af7Sopenharmony_ci callableShaderBindingTableRegion, 3960e5c31af7Sopenharmony_ci width, 3961e5c31af7Sopenharmony_ci height, 3962e5c31af7Sopenharmony_ci depth); 3963e5c31af7Sopenharmony_ci} 3964e5c31af7Sopenharmony_ci 3965e5c31af7Sopenharmony_ci 3966e5c31af7Sopenharmony_civoid cmdTraceRays (const DeviceInterface& vk, 3967e5c31af7Sopenharmony_ci VkCommandBuffer commandBuffer, 3968e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion, 3969e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion, 3970e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion, 3971e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion, 3972e5c31af7Sopenharmony_ci deUint32 width, 3973e5c31af7Sopenharmony_ci deUint32 height, 3974e5c31af7Sopenharmony_ci deUint32 depth) 3975e5c31af7Sopenharmony_ci{ 3976e5c31af7Sopenharmony_ci DE_ASSERT(raygenShaderBindingTableRegion != DE_NULL); 3977e5c31af7Sopenharmony_ci DE_ASSERT(missShaderBindingTableRegion != DE_NULL); 3978e5c31af7Sopenharmony_ci DE_ASSERT(hitShaderBindingTableRegion != DE_NULL); 3979e5c31af7Sopenharmony_ci DE_ASSERT(callableShaderBindingTableRegion != DE_NULL); 3980e5c31af7Sopenharmony_ci 3981e5c31af7Sopenharmony_ci return cmdTraceRaysKHR(vk, 3982e5c31af7Sopenharmony_ci commandBuffer, 3983e5c31af7Sopenharmony_ci raygenShaderBindingTableRegion, 3984e5c31af7Sopenharmony_ci missShaderBindingTableRegion, 3985e5c31af7Sopenharmony_ci hitShaderBindingTableRegion, 3986e5c31af7Sopenharmony_ci callableShaderBindingTableRegion, 3987e5c31af7Sopenharmony_ci width, 3988e5c31af7Sopenharmony_ci height, 3989e5c31af7Sopenharmony_ci depth); 3990e5c31af7Sopenharmony_ci} 3991e5c31af7Sopenharmony_ci 3992e5c31af7Sopenharmony_cistatic inline void cmdTraceRaysIndirectKHR (const DeviceInterface& vk, 3993e5c31af7Sopenharmony_ci VkCommandBuffer commandBuffer, 3994e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion, 3995e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion, 3996e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion, 3997e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion, 3998e5c31af7Sopenharmony_ci VkDeviceAddress indirectDeviceAddress ) 3999e5c31af7Sopenharmony_ci{ 4000e5c31af7Sopenharmony_ci DE_ASSERT(raygenShaderBindingTableRegion != DE_NULL); 4001e5c31af7Sopenharmony_ci DE_ASSERT(missShaderBindingTableRegion != DE_NULL); 4002e5c31af7Sopenharmony_ci DE_ASSERT(hitShaderBindingTableRegion != DE_NULL); 4003e5c31af7Sopenharmony_ci DE_ASSERT(callableShaderBindingTableRegion != DE_NULL); 4004e5c31af7Sopenharmony_ci DE_ASSERT(indirectDeviceAddress != 0); 4005e5c31af7Sopenharmony_ci 4006e5c31af7Sopenharmony_ci return vk.cmdTraceRaysIndirectKHR(commandBuffer, 4007e5c31af7Sopenharmony_ci raygenShaderBindingTableRegion, 4008e5c31af7Sopenharmony_ci missShaderBindingTableRegion, 4009e5c31af7Sopenharmony_ci hitShaderBindingTableRegion, 4010e5c31af7Sopenharmony_ci callableShaderBindingTableRegion, 4011e5c31af7Sopenharmony_ci indirectDeviceAddress); 4012e5c31af7Sopenharmony_ci} 4013e5c31af7Sopenharmony_ci 4014e5c31af7Sopenharmony_civoid cmdTraceRaysIndirect (const DeviceInterface& vk, 4015e5c31af7Sopenharmony_ci VkCommandBuffer commandBuffer, 4016e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion, 4017e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion, 4018e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion, 4019e5c31af7Sopenharmony_ci const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion, 4020e5c31af7Sopenharmony_ci VkDeviceAddress indirectDeviceAddress) 4021e5c31af7Sopenharmony_ci{ 4022e5c31af7Sopenharmony_ci return cmdTraceRaysIndirectKHR(vk, 4023e5c31af7Sopenharmony_ci commandBuffer, 4024e5c31af7Sopenharmony_ci raygenShaderBindingTableRegion, 4025e5c31af7Sopenharmony_ci missShaderBindingTableRegion, 4026e5c31af7Sopenharmony_ci hitShaderBindingTableRegion, 4027e5c31af7Sopenharmony_ci callableShaderBindingTableRegion, 4028e5c31af7Sopenharmony_ci indirectDeviceAddress); 4029e5c31af7Sopenharmony_ci} 4030e5c31af7Sopenharmony_ci 4031e5c31af7Sopenharmony_cistatic inline void cmdTraceRaysIndirect2KHR (const DeviceInterface& vk, 4032e5c31af7Sopenharmony_ci VkCommandBuffer commandBuffer, 4033e5c31af7Sopenharmony_ci VkDeviceAddress indirectDeviceAddress ) 4034e5c31af7Sopenharmony_ci{ 4035e5c31af7Sopenharmony_ci DE_ASSERT(indirectDeviceAddress != 0); 4036e5c31af7Sopenharmony_ci 4037e5c31af7Sopenharmony_ci return vk.cmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress); 4038e5c31af7Sopenharmony_ci} 4039e5c31af7Sopenharmony_ci 4040e5c31af7Sopenharmony_civoid cmdTraceRaysIndirect2 (const DeviceInterface& vk, 4041e5c31af7Sopenharmony_ci VkCommandBuffer commandBuffer, 4042e5c31af7Sopenharmony_ci VkDeviceAddress indirectDeviceAddress) 4043e5c31af7Sopenharmony_ci{ 4044e5c31af7Sopenharmony_ci return cmdTraceRaysIndirect2KHR(vk, commandBuffer, indirectDeviceAddress); 4045e5c31af7Sopenharmony_ci} 4046e5c31af7Sopenharmony_ci 4047e5c31af7Sopenharmony_ci#else 4048e5c31af7Sopenharmony_ci 4049e5c31af7Sopenharmony_cideUint32 rayTracingDefineAnything() 4050e5c31af7Sopenharmony_ci{ 4051e5c31af7Sopenharmony_ci return 0; 4052e5c31af7Sopenharmony_ci} 4053e5c31af7Sopenharmony_ci 4054e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 4055e5c31af7Sopenharmony_ci 4056e5c31af7Sopenharmony_ci} // vk 4057