1 /*-------------------------------------------------------------------------
5 * Copyright (c) 2020 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Utilities for creating commonly used Vulkan objects
22 *//*--------------------------------------------------------------------*/
24 #include "vkRayTracingUtil.hpp"
26 #include "vkRefUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkObjUtil.hpp"
29 #include "vkBarrierUtil.hpp"
31 #include "deStringUtil.hpp"
40 struct DeferredThreadParams
42 const DeviceInterface& vk;
44 VkDeferredOperationKHR deferredOperation;
48 std::string getFormatSimpleName (vk::VkFormat format)
50 constexpr size_t kPrefixLen = 10; // strlen("VK_FORMAT_")
51 return de::toLower(de::toString(format).substr(kPrefixLen));
54 // Returns true if VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR needs to be supported for the given format.
55 static bool isMandatoryAccelerationStructureVertexBufferFormat (vk::VkFormat format)
57 bool mandatory = false;
61 case VK_FORMAT_R32G32_SFLOAT:
62 case VK_FORMAT_R32G32B32_SFLOAT:
63 case VK_FORMAT_R16G16_SFLOAT:
64 case VK_FORMAT_R16G16B16A16_SFLOAT:
65 case VK_FORMAT_R16G16_SNORM:
66 case VK_FORMAT_R16G16B16A16_SNORM:
76 void checkAccelerationStructureVertexBufferFormat (const vk::InstanceInterface &vki, vk::VkPhysicalDevice physicalDevice, vk::VkFormat format)
78 const vk::VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
80 if ((formatProperties.bufferFeatures & vk::VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR) == 0u)
82 const std::string errorMsg = "Format not supported for acceleration structure vertex buffers";
83 if (isMandatoryAccelerationStructureVertexBufferFormat(format))
85 TCU_THROW(NotSupportedError, errorMsg);
89 std::string getCommonRayGenerationShader (void)
93 "#extension GL_EXT_ray_tracing : require\n"
94 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
95 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
99 " uint rayFlags = 0;\n"
100 " uint cullMask = 0xFF;\n"
101 " float tmin = 0.0;\n"
102 " float tmax = 9.0;\n"
103 " 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"
104 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
105 " traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
109 RaytracedGeometryBase::RaytracedGeometryBase (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType)
110 : m_geometryType (geometryType)
111 , m_vertexFormat (vertexFormat)
112 , m_indexType (indexType)
113 , m_geometryFlags ((VkGeometryFlagsKHR)0u)
115 if (m_geometryType == VK_GEOMETRY_TYPE_AABBS_KHR)
116 DE_ASSERT(m_vertexFormat == VK_FORMAT_R32G32B32_SFLOAT);
119 RaytracedGeometryBase::~RaytracedGeometryBase ()
123 struct GeometryBuilderParams
125 VkGeometryTypeKHR geometryType;
129 template <typename V, typename I>
130 RaytracedGeometryBase* buildRaytracedGeometry (const GeometryBuilderParams& params)
132 return new RaytracedGeometry<V, I>(params.geometryType, (params.usePadding ? 1u : 0u));
135 de::SharedPtr<RaytracedGeometryBase> makeRaytracedGeometry (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType, bool padVertices)
137 const GeometryBuilderParams builderParams { geometryType, padVertices };
139 switch (vertexFormat)
141 case VK_FORMAT_R32G32_SFLOAT:
144 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec2, deUint16>(builderParams));
145 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec2, deUint32>(builderParams));
146 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec2, EmptyIndex>(builderParams));
147 default: TCU_THROW(InternalError, "Wrong index type");
149 case VK_FORMAT_R32G32B32_SFLOAT:
152 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec3, deUint16>(builderParams));
153 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec3, deUint32>(builderParams));
154 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec3, EmptyIndex>(builderParams));
155 default: TCU_THROW(InternalError, "Wrong index type");
157 case VK_FORMAT_R32G32B32A32_SFLOAT:
160 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec4, deUint16>(builderParams));
161 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec4, deUint32>(builderParams));
162 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::Vec4, EmptyIndex>(builderParams));
163 default: TCU_THROW(InternalError, "Wrong index type");
165 case VK_FORMAT_R16G16_SFLOAT:
168 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16, deUint16>(builderParams));
169 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16, deUint32>(builderParams));
170 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16, EmptyIndex>(builderParams));
171 default: TCU_THROW(InternalError, "Wrong index type");
173 case VK_FORMAT_R16G16B16_SFLOAT:
176 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16, deUint16>(builderParams));
177 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16, deUint32>(builderParams));
178 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16, EmptyIndex>(builderParams));
179 default: TCU_THROW(InternalError, "Wrong index type");
181 case VK_FORMAT_R16G16B16A16_SFLOAT:
184 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16, deUint16>(builderParams));
185 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16, deUint32>(builderParams));
186 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16, EmptyIndex>(builderParams));
187 default: TCU_THROW(InternalError, "Wrong index type");
189 case VK_FORMAT_R16G16_SNORM:
192 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16SNorm, deUint16>(builderParams));
193 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16SNorm, deUint32>(builderParams));
194 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_16SNorm, EmptyIndex>(builderParams));
195 default: TCU_THROW(InternalError, "Wrong index type");
197 case VK_FORMAT_R16G16B16_SNORM:
200 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16SNorm, deUint16>(builderParams));
201 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16SNorm, deUint32>(builderParams));
202 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_16SNorm, EmptyIndex>(builderParams));
203 default: TCU_THROW(InternalError, "Wrong index type");
205 case VK_FORMAT_R16G16B16A16_SNORM:
208 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16SNorm, deUint16>(builderParams));
209 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16SNorm, deUint32>(builderParams));
210 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_16SNorm, EmptyIndex>(builderParams));
211 default: TCU_THROW(InternalError, "Wrong index type");
213 case VK_FORMAT_R64G64_SFLOAT:
216 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec2, deUint16>(builderParams));
217 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec2, deUint32>(builderParams));
218 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec2, EmptyIndex>(builderParams));
219 default: TCU_THROW(InternalError, "Wrong index type");
221 case VK_FORMAT_R64G64B64_SFLOAT:
224 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec3, deUint16>(builderParams));
225 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec3, deUint32>(builderParams));
226 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec3, EmptyIndex>(builderParams));
227 default: TCU_THROW(InternalError, "Wrong index type");
229 case VK_FORMAT_R64G64B64A64_SFLOAT:
232 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec4, deUint16>(builderParams));
233 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec4, deUint32>(builderParams));
234 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<tcu::DVec4, EmptyIndex>(builderParams));
235 default: TCU_THROW(InternalError, "Wrong index type");
237 case VK_FORMAT_R8G8_SNORM:
240 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_8SNorm, deUint16>(builderParams));
241 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_8SNorm, deUint32>(builderParams));
242 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec2_8SNorm, EmptyIndex>(builderParams));
243 default: TCU_THROW(InternalError, "Wrong index type");
245 case VK_FORMAT_R8G8B8_SNORM:
248 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_8SNorm, deUint16>(builderParams));
249 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_8SNorm, deUint32>(builderParams));
250 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec3_8SNorm, EmptyIndex>(builderParams));
251 default: TCU_THROW(InternalError, "Wrong index type");
253 case VK_FORMAT_R8G8B8A8_SNORM:
256 case VK_INDEX_TYPE_UINT16: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_8SNorm, deUint16>(builderParams));
257 case VK_INDEX_TYPE_UINT32: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_8SNorm, deUint32>(builderParams));
258 case VK_INDEX_TYPE_NONE_KHR: return de::SharedPtr<RaytracedGeometryBase>(buildRaytracedGeometry<Vec4_8SNorm, EmptyIndex>(builderParams));
259 default: TCU_THROW(InternalError, "Wrong index type");
262 TCU_THROW(InternalError, "Wrong vertex format");
267 VkDeviceAddress getBufferDeviceAddress ( const DeviceInterface& vk,
268 const VkDevice device,
269 const VkBuffer buffer,
270 VkDeviceSize offset )
273 if (buffer == DE_NULL)
276 VkBufferDeviceAddressInfo deviceAddressInfo
278 VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, // VkStructureType sType
279 DE_NULL, // const void* pNext
280 buffer // VkBuffer buffer;
282 return vk.getBufferDeviceAddress(device, &deviceAddressInfo) + offset;
286 static inline VkDeviceOrHostAddressConstKHR makeDeviceOrHostAddressConstKHR (const void* hostAddress)
288 // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
289 VkDeviceOrHostAddressConstKHR result;
291 deMemset(&result, 0, sizeof(result));
293 result.hostAddress = hostAddress;
298 static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (void* hostAddress)
300 // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
301 VkDeviceOrHostAddressKHR result;
303 deMemset(&result, 0, sizeof(result));
305 result.hostAddress = hostAddress;
310 static inline VkDeviceOrHostAddressConstKHR makeDeviceOrHostAddressConstKHR (const DeviceInterface& vk,
311 const VkDevice device,
315 // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
316 VkDeviceOrHostAddressConstKHR result;
318 deMemset(&result, 0, sizeof(result));
320 VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
322 VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType;
323 DE_NULL, // const void* pNext;
324 buffer, // VkBuffer buffer
326 result.deviceAddress = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo) + offset;
331 static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (const DeviceInterface& vk,
332 const VkDevice device,
336 // VS2015: Cannot create as a const due to cannot assign hostAddress due to it is a second field. Only assigning of first field supported.
337 VkDeviceOrHostAddressKHR result;
339 deMemset(&result, 0, sizeof(result));
341 VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
343 VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType;
344 DE_NULL, // const void* pNext;
345 buffer, // VkBuffer buffer
347 result.deviceAddress = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo) + offset;
352 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryTrianglesDataKHR& triangles)
354 VkAccelerationStructureGeometryDataKHR result;
356 deMemset(&result, 0, sizeof(result));
358 result.triangles = triangles;
363 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryAabbsDataKHR& aabbs)
365 VkAccelerationStructureGeometryDataKHR result;
367 deMemset(&result, 0, sizeof(result));
369 result.aabbs = aabbs;
374 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureInstancesDataKHR (const VkAccelerationStructureGeometryInstancesDataKHR& instances)
376 VkAccelerationStructureGeometryDataKHR result;
378 deMemset(&result, 0, sizeof(result));
380 result.instances = instances;
385 static inline VkAccelerationStructureInstanceKHR makeVkAccelerationStructureInstanceKHR (const VkTransformMatrixKHR& transform,
386 deUint32 instanceCustomIndex,
388 deUint32 instanceShaderBindingTableRecordOffset,
389 VkGeometryInstanceFlagsKHR flags,
390 deUint64 accelerationStructureReference)
392 VkAccelerationStructureInstanceKHR instance = { transform, 0, 0, 0, 0, accelerationStructureReference };
393 instance.instanceCustomIndex = instanceCustomIndex & 0xFFFFFF;
394 instance.mask = mask & 0xFF;
395 instance.instanceShaderBindingTableRecordOffset = instanceShaderBindingTableRecordOffset & 0xFFFFFF;
396 instance.flags = flags & 0xFF;
400 VkResult getRayTracingShaderGroupHandlesKHR (const DeviceInterface& vk,
401 const VkDevice device,
402 const VkPipeline pipeline,
403 const deUint32 firstGroup,
404 const deUint32 groupCount,
405 const deUintptr dataSize,
408 return vk.getRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData);
411 VkResult getRayTracingShaderGroupHandles (const DeviceInterface& vk,
412 const VkDevice device,
413 const VkPipeline pipeline,
414 const deUint32 firstGroup,
415 const deUint32 groupCount,
416 const deUintptr dataSize,
419 return getRayTracingShaderGroupHandlesKHR(vk, device, pipeline, firstGroup, groupCount, dataSize, pData);
422 VkResult finishDeferredOperation (const DeviceInterface& vk,
424 VkDeferredOperationKHR deferredOperation)
426 VkResult result = vk.deferredOperationJoinKHR(device, deferredOperation);
428 while (result == VK_THREAD_IDLE_KHR)
430 std::this_thread::yield();
431 result = vk.deferredOperationJoinKHR(device, deferredOperation);
438 // Deferred operation has finished. Query its result
439 result = vk.getDeferredOperationResultKHR(device, deferredOperation);
444 case VK_THREAD_DONE_KHR:
446 // Deferred operation is being wrapped up by another thread
447 // wait for that thread to finish
450 std::this_thread::yield();
451 result = vk.getDeferredOperationResultKHR(device, deferredOperation);
452 } while (result == VK_NOT_READY);
468 void finishDeferredOperationThreaded (DeferredThreadParams* deferredThreadParams)
470 deferredThreadParams->result = finishDeferredOperation(deferredThreadParams->vk, deferredThreadParams->device, deferredThreadParams->deferredOperation);
473 void finishDeferredOperation (const DeviceInterface& vk,
475 VkDeferredOperationKHR deferredOperation,
476 const deUint32 workerThreadCount,
477 const bool operationNotDeferred)
480 if (operationNotDeferred)
482 // when the operation deferral returns VK_OPERATION_NOT_DEFERRED_KHR,
483 // the deferred operation should act as if no command was deferred
484 VK_CHECK(vk.getDeferredOperationResultKHR(device, deferredOperation));
487 // there is not need to join any threads to the deferred operation,
488 // so below can be skipped.
492 if (workerThreadCount == 0)
494 VK_CHECK(finishDeferredOperation(vk, device, deferredOperation));
498 const deUint32 maxThreadCountSupported = deMinu32(256u, vk.getDeferredOperationMaxConcurrencyKHR(device, deferredOperation));
499 const deUint32 requestedThreadCount = workerThreadCount;
500 const deUint32 testThreadCount = requestedThreadCount == std::numeric_limits<deUint32>::max() ? maxThreadCountSupported : requestedThreadCount;
502 if (maxThreadCountSupported == 0)
503 TCU_FAIL("vkGetDeferredOperationMaxConcurrencyKHR must not return 0");
505 const DeferredThreadParams deferredThreadParams =
507 vk, // const DeviceInterface& vk;
508 device, // VkDevice device;
509 deferredOperation, // VkDeferredOperationKHR deferredOperation;
510 VK_RESULT_MAX_ENUM, // VResult result;
512 std::vector<DeferredThreadParams> threadParams (testThreadCount, deferredThreadParams);
513 std::vector<de::MovePtr<std::thread> > threads (testThreadCount);
514 bool executionResult = false;
516 DE_ASSERT(threads.size() > 0 && threads.size() == testThreadCount);
518 for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx)
519 threads[threadNdx] = de::MovePtr<std::thread>(new std::thread(finishDeferredOperationThreaded, &threadParams[threadNdx]));
521 for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx)
522 threads[threadNdx]->join();
524 for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx)
525 if (threadParams[threadNdx].result == VK_SUCCESS)
526 executionResult = true;
528 if (!executionResult)
529 TCU_FAIL("Neither reported VK_SUCCESS");
533 SerialStorage::SerialStorage (const DeviceInterface& vk,
534 const VkDevice device,
535 Allocator& allocator,
536 const VkAccelerationStructureBuildTypeKHR buildType,
537 const VkDeviceSize storageSize)
538 : m_buildType (buildType)
539 , m_storageSize(storageSize)
541 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(storageSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
544 m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
546 catch (const tcu::NotSupportedError&)
548 // retry without Cached flag
549 m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
553 VkDeviceOrHostAddressKHR SerialStorage::getAddress (const DeviceInterface& vk,
554 const VkDevice device)
556 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
557 return makeDeviceOrHostAddressKHR(vk, device, m_buffer->get(), 0);
559 return makeDeviceOrHostAddressKHR(m_buffer->getAllocation().getHostPtr());
562 VkDeviceOrHostAddressConstKHR SerialStorage::getAddressConst (const DeviceInterface& vk,
563 const VkDevice device)
565 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
566 return makeDeviceOrHostAddressConstKHR(vk, device, m_buffer->get(), 0);
568 return makeDeviceOrHostAddressConstKHR(m_buffer->getAllocation().getHostPtr());
571 VkDeviceSize SerialStorage::getStorageSize ()
573 return m_storageSize;
576 deUint64 SerialStorage::getDeserializedSize ()
579 const deUint8* startPtr = static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr());
581 DE_ASSERT(sizeof(result) == DESERIALIZED_SIZE_SIZE);
583 deMemcpy(&result, startPtr + DESERIALIZED_SIZE_OFFSET, sizeof(result));
588 BottomLevelAccelerationStructure::~BottomLevelAccelerationStructure ()
592 BottomLevelAccelerationStructure::BottomLevelAccelerationStructure ()
593 : m_structureSize (0u)
594 , m_updateScratchSize (0u)
595 , m_buildScratchSize (0u)
599 void BottomLevelAccelerationStructure::setGeometryData (const std::vector<tcu::Vec3>& geometryData,
600 const bool triangles,
601 const VkGeometryFlagsKHR geometryFlags)
604 DE_ASSERT((geometryData.size() % 3) == 0);
606 DE_ASSERT((geometryData.size() % 2) == 0);
608 setGeometryCount(1u);
610 addGeometry(geometryData, triangles, geometryFlags);
613 void BottomLevelAccelerationStructure::setDefaultGeometryData (const VkShaderStageFlagBits testStage,
614 const VkGeometryFlagsKHR geometryFlags)
616 bool trianglesData = false;
618 std::vector<tcu::Vec3> geometryData;
622 case VK_SHADER_STAGE_RAYGEN_BIT_KHR: z = -1.0f; trianglesData = true; break;
623 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: z = -1.0f; trianglesData = true; break;
624 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: z = -1.0f; trianglesData = true; break;
625 case VK_SHADER_STAGE_MISS_BIT_KHR: z = -9.9f; trianglesData = true; break;
626 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: z = -1.0f; trianglesData = false; break;
627 case VK_SHADER_STAGE_CALLABLE_BIT_KHR: z = -1.0f; trianglesData = true; break;
628 default: TCU_THROW(InternalError, "Unacceptable stage");
633 geometryData.reserve(6);
635 geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z));
636 geometryData.push_back(tcu::Vec3(-1.0f, +1.0f, z));
637 geometryData.push_back(tcu::Vec3(+1.0f, -1.0f, z));
638 geometryData.push_back(tcu::Vec3(-1.0f, +1.0f, z));
639 geometryData.push_back(tcu::Vec3(+1.0f, -1.0f, z));
640 geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z));
644 geometryData.reserve(2);
646 geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z));
647 geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z));
650 setGeometryCount(1u);
652 addGeometry(geometryData, trianglesData, geometryFlags);
655 void BottomLevelAccelerationStructure::setGeometryCount (const size_t geometryCount)
657 m_geometriesData.clear();
659 m_geometriesData.reserve(geometryCount);
662 void BottomLevelAccelerationStructure::addGeometry (de::SharedPtr<RaytracedGeometryBase>& raytracedGeometry)
664 m_geometriesData.push_back(raytracedGeometry);
667 void BottomLevelAccelerationStructure::addGeometry (const std::vector<tcu::Vec3>& geometryData,
668 const bool triangles,
669 const VkGeometryFlagsKHR geometryFlags)
671 DE_ASSERT(geometryData.size() > 0);
672 DE_ASSERT((triangles && geometryData.size() % 3 == 0) || (!triangles && geometryData.size() % 2 == 0));
675 for (size_t posNdx = 0; posNdx < geometryData.size() / 2; ++posNdx)
677 DE_ASSERT(geometryData[2 * posNdx].x() <= geometryData[2 * posNdx + 1].x());
678 DE_ASSERT(geometryData[2 * posNdx].y() <= geometryData[2 * posNdx + 1].y());
679 DE_ASSERT(geometryData[2 * posNdx].z() <= geometryData[2 * posNdx + 1].z());
682 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);
683 for (auto it = begin(geometryData), eit = end(geometryData); it != eit; ++it)
684 geometry->addVertex(*it);
686 geometry->setGeometryFlags(geometryFlags);
687 addGeometry(geometry);
690 VkDeviceSize BottomLevelAccelerationStructure::getStructureSize() const
692 return m_structureSize;
695 BufferWithMemory* createVertexBuffer (const DeviceInterface& vk,
696 const VkDevice device,
697 Allocator& allocator,
698 const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData)
700 DE_ASSERT(geometriesData.size() != 0);
702 VkDeviceSize bufferSizeBytes = 0;
703 for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
704 bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getVertexByteSize(),8);
706 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
707 return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
710 void updateVertexBuffer (const DeviceInterface& vk,
711 const VkDevice device,
712 const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData,
713 BufferWithMemory* vertexBuffer)
715 const Allocation& geometryAlloc = vertexBuffer->getAllocation();
716 deUint8* bufferStart = static_cast<deUint8*>(geometryAlloc.getHostPtr());
717 VkDeviceSize bufferOffset = 0;
719 for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
721 const void* geometryPtr = geometriesData[geometryNdx]->getVertexPointer();
722 const size_t geometryPtrSize = geometriesData[geometryNdx]->getVertexByteSize();
724 deMemcpy(&bufferStart[bufferOffset], geometryPtr, geometryPtrSize);
726 bufferOffset += deAlignSize(geometryPtrSize,8);
729 flushMappedMemoryRange(vk, device, geometryAlloc.getMemory(), geometryAlloc.getOffset(), VK_WHOLE_SIZE);
732 BufferWithMemory* createIndexBuffer (const DeviceInterface& vk,
733 const VkDevice device,
734 Allocator& allocator,
735 const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData)
737 DE_ASSERT(!geometriesData.empty());
739 VkDeviceSize bufferSizeBytes = 0;
740 for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
741 if(geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
742 bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getIndexByteSize(),8);
744 if (bufferSizeBytes == 0)
747 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
748 return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
751 void updateIndexBuffer (const DeviceInterface& vk,
752 const VkDevice device,
753 const std::vector<de::SharedPtr<RaytracedGeometryBase>>& geometriesData,
754 BufferWithMemory* indexBuffer)
756 const Allocation& indexAlloc = indexBuffer->getAllocation();
757 deUint8* bufferStart = static_cast<deUint8*>(indexAlloc.getHostPtr());
758 VkDeviceSize bufferOffset = 0;
760 for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
762 if (geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
764 const void* indexPtr = geometriesData[geometryNdx]->getIndexPointer();
765 const size_t indexPtrSize = geometriesData[geometryNdx]->getIndexByteSize();
767 deMemcpy(&bufferStart[bufferOffset], indexPtr, indexPtrSize);
769 bufferOffset += deAlignSize(indexPtrSize, 8);
773 flushMappedMemoryRange(vk, device, indexAlloc.getMemory(), indexAlloc.getOffset(), VK_WHOLE_SIZE);
776 class BottomLevelAccelerationStructureKHR : public BottomLevelAccelerationStructure
779 static deUint32 getRequiredAllocationCount (void);
781 BottomLevelAccelerationStructureKHR ();
782 BottomLevelAccelerationStructureKHR (const BottomLevelAccelerationStructureKHR& other) = delete;
783 virtual ~BottomLevelAccelerationStructureKHR ();
785 void setBuildType (const VkAccelerationStructureBuildTypeKHR buildType) override;
786 void setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags) override;
787 void setCreateGeneric (bool createGeneric) override;
788 void setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags) override;
789 void setBuildWithoutGeometries (bool buildWithoutGeometries) override;
790 void setBuildWithoutPrimitives (bool buildWithoutPrimitives) override;
791 void setDeferredOperation (const bool deferredOperation,
792 const deUint32 workerThreadCount) override;
793 void setUseArrayOfPointers (const bool useArrayOfPointers) override;
794 void setIndirectBuildParameters (const VkBuffer indirectBuffer,
795 const VkDeviceSize indirectBufferOffset,
796 const deUint32 indirectBufferStride) override;
797 VkBuildAccelerationStructureFlagsKHR getBuildFlags () const override;
799 void create (const DeviceInterface& vk,
800 const VkDevice device,
801 Allocator& allocator,
802 VkDeviceSize structureSize,
803 VkDeviceAddress deviceAddress = 0u ) override;
804 void build (const DeviceInterface& vk,
805 const VkDevice device,
806 const VkCommandBuffer cmdBuffer) override;
807 void copyFrom (const DeviceInterface& vk,
808 const VkDevice device,
809 const VkCommandBuffer cmdBuffer,
810 BottomLevelAccelerationStructure* accelerationStructure,
811 bool compactCopy) override;
813 void serialize (const DeviceInterface& vk,
814 const VkDevice device,
815 const VkCommandBuffer cmdBuffer,
816 SerialStorage* storage) override;
817 void deserialize (const DeviceInterface& vk,
818 const VkDevice device,
819 const VkCommandBuffer cmdBuffer,
820 SerialStorage* storage) override;
822 const VkAccelerationStructureKHR* getPtr (void) const override;
825 VkAccelerationStructureBuildTypeKHR m_buildType;
826 VkAccelerationStructureCreateFlagsKHR m_createFlags;
827 bool m_createGeneric;
828 VkBuildAccelerationStructureFlagsKHR m_buildFlags;
829 bool m_buildWithoutGeometries;
830 bool m_buildWithoutPrimitives;
831 bool m_deferredOperation;
832 deUint32 m_workerThreadCount;
833 bool m_useArrayOfPointers;
834 de::MovePtr<BufferWithMemory> m_accelerationStructureBuffer;
835 de::MovePtr<BufferWithMemory> m_vertexBuffer;
836 de::MovePtr<BufferWithMemory> m_indexBuffer;
837 de::MovePtr<BufferWithMemory> m_deviceScratchBuffer;
838 std::vector<deUint8> m_hostScratchBuffer;
839 Move<VkAccelerationStructureKHR> m_accelerationStructureKHR;
840 VkBuffer m_indirectBuffer;
841 VkDeviceSize m_indirectBufferOffset;
842 deUint32 m_indirectBufferStride;
844 void prepareGeometries (const DeviceInterface& vk,
845 const VkDevice device,
846 std::vector<VkAccelerationStructureGeometryKHR>& accelerationStructureGeometriesKHR,
847 std::vector<VkAccelerationStructureGeometryKHR*>& accelerationStructureGeometriesKHRPointers,
848 std::vector<VkAccelerationStructureBuildRangeInfoKHR>& accelerationStructureBuildRangeInfoKHR,
849 std::vector<deUint32>& maxPrimitiveCounts);
852 deUint32 BottomLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
855 de::MovePtr<BufferWithMemory> m_geometryBuffer; // but only when m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR
856 de::MovePtr<Allocation> m_accelerationStructureAlloc;
857 de::MovePtr<BufferWithMemory> m_deviceScratchBuffer;
862 BottomLevelAccelerationStructureKHR::~BottomLevelAccelerationStructureKHR ()
866 BottomLevelAccelerationStructureKHR::BottomLevelAccelerationStructureKHR ()
867 : BottomLevelAccelerationStructure ()
868 , m_buildType (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
870 , m_createGeneric (false)
872 , m_buildWithoutGeometries (false)
873 , m_buildWithoutPrimitives (false)
874 , m_deferredOperation (false)
875 , m_workerThreadCount (0)
876 , m_useArrayOfPointers (false)
877 , m_accelerationStructureBuffer (DE_NULL)
878 , m_vertexBuffer (DE_NULL)
879 , m_indexBuffer (DE_NULL)
880 , m_deviceScratchBuffer (DE_NULL)
881 , m_accelerationStructureKHR ()
882 , m_indirectBuffer (DE_NULL)
883 , m_indirectBufferOffset (0)
884 , m_indirectBufferStride (0)
888 void BottomLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR buildType)
890 m_buildType = buildType;
893 void BottomLevelAccelerationStructureKHR::setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags)
895 m_createFlags = createFlags;
898 void BottomLevelAccelerationStructureKHR::setCreateGeneric (bool createGeneric)
900 m_createGeneric = createGeneric;
903 void BottomLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags)
905 m_buildFlags = buildFlags;
908 void BottomLevelAccelerationStructureKHR::setBuildWithoutGeometries (bool buildWithoutGeometries)
910 m_buildWithoutGeometries = buildWithoutGeometries;
913 void BottomLevelAccelerationStructureKHR::setBuildWithoutPrimitives (bool buildWithoutPrimitives)
915 m_buildWithoutPrimitives = buildWithoutPrimitives;
918 void BottomLevelAccelerationStructureKHR::setDeferredOperation (const bool deferredOperation,
919 const deUint32 workerThreadCount)
921 m_deferredOperation = deferredOperation;
922 m_workerThreadCount = workerThreadCount;
925 void BottomLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool useArrayOfPointers)
927 m_useArrayOfPointers = useArrayOfPointers;
930 void BottomLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer indirectBuffer,
931 const VkDeviceSize indirectBufferOffset,
932 const deUint32 indirectBufferStride)
934 m_indirectBuffer = indirectBuffer;
935 m_indirectBufferOffset = indirectBufferOffset;
936 m_indirectBufferStride = indirectBufferStride;
939 VkBuildAccelerationStructureFlagsKHR BottomLevelAccelerationStructureKHR::getBuildFlags () const
944 void BottomLevelAccelerationStructureKHR::create (const DeviceInterface& vk,
945 const VkDevice device,
946 Allocator& allocator,
947 VkDeviceSize structureSize,
948 VkDeviceAddress deviceAddress)
950 // AS may be built from geometries using vkCmdBuildAccelerationStructuresKHR / vkBuildAccelerationStructuresKHR
951 // 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 ).
952 DE_ASSERT(!m_geometriesData.empty() != !(structureSize == 0)); // logical xor
954 if (structureSize == 0)
956 std::vector<VkAccelerationStructureGeometryKHR> accelerationStructureGeometriesKHR;
957 std::vector<VkAccelerationStructureGeometryKHR*> accelerationStructureGeometriesKHRPointers;
958 std::vector<VkAccelerationStructureBuildRangeInfoKHR> accelerationStructureBuildRangeInfoKHR;
959 std::vector<deUint32> maxPrimitiveCounts;
960 prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, maxPrimitiveCounts);
962 const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data();
963 const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data();
965 VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR =
967 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType;
968 DE_NULL, // const void* pNext;
969 VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, // VkAccelerationStructureTypeKHR type;
970 m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags;
971 VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode;
972 DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure;
973 DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure;
974 static_cast<deUint32>(accelerationStructureGeometriesKHR.size()), // deUint32 geometryCount;
975 m_useArrayOfPointers ? DE_NULL : accelerationStructureGeometriesKHRPointer, // const VkAccelerationStructureGeometryKHR* pGeometries;
976 m_useArrayOfPointers ? accelerationStructureGeometry : DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries;
977 makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData;
979 VkAccelerationStructureBuildSizesInfoKHR sizeInfo =
981 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType;
982 DE_NULL, // const void* pNext;
983 0, // VkDeviceSize accelerationStructureSize;
984 0, // VkDeviceSize updateScratchSize;
985 0 // VkDeviceSize buildScratchSize;
988 vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo);
990 m_structureSize = sizeInfo.accelerationStructureSize;
991 m_updateScratchSize = sizeInfo.updateScratchSize;
992 m_buildScratchSize = sizeInfo.buildScratchSize;
996 m_structureSize = structureSize;
997 m_updateScratchSize = 0u;
998 m_buildScratchSize = 0u;
1002 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_structureSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1005 m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1007 catch (const tcu::NotSupportedError&)
1009 // retry without Cached flag
1010 m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1015 const VkAccelerationStructureTypeKHR structureType = (m_createGeneric
1016 ? VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR
1017 : VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);
1018 const VkAccelerationStructureCreateInfoKHR accelerationStructureCreateInfoKHR
1020 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType;
1021 DE_NULL, // const void* pNext;
1022 m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags;
1023 m_accelerationStructureBuffer->get(), // VkBuffer buffer;
1024 0u, // VkDeviceSize offset;
1025 m_structureSize, // VkDeviceSize size;
1026 structureType, // VkAccelerationStructureTypeKHR type;
1027 deviceAddress // VkDeviceAddress deviceAddress;
1030 m_accelerationStructureKHR = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL);
1033 if (m_buildScratchSize > 0u)
1035 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1037 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_buildScratchSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1038 m_deviceScratchBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1042 m_hostScratchBuffer.resize(static_cast<size_t>(m_buildScratchSize));
1046 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR && !m_geometriesData.empty())
1048 m_vertexBuffer = de::MovePtr<BufferWithMemory>(createVertexBuffer(vk, device, allocator, m_geometriesData));
1049 m_indexBuffer = de::MovePtr<BufferWithMemory>(createIndexBuffer(vk, device, allocator, m_geometriesData));
1053 void BottomLevelAccelerationStructureKHR::build (const DeviceInterface& vk,
1054 const VkDevice device,
1055 const VkCommandBuffer cmdBuffer)
1057 DE_ASSERT(!m_geometriesData.empty());
1058 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1059 DE_ASSERT(m_buildScratchSize != 0);
1061 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1063 updateVertexBuffer(vk, device, m_geometriesData, m_vertexBuffer.get());
1064 if(m_indexBuffer.get() != DE_NULL)
1065 updateIndexBuffer(vk, device, m_geometriesData, m_indexBuffer.get());
1069 std::vector<VkAccelerationStructureGeometryKHR> accelerationStructureGeometriesKHR;
1070 std::vector<VkAccelerationStructureGeometryKHR*> accelerationStructureGeometriesKHRPointers;
1071 std::vector<VkAccelerationStructureBuildRangeInfoKHR> accelerationStructureBuildRangeInfoKHR;
1072 std::vector<deUint32> maxPrimitiveCounts;
1074 prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, maxPrimitiveCounts);
1076 const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data();
1077 const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data();
1078 VkDeviceOrHostAddressKHR scratchData = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1079 ? makeDeviceOrHostAddressKHR(vk, device, m_deviceScratchBuffer->get(), 0)
1080 : makeDeviceOrHostAddressKHR(m_hostScratchBuffer.data());
1081 const deUint32 geometryCount = (m_buildWithoutGeometries
1083 : static_cast<deUint32>(accelerationStructureGeometriesKHR.size()));
1085 VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR =
1087 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType;
1088 DE_NULL, // const void* pNext;
1089 VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, // VkAccelerationStructureTypeKHR type;
1090 m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags;
1091 VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode;
1092 DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure;
1093 m_accelerationStructureKHR.get(), // VkAccelerationStructureKHR dstAccelerationStructure;
1094 geometryCount, // deUint32 geometryCount;
1095 m_useArrayOfPointers ? DE_NULL : accelerationStructureGeometriesKHRPointer, // const VkAccelerationStructureGeometryKHR* pGeometries;
1096 m_useArrayOfPointers ? accelerationStructureGeometry : DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries;
1097 scratchData // VkDeviceOrHostAddressKHR scratchData;
1100 VkAccelerationStructureBuildRangeInfoKHR* accelerationStructureBuildRangeInfoKHRPtr = accelerationStructureBuildRangeInfoKHR.data();
1102 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1104 if (m_indirectBuffer == DE_NULL)
1105 vk.cmdBuildAccelerationStructuresKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1108 VkDeviceAddress indirectDeviceAddress = getBufferDeviceAddress(vk, device, m_indirectBuffer, m_indirectBufferOffset);
1109 deUint32* pMaxPrimitiveCounts = maxPrimitiveCounts.data();
1110 vk.cmdBuildAccelerationStructuresIndirectKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, &indirectDeviceAddress, &m_indirectBufferStride, &pMaxPrimitiveCounts);
1113 else if (!m_deferredOperation)
1115 VK_CHECK(vk.buildAccelerationStructuresKHR(device, DE_NULL, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr));
1119 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
1120 const auto deferredOperation = deferredOperationPtr.get();
1122 VkResult result = vk.buildAccelerationStructuresKHR(device, deferredOperation, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1124 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1126 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1130 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1132 const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1133 const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
1135 cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1139 void BottomLevelAccelerationStructureKHR::copyFrom (const DeviceInterface& vk,
1140 const VkDevice device,
1141 const VkCommandBuffer cmdBuffer,
1142 BottomLevelAccelerationStructure* accelerationStructure,
1145 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1146 DE_ASSERT(accelerationStructure != DE_NULL);
1148 VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo =
1150 VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType;
1151 DE_NULL, // const void* pNext;
1152 *(accelerationStructure->getPtr()), // VkAccelerationStructureKHR src;
1153 *(getPtr()), // VkAccelerationStructureKHR dst;
1154 compactCopy ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR // VkCopyAccelerationStructureModeKHR mode;
1157 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1159 vk.cmdCopyAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo);
1161 else if (!m_deferredOperation)
1163 VK_CHECK(vk.copyAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo));
1167 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
1168 const auto deferredOperation = deferredOperationPtr.get();
1170 VkResult result = vk.copyAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo);
1172 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1174 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1177 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1179 const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1180 const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
1182 cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1186 void BottomLevelAccelerationStructureKHR::serialize (const DeviceInterface& vk,
1187 const VkDevice device,
1188 const VkCommandBuffer cmdBuffer,
1189 SerialStorage* storage)
1191 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1192 DE_ASSERT(storage != DE_NULL);
1194 const VkCopyAccelerationStructureToMemoryInfoKHR copyAccelerationStructureInfo =
1196 VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR, // VkStructureType sType;
1197 DE_NULL, // const void* pNext;
1198 *(getPtr()), // VkAccelerationStructureKHR src;
1199 storage->getAddress(vk,device), // VkDeviceOrHostAddressKHR dst;
1200 VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode;
1203 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1205 vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, ©AccelerationStructureInfo);
1207 else if (!m_deferredOperation)
1209 VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, ©AccelerationStructureInfo));
1213 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
1214 const auto deferredOperation = deferredOperationPtr.get();
1216 const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, ©AccelerationStructureInfo);
1218 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1220 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1224 void BottomLevelAccelerationStructureKHR::deserialize (const DeviceInterface& vk,
1225 const VkDevice device,
1226 const VkCommandBuffer cmdBuffer,
1227 SerialStorage* storage)
1229 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1230 DE_ASSERT(storage != DE_NULL);
1232 const VkCopyMemoryToAccelerationStructureInfoKHR copyAccelerationStructureInfo =
1234 VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType;
1235 DE_NULL, // const void* pNext;
1236 storage->getAddressConst(vk,device), // VkDeviceOrHostAddressConstKHR src;
1237 *(getPtr()), // VkAccelerationStructureKHR dst;
1238 VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode;
1241 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1243 vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo);
1245 else if (!m_deferredOperation)
1247 VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo));
1251 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
1252 const auto deferredOperation = deferredOperationPtr.get();
1254 const VkResult result = vk.copyMemoryToAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo);
1256 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1258 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1261 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1263 const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1264 const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
1266 cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1270 const VkAccelerationStructureKHR* BottomLevelAccelerationStructureKHR::getPtr (void) const
1272 return &m_accelerationStructureKHR.get();
1275 void BottomLevelAccelerationStructureKHR::prepareGeometries (const DeviceInterface& vk,
1276 const VkDevice device,
1277 std::vector<VkAccelerationStructureGeometryKHR>& accelerationStructureGeometriesKHR,
1278 std::vector<VkAccelerationStructureGeometryKHR*>& accelerationStructureGeometriesKHRPointers,
1279 std::vector<VkAccelerationStructureBuildRangeInfoKHR>& accelerationStructureBuildRangeInfoKHR,
1280 std::vector<deUint32>& maxPrimitiveCounts)
1282 accelerationStructureGeometriesKHR.resize(m_geometriesData.size());
1283 accelerationStructureGeometriesKHRPointers.resize(m_geometriesData.size());
1284 accelerationStructureBuildRangeInfoKHR.resize(m_geometriesData.size());
1285 maxPrimitiveCounts.resize(m_geometriesData.size());
1287 VkDeviceSize vertexBufferOffset = 0, indexBufferOffset = 0;
1289 for (size_t geometryNdx = 0; geometryNdx < m_geometriesData.size(); ++geometryNdx)
1291 de::SharedPtr<RaytracedGeometryBase>& geometryData = m_geometriesData[geometryNdx];
1292 VkDeviceOrHostAddressConstKHR vertexData, indexData;
1293 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1295 if (m_vertexBuffer.get() != DE_NULL)
1297 vertexData = makeDeviceOrHostAddressConstKHR(vk, device, m_vertexBuffer->get(), vertexBufferOffset);
1298 vertexBufferOffset += deAlignSize(geometryData->getVertexByteSize(), 8);
1301 vertexData = makeDeviceOrHostAddressConstKHR(DE_NULL);
1303 if (m_indexBuffer.get() != DE_NULL && geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
1305 indexData = makeDeviceOrHostAddressConstKHR(vk, device, m_indexBuffer->get(), indexBufferOffset);
1306 indexBufferOffset += deAlignSize(geometryData->getIndexByteSize(), 8);
1309 indexData = makeDeviceOrHostAddressConstKHR(DE_NULL);
1313 vertexData = makeDeviceOrHostAddressConstKHR(geometryData->getVertexPointer());
1314 if (geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
1315 indexData = makeDeviceOrHostAddressConstKHR(geometryData->getIndexPointer());
1317 indexData = makeDeviceOrHostAddressConstKHR(DE_NULL);
1320 const VkAccelerationStructureGeometryTrianglesDataKHR accelerationStructureGeometryTrianglesDataKHR =
1322 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR, // VkStructureType sType;
1323 DE_NULL, // const void* pNext;
1324 geometryData->getVertexFormat(), // VkFormat vertexFormat;
1325 vertexData, // VkDeviceOrHostAddressConstKHR vertexData;
1326 geometryData->getVertexStride(), // VkDeviceSize vertexStride;
1327 static_cast<deUint32>(geometryData->getVertexCount()), // uint32_t maxVertex;
1328 geometryData->getIndexType(), // VkIndexType indexType;
1329 indexData, // VkDeviceOrHostAddressConstKHR indexData;
1330 makeDeviceOrHostAddressConstKHR(DE_NULL), // VkDeviceOrHostAddressConstKHR transformData;
1333 const VkAccelerationStructureGeometryAabbsDataKHR accelerationStructureGeometryAabbsDataKHR =
1335 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR, // VkStructureType sType;
1336 DE_NULL, // const void* pNext;
1337 vertexData, // VkDeviceOrHostAddressConstKHR data;
1338 geometryData->getAABBStride() // VkDeviceSize stride;
1340 const VkAccelerationStructureGeometryDataKHR geometry = (geometryData->isTrianglesType())
1341 ? makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryTrianglesDataKHR)
1342 : makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryAabbsDataKHR);
1343 const VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR =
1345 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // VkStructureType sType;
1346 DE_NULL, // const void* pNext;
1347 geometryData->getGeometryType(), // VkGeometryTypeKHR geometryType;
1348 geometry, // VkAccelerationStructureGeometryDataKHR geometry;
1349 geometryData->getGeometryFlags() // VkGeometryFlagsKHR flags;
1352 const deUint32 primitiveCount = (m_buildWithoutPrimitives ? 0u : geometryData->getPrimitiveCount());
1354 const VkAccelerationStructureBuildRangeInfoKHR accelerationStructureBuildRangeInfosKHR =
1356 primitiveCount, // deUint32 primitiveCount;
1357 0, // deUint32 primitiveOffset;
1358 0, // deUint32 firstVertex;
1359 0 // deUint32 firstTransform;
1362 accelerationStructureGeometriesKHR[geometryNdx] = accelerationStructureGeometryKHR;
1363 accelerationStructureGeometriesKHRPointers[geometryNdx] = &accelerationStructureGeometriesKHR[geometryNdx];
1364 accelerationStructureBuildRangeInfoKHR[geometryNdx] = accelerationStructureBuildRangeInfosKHR;
1365 maxPrimitiveCounts[geometryNdx] = geometryData->getPrimitiveCount();
1369 deUint32 BottomLevelAccelerationStructure::getRequiredAllocationCount (void)
1371 return BottomLevelAccelerationStructureKHR::getRequiredAllocationCount();
1374 void BottomLevelAccelerationStructure::createAndBuild (const DeviceInterface& vk,
1375 const VkDevice device,
1376 const VkCommandBuffer cmdBuffer,
1377 Allocator& allocator,
1378 VkDeviceAddress deviceAddress)
1380 create(vk, device, allocator, 0u, deviceAddress);
1381 build(vk, device, cmdBuffer);
1384 void BottomLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface& vk,
1385 const VkDevice device,
1386 const VkCommandBuffer cmdBuffer,
1387 Allocator& allocator,
1388 BottomLevelAccelerationStructure* accelerationStructure,
1389 VkDeviceSize compactCopySize,
1390 VkDeviceAddress deviceAddress)
1392 DE_ASSERT(accelerationStructure != NULL);
1393 VkDeviceSize copiedSize = compactCopySize > 0u ? compactCopySize : accelerationStructure->getStructureSize();
1394 DE_ASSERT(copiedSize != 0u);
1396 create(vk, device, allocator, copiedSize, deviceAddress);
1397 copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u);
1400 void BottomLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
1401 const VkDevice device,
1402 const VkCommandBuffer cmdBuffer,
1403 Allocator& allocator,
1404 SerialStorage* storage,
1405 VkDeviceAddress deviceAddress )
1407 DE_ASSERT(storage != NULL);
1408 DE_ASSERT(storage->getStorageSize() >= SerialStorage::SERIAL_STORAGE_SIZE_MIN);
1409 create(vk, device, allocator, storage->getDeserializedSize(), deviceAddress);
1410 deserialize(vk, device, cmdBuffer, storage);
1413 de::MovePtr<BottomLevelAccelerationStructure> makeBottomLevelAccelerationStructure ()
1415 return de::MovePtr<BottomLevelAccelerationStructure>(new BottomLevelAccelerationStructureKHR);
1418 TopLevelAccelerationStructure::~TopLevelAccelerationStructure ()
1422 TopLevelAccelerationStructure::TopLevelAccelerationStructure ()
1423 : m_structureSize (0u)
1424 , m_updateScratchSize (0u)
1425 , m_buildScratchSize (0u)
1429 void TopLevelAccelerationStructure::setInstanceCount (const size_t instanceCount)
1431 m_bottomLevelInstances.reserve(instanceCount);
1432 m_instanceData.reserve(instanceCount);
1435 void TopLevelAccelerationStructure::addInstance (de::SharedPtr<BottomLevelAccelerationStructure> bottomLevelStructure,
1436 const VkTransformMatrixKHR& matrix,
1437 deUint32 instanceCustomIndex,
1439 deUint32 instanceShaderBindingTableRecordOffset,
1440 VkGeometryInstanceFlagsKHR flags)
1442 m_bottomLevelInstances.push_back(bottomLevelStructure);
1443 m_instanceData.push_back(InstanceData(matrix, instanceCustomIndex, mask, instanceShaderBindingTableRecordOffset, flags));
1446 VkDeviceSize TopLevelAccelerationStructure::getStructureSize () const
1448 return m_structureSize;
1451 void TopLevelAccelerationStructure::createAndBuild (const DeviceInterface& vk,
1452 const VkDevice device,
1453 const VkCommandBuffer cmdBuffer,
1454 Allocator& allocator,
1455 VkDeviceAddress deviceAddress)
1457 create(vk, device, allocator, 0u, deviceAddress);
1458 build(vk, device, cmdBuffer);
1461 void TopLevelAccelerationStructure::createAndCopyFrom (const DeviceInterface& vk,
1462 const VkDevice device,
1463 const VkCommandBuffer cmdBuffer,
1464 Allocator& allocator,
1465 TopLevelAccelerationStructure* accelerationStructure,
1466 VkDeviceSize compactCopySize,
1467 VkDeviceAddress deviceAddress)
1469 DE_ASSERT(accelerationStructure != NULL);
1470 VkDeviceSize copiedSize = compactCopySize > 0u ? compactCopySize : accelerationStructure->getStructureSize();
1471 DE_ASSERT(copiedSize != 0u);
1473 create(vk, device, allocator, copiedSize, deviceAddress);
1474 copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u);
1477 void TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
1478 const VkDevice device,
1479 const VkCommandBuffer cmdBuffer,
1480 Allocator& allocator,
1481 SerialStorage* storage,
1482 VkDeviceAddress deviceAddress)
1484 DE_ASSERT(storage != NULL);
1485 DE_ASSERT(storage->getStorageSize() >= SerialStorage::SERIAL_STORAGE_SIZE_MIN);
1486 create(vk, device, allocator, storage->getDeserializedSize(), deviceAddress);
1487 deserialize(vk, device, cmdBuffer, storage);
1490 BufferWithMemory* createInstanceBuffer (const DeviceInterface& vk,
1491 const VkDevice device,
1492 Allocator& allocator,
1493 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelInstances,
1494 std::vector<InstanceData> instanceData)
1496 DE_ASSERT(bottomLevelInstances.size() != 0);
1497 DE_ASSERT(bottomLevelInstances.size() == instanceData.size());
1498 DE_UNREF(instanceData);
1500 const VkDeviceSize bufferSizeBytes = bottomLevelInstances.size() * sizeof(VkAccelerationStructureInstanceKHR);
1501 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1504 return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
1506 catch (const tcu::NotSupportedError&)
1508 // retry without Cached flag
1509 return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
1513 void updateInstanceBuffer (const DeviceInterface& vk,
1514 const VkDevice device,
1515 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelInstances,
1516 std::vector<InstanceData> instanceData,
1517 BufferWithMemory* instanceBuffer,
1518 VkAccelerationStructureBuildTypeKHR buildType,
1519 bool inactiveInstances)
1521 DE_ASSERT(bottomLevelInstances.size() != 0);
1522 DE_ASSERT(bottomLevelInstances.size() == instanceData.size());
1524 const Allocation& instancesAlloc = instanceBuffer->getAllocation();
1526 deUint8* bufferStart = static_cast<deUint8*>(instancesAlloc.getHostPtr());
1527 VkDeviceSize bufferOffset = 0;
1529 for (size_t instanceNdx = 0; instanceNdx < bottomLevelInstances.size(); ++instanceNdx)
1531 const BottomLevelAccelerationStructure& bottomLevelAccelerationStructure = *bottomLevelInstances[instanceNdx];
1532 const VkAccelerationStructureKHR accelerationStructureKHR = *bottomLevelAccelerationStructure.getPtr();
1534 // This part needs to be fixed once a new version of the VkAccelerationStructureInstanceKHR will be added to vkStructTypes.inl
1535 VkDeviceAddress accelerationStructureAddress;
1536 if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1538 VkAccelerationStructureDeviceAddressInfoKHR asDeviceAddressInfo =
1540 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType;
1541 DE_NULL, // const void* pNext;
1542 accelerationStructureKHR // VkAccelerationStructureKHR accelerationStructure;
1544 accelerationStructureAddress = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo);
1547 deUint64 structureReference;
1548 if (inactiveInstances)
1550 // Instances will be marked inactive by making their references VK_NULL_HANDLE or having address zero.
1551 structureReference = 0ull;
1555 structureReference = (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1556 ? deUint64(accelerationStructureAddress)
1557 : deUint64(accelerationStructureKHR.getInternal());
1560 VkAccelerationStructureInstanceKHR accelerationStructureInstanceKHR = makeVkAccelerationStructureInstanceKHR
1562 instanceData[instanceNdx].matrix, // VkTransformMatrixKHR transform;
1563 instanceData[instanceNdx].instanceCustomIndex, // deUint32 instanceCustomIndex:24;
1564 instanceData[instanceNdx].mask, // deUint32 mask:8;
1565 instanceData[instanceNdx].instanceShaderBindingTableRecordOffset, // deUint32 instanceShaderBindingTableRecordOffset:24;
1566 instanceData[instanceNdx].flags, // VkGeometryInstanceFlagsKHR flags:8;
1567 structureReference // deUint64 accelerationStructureReference;
1570 deMemcpy(&bufferStart[bufferOffset], &accelerationStructureInstanceKHR, sizeof(VkAccelerationStructureInstanceKHR));
1572 bufferOffset += sizeof(VkAccelerationStructureInstanceKHR);
1575 flushMappedMemoryRange(vk, device, instancesAlloc.getMemory(), instancesAlloc.getOffset(), VK_WHOLE_SIZE);
1578 class TopLevelAccelerationStructureKHR : public TopLevelAccelerationStructure
1581 static deUint32 getRequiredAllocationCount (void);
1583 TopLevelAccelerationStructureKHR ();
1584 TopLevelAccelerationStructureKHR (const TopLevelAccelerationStructureKHR& other) = delete;
1585 virtual ~TopLevelAccelerationStructureKHR ();
1587 void setBuildType (const VkAccelerationStructureBuildTypeKHR buildType) override;
1588 void setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags) override;
1589 void setCreateGeneric (bool createGeneric) override;
1590 void setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags) override;
1591 void setBuildWithoutPrimitives (bool buildWithoutPrimitives) override;
1592 void setInactiveInstances (bool inactiveInstances) override;
1593 void setDeferredOperation (const bool deferredOperation,
1594 const deUint32 workerThreadCount) override;
1595 void setUseArrayOfPointers (const bool useArrayOfPointers) override;
1596 void setIndirectBuildParameters (const VkBuffer indirectBuffer,
1597 const VkDeviceSize indirectBufferOffset,
1598 const deUint32 indirectBufferStride) override;
1599 VkBuildAccelerationStructureFlagsKHR getBuildFlags () const override;
1601 void create (const DeviceInterface& vk,
1602 const VkDevice device,
1603 Allocator& allocator,
1604 VkDeviceSize structureSize,
1605 VkDeviceAddress deviceAddress = 0u ) override;
1606 void build (const DeviceInterface& vk,
1607 const VkDevice device,
1608 const VkCommandBuffer cmdBuffer) override;
1609 void copyFrom (const DeviceInterface& vk,
1610 const VkDevice device,
1611 const VkCommandBuffer cmdBuffer,
1612 TopLevelAccelerationStructure* accelerationStructure,
1613 bool compactCopy) override;
1614 void serialize (const DeviceInterface& vk,
1615 const VkDevice device,
1616 const VkCommandBuffer cmdBuffer,
1617 SerialStorage* storage) override;
1618 void deserialize (const DeviceInterface& vk,
1619 const VkDevice device,
1620 const VkCommandBuffer cmdBuffer,
1621 SerialStorage* storage) override;
1623 const VkAccelerationStructureKHR* getPtr (void) const override;
1626 VkAccelerationStructureBuildTypeKHR m_buildType;
1627 VkAccelerationStructureCreateFlagsKHR m_createFlags;
1628 bool m_createGeneric;
1629 VkBuildAccelerationStructureFlagsKHR m_buildFlags;
1630 bool m_buildWithoutPrimitives;
1631 bool m_inactiveInstances;
1632 bool m_deferredOperation;
1633 deUint32 m_workerThreadCount;
1634 bool m_useArrayOfPointers;
1635 de::MovePtr<BufferWithMemory> m_accelerationStructureBuffer;
1636 de::MovePtr<BufferWithMemory> m_instanceBuffer;
1637 de::MovePtr<BufferWithMemory> m_instanceAddressBuffer;
1638 de::MovePtr<BufferWithMemory> m_deviceScratchBuffer;
1639 std::vector<deUint8> m_hostScratchBuffer;
1640 Move<VkAccelerationStructureKHR> m_accelerationStructureKHR;
1641 VkBuffer m_indirectBuffer;
1642 VkDeviceSize m_indirectBufferOffset;
1643 deUint32 m_indirectBufferStride;
1645 void prepareInstances (const DeviceInterface& vk,
1646 const VkDevice device,
1647 VkAccelerationStructureGeometryKHR& accelerationStructureGeometryKHR,
1648 std::vector<deUint32>& maxPrimitiveCounts);
1651 deUint32 TopLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
1654 de::MovePtr<BufferWithMemory> m_instanceBuffer;
1655 de::MovePtr<Allocation> m_accelerationStructureAlloc;
1656 de::MovePtr<BufferWithMemory> m_deviceScratchBuffer;
1661 TopLevelAccelerationStructureKHR::TopLevelAccelerationStructureKHR ()
1662 : TopLevelAccelerationStructure ()
1663 , m_buildType (VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1664 , m_createFlags (0u)
1665 , m_createGeneric (false)
1667 , m_buildWithoutPrimitives (false)
1668 , m_inactiveInstances (false)
1669 , m_deferredOperation (false)
1670 , m_workerThreadCount (0)
1671 , m_useArrayOfPointers (false)
1672 , m_accelerationStructureBuffer (DE_NULL)
1673 , m_instanceBuffer (DE_NULL)
1674 , m_instanceAddressBuffer (DE_NULL)
1675 , m_deviceScratchBuffer (DE_NULL)
1676 , m_accelerationStructureKHR ()
1677 , m_indirectBuffer (DE_NULL)
1678 , m_indirectBufferOffset (0)
1679 , m_indirectBufferStride (0)
1683 TopLevelAccelerationStructureKHR::~TopLevelAccelerationStructureKHR ()
1687 void TopLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR buildType)
1689 m_buildType = buildType;
1692 void TopLevelAccelerationStructureKHR::setCreateFlags (const VkAccelerationStructureCreateFlagsKHR createFlags)
1694 m_createFlags = createFlags;
1697 void TopLevelAccelerationStructureKHR::setCreateGeneric (bool createGeneric)
1699 m_createGeneric = createGeneric;
1702 void TopLevelAccelerationStructureKHR::setInactiveInstances (bool inactiveInstances)
1704 m_inactiveInstances = inactiveInstances;
1707 void TopLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR buildFlags)
1709 m_buildFlags = buildFlags;
1712 void TopLevelAccelerationStructureKHR::setBuildWithoutPrimitives (bool buildWithoutPrimitives)
1714 m_buildWithoutPrimitives = buildWithoutPrimitives;
1717 void TopLevelAccelerationStructureKHR::setDeferredOperation (const bool deferredOperation,
1718 const deUint32 workerThreadCount)
1720 m_deferredOperation = deferredOperation;
1721 m_workerThreadCount = workerThreadCount;
1724 void TopLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool useArrayOfPointers)
1726 m_useArrayOfPointers = useArrayOfPointers;
1729 void TopLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer indirectBuffer,
1730 const VkDeviceSize indirectBufferOffset,
1731 const deUint32 indirectBufferStride)
1733 m_indirectBuffer = indirectBuffer;
1734 m_indirectBufferOffset = indirectBufferOffset;
1735 m_indirectBufferStride = indirectBufferStride;
1738 VkBuildAccelerationStructureFlagsKHR TopLevelAccelerationStructureKHR::getBuildFlags () const
1740 return m_buildFlags;
1743 void TopLevelAccelerationStructureKHR::create (const DeviceInterface& vk,
1744 const VkDevice device,
1745 Allocator& allocator,
1746 VkDeviceSize structureSize,
1747 VkDeviceAddress deviceAddress)
1749 // AS may be built from geometries using vkCmdBuildAccelerationStructureKHR / vkBuildAccelerationStructureKHR
1750 // 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 ).
1751 DE_ASSERT(!m_bottomLevelInstances.empty() != !(structureSize == 0)); // logical xor
1753 if (structureSize == 0)
1755 VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR;
1756 std::vector<deUint32> maxPrimitiveCounts;
1757 prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts);
1759 VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR =
1761 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType;
1762 DE_NULL, // const void* pNext;
1763 VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, // VkAccelerationStructureTypeKHR type;
1764 m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags;
1765 VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode;
1766 DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure;
1767 DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure;
1768 1u, // deUint32 geometryCount;
1769 &accelerationStructureGeometryKHR, // const VkAccelerationStructureGeometryKHR* pGeometries;
1770 DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries;
1771 makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData;
1774 VkAccelerationStructureBuildSizesInfoKHR sizeInfo =
1776 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType;
1777 DE_NULL, // const void* pNext;
1778 0, // VkDeviceSize accelerationStructureSize;
1779 0, // VkDeviceSize updateScratchSize;
1780 0 // VkDeviceSize buildScratchSize;
1783 vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo);
1785 m_structureSize = sizeInfo.accelerationStructureSize;
1786 m_updateScratchSize = sizeInfo.updateScratchSize;
1787 m_buildScratchSize = sizeInfo.buildScratchSize;
1791 m_structureSize = structureSize;
1792 m_updateScratchSize = 0u;
1793 m_buildScratchSize = 0u;
1797 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_structureSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1800 m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1802 catch (const tcu::NotSupportedError&)
1804 // retry without Cached flag
1805 m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1810 const VkAccelerationStructureTypeKHR structureType = (m_createGeneric
1811 ? VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR
1812 : VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR);
1813 const VkAccelerationStructureCreateInfoKHR accelerationStructureCreateInfoKHR =
1815 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType;
1816 DE_NULL, // const void* pNext;
1817 m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags;
1818 m_accelerationStructureBuffer->get(), // VkBuffer buffer;
1819 0u, // VkDeviceSize offset;
1820 m_structureSize, // VkDeviceSize size;
1821 structureType, // VkAccelerationStructureTypeKHR type;
1822 deviceAddress // VkDeviceAddress deviceAddress;
1825 m_accelerationStructureKHR = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL);
1828 if (m_buildScratchSize > 0u)
1830 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1832 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_buildScratchSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1833 m_deviceScratchBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1837 m_hostScratchBuffer.resize(static_cast<size_t>(m_buildScratchSize));
1841 if (m_useArrayOfPointers)
1843 const size_t pointerSize = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) ? sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress) : sizeof(VkDeviceOrHostAddressConstKHR::hostAddress);
1844 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);
1845 m_instanceAddressBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1848 if(!m_bottomLevelInstances.empty())
1849 m_instanceBuffer = de::MovePtr<BufferWithMemory>(createInstanceBuffer(vk, device, allocator, m_bottomLevelInstances, m_instanceData));
1852 void TopLevelAccelerationStructureKHR::build (const DeviceInterface& vk,
1853 const VkDevice device,
1854 const VkCommandBuffer cmdBuffer)
1856 DE_ASSERT(!m_bottomLevelInstances.empty());
1857 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1858 DE_ASSERT(m_buildScratchSize != 0);
1860 updateInstanceBuffer(vk, device, m_bottomLevelInstances, m_instanceData, m_instanceBuffer.get(), m_buildType, m_inactiveInstances);
1862 VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR;
1863 std::vector<deUint32> maxPrimitiveCounts;
1864 prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts);
1866 VkDeviceOrHostAddressKHR scratchData = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1867 ? makeDeviceOrHostAddressKHR(vk, device, m_deviceScratchBuffer->get(), 0)
1868 : makeDeviceOrHostAddressKHR(m_hostScratchBuffer.data());
1870 VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR =
1872 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType;
1873 DE_NULL, // const void* pNext;
1874 VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, // VkAccelerationStructureTypeKHR type;
1875 m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags;
1876 VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode;
1877 DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure;
1878 m_accelerationStructureKHR.get(), // VkAccelerationStructureKHR dstAccelerationStructure;
1879 1u, // deUint32 geometryCount;
1880 &accelerationStructureGeometryKHR, // const VkAccelerationStructureGeometryKHR* pGeometries;
1881 DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries;
1882 scratchData // VkDeviceOrHostAddressKHR scratchData;
1885 const deUint32 primitiveCount = (m_buildWithoutPrimitives ? 0u : static_cast<deUint32>(m_bottomLevelInstances.size()));
1887 VkAccelerationStructureBuildRangeInfoKHR accelerationStructureBuildRangeInfoKHR =
1889 primitiveCount, // deUint32 primitiveCount;
1890 0, // deUint32 primitiveOffset;
1891 0, // deUint32 firstVertex;
1892 0 // deUint32 transformOffset;
1894 VkAccelerationStructureBuildRangeInfoKHR* accelerationStructureBuildRangeInfoKHRPtr = &accelerationStructureBuildRangeInfoKHR;
1896 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1898 if (m_indirectBuffer == DE_NULL)
1899 vk.cmdBuildAccelerationStructuresKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1902 VkDeviceAddress indirectDeviceAddress = getBufferDeviceAddress(vk, device, m_indirectBuffer, m_indirectBufferOffset);
1903 deUint32* pMaxPrimitiveCounts = maxPrimitiveCounts.data();
1904 vk.cmdBuildAccelerationStructuresIndirectKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, &indirectDeviceAddress, &m_indirectBufferStride, &pMaxPrimitiveCounts);
1907 else if (!m_deferredOperation)
1909 VK_CHECK(vk.buildAccelerationStructuresKHR(device, DE_NULL, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr));
1913 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
1914 const auto deferredOperation = deferredOperationPtr.get();
1916 VkResult result = vk.buildAccelerationStructuresKHR(device, deferredOperation, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1918 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1920 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1922 accelerationStructureBuildGeometryInfoKHR.pNext = DE_NULL;
1925 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1927 const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1928 const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
1930 cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1934 void TopLevelAccelerationStructureKHR::copyFrom (const DeviceInterface& vk,
1935 const VkDevice device,
1936 const VkCommandBuffer cmdBuffer,
1937 TopLevelAccelerationStructure* accelerationStructure,
1940 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1941 DE_ASSERT(accelerationStructure != DE_NULL);
1943 VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo =
1945 VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType;
1946 DE_NULL, // const void* pNext;
1947 *(accelerationStructure->getPtr()), // VkAccelerationStructureKHR src;
1948 *(getPtr()), // VkAccelerationStructureKHR dst;
1949 compactCopy ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR // VkCopyAccelerationStructureModeKHR mode;
1952 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1954 vk.cmdCopyAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo);
1956 else if (!m_deferredOperation)
1958 VK_CHECK(vk.copyAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo));
1962 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
1963 const auto deferredOperation = deferredOperationPtr.get();
1965 VkResult result = vk.copyAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo);
1967 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1969 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1972 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1974 const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1975 const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
1977 cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1982 void TopLevelAccelerationStructureKHR::serialize (const DeviceInterface& vk,
1983 const VkDevice device,
1984 const VkCommandBuffer cmdBuffer,
1985 SerialStorage* storage)
1987 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1988 DE_ASSERT(storage != DE_NULL);
1990 const VkCopyAccelerationStructureToMemoryInfoKHR copyAccelerationStructureInfo =
1992 VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR, // VkStructureType sType;
1993 DE_NULL, // const void* pNext;
1994 *(getPtr()), // VkAccelerationStructureKHR src;
1995 storage->getAddress(vk,device), // VkDeviceOrHostAddressKHR dst;
1996 VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode;
1999 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2001 vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, ©AccelerationStructureInfo);
2003 else if (!m_deferredOperation)
2005 VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, ©AccelerationStructureInfo));
2009 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
2010 const auto deferredOperation = deferredOperationPtr.get();
2012 const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, ©AccelerationStructureInfo);
2014 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
2016 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
2020 void TopLevelAccelerationStructureKHR::deserialize (const DeviceInterface& vk,
2021 const VkDevice device,
2022 const VkCommandBuffer cmdBuffer,
2023 SerialStorage* storage)
2025 DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
2026 DE_ASSERT(storage != DE_NULL);
2028 const VkCopyMemoryToAccelerationStructureInfoKHR copyAccelerationStructureInfo =
2030 VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR, // VkStructureType sType;
2031 DE_NULL, // const void* pNext;
2032 storage->getAddressConst(vk,device), // VkDeviceOrHostAddressConstKHR src;
2033 *(getPtr()), // VkAccelerationStructureKHR dst;
2034 VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR // VkCopyAccelerationStructureModeKHR mode;
2037 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2039 vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, ©AccelerationStructureInfo);
2041 else if (!m_deferredOperation)
2043 VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, DE_NULL, ©AccelerationStructureInfo));
2047 const auto deferredOperationPtr = createDeferredOperationKHR(vk, device);
2048 const auto deferredOperation = deferredOperationPtr.get();
2050 const VkResult result = vk.copyMemoryToAccelerationStructureKHR(device, deferredOperation, ©AccelerationStructureInfo);
2052 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
2054 finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
2057 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2059 const VkAccessFlags accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
2060 const VkMemoryBarrier memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
2062 cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
2066 const VkAccelerationStructureKHR* TopLevelAccelerationStructureKHR::getPtr (void) const
2068 return &m_accelerationStructureKHR.get();
2071 void TopLevelAccelerationStructureKHR::prepareInstances (const DeviceInterface& vk,
2072 const VkDevice device,
2073 VkAccelerationStructureGeometryKHR& accelerationStructureGeometryKHR,
2074 std::vector<deUint32>& maxPrimitiveCounts)
2076 maxPrimitiveCounts.resize(1);
2077 maxPrimitiveCounts[0] = static_cast<deUint32>(m_bottomLevelInstances.size());
2079 VkDeviceOrHostAddressConstKHR instancesData;
2080 if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2082 if(m_instanceBuffer.get() != DE_NULL)
2084 if (m_useArrayOfPointers)
2086 deUint8* bufferStart = static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr());
2087 VkDeviceSize bufferOffset = 0;
2088 VkDeviceOrHostAddressConstKHR firstInstance = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0);
2089 for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
2091 VkDeviceOrHostAddressConstKHR currentInstance;
2092 currentInstance.deviceAddress = firstInstance.deviceAddress + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR);
2094 deMemcpy(&bufferStart[bufferOffset], ¤tInstance, sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress));
2095 bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR::deviceAddress);
2097 flushMappedMemoryRange(vk, device, m_instanceAddressBuffer->getAllocation().getMemory(), m_instanceAddressBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2099 instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceAddressBuffer->get(), 0);
2102 instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0);
2105 instancesData = makeDeviceOrHostAddressConstKHR(DE_NULL);
2109 if (m_instanceBuffer.get() != DE_NULL)
2111 if (m_useArrayOfPointers)
2113 deUint8* bufferStart = static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr());
2114 VkDeviceSize bufferOffset = 0;
2115 for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
2117 VkDeviceOrHostAddressConstKHR currentInstance;
2118 currentInstance.hostAddress = (deUint8*)m_instanceBuffer->getAllocation().getHostPtr() + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR);
2120 deMemcpy(&bufferStart[bufferOffset], ¤tInstance, sizeof(VkDeviceOrHostAddressConstKHR::hostAddress));
2121 bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR::hostAddress);
2123 instancesData = makeDeviceOrHostAddressConstKHR(m_instanceAddressBuffer->getAllocation().getHostPtr());
2126 instancesData = makeDeviceOrHostAddressConstKHR(m_instanceBuffer->getAllocation().getHostPtr());
2129 instancesData = makeDeviceOrHostAddressConstKHR(DE_NULL);
2132 VkAccelerationStructureGeometryInstancesDataKHR accelerationStructureGeometryInstancesDataKHR =
2134 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR, // VkStructureType sType;
2135 DE_NULL, // const void* pNext;
2136 (VkBool32)( m_useArrayOfPointers ? DE_TRUE : DE_FALSE ), // VkBool32 arrayOfPointers;
2137 instancesData // VkDeviceOrHostAddressConstKHR data;
2140 accelerationStructureGeometryKHR =
2142 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // VkStructureType sType;
2143 DE_NULL, // const void* pNext;
2144 VK_GEOMETRY_TYPE_INSTANCES_KHR, // VkGeometryTypeKHR geometryType;
2145 makeVkAccelerationStructureInstancesDataKHR(accelerationStructureGeometryInstancesDataKHR), // VkAccelerationStructureGeometryDataKHR geometry;
2146 (VkGeometryFlagsKHR)0u // VkGeometryFlagsKHR flags;
2150 deUint32 TopLevelAccelerationStructure::getRequiredAllocationCount (void)
2152 return TopLevelAccelerationStructureKHR::getRequiredAllocationCount();
2155 de::MovePtr<TopLevelAccelerationStructure> makeTopLevelAccelerationStructure ()
2157 return de::MovePtr<TopLevelAccelerationStructure>(new TopLevelAccelerationStructureKHR);
2160 bool queryAccelerationStructureSizeKHR (const DeviceInterface& vk,
2161 const VkDevice device,
2162 const VkCommandBuffer cmdBuffer,
2163 const std::vector<VkAccelerationStructureKHR>& accelerationStructureHandles,
2164 VkAccelerationStructureBuildTypeKHR buildType,
2165 const VkQueryPool queryPool,
2166 VkQueryType queryType,
2167 deUint32 firstQuery,
2168 std::vector<VkDeviceSize>& results)
2170 DE_ASSERT(queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR || queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR);
2172 if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2174 // queryPool must be large enough to contain at least (firstQuery + accelerationStructureHandles.size()) queries
2175 vk.cmdResetQueryPool(cmdBuffer, queryPool, firstQuery, deUint32(accelerationStructureHandles.size()));
2176 vk.cmdWriteAccelerationStructuresPropertiesKHR(cmdBuffer, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType, queryPool, firstQuery);
2177 // 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.
2178 results.resize(accelerationStructureHandles.size(), 0u);
2181 // buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR
2182 results.resize(accelerationStructureHandles.size(), 0u);
2183 vk.writeAccelerationStructuresPropertiesKHR(device, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType,
2184 sizeof(VkDeviceSize) * accelerationStructureHandles.size(), results.data(), sizeof(VkDeviceSize));
2185 // results will contain proper values
2189 bool queryAccelerationStructureSize (const DeviceInterface& vk,
2190 const VkDevice device,
2191 const VkCommandBuffer cmdBuffer,
2192 const std::vector<VkAccelerationStructureKHR>& accelerationStructureHandles,
2193 VkAccelerationStructureBuildTypeKHR buildType,
2194 const VkQueryPool queryPool,
2195 VkQueryType queryType,
2196 deUint32 firstQuery,
2197 std::vector<VkDeviceSize>& results)
2199 return queryAccelerationStructureSizeKHR(vk, device, cmdBuffer, accelerationStructureHandles, buildType, queryPool, queryType, firstQuery, results);
2202 RayTracingPipeline::RayTracingPipeline ()
2203 : m_shadersModules ()
2204 , m_pipelineLibraries ()
2205 , m_shaderCreateInfos ()
2206 , m_shadersGroupCreateInfos ()
2207 , m_pipelineCreateFlags (0U)
2208 , m_maxRecursionDepth (1U)
2209 , m_maxPayloadSize (0U)
2210 , m_maxAttributeSize (0U)
2211 , m_deferredOperation (false)
2212 , m_workerThreadCount (0)
2216 RayTracingPipeline::~RayTracingPipeline ()
2220 #define CHECKED_ASSIGN_SHADER(SHADER, STAGE) \
2221 if (SHADER == VK_SHADER_UNUSED_KHR) \
2224 TCU_THROW(InternalError, "Attempt to reassign shader")
2226 void RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, Move<VkShaderModule> shaderModule, deUint32 group, const VkSpecializationInfo* specializationInfo)
2228 addShader(shaderStage, makeVkSharedPtr(shaderModule), group, specializationInfo);
2231 void RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, de::SharedPtr<Move<VkShaderModule>> shaderModule, deUint32 group, const VkSpecializationInfo* specializationInfoPtr)
2233 if (group >= m_shadersGroupCreateInfos.size())
2235 for (size_t groupNdx = m_shadersGroupCreateInfos.size(); groupNdx <= group; ++groupNdx)
2237 VkRayTracingShaderGroupCreateInfoKHR shaderGroupCreateInfo =
2239 VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, // VkStructureType sType;
2240 DE_NULL, // const void* pNext;
2241 VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR, // VkRayTracingShaderGroupTypeKHR type;
2242 VK_SHADER_UNUSED_KHR, // deUint32 generalShader;
2243 VK_SHADER_UNUSED_KHR, // deUint32 closestHitShader;
2244 VK_SHADER_UNUSED_KHR, // deUint32 anyHitShader;
2245 VK_SHADER_UNUSED_KHR, // deUint32 intersectionShader;
2246 DE_NULL, // const void* pShaderGroupCaptureReplayHandle;
2249 m_shadersGroupCreateInfos.push_back(shaderGroupCreateInfo);
2253 const deUint32 shaderStageNdx = (deUint32)m_shaderCreateInfos.size();
2254 VkRayTracingShaderGroupCreateInfoKHR& shaderGroupCreateInfo = m_shadersGroupCreateInfos[group];
2256 switch (shaderStage)
2258 case VK_SHADER_STAGE_RAYGEN_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader, shaderStageNdx); break;
2259 case VK_SHADER_STAGE_MISS_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader, shaderStageNdx); break;
2260 case VK_SHADER_STAGE_CALLABLE_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader, shaderStageNdx); break;
2261 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.anyHitShader, shaderStageNdx); break;
2262 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.closestHitShader, shaderStageNdx); break;
2263 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.intersectionShader, shaderStageNdx); break;
2264 default: TCU_THROW(InternalError, "Unacceptable stage");
2267 switch (shaderStage)
2269 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2270 case VK_SHADER_STAGE_MISS_BIT_KHR:
2271 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2273 DE_ASSERT(shaderGroupCreateInfo.type == VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR);
2274 shaderGroupCreateInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
2279 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2280 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2281 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2283 DE_ASSERT(shaderGroupCreateInfo.type != VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR);
2284 shaderGroupCreateInfo.type = (shaderGroupCreateInfo.intersectionShader == VK_SHADER_UNUSED_KHR)
2285 ? VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR
2286 : VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR;
2291 default: TCU_THROW(InternalError, "Unacceptable stage");
2295 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
2297 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2298 DE_NULL, // const void* pNext;
2299 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2300 shaderStage, // VkShaderStageFlagBits stage;
2301 **shaderModule, // VkShaderModule module;
2302 "main", // const char* pName;
2303 specializationInfoPtr, // const VkSpecializationInfo* pSpecializationInfo;
2306 m_shaderCreateInfos.push_back(shaderCreateInfo);
2309 m_shadersModules.push_back(shaderModule);
2312 void RayTracingPipeline::addLibrary (de::SharedPtr<de::MovePtr<RayTracingPipeline>> pipelineLibrary)
2314 m_pipelineLibraries.push_back(pipelineLibrary);
2317 Move<VkPipeline> RayTracingPipeline::createPipelineKHR (const DeviceInterface& vk,
2318 const VkDevice device,
2319 const VkPipelineLayout pipelineLayout,
2320 const std::vector<de::SharedPtr<Move<VkPipeline>>>& pipelineLibraries)
2322 for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx)
2323 DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR);
2325 DE_ASSERT(m_shaderCreateInfos.size() > 0);
2326 DE_ASSERT(m_shadersGroupCreateInfos.size() > 0);
2328 std::vector<VkPipeline> vkPipelineLibraries;
2329 for (auto it = begin(pipelineLibraries), eit = end(pipelineLibraries); it != eit; ++it)
2330 vkPipelineLibraries.push_back( it->get()->get() );
2331 VkPipelineLibraryCreateInfoKHR librariesCreateInfo =
2333 VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType;
2334 DE_NULL, // const void* pNext;
2335 deUint32(vkPipelineLibraries.size()), // deUint32 libraryCount;
2336 dataOrNullPtr(vkPipelineLibraries) // VkPipeline* pLibraries;
2338 const VkRayTracingPipelineInterfaceCreateInfoKHR pipelineInterfaceCreateInfo =
2340 VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR, // VkStructureType sType;
2341 DE_NULL, // const void* pNext;
2342 m_maxPayloadSize, // deUint32 maxPayloadSize;
2343 m_maxAttributeSize // deUint32 maxAttributeSize;
2345 const bool addPipelineInterfaceCreateInfo = m_maxPayloadSize != 0 || m_maxAttributeSize != 0;
2346 const VkRayTracingPipelineInterfaceCreateInfoKHR* pipelineInterfaceCreateInfoPtr = addPipelineInterfaceCreateInfo ? &pipelineInterfaceCreateInfo : DE_NULL;
2347 const VkPipelineLibraryCreateInfoKHR* librariesCreateInfoPtr = (vkPipelineLibraries.empty() ? nullptr : &librariesCreateInfo);
2349 Move<VkDeferredOperationKHR> deferredOperation;
2350 if (m_deferredOperation)
2351 deferredOperation = createDeferredOperationKHR(vk, device);
2353 VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
2355 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
2356 DE_NULL, // const void* pNext;
2357 0, // VkPipelineDynamicStateCreateFlags flags;
2358 static_cast<deUint32>(m_dynamicStates.size() ), // deUint32 dynamicStateCount;
2359 m_dynamicStates.data(), // const VkDynamicState* pDynamicStates;
2362 const VkRayTracingPipelineCreateInfoKHR pipelineCreateInfo =
2364 VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, // VkStructureType sType;
2365 DE_NULL, // const void* pNext;
2366 m_pipelineCreateFlags, // VkPipelineCreateFlags flags;
2367 (deUint32)m_shaderCreateInfos.size(), // deUint32 stageCount;
2368 m_shaderCreateInfos.data(), // const VkPipelineShaderStageCreateInfo* pStages;
2369 (deUint32)m_shadersGroupCreateInfos.size(), // deUint32 groupCount;
2370 m_shadersGroupCreateInfos.data(), // const VkRayTracingShaderGroupCreateInfoKHR* pGroups;
2371 m_maxRecursionDepth, // deUint32 maxRecursionDepth;
2372 librariesCreateInfoPtr, // VkPipelineLibraryCreateInfoKHR* pLibraryInfo;
2373 pipelineInterfaceCreateInfoPtr, // VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface;
2374 &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2375 pipelineLayout, // VkPipelineLayout layout;
2376 (VkPipeline)DE_NULL, // VkPipeline basePipelineHandle;
2377 0, // deInt32 basePipelineIndex;
2379 VkPipeline object = DE_NULL;
2380 VkResult result = vk.createRayTracingPipelinesKHR(device, deferredOperation.get(), DE_NULL, 1u, &pipelineCreateInfo, DE_NULL, &object);
2381 Move<VkPipeline> pipeline (check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, DE_NULL));
2383 if (m_deferredOperation)
2385 DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
2387 finishDeferredOperation(vk, device, deferredOperation.get(), m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
2394 Move<VkPipeline> RayTracingPipeline::createPipeline (const DeviceInterface& vk,
2395 const VkDevice device,
2396 const VkPipelineLayout pipelineLayout,
2397 const std::vector<de::SharedPtr<Move<VkPipeline>>>& pipelineLibraries)
2399 return createPipelineKHR(vk, device, pipelineLayout, pipelineLibraries);
2402 std::vector<de::SharedPtr<Move<VkPipeline>>> RayTracingPipeline::createPipelineWithLibraries (const DeviceInterface& vk,
2403 const VkDevice device,
2404 const VkPipelineLayout pipelineLayout)
2406 for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx)
2407 DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR);
2409 DE_ASSERT(m_shaderCreateInfos.size() > 0);
2410 DE_ASSERT(m_shadersGroupCreateInfos.size() > 0);
2412 std::vector<de::SharedPtr<Move<VkPipeline>>> result, allLibraries, firstLibraries;
2413 for(auto it=begin(m_pipelineLibraries), eit=end(m_pipelineLibraries); it!=eit; ++it)
2415 auto childLibraries = (*it)->get()->createPipelineWithLibraries(vk, device, pipelineLayout);
2416 DE_ASSERT(childLibraries.size() > 0);
2417 firstLibraries.push_back(childLibraries[0]);
2418 std::copy(begin(childLibraries), end(childLibraries), std::back_inserter(allLibraries));
2420 result.push_back(makeVkSharedPtr(createPipeline(vk, device, pipelineLayout, firstLibraries)));
2421 std::copy(begin(allLibraries), end(allLibraries), std::back_inserter(result));
2425 de::MovePtr<BufferWithMemory> RayTracingPipeline::createShaderBindingTable (const DeviceInterface& vk,
2426 const VkDevice device,
2427 const VkPipeline pipeline,
2428 Allocator& allocator,
2429 const deUint32& shaderGroupHandleSize,
2430 const deUint32 shaderGroupBaseAlignment,
2431 const deUint32& firstGroup,
2432 const deUint32& groupCount,
2433 const VkBufferCreateFlags& additionalBufferCreateFlags,
2434 const VkBufferUsageFlags& additionalBufferUsageFlags,
2435 const MemoryRequirement& additionalMemoryRequirement,
2436 const VkDeviceAddress& opaqueCaptureAddress,
2437 const deUint32 shaderBindingTableOffset,
2438 const deUint32 shaderRecordSize,
2439 const void** shaderGroupDataPtrPerGroup)
2441 DE_ASSERT(shaderGroupBaseAlignment != 0u);
2442 DE_ASSERT((shaderBindingTableOffset % shaderGroupBaseAlignment) == 0);
2443 DE_UNREF(shaderGroupBaseAlignment);
2445 const deUint32 sbtSize = shaderBindingTableOffset + groupCount * deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize);
2446 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;
2447 VkBufferCreateInfo sbtCreateInfo = makeBufferCreateInfo(sbtSize, sbtFlags);
2448 sbtCreateInfo.flags |= additionalBufferCreateFlags;
2449 VkBufferOpaqueCaptureAddressCreateInfo sbtCaptureAddressInfo =
2451 VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, // VkStructureType sType;
2452 DE_NULL, // const void* pNext;
2453 deUint64(opaqueCaptureAddress) // deUint64 opaqueCaptureAddress;
2456 if (opaqueCaptureAddress != 0u)
2458 sbtCreateInfo.pNext = &sbtCaptureAddressInfo;
2459 sbtCreateInfo.flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
2461 const MemoryRequirement sbtMemRequirements = MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress | additionalMemoryRequirement;
2462 de::MovePtr<BufferWithMemory> sbtBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, sbtCreateInfo, sbtMemRequirements));
2463 vk::Allocation& sbtAlloc = sbtBuffer->getAllocation();
2465 // collect shader group handles
2466 std::vector<deUint8> shaderHandles (groupCount * shaderGroupHandleSize);
2467 VK_CHECK(getRayTracingShaderGroupHandles(vk, device, pipeline, firstGroup, groupCount, groupCount * shaderGroupHandleSize, shaderHandles.data()));
2469 // reserve place for ShaderRecordKHR after each shader handle ( ShaderRecordKHR size might be 0 ). Also take alignment into consideration
2470 deUint8* shaderBegin = (deUint8*)sbtAlloc.getHostPtr() + shaderBindingTableOffset;
2471 for (deUint32 idx = 0; idx < groupCount; ++idx)
2473 deUint8* shaderSrcPos = shaderHandles.data() + idx * shaderGroupHandleSize;
2474 deUint8* shaderDstPos = shaderBegin + idx * deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize);
2475 deMemcpy(shaderDstPos, shaderSrcPos, shaderGroupHandleSize);
2477 if (shaderGroupDataPtrPerGroup != nullptr &&
2478 shaderGroupDataPtrPerGroup[idx] != nullptr)
2480 DE_ASSERT(sbtSize >= static_cast<deUint32>(shaderDstPos - shaderBegin) + shaderGroupHandleSize);
2482 deMemcpy( shaderDstPos + shaderGroupHandleSize,
2483 shaderGroupDataPtrPerGroup[idx],
2488 flushMappedMemoryRange(vk, device, sbtAlloc.getMemory(), sbtAlloc.getOffset(), VK_WHOLE_SIZE);
2493 void RayTracingPipeline::setCreateFlags (const VkPipelineCreateFlags& pipelineCreateFlags)
2495 m_pipelineCreateFlags = pipelineCreateFlags;
2498 void RayTracingPipeline::setMaxRecursionDepth (const deUint32& maxRecursionDepth)
2500 m_maxRecursionDepth = maxRecursionDepth;
2503 void RayTracingPipeline::setMaxPayloadSize (const deUint32& maxPayloadSize)
2505 m_maxPayloadSize = maxPayloadSize;
2508 void RayTracingPipeline::setMaxAttributeSize (const deUint32& maxAttributeSize)
2510 m_maxAttributeSize = maxAttributeSize;
2513 void RayTracingPipeline::setDeferredOperation (const bool deferredOperation,
2514 const deUint32 workerThreadCount)
2516 m_deferredOperation = deferredOperation;
2517 m_workerThreadCount = workerThreadCount;
2520 void RayTracingPipeline::addDynamicState(const VkDynamicState& dynamicState)
2522 m_dynamicStates.push_back(dynamicState);
2525 class RayTracingPropertiesKHR : public RayTracingProperties
2528 RayTracingPropertiesKHR () = delete;
2529 RayTracingPropertiesKHR (const InstanceInterface& vki,
2530 const VkPhysicalDevice physicalDevice);
2531 virtual ~RayTracingPropertiesKHR ();
2533 virtual deUint32 getShaderGroupHandleSize (void) { return m_rayTracingPipelineProperties.shaderGroupHandleSize; };
2534 virtual deUint32 getMaxRecursionDepth (void) { return m_rayTracingPipelineProperties.maxRayRecursionDepth; };
2535 virtual deUint32 getMaxShaderGroupStride (void) { return m_rayTracingPipelineProperties.maxShaderGroupStride; };
2536 virtual deUint32 getShaderGroupBaseAlignment (void) { return m_rayTracingPipelineProperties.shaderGroupBaseAlignment; };
2537 virtual deUint64 getMaxGeometryCount (void) { return m_accelerationStructureProperties.maxGeometryCount; };
2538 virtual deUint64 getMaxInstanceCount (void) { return m_accelerationStructureProperties.maxInstanceCount; };
2539 virtual deUint64 getMaxPrimitiveCount (void) { return m_accelerationStructureProperties.maxPrimitiveCount; };
2540 virtual deUint32 getMaxDescriptorSetAccelerationStructures (void) { return m_accelerationStructureProperties.maxDescriptorSetAccelerationStructures; };
2541 deUint32 getMaxRayDispatchInvocationCount (void) { return m_rayTracingPipelineProperties.maxRayDispatchInvocationCount; };
2542 deUint32 getMaxRayHitAttributeSize (void) { return m_rayTracingPipelineProperties.maxRayHitAttributeSize; };
2545 VkPhysicalDeviceAccelerationStructurePropertiesKHR m_accelerationStructureProperties;
2546 VkPhysicalDeviceRayTracingPipelinePropertiesKHR m_rayTracingPipelineProperties;
2549 RayTracingPropertiesKHR::~RayTracingPropertiesKHR ()
2553 RayTracingPropertiesKHR::RayTracingPropertiesKHR (const InstanceInterface& vki,
2554 const VkPhysicalDevice physicalDevice)
2555 : RayTracingProperties (vki, physicalDevice)
2557 m_accelerationStructureProperties = getPhysicalDeviceExtensionProperties(vki, physicalDevice);
2558 m_rayTracingPipelineProperties = getPhysicalDeviceExtensionProperties(vki, physicalDevice);
2561 de::MovePtr<RayTracingProperties> makeRayTracingProperties (const InstanceInterface& vki,
2562 const VkPhysicalDevice physicalDevice)
2564 return de::MovePtr<RayTracingProperties>(new RayTracingPropertiesKHR(vki, physicalDevice));
2567 static inline void cmdTraceRaysKHR (const DeviceInterface& vk,
2568 VkCommandBuffer commandBuffer,
2569 const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion,
2570 const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion,
2571 const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion,
2572 const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion,
2577 return vk.cmdTraceRaysKHR(commandBuffer,
2578 raygenShaderBindingTableRegion,
2579 missShaderBindingTableRegion,
2580 hitShaderBindingTableRegion,
2581 callableShaderBindingTableRegion,
2588 void cmdTraceRays (const DeviceInterface& vk,
2589 VkCommandBuffer commandBuffer,
2590 const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion,
2591 const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion,
2592 const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion,
2593 const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion,
2598 DE_ASSERT(raygenShaderBindingTableRegion != DE_NULL);
2599 DE_ASSERT(missShaderBindingTableRegion != DE_NULL);
2600 DE_ASSERT(hitShaderBindingTableRegion != DE_NULL);
2601 DE_ASSERT(callableShaderBindingTableRegion != DE_NULL);
2603 return cmdTraceRaysKHR(vk,
2605 raygenShaderBindingTableRegion,
2606 missShaderBindingTableRegion,
2607 hitShaderBindingTableRegion,
2608 callableShaderBindingTableRegion,
2614 static inline void cmdTraceRaysIndirectKHR (const DeviceInterface& vk,
2615 VkCommandBuffer commandBuffer,
2616 const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion,
2617 const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion,
2618 const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion,
2619 const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion,
2620 VkDeviceAddress indirectDeviceAddress )
2622 DE_ASSERT(raygenShaderBindingTableRegion != DE_NULL);
2623 DE_ASSERT(missShaderBindingTableRegion != DE_NULL);
2624 DE_ASSERT(hitShaderBindingTableRegion != DE_NULL);
2625 DE_ASSERT(callableShaderBindingTableRegion != DE_NULL);
2626 DE_ASSERT(indirectDeviceAddress != 0);
2628 return vk.cmdTraceRaysIndirectKHR(commandBuffer,
2629 raygenShaderBindingTableRegion,
2630 missShaderBindingTableRegion,
2631 hitShaderBindingTableRegion,
2632 callableShaderBindingTableRegion,
2633 indirectDeviceAddress);
2636 void cmdTraceRaysIndirect (const DeviceInterface& vk,
2637 VkCommandBuffer commandBuffer,
2638 const VkStridedDeviceAddressRegionKHR* raygenShaderBindingTableRegion,
2639 const VkStridedDeviceAddressRegionKHR* missShaderBindingTableRegion,
2640 const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion,
2641 const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion,
2642 VkDeviceAddress indirectDeviceAddress)
2644 return cmdTraceRaysIndirectKHR(vk,
2646 raygenShaderBindingTableRegion,
2647 missShaderBindingTableRegion,
2648 hitShaderBindingTableRegion,
2649 callableShaderBindingTableRegion,
2650 indirectDeviceAddress);