1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief Utilities for creating commonly used Vulkan objects
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vkRayTracingUtil.hpp"
25 
26 #include "vkRefUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkObjUtil.hpp"
29 #include "vkBarrierUtil.hpp"
30 
31 #include "deStringUtil.hpp"
32 
33 #include <vector>
34 #include <string>
35 #include <thread>
36 
37 namespace vk
38 {
39 
40 struct DeferredThreadParams
41 {
42 	const DeviceInterface&	vk;
43 	VkDevice				device;
44 	VkDeferredOperationKHR	deferredOperation;
45 	VkResult				result;
46 };
47 
getFormatSimpleName(vk::VkFormat format)48 std::string getFormatSimpleName (vk::VkFormat format)
49 {
50 	constexpr size_t kPrefixLen = 10; // strlen("VK_FORMAT_")
51 	return de::toLower(de::toString(format).substr(kPrefixLen));
52 }
53 
54 // Returns true if VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR needs to be supported for the given format.
isMandatoryAccelerationStructureVertexBufferFormat(vk::VkFormat format)55 static bool isMandatoryAccelerationStructureVertexBufferFormat (vk::VkFormat format)
56 {
57 	bool mandatory = false;
58 
59 	switch (format)
60 	{
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:
67 		mandatory = true;
68 		break;
69 	default:
70 		break;
71 	}
72 
73 	return mandatory;
74 }
75 
checkAccelerationStructureVertexBufferFormat(const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice,vk::VkFormat format)76 void checkAccelerationStructureVertexBufferFormat (const vk::InstanceInterface &vki, vk::VkPhysicalDevice physicalDevice, vk::VkFormat format)
77 {
78 	const vk::VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
79 
80 	if ((formatProperties.bufferFeatures & vk::VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR) == 0u)
81 	{
82 		const std::string errorMsg = "Format not supported for acceleration structure vertex buffers";
83 		if (isMandatoryAccelerationStructureVertexBufferFormat(format))
84 			TCU_FAIL(errorMsg);
85 		TCU_THROW(NotSupportedError, errorMsg);
86 	}
87 }
88 
getCommonRayGenerationShader(void)89 std::string getCommonRayGenerationShader (void)
90 {
91 	return
92 		"#version 460 core\n"
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"
96 		"\n"
97 		"void main()\n"
98 		"{\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"
106 		"}\n";
107 }
108 
RaytracedGeometryBase(VkGeometryTypeKHR geometryType,VkFormat vertexFormat,VkIndexType indexType)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)
114 {
115 	if (m_geometryType == VK_GEOMETRY_TYPE_AABBS_KHR)
116 		DE_ASSERT(m_vertexFormat == VK_FORMAT_R32G32B32_SFLOAT);
117 }
118 
~RaytracedGeometryBase()119 RaytracedGeometryBase::~RaytracedGeometryBase ()
120 {
121 }
122 
123 struct GeometryBuilderParams
124 {
125 	VkGeometryTypeKHR	geometryType;
126 	bool				usePadding;
127 };
128 
129 template <typename V, typename I>
buildRaytracedGeometry(const GeometryBuilderParams & params)130 RaytracedGeometryBase* buildRaytracedGeometry (const GeometryBuilderParams& params)
131 {
132 	return new RaytracedGeometry<V, I>(params.geometryType, (params.usePadding ? 1u : 0u));
133 }
134 
makeRaytracedGeometry(VkGeometryTypeKHR geometryType,VkFormat vertexFormat,VkIndexType indexType,bool padVertices)135 de::SharedPtr<RaytracedGeometryBase> makeRaytracedGeometry (VkGeometryTypeKHR geometryType, VkFormat vertexFormat, VkIndexType indexType, bool padVertices)
136 {
137 	const GeometryBuilderParams builderParams { geometryType, padVertices };
138 
139 	switch (vertexFormat)
140 	{
141 		case VK_FORMAT_R32G32_SFLOAT:
142 			switch (indexType)
143 			{
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");
148 			};
149 		case VK_FORMAT_R32G32B32_SFLOAT:
150 			switch (indexType)
151 			{
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");
156 			};
157 		case VK_FORMAT_R32G32B32A32_SFLOAT:
158 			switch (indexType)
159 			{
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");
164 			};
165 		case VK_FORMAT_R16G16_SFLOAT:
166 			switch (indexType)
167 			{
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");
172 			};
173 		case VK_FORMAT_R16G16B16_SFLOAT:
174 			switch (indexType)
175 			{
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");
180 			};
181 		case VK_FORMAT_R16G16B16A16_SFLOAT:
182 			switch (indexType)
183 			{
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");
188 			};
189 		case VK_FORMAT_R16G16_SNORM:
190 			switch (indexType)
191 			{
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");
196 			};
197 		case VK_FORMAT_R16G16B16_SNORM:
198 			switch (indexType)
199 			{
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");
204 			};
205 		case VK_FORMAT_R16G16B16A16_SNORM:
206 			switch (indexType)
207 			{
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");
212 			};
213 		case VK_FORMAT_R64G64_SFLOAT:
214 			switch (indexType)
215 			{
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");
220 			};
221 		case VK_FORMAT_R64G64B64_SFLOAT:
222 			switch (indexType)
223 			{
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");
228 			};
229 		case VK_FORMAT_R64G64B64A64_SFLOAT:
230 			switch (indexType)
231 			{
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");
236 			};
237 		case VK_FORMAT_R8G8_SNORM:
238 			switch (indexType)
239 			{
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");
244 			};
245 		case VK_FORMAT_R8G8B8_SNORM:
246 			switch (indexType)
247 			{
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");
252 			};
253 		case VK_FORMAT_R8G8B8A8_SNORM:
254 			switch (indexType)
255 			{
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");
260 			};
261 		default:
262 			TCU_THROW(InternalError, "Wrong vertex format");
263 	};
264 
265 }
266 
getBufferDeviceAddress(const DeviceInterface & vk,const VkDevice device,const VkBuffer buffer,VkDeviceSize offset)267 VkDeviceAddress getBufferDeviceAddress ( const DeviceInterface&	vk,
268 										 const VkDevice			device,
269 										 const VkBuffer			buffer,
270 										 VkDeviceSize			offset )
271 {
272 
273 	if (buffer == DE_NULL)
274 		return 0;
275 
276 	VkBufferDeviceAddressInfo deviceAddressInfo
277 	{
278 		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,		// VkStructureType    sType
279 		DE_NULL,											// const void*        pNext
280 		buffer												// VkBuffer           buffer;
281 	};
282 	return vk.getBufferDeviceAddress(device, &deviceAddressInfo) + offset;
283 }
284 
285 
makeDeviceOrHostAddressConstKHR(const void * hostAddress)286 static inline VkDeviceOrHostAddressConstKHR makeDeviceOrHostAddressConstKHR (const void* hostAddress)
287 {
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;
290 
291 	deMemset(&result, 0, sizeof(result));
292 
293 	result.hostAddress = hostAddress;
294 
295 	return result;
296 }
297 
makeDeviceOrHostAddressKHR(void * hostAddress)298 static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (void* hostAddress)
299 {
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;
302 
303 	deMemset(&result, 0, sizeof(result));
304 
305 	result.hostAddress = hostAddress;
306 
307 	return result;
308 }
309 
makeDeviceOrHostAddressConstKHR(const DeviceInterface & vk,const VkDevice device,VkBuffer buffer,VkDeviceSize offset)310 static inline VkDeviceOrHostAddressConstKHR makeDeviceOrHostAddressConstKHR (const DeviceInterface&	vk,
311 																	  const VkDevice			device,
312 																	  VkBuffer					buffer,
313 																	  VkDeviceSize				offset)
314 {
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;
317 
318 	deMemset(&result, 0, sizeof(result));
319 
320 	VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
321 	{
322 		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType	 sType;
323 		DE_NULL,											// const void*		 pNext;
324 		buffer,												// VkBuffer			buffer
325 	};
326 	result.deviceAddress = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo) + offset;
327 
328 	return result;
329 }
330 
makeDeviceOrHostAddressKHR(const DeviceInterface & vk,const VkDevice device,VkBuffer buffer,VkDeviceSize offset)331 static inline VkDeviceOrHostAddressKHR makeDeviceOrHostAddressKHR (const DeviceInterface&	vk,
332 																   const VkDevice			device,
333 																   VkBuffer					buffer,
334 																   VkDeviceSize				offset)
335 {
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;
338 
339 	deMemset(&result, 0, sizeof(result));
340 
341 	VkBufferDeviceAddressInfo bufferDeviceAddressInfo =
342 	{
343 		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType	 sType;
344 		DE_NULL,											// const void*		 pNext;
345 		buffer,												// VkBuffer			buffer
346 	};
347 	result.deviceAddress = vk.getBufferDeviceAddress(device, &bufferDeviceAddressInfo) + offset;
348 
349 	return result;
350 }
351 
makeVkAccelerationStructureGeometryDataKHR(const VkAccelerationStructureGeometryTrianglesDataKHR & triangles)352 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryTrianglesDataKHR& triangles)
353 {
354 	VkAccelerationStructureGeometryDataKHR result;
355 
356 	deMemset(&result, 0, sizeof(result));
357 
358 	result.triangles = triangles;
359 
360 	return result;
361 }
362 
makeVkAccelerationStructureGeometryDataKHR(const VkAccelerationStructureGeometryAabbsDataKHR & aabbs)363 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureGeometryDataKHR (const VkAccelerationStructureGeometryAabbsDataKHR& aabbs)
364 {
365 	VkAccelerationStructureGeometryDataKHR result;
366 
367 	deMemset(&result, 0, sizeof(result));
368 
369 	result.aabbs = aabbs;
370 
371 	return result;
372 }
373 
makeVkAccelerationStructureInstancesDataKHR(const VkAccelerationStructureGeometryInstancesDataKHR & instances)374 static inline VkAccelerationStructureGeometryDataKHR makeVkAccelerationStructureInstancesDataKHR (const VkAccelerationStructureGeometryInstancesDataKHR& instances)
375 {
376 	VkAccelerationStructureGeometryDataKHR result;
377 
378 	deMemset(&result, 0, sizeof(result));
379 
380 	result.instances = instances;
381 
382 	return result;
383 }
384 
makeVkAccelerationStructureInstanceKHR(const VkTransformMatrixKHR & transform,deUint32 instanceCustomIndex,deUint32 mask,deUint32 instanceShaderBindingTableRecordOffset,VkGeometryInstanceFlagsKHR flags,deUint64 accelerationStructureReference)385 static inline VkAccelerationStructureInstanceKHR makeVkAccelerationStructureInstanceKHR (const VkTransformMatrixKHR&			transform,
386 																						 deUint32								instanceCustomIndex,
387 																						 deUint32								mask,
388 																						 deUint32								instanceShaderBindingTableRecordOffset,
389 																						 VkGeometryInstanceFlagsKHR				flags,
390 																						 deUint64								accelerationStructureReference)
391 {
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;
397 	return instance;
398 }
399 
getRayTracingShaderGroupHandlesKHR(const DeviceInterface & vk,const VkDevice device,const VkPipeline pipeline,const deUint32 firstGroup,const deUint32 groupCount,const deUintptr dataSize,void * pData)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,
406 											 void*						pData)
407 {
408 	return vk.getRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData);
409 }
410 
getRayTracingShaderGroupHandles(const DeviceInterface & vk,const VkDevice device,const VkPipeline pipeline,const deUint32 firstGroup,const deUint32 groupCount,const deUintptr dataSize,void * 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,
417 										  void*							pData)
418 {
419 	return getRayTracingShaderGroupHandlesKHR(vk, device, pipeline, firstGroup, groupCount, dataSize, pData);
420 }
421 
finishDeferredOperation(const DeviceInterface & vk,VkDevice device,VkDeferredOperationKHR deferredOperation)422 VkResult finishDeferredOperation (const DeviceInterface&	vk,
423 								  VkDevice					device,
424 								  VkDeferredOperationKHR	deferredOperation)
425 {
426 	VkResult result = vk.deferredOperationJoinKHR(device, deferredOperation);
427 
428 	while (result == VK_THREAD_IDLE_KHR)
429 	{
430 		std::this_thread::yield();
431 		result = vk.deferredOperationJoinKHR(device, deferredOperation);
432 	}
433 
434 	switch( result )
435 	{
436 		case VK_SUCCESS:
437 		{
438 			// Deferred operation has finished. Query its result
439 			result = vk.getDeferredOperationResultKHR(device, deferredOperation);
440 
441 			break;
442 		}
443 
444 		case VK_THREAD_DONE_KHR:
445 		{
446 			// Deferred operation is being wrapped up by another thread
447 			// wait for that thread to finish
448 			do
449 			{
450 				std::this_thread::yield();
451 				result = vk.getDeferredOperationResultKHR(device, deferredOperation);
452 			} while (result == VK_NOT_READY);
453 
454 			break;
455 		}
456 
457 		default:
458 		{
459 			DE_ASSERT(false);
460 
461 			break;
462 		}
463 	}
464 
465 	return result;
466 }
467 
finishDeferredOperationThreaded(DeferredThreadParams * deferredThreadParams)468 void finishDeferredOperationThreaded (DeferredThreadParams* deferredThreadParams)
469 {
470 	deferredThreadParams->result = finishDeferredOperation(deferredThreadParams->vk, deferredThreadParams->device, deferredThreadParams->deferredOperation);
471 }
472 
finishDeferredOperation(const DeviceInterface & vk,VkDevice device,VkDeferredOperationKHR deferredOperation,const deUint32 workerThreadCount,const bool operationNotDeferred)473 void finishDeferredOperation (const DeviceInterface&	vk,
474 							  VkDevice					device,
475 							  VkDeferredOperationKHR	deferredOperation,
476 							  const deUint32			workerThreadCount,
477 							  const bool				operationNotDeferred)
478 {
479 
480 	if (operationNotDeferred)
481 	{
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));
485 
486 
487 		// there is not need to join any threads to the deferred operation,
488 		// so below can be skipped.
489 		return;
490 	}
491 
492 	if (workerThreadCount == 0)
493 	{
494 		VK_CHECK(finishDeferredOperation(vk, device, deferredOperation));
495 	}
496 	else
497 	{
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;
501 
502 		if (maxThreadCountSupported == 0)
503 			TCU_FAIL("vkGetDeferredOperationMaxConcurrencyKHR must not return 0");
504 
505 		const DeferredThreadParams				deferredThreadParams	=
506 		{
507 			vk,					//  const DeviceInterface&	vk;
508 			device,				//  VkDevice				device;
509 			deferredOperation,	//  VkDeferredOperationKHR	deferredOperation;
510 			VK_RESULT_MAX_ENUM,	//  VResult					result;
511 		};
512 		std::vector<DeferredThreadParams>		threadParams	(testThreadCount, deferredThreadParams);
513 		std::vector<de::MovePtr<std::thread> >	threads			(testThreadCount);
514 		bool									executionResult	= false;
515 
516 		DE_ASSERT(threads.size() > 0 && threads.size() == testThreadCount);
517 
518 		for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx)
519 			threads[threadNdx] = de::MovePtr<std::thread>(new std::thread(finishDeferredOperationThreaded, &threadParams[threadNdx]));
520 
521 		for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx)
522 			threads[threadNdx]->join();
523 
524 		for (deUint32 threadNdx = 0; threadNdx < testThreadCount; ++threadNdx)
525 			if (threadParams[threadNdx].result == VK_SUCCESS)
526 				executionResult = true;
527 
528 		if (!executionResult)
529 			TCU_FAIL("Neither reported VK_SUCCESS");
530 	}
531 }
532 
SerialStorage(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkAccelerationStructureBuildTypeKHR buildType,const VkDeviceSize storageSize)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)
540 {
541 	const VkBufferCreateInfo	bufferCreateInfo	= makeBufferCreateInfo(storageSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
542 	try
543 	{
544 		m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
545 	}
546 	catch (const tcu::NotSupportedError&)
547 	{
548 		// retry without Cached flag
549 		m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
550 	}
551 }
552 
getAddress(const DeviceInterface & vk,const VkDevice device)553 VkDeviceOrHostAddressKHR SerialStorage::getAddress (const DeviceInterface&				vk,
554 													const VkDevice						device)
555 {
556 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
557 		return makeDeviceOrHostAddressKHR(vk, device, m_buffer->get(), 0);
558 	else
559 		return makeDeviceOrHostAddressKHR(m_buffer->getAllocation().getHostPtr());
560 }
561 
getAddressConst(const DeviceInterface & vk,const VkDevice device)562 VkDeviceOrHostAddressConstKHR SerialStorage::getAddressConst (const DeviceInterface&	vk,
563 															  const VkDevice			device)
564 {
565 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
566 		return makeDeviceOrHostAddressConstKHR(vk, device, m_buffer->get(), 0);
567 	else
568 		return makeDeviceOrHostAddressConstKHR(m_buffer->getAllocation().getHostPtr());
569 }
570 
getStorageSize()571 VkDeviceSize SerialStorage::getStorageSize ()
572 {
573 	return m_storageSize;
574 }
575 
getDeserializedSize()576 deUint64 SerialStorage::getDeserializedSize ()
577 {
578 	deUint64		result		= 0;
579 	const deUint8*	startPtr	= static_cast<deUint8*>(m_buffer->getAllocation().getHostPtr());
580 
581 	DE_ASSERT(sizeof(result) == DESERIALIZED_SIZE_SIZE);
582 
583 	deMemcpy(&result, startPtr + DESERIALIZED_SIZE_OFFSET, sizeof(result));
584 
585 	return result;
586 }
587 
~BottomLevelAccelerationStructure()588 BottomLevelAccelerationStructure::~BottomLevelAccelerationStructure ()
589 {
590 }
591 
BottomLevelAccelerationStructure()592 BottomLevelAccelerationStructure::BottomLevelAccelerationStructure ()
593 	: m_structureSize		(0u)
594 	, m_updateScratchSize	(0u)
595 	, m_buildScratchSize	(0u)
596 {
597 }
598 
setGeometryData(const std::vector<tcu::Vec3> & geometryData,const bool triangles,const VkGeometryFlagsKHR geometryFlags)599 void BottomLevelAccelerationStructure::setGeometryData (const std::vector<tcu::Vec3>&	geometryData,
600 														const bool						triangles,
601 														const VkGeometryFlagsKHR		geometryFlags)
602 {
603 	if (triangles)
604 		DE_ASSERT((geometryData.size() % 3) == 0);
605 	else
606 		DE_ASSERT((geometryData.size() % 2) == 0);
607 
608 	setGeometryCount(1u);
609 
610 	addGeometry(geometryData, triangles, geometryFlags);
611 }
612 
setDefaultGeometryData(const VkShaderStageFlagBits testStage,const VkGeometryFlagsKHR geometryFlags)613 void BottomLevelAccelerationStructure::setDefaultGeometryData (const VkShaderStageFlagBits	testStage,
614 															   const VkGeometryFlagsKHR		geometryFlags)
615 {
616 	bool					trianglesData	= false;
617 	float					z				= 0.0f;
618 	std::vector<tcu::Vec3>	geometryData;
619 
620 	switch (testStage)
621 	{
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");
629 	}
630 
631 	if (trianglesData)
632 	{
633 		geometryData.reserve(6);
634 
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));
641 	}
642 	else
643 	{
644 		geometryData.reserve(2);
645 
646 		geometryData.push_back(tcu::Vec3(-1.0f, -1.0f, z));
647 		geometryData.push_back(tcu::Vec3(+1.0f, +1.0f, z));
648 	}
649 
650 	setGeometryCount(1u);
651 
652 	addGeometry(geometryData, trianglesData, geometryFlags);
653 }
654 
setGeometryCount(const size_t geometryCount)655 void BottomLevelAccelerationStructure::setGeometryCount (const size_t geometryCount)
656 {
657 	m_geometriesData.clear();
658 
659 	m_geometriesData.reserve(geometryCount);
660 }
661 
addGeometry(de::SharedPtr<RaytracedGeometryBase> & raytracedGeometry)662 void BottomLevelAccelerationStructure::addGeometry (de::SharedPtr<RaytracedGeometryBase>&		raytracedGeometry)
663 {
664 	m_geometriesData.push_back(raytracedGeometry);
665 }
666 
addGeometry(const std::vector<tcu::Vec3> & geometryData,const bool triangles,const VkGeometryFlagsKHR geometryFlags)667 void BottomLevelAccelerationStructure::addGeometry (const std::vector<tcu::Vec3>&	geometryData,
668 													const bool						triangles,
669 													const VkGeometryFlagsKHR		geometryFlags)
670 {
671 	DE_ASSERT(geometryData.size() > 0);
672 	DE_ASSERT((triangles && geometryData.size() % 3 == 0) || (!triangles && geometryData.size() % 2 == 0));
673 
674 	if (!triangles)
675 		for (size_t posNdx = 0; posNdx < geometryData.size() / 2; ++posNdx)
676 		{
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());
680 		}
681 
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);
685 
686 	geometry->setGeometryFlags(geometryFlags);
687 	addGeometry(geometry);
688 }
689 
getStructureSize() const690 VkDeviceSize BottomLevelAccelerationStructure::getStructureSize() const
691 {
692 	return m_structureSize;
693 }
694 
createVertexBuffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const std::vector<de::SharedPtr<RaytracedGeometryBase>> & geometriesData)695 BufferWithMemory* createVertexBuffer (const DeviceInterface&									vk,
696 									  const VkDevice											device,
697 									  Allocator&												allocator,
698 									  const std::vector<de::SharedPtr<RaytracedGeometryBase>>&	geometriesData)
699 {
700 	DE_ASSERT(geometriesData.size() != 0);
701 
702 	VkDeviceSize					bufferSizeBytes = 0;
703 	for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
704 		bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getVertexByteSize(),8);
705 
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);
708 }
709 
updateVertexBuffer(const DeviceInterface & vk,const VkDevice device,const std::vector<de::SharedPtr<RaytracedGeometryBase>> & geometriesData,BufferWithMemory * vertexBuffer)710 void updateVertexBuffer (const DeviceInterface&										vk,
711 						 const VkDevice												device,
712 						 const std::vector<de::SharedPtr<RaytracedGeometryBase>>&	geometriesData,
713 						 BufferWithMemory*											vertexBuffer)
714 {
715 	const Allocation&				geometryAlloc		= vertexBuffer->getAllocation();
716 	deUint8*						bufferStart			= static_cast<deUint8*>(geometryAlloc.getHostPtr());
717 	VkDeviceSize					bufferOffset		= 0;
718 
719 	for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
720 	{
721 		const void*					geometryPtr			= geometriesData[geometryNdx]->getVertexPointer();
722 		const size_t				geometryPtrSize		= geometriesData[geometryNdx]->getVertexByteSize();
723 
724 		deMemcpy(&bufferStart[bufferOffset], geometryPtr, geometryPtrSize);
725 
726 		bufferOffset += deAlignSize(geometryPtrSize,8);
727 	}
728 
729 	flushMappedMemoryRange(vk, device, geometryAlloc.getMemory(), geometryAlloc.getOffset(), VK_WHOLE_SIZE);
730 }
731 
createIndexBuffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const std::vector<de::SharedPtr<RaytracedGeometryBase>> & geometriesData)732 BufferWithMemory* createIndexBuffer (const DeviceInterface&										vk,
733 									 const VkDevice												device,
734 									 Allocator&													allocator,
735 									 const std::vector<de::SharedPtr<RaytracedGeometryBase>>&	geometriesData)
736 {
737 	DE_ASSERT(!geometriesData.empty());
738 
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);
743 
744 	if (bufferSizeBytes == 0)
745 		return DE_NULL;
746 
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);
749 }
750 
updateIndexBuffer(const DeviceInterface & vk,const VkDevice device,const std::vector<de::SharedPtr<RaytracedGeometryBase>> & geometriesData,BufferWithMemory * indexBuffer)751 void updateIndexBuffer (const DeviceInterface&										vk,
752 						const VkDevice												device,
753 						const std::vector<de::SharedPtr<RaytracedGeometryBase>>&	geometriesData,
754 						BufferWithMemory*											indexBuffer)
755 {
756 	const Allocation&				indexAlloc			= indexBuffer->getAllocation();
757 	deUint8*						bufferStart			= static_cast<deUint8*>(indexAlloc.getHostPtr());
758 	VkDeviceSize					bufferOffset		= 0;
759 
760 	for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
761 	{
762 		if (geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
763 		{
764 			const void*					indexPtr		= geometriesData[geometryNdx]->getIndexPointer();
765 			const size_t				indexPtrSize	= geometriesData[geometryNdx]->getIndexByteSize();
766 
767 			deMemcpy(&bufferStart[bufferOffset], indexPtr, indexPtrSize);
768 
769 			bufferOffset += deAlignSize(indexPtrSize, 8);
770 		}
771 	}
772 
773 	flushMappedMemoryRange(vk, device, indexAlloc.getMemory(), indexAlloc.getOffset(), VK_WHOLE_SIZE);
774 }
775 
776 class BottomLevelAccelerationStructureKHR : public BottomLevelAccelerationStructure
777 {
778 public:
779 	static deUint32											getRequiredAllocationCount						(void);
780 
781 															BottomLevelAccelerationStructureKHR				();
782 															BottomLevelAccelerationStructureKHR				(const BottomLevelAccelerationStructureKHR&		other) = delete;
783 	virtual													~BottomLevelAccelerationStructureKHR			();
784 
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;
798 
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;
812 
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;
821 
822 	const VkAccelerationStructureKHR*						getPtr											(void) const override;
823 
824 protected:
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;
843 
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);
850 };
851 
getRequiredAllocationCount(void)852 deUint32 BottomLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
853 {
854 	/*
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;
858 	*/
859 	return 3u;
860 }
861 
~BottomLevelAccelerationStructureKHR()862 BottomLevelAccelerationStructureKHR::~BottomLevelAccelerationStructureKHR ()
863 {
864 }
865 
BottomLevelAccelerationStructureKHR()866 BottomLevelAccelerationStructureKHR::BottomLevelAccelerationStructureKHR ()
867 	: BottomLevelAccelerationStructure	()
868 	, m_buildType						(VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
869 	, m_createFlags						(0u)
870 	, m_createGeneric					(false)
871 	, m_buildFlags						(0u)
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)
885 {
886 }
887 
setBuildType(const VkAccelerationStructureBuildTypeKHR buildType)888 void BottomLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR	buildType)
889 {
890 	m_buildType = buildType;
891 }
892 
setCreateFlags(const VkAccelerationStructureCreateFlagsKHR createFlags)893 void BottomLevelAccelerationStructureKHR::setCreateFlags (const VkAccelerationStructureCreateFlagsKHR	createFlags)
894 {
895 	m_createFlags = createFlags;
896 }
897 
setCreateGeneric(bool createGeneric)898 void BottomLevelAccelerationStructureKHR::setCreateGeneric (bool createGeneric)
899 {
900 	m_createGeneric = createGeneric;
901 }
902 
setBuildFlags(const VkBuildAccelerationStructureFlagsKHR buildFlags)903 void BottomLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR	buildFlags)
904 {
905 	m_buildFlags = buildFlags;
906 }
907 
setBuildWithoutGeometries(bool buildWithoutGeometries)908 void BottomLevelAccelerationStructureKHR::setBuildWithoutGeometries (bool buildWithoutGeometries)
909 {
910 	m_buildWithoutGeometries = buildWithoutGeometries;
911 }
912 
setBuildWithoutPrimitives(bool buildWithoutPrimitives)913 void BottomLevelAccelerationStructureKHR::setBuildWithoutPrimitives (bool buildWithoutPrimitives)
914 {
915 	m_buildWithoutPrimitives = buildWithoutPrimitives;
916 }
917 
setDeferredOperation(const bool deferredOperation,const deUint32 workerThreadCount)918 void BottomLevelAccelerationStructureKHR::setDeferredOperation (const bool		deferredOperation,
919 																const deUint32	workerThreadCount)
920 {
921 	m_deferredOperation = deferredOperation;
922 	m_workerThreadCount = workerThreadCount;
923 }
924 
setUseArrayOfPointers(const bool useArrayOfPointers)925 void BottomLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool	useArrayOfPointers)
926 {
927 	m_useArrayOfPointers = useArrayOfPointers;
928 }
929 
setIndirectBuildParameters(const VkBuffer indirectBuffer,const VkDeviceSize indirectBufferOffset,const deUint32 indirectBufferStride)930 void BottomLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer		indirectBuffer,
931 																	  const VkDeviceSize	indirectBufferOffset,
932 																	  const deUint32		indirectBufferStride)
933 {
934 	m_indirectBuffer		= indirectBuffer;
935 	m_indirectBufferOffset	= indirectBufferOffset;
936 	m_indirectBufferStride	= indirectBufferStride;
937 }
938 
getBuildFlags() const939 VkBuildAccelerationStructureFlagsKHR BottomLevelAccelerationStructureKHR::getBuildFlags () const
940 {
941 	return m_buildFlags;
942 }
943 
create(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,VkDeviceSize structureSize,VkDeviceAddress deviceAddress)944 void BottomLevelAccelerationStructureKHR::create (const DeviceInterface&				vk,
945 												  const VkDevice						device,
946 												  Allocator&							allocator,
947 												  VkDeviceSize							structureSize,
948 												  VkDeviceAddress						deviceAddress)
949 {
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
953 
954 	if (structureSize == 0)
955 	{
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);
961 
962 		const VkAccelerationStructureGeometryKHR*				accelerationStructureGeometriesKHRPointer	= accelerationStructureGeometriesKHR.data();
963 		const VkAccelerationStructureGeometryKHR* const*		accelerationStructureGeometry				= accelerationStructureGeometriesKHRPointers.data();
964 
965 		VkAccelerationStructureBuildGeometryInfoKHR	accelerationStructureBuildGeometryInfoKHR	=
966 		{
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;
978 		};
979 		VkAccelerationStructureBuildSizesInfoKHR sizeInfo =
980 		{
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;
986 		};
987 
988 		vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo);
989 
990 		m_structureSize		= sizeInfo.accelerationStructureSize;
991 		m_updateScratchSize	= sizeInfo.updateScratchSize;
992 		m_buildScratchSize	= sizeInfo.buildScratchSize;
993 	}
994 	else
995 	{
996 		m_structureSize		= structureSize;
997 		m_updateScratchSize	= 0u;
998 		m_buildScratchSize	= 0u;
999 	}
1000 
1001 	{
1002 		const VkBufferCreateInfo		bufferCreateInfo	= makeBufferCreateInfo(m_structureSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1003 		try
1004 		{
1005 			m_accelerationStructureBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1006 		}
1007 		catch (const tcu::NotSupportedError&)
1008 		{
1009 			// retry without Cached flag
1010 			m_accelerationStructureBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1011 		}
1012 	}
1013 
1014 	{
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
1019 		{
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;
1028 		};
1029 
1030 		m_accelerationStructureKHR	= createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL);
1031 	}
1032 
1033 	if (m_buildScratchSize > 0u)
1034 	{
1035 		if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1036 		{
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));
1039 		}
1040 		else
1041 		{
1042 			m_hostScratchBuffer.resize(static_cast<size_t>(m_buildScratchSize));
1043 		}
1044 	}
1045 
1046 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR && !m_geometriesData.empty())
1047 	{
1048 		m_vertexBuffer	= de::MovePtr<BufferWithMemory>(createVertexBuffer(vk, device, allocator, m_geometriesData));
1049 		m_indexBuffer	= de::MovePtr<BufferWithMemory>(createIndexBuffer(vk, device, allocator, m_geometriesData));
1050 	}
1051 }
1052 
build(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer)1053 void BottomLevelAccelerationStructureKHR::build (const DeviceInterface&						vk,
1054 												 const VkDevice								device,
1055 												 const VkCommandBuffer						cmdBuffer)
1056 {
1057 	DE_ASSERT(!m_geometriesData.empty());
1058 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1059 	DE_ASSERT(m_buildScratchSize != 0);
1060 
1061 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1062 	{
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());
1066 	}
1067 
1068 	{
1069 		std::vector<VkAccelerationStructureGeometryKHR>			accelerationStructureGeometriesKHR;
1070 		std::vector<VkAccelerationStructureGeometryKHR*>		accelerationStructureGeometriesKHRPointers;
1071 		std::vector<VkAccelerationStructureBuildRangeInfoKHR>	accelerationStructureBuildRangeInfoKHR;
1072 		std::vector<deUint32>									maxPrimitiveCounts;
1073 
1074 		prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, maxPrimitiveCounts);
1075 
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
1082 																										? 0u
1083 																										: static_cast<deUint32>(accelerationStructureGeometriesKHR.size()));
1084 
1085 		VkAccelerationStructureBuildGeometryInfoKHR	accelerationStructureBuildGeometryInfoKHR	=
1086 		{
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;
1098 		};
1099 
1100 		VkAccelerationStructureBuildRangeInfoKHR* accelerationStructureBuildRangeInfoKHRPtr	= accelerationStructureBuildRangeInfoKHR.data();
1101 
1102 		if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1103 		{
1104 			if (m_indirectBuffer == DE_NULL)
1105 				vk.cmdBuildAccelerationStructuresKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1106 			else
1107 			{
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);
1111 			}
1112 		}
1113 		else if (!m_deferredOperation)
1114 		{
1115 			VK_CHECK(vk.buildAccelerationStructuresKHR(device, DE_NULL, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr));
1116 		}
1117 		else
1118 		{
1119 			const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
1120 			const auto deferredOperation	= deferredOperationPtr.get();
1121 
1122 			VkResult result = vk.buildAccelerationStructuresKHR(device, deferredOperation, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1123 
1124 			DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1125 
1126 			finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1127 		}
1128 	}
1129 
1130 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1131 	{
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);
1134 
1135 		cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1136 	}
1137 }
1138 
copyFrom(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,BottomLevelAccelerationStructure * accelerationStructure,bool compactCopy)1139 void BottomLevelAccelerationStructureKHR::copyFrom (const DeviceInterface&						vk,
1140 													const VkDevice								device,
1141 													const VkCommandBuffer						cmdBuffer,
1142 													BottomLevelAccelerationStructure*			accelerationStructure,
1143 													bool										compactCopy)
1144 {
1145 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1146 	DE_ASSERT(accelerationStructure != DE_NULL);
1147 
1148 	VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo =
1149 	{
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;
1155 	};
1156 
1157 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1158 	{
1159 		vk.cmdCopyAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
1160 	}
1161 	else if (!m_deferredOperation)
1162 	{
1163 		VK_CHECK(vk.copyAccelerationStructureKHR(device, DE_NULL, &copyAccelerationStructureInfo));
1164 	}
1165 	else
1166 	{
1167 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
1168 		const auto deferredOperation	= deferredOperationPtr.get();
1169 
1170 		VkResult result = vk.copyAccelerationStructureKHR(device, deferredOperation, &copyAccelerationStructureInfo);
1171 
1172 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1173 
1174 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1175 	}
1176 
1177 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1178 	{
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);
1181 
1182 		cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1183 	}
1184 }
1185 
serialize(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,SerialStorage * storage)1186 void BottomLevelAccelerationStructureKHR::serialize (const DeviceInterface&		vk,
1187 													 const VkDevice				device,
1188 													 const VkCommandBuffer		cmdBuffer,
1189 													 SerialStorage*				storage)
1190 {
1191 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1192 	DE_ASSERT(storage != DE_NULL);
1193 
1194 	const VkCopyAccelerationStructureToMemoryInfoKHR	copyAccelerationStructureInfo	=
1195 	{
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;
1201 	};
1202 
1203 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1204 	{
1205 		vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, &copyAccelerationStructureInfo);
1206 	}
1207 	else if (!m_deferredOperation)
1208 	{
1209 		VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, &copyAccelerationStructureInfo));
1210 	}
1211 	else
1212 	{
1213 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
1214 		const auto deferredOperation	= deferredOperationPtr.get();
1215 
1216 		const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, &copyAccelerationStructureInfo);
1217 
1218 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1219 
1220 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1221 	}
1222 }
1223 
deserialize(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,SerialStorage * storage)1224 void BottomLevelAccelerationStructureKHR::deserialize (const DeviceInterface&	vk,
1225 													   const VkDevice			device,
1226 													   const VkCommandBuffer	cmdBuffer,
1227 													   SerialStorage*			storage)
1228 {
1229 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1230 	DE_ASSERT(storage != DE_NULL);
1231 
1232 	const VkCopyMemoryToAccelerationStructureInfoKHR	copyAccelerationStructureInfo	=
1233 	{
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;
1239 	};
1240 
1241 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1242 	{
1243 		vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
1244 	}
1245 	else if (!m_deferredOperation)
1246 	{
1247 		VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, DE_NULL, &copyAccelerationStructureInfo));
1248 	}
1249 	else
1250 	{
1251 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
1252 		const auto deferredOperation	= deferredOperationPtr.get();
1253 
1254 		const VkResult result = vk.copyMemoryToAccelerationStructureKHR(device, deferredOperation, &copyAccelerationStructureInfo);
1255 
1256 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1257 
1258 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1259 	}
1260 
1261 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1262 	{
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);
1265 
1266 		cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1267 	}
1268 }
1269 
getPtr(void) const1270 const VkAccelerationStructureKHR* BottomLevelAccelerationStructureKHR::getPtr (void) const
1271 {
1272 	return &m_accelerationStructureKHR.get();
1273 }
1274 
prepareGeometries(const DeviceInterface & vk,const VkDevice device,std::vector<VkAccelerationStructureGeometryKHR> & accelerationStructureGeometriesKHR,std::vector<VkAccelerationStructureGeometryKHR * > & accelerationStructureGeometriesKHRPointers,std::vector<VkAccelerationStructureBuildRangeInfoKHR> & accelerationStructureBuildRangeInfoKHR,std::vector<deUint32> & maxPrimitiveCounts)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)
1281 {
1282 	accelerationStructureGeometriesKHR.resize(m_geometriesData.size());
1283 	accelerationStructureGeometriesKHRPointers.resize(m_geometriesData.size());
1284 	accelerationStructureBuildRangeInfoKHR.resize(m_geometriesData.size());
1285 	maxPrimitiveCounts.resize(m_geometriesData.size());
1286 
1287 	VkDeviceSize vertexBufferOffset = 0, indexBufferOffset = 0;
1288 
1289 	for (size_t geometryNdx = 0; geometryNdx < m_geometriesData.size(); ++geometryNdx)
1290 	{
1291 		de::SharedPtr<RaytracedGeometryBase>&					geometryData = m_geometriesData[geometryNdx];
1292 		VkDeviceOrHostAddressConstKHR							vertexData, indexData;
1293 		if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1294 		{
1295 			if (m_vertexBuffer.get() != DE_NULL)
1296 			{
1297 				vertexData			= makeDeviceOrHostAddressConstKHR(vk, device, m_vertexBuffer->get(), vertexBufferOffset);
1298 				vertexBufferOffset	+= deAlignSize(geometryData->getVertexByteSize(), 8);
1299 			}
1300 			else
1301 				vertexData			= makeDeviceOrHostAddressConstKHR(DE_NULL);
1302 
1303 			if (m_indexBuffer.get() != DE_NULL &&  geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
1304 			{
1305 				indexData			= makeDeviceOrHostAddressConstKHR(vk, device, m_indexBuffer->get(), indexBufferOffset);
1306 				indexBufferOffset	+= deAlignSize(geometryData->getIndexByteSize(), 8);
1307 			}
1308 			else
1309 				indexData = makeDeviceOrHostAddressConstKHR(DE_NULL);
1310 		}
1311 		else
1312 		{
1313 			vertexData = makeDeviceOrHostAddressConstKHR(geometryData->getVertexPointer());
1314 			if (geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR)
1315 				indexData = makeDeviceOrHostAddressConstKHR(geometryData->getIndexPointer());
1316 			else
1317 				indexData = makeDeviceOrHostAddressConstKHR(DE_NULL);
1318 		}
1319 
1320 		const VkAccelerationStructureGeometryTrianglesDataKHR	accelerationStructureGeometryTrianglesDataKHR =
1321 		{
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;
1331 		};
1332 
1333 		const VkAccelerationStructureGeometryAabbsDataKHR		accelerationStructureGeometryAabbsDataKHR =
1334 		{
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;
1339 		};
1340 		const VkAccelerationStructureGeometryDataKHR			geometry = (geometryData->isTrianglesType())
1341 																		 ? makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryTrianglesDataKHR)
1342 																		 : makeVkAccelerationStructureGeometryDataKHR(accelerationStructureGeometryAabbsDataKHR);
1343 		const VkAccelerationStructureGeometryKHR				accelerationStructureGeometryKHR =
1344 		{
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;
1350 		};
1351 
1352 		const deUint32 primitiveCount = (m_buildWithoutPrimitives ? 0u : geometryData->getPrimitiveCount());
1353 
1354 		const VkAccelerationStructureBuildRangeInfoKHR			accelerationStructureBuildRangeInfosKHR =
1355 		{
1356 			primitiveCount,	//  deUint32	primitiveCount;
1357 			0,				//  deUint32	primitiveOffset;
1358 			0,				//  deUint32	firstVertex;
1359 			0				//  deUint32	firstTransform;
1360 		};
1361 
1362 		accelerationStructureGeometriesKHR[geometryNdx]			= accelerationStructureGeometryKHR;
1363 		accelerationStructureGeometriesKHRPointers[geometryNdx]	= &accelerationStructureGeometriesKHR[geometryNdx];
1364 		accelerationStructureBuildRangeInfoKHR[geometryNdx]		= accelerationStructureBuildRangeInfosKHR;
1365 		maxPrimitiveCounts[geometryNdx]							= geometryData->getPrimitiveCount();
1366 	}
1367 }
1368 
getRequiredAllocationCount(void)1369 deUint32 BottomLevelAccelerationStructure::getRequiredAllocationCount (void)
1370 {
1371 	return BottomLevelAccelerationStructureKHR::getRequiredAllocationCount();
1372 }
1373 
createAndBuild(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,Allocator & allocator,VkDeviceAddress deviceAddress)1374 void BottomLevelAccelerationStructure::createAndBuild (const DeviceInterface&	vk,
1375 													   const VkDevice			device,
1376 													   const VkCommandBuffer	cmdBuffer,
1377 													   Allocator&				allocator,
1378 													   VkDeviceAddress			deviceAddress)
1379 {
1380 	create(vk, device, allocator, 0u, deviceAddress);
1381 	build(vk, device, cmdBuffer);
1382 }
1383 
createAndCopyFrom(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,Allocator & allocator,BottomLevelAccelerationStructure * accelerationStructure,VkDeviceSize compactCopySize,VkDeviceAddress deviceAddress)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)
1391 {
1392 	DE_ASSERT(accelerationStructure != NULL);
1393 	VkDeviceSize copiedSize = compactCopySize > 0u ? compactCopySize : accelerationStructure->getStructureSize();
1394 	DE_ASSERT(copiedSize != 0u);
1395 
1396 	create(vk, device, allocator, copiedSize, deviceAddress);
1397 	copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u);
1398 }
1399 
createAndDeserializeFrom(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,Allocator & allocator,SerialStorage * storage,VkDeviceAddress deviceAddress)1400 void BottomLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
1401 																 const VkDevice								device,
1402 																 const VkCommandBuffer						cmdBuffer,
1403 																 Allocator&									allocator,
1404 																 SerialStorage*								storage,
1405 																 VkDeviceAddress							deviceAddress )
1406 {
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);
1411 }
1412 
makeBottomLevelAccelerationStructure()1413 de::MovePtr<BottomLevelAccelerationStructure> makeBottomLevelAccelerationStructure ()
1414 {
1415 	return de::MovePtr<BottomLevelAccelerationStructure>(new BottomLevelAccelerationStructureKHR);
1416 }
1417 
~TopLevelAccelerationStructure()1418 TopLevelAccelerationStructure::~TopLevelAccelerationStructure ()
1419 {
1420 }
1421 
TopLevelAccelerationStructure()1422 TopLevelAccelerationStructure::TopLevelAccelerationStructure ()
1423 	: m_structureSize		(0u)
1424 	, m_updateScratchSize	(0u)
1425 	, m_buildScratchSize	(0u)
1426 {
1427 }
1428 
setInstanceCount(const size_t instanceCount)1429 void TopLevelAccelerationStructure::setInstanceCount (const size_t instanceCount)
1430 {
1431 	m_bottomLevelInstances.reserve(instanceCount);
1432 	m_instanceData.reserve(instanceCount);
1433 }
1434 
addInstance(de::SharedPtr<BottomLevelAccelerationStructure> bottomLevelStructure,const VkTransformMatrixKHR & matrix,deUint32 instanceCustomIndex,deUint32 mask,deUint32 instanceShaderBindingTableRecordOffset,VkGeometryInstanceFlagsKHR flags)1435 void TopLevelAccelerationStructure::addInstance (de::SharedPtr<BottomLevelAccelerationStructure>	bottomLevelStructure,
1436 												 const VkTransformMatrixKHR&						matrix,
1437 												 deUint32											instanceCustomIndex,
1438 												 deUint32											mask,
1439 												 deUint32											instanceShaderBindingTableRecordOffset,
1440 												 VkGeometryInstanceFlagsKHR							flags)
1441 {
1442 	m_bottomLevelInstances.push_back(bottomLevelStructure);
1443 	m_instanceData.push_back(InstanceData(matrix, instanceCustomIndex, mask, instanceShaderBindingTableRecordOffset, flags));
1444 }
1445 
getStructureSize() const1446 VkDeviceSize TopLevelAccelerationStructure::getStructureSize () const
1447 {
1448 	return m_structureSize;
1449 }
1450 
createAndBuild(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,Allocator & allocator,VkDeviceAddress deviceAddress)1451 void TopLevelAccelerationStructure::createAndBuild (const DeviceInterface&	vk,
1452 													const VkDevice			device,
1453 													const VkCommandBuffer	cmdBuffer,
1454 													Allocator&				allocator,
1455 													VkDeviceAddress			deviceAddress)
1456 {
1457 	create(vk, device, allocator, 0u, deviceAddress);
1458 	build(vk, device, cmdBuffer);
1459 }
1460 
createAndCopyFrom(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,Allocator & allocator,TopLevelAccelerationStructure * accelerationStructure,VkDeviceSize compactCopySize,VkDeviceAddress deviceAddress)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)
1468 {
1469 	DE_ASSERT(accelerationStructure != NULL);
1470 	VkDeviceSize copiedSize = compactCopySize > 0u ? compactCopySize : accelerationStructure->getStructureSize();
1471 	DE_ASSERT(copiedSize != 0u);
1472 
1473 	create(vk, device, allocator, copiedSize, deviceAddress);
1474 	copyFrom(vk, device, cmdBuffer, accelerationStructure, compactCopySize > 0u);
1475 }
1476 
createAndDeserializeFrom(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,Allocator & allocator,SerialStorage * storage,VkDeviceAddress deviceAddress)1477 void TopLevelAccelerationStructure::createAndDeserializeFrom (const DeviceInterface& vk,
1478 															  const VkDevice							device,
1479 															  const VkCommandBuffer						cmdBuffer,
1480 															  Allocator&								allocator,
1481 															  SerialStorage*							storage,
1482 															  VkDeviceAddress							deviceAddress)
1483 {
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);
1488 }
1489 
createInstanceBuffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelInstances,std::vector<InstanceData> instanceData)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)
1495 {
1496 	DE_ASSERT(bottomLevelInstances.size() != 0);
1497 	DE_ASSERT(bottomLevelInstances.size() == instanceData.size());
1498 	DE_UNREF(instanceData);
1499 
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);
1502 	try
1503 	{
1504 		return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
1505 	}
1506 	catch (const tcu::NotSupportedError&)
1507 	{
1508 		// retry without Cached flag
1509 		return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress);
1510 	}
1511 }
1512 
updateInstanceBuffer(const DeviceInterface & vk,const VkDevice device,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelInstances,std::vector<InstanceData> instanceData,BufferWithMemory * instanceBuffer,VkAccelerationStructureBuildTypeKHR buildType,bool inactiveInstances)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)
1520 {
1521 	DE_ASSERT(bottomLevelInstances.size() != 0);
1522 	DE_ASSERT(bottomLevelInstances.size() == instanceData.size());
1523 
1524 	const Allocation&			instancesAlloc		= instanceBuffer->getAllocation();
1525 
1526 	deUint8*					bufferStart			= static_cast<deUint8*>(instancesAlloc.getHostPtr());
1527 	VkDeviceSize				bufferOffset		= 0;
1528 
1529 	for (size_t instanceNdx = 0; instanceNdx < bottomLevelInstances.size(); ++instanceNdx)
1530 	{
1531 		const BottomLevelAccelerationStructure&		bottomLevelAccelerationStructure	= *bottomLevelInstances[instanceNdx];
1532 		const VkAccelerationStructureKHR			accelerationStructureKHR			= *bottomLevelAccelerationStructure.getPtr();
1533 
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)
1537 		{
1538 			VkAccelerationStructureDeviceAddressInfoKHR asDeviceAddressInfo =
1539 			{
1540 				VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType				sType;
1541 				DE_NULL,															// const void*					pNext;
1542 				accelerationStructureKHR											// VkAccelerationStructureKHR	accelerationStructure;
1543 			};
1544 			accelerationStructureAddress = vk.getAccelerationStructureDeviceAddressKHR(device, &asDeviceAddressInfo);
1545 		}
1546 
1547 		deUint64 structureReference;
1548 		if (inactiveInstances)
1549 		{
1550 			// Instances will be marked inactive by making their references VK_NULL_HANDLE or having address zero.
1551 			structureReference = 0ull;
1552 		}
1553 		else
1554 		{
1555 			structureReference	= (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1556 								? deUint64(accelerationStructureAddress)
1557 								: deUint64(accelerationStructureKHR.getInternal());
1558 		}
1559 
1560 		VkAccelerationStructureInstanceKHR	accelerationStructureInstanceKHR = makeVkAccelerationStructureInstanceKHR
1561 		(
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;
1568 		);
1569 
1570 		deMemcpy(&bufferStart[bufferOffset], &accelerationStructureInstanceKHR, sizeof(VkAccelerationStructureInstanceKHR));
1571 
1572 		bufferOffset += sizeof(VkAccelerationStructureInstanceKHR);
1573 	}
1574 
1575 	flushMappedMemoryRange(vk, device, instancesAlloc.getMemory(), instancesAlloc.getOffset(), VK_WHOLE_SIZE);
1576 }
1577 
1578 class TopLevelAccelerationStructureKHR : public TopLevelAccelerationStructure
1579 {
1580 public:
1581 	static deUint32											getRequiredAllocationCount							(void);
1582 
1583 															TopLevelAccelerationStructureKHR					();
1584 															TopLevelAccelerationStructureKHR					(const TopLevelAccelerationStructureKHR&		other) = delete;
1585 	virtual													~TopLevelAccelerationStructureKHR					();
1586 
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;
1600 
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;
1622 
1623 	const VkAccelerationStructureKHR*						getPtr												(void) const override;
1624 
1625 protected:
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;
1644 
1645 	void													prepareInstances									(const DeviceInterface&							vk,
1646 																												 const VkDevice									device,
1647 																												 VkAccelerationStructureGeometryKHR&			accelerationStructureGeometryKHR,
1648 																												 std::vector<deUint32>&							maxPrimitiveCounts);
1649 };
1650 
getRequiredAllocationCount(void)1651 deUint32 TopLevelAccelerationStructureKHR::getRequiredAllocationCount (void)
1652 {
1653 	/*
1654 		de::MovePtr<BufferWithMemory>							m_instanceBuffer;
1655 		de::MovePtr<Allocation>									m_accelerationStructureAlloc;
1656 		de::MovePtr<BufferWithMemory>							m_deviceScratchBuffer;
1657 	*/
1658 	return 3u;
1659 }
1660 
TopLevelAccelerationStructureKHR()1661 TopLevelAccelerationStructureKHR::TopLevelAccelerationStructureKHR ()
1662 	: TopLevelAccelerationStructure	()
1663 	, m_buildType					(VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1664 	, m_createFlags					(0u)
1665 	, m_createGeneric				(false)
1666 	, m_buildFlags					(0u)
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)
1680 {
1681 }
1682 
~TopLevelAccelerationStructureKHR()1683 TopLevelAccelerationStructureKHR::~TopLevelAccelerationStructureKHR ()
1684 {
1685 }
1686 
setBuildType(const VkAccelerationStructureBuildTypeKHR buildType)1687 void TopLevelAccelerationStructureKHR::setBuildType (const VkAccelerationStructureBuildTypeKHR	buildType)
1688 {
1689 	m_buildType = buildType;
1690 }
1691 
setCreateFlags(const VkAccelerationStructureCreateFlagsKHR createFlags)1692 void TopLevelAccelerationStructureKHR::setCreateFlags (const VkAccelerationStructureCreateFlagsKHR	createFlags)
1693 {
1694 	m_createFlags = createFlags;
1695 }
1696 
setCreateGeneric(bool createGeneric)1697 void TopLevelAccelerationStructureKHR::setCreateGeneric (bool createGeneric)
1698 {
1699 	m_createGeneric = createGeneric;
1700 }
1701 
setInactiveInstances(bool inactiveInstances)1702 void TopLevelAccelerationStructureKHR::setInactiveInstances (bool inactiveInstances)
1703 {
1704 	m_inactiveInstances = inactiveInstances;
1705 }
1706 
setBuildFlags(const VkBuildAccelerationStructureFlagsKHR buildFlags)1707 void TopLevelAccelerationStructureKHR::setBuildFlags (const VkBuildAccelerationStructureFlagsKHR	buildFlags)
1708 {
1709 	m_buildFlags = buildFlags;
1710 }
1711 
setBuildWithoutPrimitives(bool buildWithoutPrimitives)1712 void TopLevelAccelerationStructureKHR::setBuildWithoutPrimitives (bool buildWithoutPrimitives)
1713 {
1714 	m_buildWithoutPrimitives = buildWithoutPrimitives;
1715 }
1716 
setDeferredOperation(const bool deferredOperation,const deUint32 workerThreadCount)1717 void TopLevelAccelerationStructureKHR::setDeferredOperation (const bool		deferredOperation,
1718 															 const deUint32	workerThreadCount)
1719 {
1720 	m_deferredOperation = deferredOperation;
1721 	m_workerThreadCount = workerThreadCount;
1722 }
1723 
setUseArrayOfPointers(const bool useArrayOfPointers)1724 void TopLevelAccelerationStructureKHR::setUseArrayOfPointers (const bool	useArrayOfPointers)
1725 {
1726 	m_useArrayOfPointers = useArrayOfPointers;
1727 }
1728 
setIndirectBuildParameters(const VkBuffer indirectBuffer,const VkDeviceSize indirectBufferOffset,const deUint32 indirectBufferStride)1729 void TopLevelAccelerationStructureKHR::setIndirectBuildParameters (const VkBuffer		indirectBuffer,
1730 																   const VkDeviceSize	indirectBufferOffset,
1731 																   const deUint32		indirectBufferStride)
1732 {
1733 	m_indirectBuffer		= indirectBuffer;
1734 	m_indirectBufferOffset	= indirectBufferOffset;
1735 	m_indirectBufferStride	= indirectBufferStride;
1736 }
1737 
getBuildFlags() const1738 VkBuildAccelerationStructureFlagsKHR TopLevelAccelerationStructureKHR::getBuildFlags () const
1739 {
1740 	return m_buildFlags;
1741 }
1742 
create(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,VkDeviceSize structureSize,VkDeviceAddress deviceAddress)1743 void TopLevelAccelerationStructureKHR::create (const DeviceInterface&				vk,
1744 											   const VkDevice						device,
1745 											   Allocator&							allocator,
1746 											   VkDeviceSize							structureSize,
1747 											   VkDeviceAddress						deviceAddress)
1748 {
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
1752 
1753 	if (structureSize == 0)
1754 	{
1755 		VkAccelerationStructureGeometryKHR		accelerationStructureGeometryKHR;
1756 		std::vector<deUint32>					maxPrimitiveCounts;
1757 		prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts);
1758 
1759 		VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR		=
1760 		{
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;
1772 		};
1773 
1774 		VkAccelerationStructureBuildSizesInfoKHR	sizeInfo =
1775 		{
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;
1781 		};
1782 
1783 		vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo);
1784 
1785 		m_structureSize		= sizeInfo.accelerationStructureSize;
1786 		m_updateScratchSize	= sizeInfo.updateScratchSize;
1787 		m_buildScratchSize	= sizeInfo.buildScratchSize;
1788 	}
1789 	else
1790 	{
1791 		m_structureSize		= structureSize;
1792 		m_updateScratchSize	= 0u;
1793 		m_buildScratchSize	= 0u;
1794 	}
1795 
1796 	{
1797 		const VkBufferCreateInfo		bufferCreateInfo = makeBufferCreateInfo(m_structureSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1798 		try
1799 		{
1800 			m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1801 		}
1802 		catch (const tcu::NotSupportedError&)
1803 		{
1804 			// retry without Cached flag
1805 			m_accelerationStructureBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1806 		}
1807 	}
1808 
1809 	{
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	=
1814 		{
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;
1823 		};
1824 
1825 		m_accelerationStructureKHR	= createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL);
1826 	}
1827 
1828 	if (m_buildScratchSize > 0u)
1829 	{
1830 		if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1831 		{
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));
1834 		}
1835 		else
1836 		{
1837 			m_hostScratchBuffer.resize(static_cast<size_t>(m_buildScratchSize));
1838 		}
1839 	}
1840 
1841 	if (m_useArrayOfPointers)
1842 	{
1843 		const VkBufferCreateInfo	bufferCreateInfo = makeBufferCreateInfo(m_bottomLevelInstances.size() * sizeof(VkDeviceOrHostAddressConstKHR), VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
1844 		m_instanceAddressBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress));
1845 	}
1846 
1847 	if(!m_bottomLevelInstances.empty())
1848 		m_instanceBuffer = de::MovePtr<BufferWithMemory>(createInstanceBuffer(vk, device, allocator, m_bottomLevelInstances, m_instanceData));
1849 }
1850 
build(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer)1851 void TopLevelAccelerationStructureKHR::build (const DeviceInterface&	vk,
1852 											  const VkDevice			device,
1853 											  const VkCommandBuffer		cmdBuffer)
1854 {
1855 	DE_ASSERT(!m_bottomLevelInstances.empty());
1856 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1857 	DE_ASSERT(m_buildScratchSize != 0);
1858 
1859 	updateInstanceBuffer(vk, device, m_bottomLevelInstances, m_instanceData, m_instanceBuffer.get(), m_buildType, m_inactiveInstances);
1860 
1861 	VkAccelerationStructureGeometryKHR		accelerationStructureGeometryKHR;
1862 	std::vector<deUint32>					maxPrimitiveCounts;
1863 	prepareInstances(vk, device, accelerationStructureGeometryKHR, maxPrimitiveCounts);
1864 
1865 	VkDeviceOrHostAddressKHR				scratchData										= (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1866 																							? makeDeviceOrHostAddressKHR(vk, device, m_deviceScratchBuffer->get(), 0)
1867 																							: makeDeviceOrHostAddressKHR(m_hostScratchBuffer.data());
1868 
1869 	VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR		=
1870 	{
1871 		VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,						//  VkStructureType										sType;
1872 		DE_NULL,																				//  const void*											pNext;
1873 		VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,											//  VkAccelerationStructureTypeKHR						type;
1874 		m_buildFlags,																			//  VkBuildAccelerationStructureFlagsKHR				flags;
1875 		VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR,											//  VkBuildAccelerationStructureModeKHR					mode;
1876 		DE_NULL,																				//  VkAccelerationStructureKHR							srcAccelerationStructure;
1877 		m_accelerationStructureKHR.get(),														//  VkAccelerationStructureKHR							dstAccelerationStructure;
1878 		1u,																						//  deUint32											geometryCount;
1879 		&accelerationStructureGeometryKHR,														//  const VkAccelerationStructureGeometryKHR*			pGeometries;
1880 		DE_NULL,																				//  const VkAccelerationStructureGeometryKHR* const*	ppGeometries;
1881 		scratchData																				//  VkDeviceOrHostAddressKHR							scratchData;
1882 	};
1883 
1884 	const deUint32 primitiveCount = (m_buildWithoutPrimitives ? 0u : static_cast<deUint32>(m_bottomLevelInstances.size()));
1885 
1886 	VkAccelerationStructureBuildRangeInfoKHR accelerationStructureBuildRangeInfoKHR =
1887 	{
1888 		primitiveCount,	//  deUint32	primitiveCount;
1889 		0,				//  deUint32	primitiveOffset;
1890 		0,				//  deUint32	firstVertex;
1891 		0				//  deUint32	transformOffset;
1892 	};
1893 	VkAccelerationStructureBuildRangeInfoKHR* accelerationStructureBuildRangeInfoKHRPtr	= &accelerationStructureBuildRangeInfoKHR;
1894 
1895 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1896 	{
1897 		if (m_indirectBuffer == DE_NULL)
1898 			vk.cmdBuildAccelerationStructuresKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1899 		else
1900 		{
1901 			VkDeviceAddress	indirectDeviceAddress = getBufferDeviceAddress(vk, device, m_indirectBuffer, m_indirectBufferOffset);
1902 			deUint32*		pMaxPrimitiveCounts = maxPrimitiveCounts.data();
1903 			vk.cmdBuildAccelerationStructuresIndirectKHR(cmdBuffer, 1u, &accelerationStructureBuildGeometryInfoKHR, &indirectDeviceAddress, &m_indirectBufferStride, &pMaxPrimitiveCounts);
1904 		}
1905 	}
1906 	else if (!m_deferredOperation)
1907 	{
1908 		VK_CHECK(vk.buildAccelerationStructuresKHR(device, DE_NULL, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr));
1909 	}
1910 	else
1911 	{
1912 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
1913 		const auto deferredOperation	= deferredOperationPtr.get();
1914 
1915 		VkResult result = vk.buildAccelerationStructuresKHR(device, deferredOperation, 1u, &accelerationStructureBuildGeometryInfoKHR, (const VkAccelerationStructureBuildRangeInfoKHR**)&accelerationStructureBuildRangeInfoKHRPtr);
1916 
1917 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1918 
1919 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1920 
1921 		accelerationStructureBuildGeometryInfoKHR.pNext = DE_NULL;
1922 	}
1923 
1924 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1925 	{
1926 		const VkAccessFlags		accessMasks	= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1927 		const VkMemoryBarrier	memBarrier	= makeMemoryBarrier(accessMasks, accessMasks);
1928 
1929 		cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1930 	}
1931 }
1932 
copyFrom(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,TopLevelAccelerationStructure * accelerationStructure,bool compactCopy)1933 void TopLevelAccelerationStructureKHR::copyFrom (const DeviceInterface&				vk,
1934 												 const VkDevice						device,
1935 												 const VkCommandBuffer				cmdBuffer,
1936 												 TopLevelAccelerationStructure*		accelerationStructure,
1937 												 bool								compactCopy)
1938 {
1939 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1940 	DE_ASSERT(accelerationStructure != DE_NULL);
1941 
1942 	VkCopyAccelerationStructureInfoKHR copyAccelerationStructureInfo =
1943 	{
1944 		VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR,															// VkStructureType						sType;
1945 		DE_NULL,																										// const void*							pNext;
1946 		*(accelerationStructure->getPtr()),																				// VkAccelerationStructureKHR			src;
1947 		*(getPtr()),																									// VkAccelerationStructureKHR			dst;
1948 		compactCopy ? VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR : VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR	// VkCopyAccelerationStructureModeKHR	mode;
1949 	};
1950 
1951 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1952 	{
1953 		vk.cmdCopyAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
1954 	}
1955 	else if (!m_deferredOperation)
1956 	{
1957 		VK_CHECK(vk.copyAccelerationStructureKHR(device, DE_NULL, &copyAccelerationStructureInfo));
1958 	}
1959 	else
1960 	{
1961 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
1962 		const auto deferredOperation	= deferredOperationPtr.get();
1963 
1964 		VkResult result = vk.copyAccelerationStructureKHR(device, deferredOperation, &copyAccelerationStructureInfo);
1965 
1966 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
1967 
1968 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
1969 	}
1970 
1971 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1972 	{
1973 		const VkAccessFlags		accessMasks	= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1974 		const VkMemoryBarrier	memBarrier	= makeMemoryBarrier(accessMasks, accessMasks);
1975 
1976 		cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
1977 	}
1978 
1979 }
1980 
serialize(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,SerialStorage * storage)1981 void TopLevelAccelerationStructureKHR::serialize (const DeviceInterface&	vk,
1982 												  const VkDevice			device,
1983 												  const VkCommandBuffer		cmdBuffer,
1984 												  SerialStorage*			storage)
1985 {
1986 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
1987 	DE_ASSERT(storage != DE_NULL);
1988 
1989 	const VkCopyAccelerationStructureToMemoryInfoKHR	copyAccelerationStructureInfo	=
1990 	{
1991 		VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR,	// VkStructureType						sType;
1992 		DE_NULL,															// const void*							pNext;
1993 		*(getPtr()),														// VkAccelerationStructureKHR			src;
1994 		storage->getAddress(vk,device),										// VkDeviceOrHostAddressKHR				dst;
1995 		VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR					// VkCopyAccelerationStructureModeKHR	mode;
1996 	};
1997 
1998 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1999 	{
2000 		vk.cmdCopyAccelerationStructureToMemoryKHR(cmdBuffer, &copyAccelerationStructureInfo);
2001 	}
2002 	else if (!m_deferredOperation)
2003 	{
2004 		VK_CHECK(vk.copyAccelerationStructureToMemoryKHR(device, DE_NULL, &copyAccelerationStructureInfo));
2005 	}
2006 	else
2007 	{
2008 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
2009 		const auto deferredOperation	= deferredOperationPtr.get();
2010 
2011 		const VkResult result = vk.copyAccelerationStructureToMemoryKHR(device, deferredOperation, &copyAccelerationStructureInfo);
2012 
2013 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
2014 
2015 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
2016 	}
2017 }
2018 
deserialize(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,SerialStorage * storage)2019 void TopLevelAccelerationStructureKHR::deserialize (const DeviceInterface&	vk,
2020 													const VkDevice			device,
2021 													const VkCommandBuffer	cmdBuffer,
2022 													SerialStorage*			storage)
2023 {
2024 	DE_ASSERT(m_accelerationStructureKHR.get() != DE_NULL);
2025 	DE_ASSERT(storage != DE_NULL);
2026 
2027 	const VkCopyMemoryToAccelerationStructureInfoKHR	copyAccelerationStructureInfo	=
2028 	{
2029 		VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR,	// VkStructureType							sType;
2030 		DE_NULL,															// const void*								pNext;
2031 		storage->getAddressConst(vk,device),								// VkDeviceOrHostAddressConstKHR			src;
2032 		*(getPtr()),														// VkAccelerationStructureKHR				dst;
2033 		VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR					// VkCopyAccelerationStructureModeKHR		mode;
2034 	};
2035 
2036 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2037 	{
2038 		vk.cmdCopyMemoryToAccelerationStructureKHR(cmdBuffer, &copyAccelerationStructureInfo);
2039 	}
2040 	else if (!m_deferredOperation)
2041 	{
2042 		VK_CHECK(vk.copyMemoryToAccelerationStructureKHR(device, DE_NULL, &copyAccelerationStructureInfo));
2043 	}
2044 	else
2045 	{
2046 		const auto deferredOperationPtr	= createDeferredOperationKHR(vk, device);
2047 		const auto deferredOperation	= deferredOperationPtr.get();
2048 
2049 		const VkResult result = vk.copyMemoryToAccelerationStructureKHR(device, deferredOperation, &copyAccelerationStructureInfo);
2050 
2051 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
2052 
2053 		finishDeferredOperation(vk, device, deferredOperation, m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
2054 	}
2055 
2056 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2057 	{
2058 		const VkAccessFlags		accessMasks = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
2059 		const VkMemoryBarrier	memBarrier = makeMemoryBarrier(accessMasks, accessMasks);
2060 
2061 		cmdPipelineMemoryBarrier(vk, cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &memBarrier);
2062 	}
2063 }
2064 
getPtr(void) const2065 const VkAccelerationStructureKHR* TopLevelAccelerationStructureKHR::getPtr (void) const
2066 {
2067 	return &m_accelerationStructureKHR.get();
2068 }
2069 
prepareInstances(const DeviceInterface & vk,const VkDevice device,VkAccelerationStructureGeometryKHR & accelerationStructureGeometryKHR,std::vector<deUint32> & maxPrimitiveCounts)2070 void TopLevelAccelerationStructureKHR::prepareInstances (const DeviceInterface&							vk,
2071 														 const VkDevice									device,
2072 														 VkAccelerationStructureGeometryKHR&			accelerationStructureGeometryKHR,
2073 														 std::vector<deUint32>&							maxPrimitiveCounts)
2074 {
2075 	maxPrimitiveCounts.resize(1);
2076 	maxPrimitiveCounts[0] = static_cast<deUint32>(m_bottomLevelInstances.size());
2077 
2078 	VkDeviceOrHostAddressConstKHR							instancesData;
2079 	if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2080 	{
2081 		if(m_instanceBuffer.get() != DE_NULL)
2082 		{
2083 			if (m_useArrayOfPointers)
2084 			{
2085 				deUint8*						bufferStart			= static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr());
2086 				VkDeviceSize					bufferOffset		= 0;
2087 				VkDeviceOrHostAddressConstKHR	firstInstance		= makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0);
2088 				for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
2089 				{
2090 					VkDeviceOrHostAddressConstKHR	currentInstance;
2091 					currentInstance.deviceAddress	= firstInstance.deviceAddress + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR);
2092 
2093 					deMemcpy(&bufferStart[bufferOffset], &currentInstance, sizeof(VkDeviceOrHostAddressConstKHR));
2094 					bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR);
2095 				}
2096 				flushMappedMemoryRange(vk, device, m_instanceAddressBuffer->getAllocation().getMemory(), m_instanceAddressBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2097 
2098 				instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceAddressBuffer->get(), 0);
2099 			}
2100 			else
2101 				instancesData = makeDeviceOrHostAddressConstKHR(vk, device, m_instanceBuffer->get(), 0);
2102 		}
2103 		else
2104 			instancesData = makeDeviceOrHostAddressConstKHR(DE_NULL);
2105 	}
2106 	else
2107 	{
2108 		if (m_instanceBuffer.get() != DE_NULL)
2109 		{
2110 			if (m_useArrayOfPointers)
2111 			{
2112 				deUint8*						bufferStart			= static_cast<deUint8*>(m_instanceAddressBuffer->getAllocation().getHostPtr());
2113 				VkDeviceSize					bufferOffset		= 0;
2114 				for (size_t instanceNdx = 0; instanceNdx < m_bottomLevelInstances.size(); ++instanceNdx)
2115 				{
2116 					VkDeviceOrHostAddressConstKHR	currentInstance;
2117 					currentInstance.hostAddress	= (deUint8*)m_instanceBuffer->getAllocation().getHostPtr() + instanceNdx * sizeof(VkAccelerationStructureInstanceKHR);
2118 
2119 					deMemcpy(&bufferStart[bufferOffset], &currentInstance, sizeof(VkDeviceOrHostAddressConstKHR));
2120 					bufferOffset += sizeof(VkDeviceOrHostAddressConstKHR);
2121 				}
2122 				instancesData = makeDeviceOrHostAddressConstKHR(m_instanceAddressBuffer->getAllocation().getHostPtr());
2123 			}
2124 			else
2125 				instancesData = makeDeviceOrHostAddressConstKHR(m_instanceBuffer->getAllocation().getHostPtr());
2126 		}
2127 		else
2128 			instancesData = makeDeviceOrHostAddressConstKHR(DE_NULL);
2129 	}
2130 
2131 	VkAccelerationStructureGeometryInstancesDataKHR accelerationStructureGeometryInstancesDataKHR	=
2132 	{
2133 		VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR,	//  VkStructureType					sType;
2134 		DE_NULL,																//  const void*						pNext;
2135 		(VkBool32)( m_useArrayOfPointers ? DE_TRUE : DE_FALSE ),				//  VkBool32						arrayOfPointers;
2136 		instancesData															//  VkDeviceOrHostAddressConstKHR	data;
2137 	};
2138 
2139 	accelerationStructureGeometryKHR					=
2140 	{
2141 		VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,										//  VkStructureType							sType;
2142 		DE_NULL,																					//  const void*								pNext;
2143 		VK_GEOMETRY_TYPE_INSTANCES_KHR,																//  VkGeometryTypeKHR						geometryType;
2144 		makeVkAccelerationStructureInstancesDataKHR(accelerationStructureGeometryInstancesDataKHR),	//  VkAccelerationStructureGeometryDataKHR	geometry;
2145 		(VkGeometryFlagsKHR)0u																		//  VkGeometryFlagsKHR						flags;
2146 	};
2147 }
2148 
getRequiredAllocationCount(void)2149 deUint32 TopLevelAccelerationStructure::getRequiredAllocationCount (void)
2150 {
2151 	return TopLevelAccelerationStructureKHR::getRequiredAllocationCount();
2152 }
2153 
makeTopLevelAccelerationStructure()2154 de::MovePtr<TopLevelAccelerationStructure> makeTopLevelAccelerationStructure ()
2155 {
2156 	return de::MovePtr<TopLevelAccelerationStructure>(new TopLevelAccelerationStructureKHR);
2157 }
2158 
queryAccelerationStructureSizeKHR(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,const std::vector<VkAccelerationStructureKHR> & accelerationStructureHandles,VkAccelerationStructureBuildTypeKHR buildType,const VkQueryPool queryPool,VkQueryType queryType,deUint32 firstQuery,std::vector<VkDeviceSize> & results)2159 bool queryAccelerationStructureSizeKHR (const DeviceInterface&							vk,
2160 										const VkDevice									device,
2161 										const VkCommandBuffer							cmdBuffer,
2162 										const std::vector<VkAccelerationStructureKHR>&	accelerationStructureHandles,
2163 										VkAccelerationStructureBuildTypeKHR				buildType,
2164 										const VkQueryPool								queryPool,
2165 										VkQueryType										queryType,
2166 										deUint32										firstQuery,
2167 										std::vector<VkDeviceSize>&						results)
2168 {
2169 	DE_ASSERT(queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR || queryType == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR);
2170 
2171 	if (buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2172 	{
2173 		// queryPool must be large enough to contain at least (firstQuery + accelerationStructureHandles.size()) queries
2174 		vk.cmdResetQueryPool(cmdBuffer, queryPool, firstQuery, deUint32(accelerationStructureHandles.size()));
2175 		vk.cmdWriteAccelerationStructuresPropertiesKHR(cmdBuffer, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType, queryPool, firstQuery);
2176 		// 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.
2177 		results.resize(accelerationStructureHandles.size(), 0u);
2178 		return false;
2179 	}
2180 	// buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR
2181 	results.resize(accelerationStructureHandles.size(), 0u);
2182 	vk.writeAccelerationStructuresPropertiesKHR(device, deUint32(accelerationStructureHandles.size()), accelerationStructureHandles.data(), queryType,
2183 												sizeof(VkDeviceSize) * accelerationStructureHandles.size(), results.data(), sizeof(VkDeviceSize));
2184 	// results will contain proper values
2185 	return true;
2186 }
2187 
queryAccelerationStructureSize(const DeviceInterface & vk,const VkDevice device,const VkCommandBuffer cmdBuffer,const std::vector<VkAccelerationStructureKHR> & accelerationStructureHandles,VkAccelerationStructureBuildTypeKHR buildType,const VkQueryPool queryPool,VkQueryType queryType,deUint32 firstQuery,std::vector<VkDeviceSize> & results)2188 bool queryAccelerationStructureSize (const DeviceInterface&							vk,
2189 									 const VkDevice									device,
2190 									 const VkCommandBuffer							cmdBuffer,
2191 									 const std::vector<VkAccelerationStructureKHR>&	accelerationStructureHandles,
2192 									 VkAccelerationStructureBuildTypeKHR			buildType,
2193 									 const VkQueryPool								queryPool,
2194 									 VkQueryType									queryType,
2195 									 deUint32										firstQuery,
2196 									 std::vector<VkDeviceSize>&						results)
2197 {
2198 	return queryAccelerationStructureSizeKHR(vk, device, cmdBuffer, accelerationStructureHandles, buildType, queryPool, queryType, firstQuery, results);
2199 }
2200 
RayTracingPipeline()2201 RayTracingPipeline::RayTracingPipeline ()
2202 	: m_shadersModules			()
2203 	, m_pipelineLibraries		()
2204 	, m_shaderCreateInfos		()
2205 	, m_shadersGroupCreateInfos	()
2206 	, m_pipelineCreateFlags		(0U)
2207 	, m_maxRecursionDepth		(1U)
2208 	, m_maxPayloadSize			(0U)
2209 	, m_maxAttributeSize		(0U)
2210 	, m_deferredOperation		(false)
2211 	, m_workerThreadCount		(0)
2212 {
2213 }
2214 
~RayTracingPipeline()2215 RayTracingPipeline::~RayTracingPipeline ()
2216 {
2217 }
2218 
2219 #define CHECKED_ASSIGN_SHADER(SHADER, STAGE)						\
2220 	if (SHADER == VK_SHADER_UNUSED_KHR)								\
2221 		SHADER = STAGE;												\
2222 	else															\
2223 		TCU_THROW(InternalError, "Attempt to reassign shader")
2224 
addShader(VkShaderStageFlagBits shaderStage,Move<VkShaderModule> shaderModule,deUint32 group,const VkSpecializationInfo * specializationInfo)2225 void RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, Move<VkShaderModule> shaderModule, deUint32 group, const VkSpecializationInfo* specializationInfo)
2226 {
2227 	addShader(shaderStage, makeVkSharedPtr(shaderModule), group, specializationInfo);
2228 }
2229 
addShader(VkShaderStageFlagBits shaderStage,de::SharedPtr<Move<VkShaderModule>> shaderModule,deUint32 group,const VkSpecializationInfo * specializationInfoPtr)2230 void RayTracingPipeline::addShader (VkShaderStageFlagBits shaderStage, de::SharedPtr<Move<VkShaderModule>> shaderModule, deUint32 group, const VkSpecializationInfo* specializationInfoPtr)
2231 {
2232 	if (group >= m_shadersGroupCreateInfos.size())
2233 	{
2234 		for (size_t groupNdx = m_shadersGroupCreateInfos.size(); groupNdx <= group; ++groupNdx)
2235 		{
2236 			VkRayTracingShaderGroupCreateInfoKHR	shaderGroupCreateInfo	=
2237 			{
2238 				VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,	//  VkStructureType					sType;
2239 				DE_NULL,													//  const void*						pNext;
2240 				VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR,				//  VkRayTracingShaderGroupTypeKHR	type;
2241 				VK_SHADER_UNUSED_KHR,										//  deUint32						generalShader;
2242 				VK_SHADER_UNUSED_KHR,										//  deUint32						closestHitShader;
2243 				VK_SHADER_UNUSED_KHR,										//  deUint32						anyHitShader;
2244 				VK_SHADER_UNUSED_KHR,										//  deUint32						intersectionShader;
2245 				DE_NULL,													//  const void*						pShaderGroupCaptureReplayHandle;
2246 			};
2247 
2248 			m_shadersGroupCreateInfos.push_back(shaderGroupCreateInfo);
2249 		}
2250 	}
2251 
2252 	const deUint32							shaderStageNdx			= (deUint32)m_shaderCreateInfos.size();
2253 	VkRayTracingShaderGroupCreateInfoKHR&	shaderGroupCreateInfo	= m_shadersGroupCreateInfos[group];
2254 
2255 	switch (shaderStage)
2256 	{
2257 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:		CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader,		shaderStageNdx);	break;
2258 		case VK_SHADER_STAGE_MISS_BIT_KHR:			CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader,		shaderStageNdx);	break;
2259 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:		CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.generalShader,		shaderStageNdx);	break;
2260 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:		CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.anyHitShader,		shaderStageNdx);	break;
2261 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:	CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.closestHitShader,	shaderStageNdx);	break;
2262 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:	CHECKED_ASSIGN_SHADER(shaderGroupCreateInfo.intersectionShader,	shaderStageNdx);	break;
2263 		default:									TCU_THROW(InternalError, "Unacceptable stage");
2264 	}
2265 
2266 	switch (shaderStage)
2267 	{
2268 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2269 		case VK_SHADER_STAGE_MISS_BIT_KHR:
2270 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2271 		{
2272 			DE_ASSERT(shaderGroupCreateInfo.type == VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR);
2273 			shaderGroupCreateInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
2274 
2275 			break;
2276 		}
2277 
2278 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2279 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2280 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2281 		{
2282 			DE_ASSERT(shaderGroupCreateInfo.type != VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR);
2283 			shaderGroupCreateInfo.type	= (shaderGroupCreateInfo.intersectionShader == VK_SHADER_UNUSED_KHR)
2284 										? VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR
2285 										: VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR;
2286 
2287 			break;
2288 		}
2289 
2290 		default: TCU_THROW(InternalError, "Unacceptable stage");
2291 	}
2292 
2293 	{
2294 		const VkPipelineShaderStageCreateInfo	shaderCreateInfo	=
2295 		{
2296 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//  VkStructureType						sType;
2297 			DE_NULL,												//  const void*							pNext;
2298 			(VkPipelineShaderStageCreateFlags)0,					//  VkPipelineShaderStageCreateFlags	flags;
2299 			shaderStage,											//  VkShaderStageFlagBits				stage;
2300 			**shaderModule,											//  VkShaderModule						module;
2301 			"main",													//  const char*							pName;
2302 			specializationInfoPtr,									//  const VkSpecializationInfo*			pSpecializationInfo;
2303 		};
2304 
2305 		m_shaderCreateInfos.push_back(shaderCreateInfo);
2306 	}
2307 
2308 	m_shadersModules.push_back(shaderModule);
2309 }
2310 
addLibrary(de::SharedPtr<de::MovePtr<RayTracingPipeline>> pipelineLibrary)2311 void RayTracingPipeline::addLibrary (de::SharedPtr<de::MovePtr<RayTracingPipeline>> pipelineLibrary)
2312 {
2313 	m_pipelineLibraries.push_back(pipelineLibrary);
2314 }
2315 
createPipelineKHR(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const std::vector<de::SharedPtr<Move<VkPipeline>>> & pipelineLibraries)2316 Move<VkPipeline> RayTracingPipeline::createPipelineKHR (const DeviceInterface&								vk,
2317 														const VkDevice										device,
2318 														const VkPipelineLayout								pipelineLayout,
2319 														const std::vector<de::SharedPtr<Move<VkPipeline>>>&	pipelineLibraries)
2320 {
2321 	for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx)
2322 		DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR);
2323 
2324 	DE_ASSERT(m_shaderCreateInfos.size() > 0);
2325 	DE_ASSERT(m_shadersGroupCreateInfos.size() > 0);
2326 
2327 	std::vector<VkPipeline>								vkPipelineLibraries;
2328 	for (auto it = begin(pipelineLibraries), eit = end(pipelineLibraries); it != eit; ++it)
2329 		vkPipelineLibraries.push_back( it->get()->get() );
2330 	VkPipelineLibraryCreateInfoKHR				librariesCreateInfo	=
2331 	{
2332 		VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR,		//  VkStructureType	sType;
2333 		DE_NULL,												//  const void*		pNext;
2334 		deUint32(vkPipelineLibraries.size()),					//  deUint32		libraryCount;
2335 		dataOrNullPtr(vkPipelineLibraries)						//  VkPipeline*		pLibraries;
2336 	};
2337 	const VkRayTracingPipelineInterfaceCreateInfoKHR	pipelineInterfaceCreateInfo		=
2338 	{
2339 		VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR,	//  VkStructureType	sType;
2340 		DE_NULL,															//  const void*		pNext;
2341 		m_maxPayloadSize,													//  deUint32		maxPayloadSize;
2342 		m_maxAttributeSize													//  deUint32		maxAttributeSize;
2343 	};
2344 	const bool											addPipelineInterfaceCreateInfo	= m_maxPayloadSize != 0 || m_maxAttributeSize != 0;
2345 	const VkRayTracingPipelineInterfaceCreateInfoKHR*	pipelineInterfaceCreateInfoPtr	= addPipelineInterfaceCreateInfo ? &pipelineInterfaceCreateInfo : DE_NULL;
2346 	const VkPipelineLibraryCreateInfoKHR*				librariesCreateInfoPtr			= (vkPipelineLibraries.empty() ? nullptr : &librariesCreateInfo);
2347 
2348 	Move<VkDeferredOperationKHR>						deferredOperation;
2349 	if (m_deferredOperation)
2350 		deferredOperation = createDeferredOperationKHR(vk, device);
2351 
2352 	VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo	=
2353 	{
2354 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
2355 		DE_NULL,												// const void*							pNext;
2356 		0,														// VkPipelineDynamicStateCreateFlags	flags;
2357 		static_cast<deUint32>(m_dynamicStates.size() ),			// deUint32								dynamicStateCount;
2358 		m_dynamicStates.data(),									// const VkDynamicState*				pDynamicStates;
2359 	};
2360 
2361 	const VkRayTracingPipelineCreateInfoKHR				pipelineCreateInfo				=
2362 	{
2363 		VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,	//  VkStructureType								sType;
2364 		DE_NULL,												//  const void*									pNext;
2365 		m_pipelineCreateFlags,									//  VkPipelineCreateFlags						flags;
2366 		(deUint32)m_shaderCreateInfos.size(),					//  deUint32									stageCount;
2367 		m_shaderCreateInfos.data(),								//  const VkPipelineShaderStageCreateInfo*		pStages;
2368 		(deUint32)m_shadersGroupCreateInfos.size(),				//  deUint32									groupCount;
2369 		m_shadersGroupCreateInfos.data(),						//  const VkRayTracingShaderGroupCreateInfoKHR*	pGroups;
2370 		m_maxRecursionDepth,									//  deUint32									maxRecursionDepth;
2371 		librariesCreateInfoPtr,									//  VkPipelineLibraryCreateInfoKHR*				pLibraryInfo;
2372 		pipelineInterfaceCreateInfoPtr,							//  VkRayTracingPipelineInterfaceCreateInfoKHR*	pLibraryInterface;
2373 		&dynamicStateCreateInfo,								//  const VkPipelineDynamicStateCreateInfo*		pDynamicState;
2374 		pipelineLayout,											//  VkPipelineLayout							layout;
2375 		(VkPipeline)DE_NULL,									//  VkPipeline									basePipelineHandle;
2376 		0,														//  deInt32										basePipelineIndex;
2377 	};
2378 	VkPipeline											object							= DE_NULL;
2379 	VkResult											result							= vk.createRayTracingPipelinesKHR(device, deferredOperation.get(), DE_NULL, 1u, &pipelineCreateInfo, DE_NULL, &object);
2380 	Move<VkPipeline>									pipeline						(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, DE_NULL));
2381 
2382 	if (m_deferredOperation)
2383 	{
2384 		DE_ASSERT(result == VK_OPERATION_DEFERRED_KHR || result == VK_OPERATION_NOT_DEFERRED_KHR || result == VK_SUCCESS);
2385 
2386 		finishDeferredOperation(vk, device, deferredOperation.get(), m_workerThreadCount, result == VK_OPERATION_NOT_DEFERRED_KHR);
2387 	}
2388 
2389 	return pipeline;
2390 }
2391 
2392 
createPipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const std::vector<de::SharedPtr<Move<VkPipeline>>> & pipelineLibraries)2393 Move<VkPipeline> RayTracingPipeline::createPipeline (const DeviceInterface&									vk,
2394 													 const VkDevice											device,
2395 													 const VkPipelineLayout									pipelineLayout,
2396 													 const std::vector<de::SharedPtr<Move<VkPipeline>>>&	pipelineLibraries)
2397 {
2398 	return createPipelineKHR(vk, device, pipelineLayout, pipelineLibraries);
2399 }
2400 
createPipelineWithLibraries(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout)2401 std::vector<de::SharedPtr<Move<VkPipeline>>> RayTracingPipeline::createPipelineWithLibraries (const DeviceInterface&			vk,
2402 																								const VkDevice					device,
2403 																								const VkPipelineLayout			pipelineLayout)
2404 {
2405 	for (size_t groupNdx = 0; groupNdx < m_shadersGroupCreateInfos.size(); ++groupNdx)
2406 		DE_ASSERT(m_shadersGroupCreateInfos[groupNdx].sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR);
2407 
2408 	DE_ASSERT(m_shaderCreateInfos.size() > 0);
2409 	DE_ASSERT(m_shadersGroupCreateInfos.size() > 0);
2410 
2411 	std::vector<de::SharedPtr<Move<VkPipeline>>> result, allLibraries, firstLibraries;
2412 	for(auto it=begin(m_pipelineLibraries), eit=end(m_pipelineLibraries); it!=eit; ++it)
2413 	{
2414 		auto childLibraries = (*it)->get()->createPipelineWithLibraries(vk, device, pipelineLayout);
2415 		DE_ASSERT(childLibraries.size() > 0);
2416 		firstLibraries.push_back(childLibraries[0]);
2417 		std::copy(begin(childLibraries), end(childLibraries), std::back_inserter(allLibraries));
2418 	}
2419 	result.push_back(makeVkSharedPtr(createPipeline(vk, device, pipelineLayout, firstLibraries)));
2420 	std::copy(begin(allLibraries), end(allLibraries), std::back_inserter(result));
2421 	return result;
2422 }
2423 
createShaderBindingTable(const DeviceInterface & vk,const VkDevice device,const VkPipeline pipeline,Allocator & allocator,const deUint32 & shaderGroupHandleSize,const deUint32 shaderGroupBaseAlignment,const deUint32 & firstGroup,const deUint32 & groupCount,const VkBufferCreateFlags & additionalBufferCreateFlags,const VkBufferUsageFlags & additionalBufferUsageFlags,const MemoryRequirement & additionalMemoryRequirement,const VkDeviceAddress & opaqueCaptureAddress,const deUint32 shaderBindingTableOffset,const deUint32 shaderRecordSize,const void ** shaderGroupDataPtrPerGroup)2424 de::MovePtr<BufferWithMemory> RayTracingPipeline::createShaderBindingTable (const DeviceInterface&		vk,
2425 																			const VkDevice				device,
2426 																			const VkPipeline			pipeline,
2427 																			Allocator&					allocator,
2428 																			const deUint32&				shaderGroupHandleSize,
2429 																			const deUint32				shaderGroupBaseAlignment,
2430 																			const deUint32&				firstGroup,
2431 																			const deUint32&				groupCount,
2432 																			const VkBufferCreateFlags&	additionalBufferCreateFlags,
2433 																			const VkBufferUsageFlags&	additionalBufferUsageFlags,
2434 																			const MemoryRequirement&	additionalMemoryRequirement,
2435 																			const VkDeviceAddress&		opaqueCaptureAddress,
2436 																			const deUint32				shaderBindingTableOffset,
2437 																			const deUint32				shaderRecordSize,
2438 																			const void**				shaderGroupDataPtrPerGroup)
2439 {
2440 	DE_ASSERT(shaderGroupBaseAlignment != 0u);
2441 	DE_ASSERT((shaderBindingTableOffset % shaderGroupBaseAlignment) == 0);
2442 	DE_UNREF(shaderGroupBaseAlignment);
2443 
2444 	const deUint32							sbtSize							= shaderBindingTableOffset + groupCount * deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize);
2445 	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;
2446 	VkBufferCreateInfo						sbtCreateInfo					= makeBufferCreateInfo(sbtSize, sbtFlags);
2447 	sbtCreateInfo.flags														|= additionalBufferCreateFlags;
2448 	VkBufferOpaqueCaptureAddressCreateInfo	sbtCaptureAddressInfo			=
2449 	{
2450 		VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,	// VkStructureType	sType;
2451 		DE_NULL,														// const void*		pNext;
2452 		deUint64(opaqueCaptureAddress)									// deUint64			opaqueCaptureAddress;
2453 	};
2454 
2455 	if (opaqueCaptureAddress != 0u)
2456 	{
2457 		sbtCreateInfo.pNext = &sbtCaptureAddressInfo;
2458 		sbtCreateInfo.flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
2459 	}
2460 	const MemoryRequirement			sbtMemRequirements						= MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress | additionalMemoryRequirement;
2461 	de::MovePtr<BufferWithMemory>	sbtBuffer								= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, sbtCreateInfo, sbtMemRequirements));
2462 	vk::Allocation&					sbtAlloc								= sbtBuffer->getAllocation();
2463 
2464 	// collect shader group handles
2465 	std::vector<deUint8>			shaderHandles							(groupCount * shaderGroupHandleSize);
2466 	VK_CHECK(getRayTracingShaderGroupHandles(vk, device, pipeline, firstGroup, groupCount, groupCount * shaderGroupHandleSize, shaderHandles.data()));
2467 
2468 	// reserve place for ShaderRecordKHR after each shader handle ( ShaderRecordKHR size might be 0 ). Also take alignment into consideration
2469 	deUint8* shaderBegin = (deUint8*)sbtAlloc.getHostPtr() + shaderBindingTableOffset;
2470 	for (deUint32 idx = 0; idx < groupCount; ++idx)
2471 	{
2472 		deUint8* shaderSrcPos	= shaderHandles.data() + idx * shaderGroupHandleSize;
2473 		deUint8* shaderDstPos	= shaderBegin + idx * deAlign32(shaderGroupHandleSize + shaderRecordSize, shaderGroupHandleSize);
2474 		deMemcpy(shaderDstPos, shaderSrcPos, shaderGroupHandleSize);
2475 
2476 		if (shaderGroupDataPtrPerGroup		!= nullptr &&
2477 			shaderGroupDataPtrPerGroup[idx] != nullptr)
2478 		{
2479 			DE_ASSERT(sbtSize >= static_cast<deUint32>(shaderDstPos - shaderBegin) + shaderGroupHandleSize);
2480 
2481 			deMemcpy(	shaderDstPos + shaderGroupHandleSize,
2482 						shaderGroupDataPtrPerGroup[idx],
2483 						shaderRecordSize);
2484 		}
2485 	}
2486 
2487 	flushMappedMemoryRange(vk, device, sbtAlloc.getMemory(), sbtAlloc.getOffset(), VK_WHOLE_SIZE);
2488 
2489 	return sbtBuffer;
2490 }
2491 
setCreateFlags(const VkPipelineCreateFlags & pipelineCreateFlags)2492 void RayTracingPipeline::setCreateFlags (const VkPipelineCreateFlags& pipelineCreateFlags)
2493 {
2494 	m_pipelineCreateFlags = pipelineCreateFlags;
2495 }
2496 
setMaxRecursionDepth(const deUint32 & maxRecursionDepth)2497 void RayTracingPipeline::setMaxRecursionDepth (const deUint32& maxRecursionDepth)
2498 {
2499 	m_maxRecursionDepth = maxRecursionDepth;
2500 }
2501 
setMaxPayloadSize(const deUint32 & maxPayloadSize)2502 void RayTracingPipeline::setMaxPayloadSize (const deUint32& maxPayloadSize)
2503 {
2504 	m_maxPayloadSize = maxPayloadSize;
2505 }
2506 
setMaxAttributeSize(const deUint32 & maxAttributeSize)2507 void RayTracingPipeline::setMaxAttributeSize (const deUint32& maxAttributeSize)
2508 {
2509 	m_maxAttributeSize = maxAttributeSize;
2510 }
2511 
setDeferredOperation(const bool deferredOperation,const deUint32 workerThreadCount)2512 void RayTracingPipeline::setDeferredOperation (const bool		deferredOperation,
2513 											   const deUint32	workerThreadCount)
2514 {
2515 	m_deferredOperation = deferredOperation;
2516 	m_workerThreadCount = workerThreadCount;
2517 }
2518 
addDynamicState(const VkDynamicState & dynamicState)2519 void RayTracingPipeline::addDynamicState(const VkDynamicState& dynamicState)
2520 {
2521 	m_dynamicStates.push_back(dynamicState);
2522 }
2523 
2524 class RayTracingPropertiesKHR : public RayTracingProperties
2525 {
2526 public:
2527 							RayTracingPropertiesKHR						() = delete;
2528 							RayTracingPropertiesKHR						(const InstanceInterface&	vki,
2529 																		 const VkPhysicalDevice		physicalDevice);
2530 	virtual					~RayTracingPropertiesKHR					();
2531 
getShaderGroupHandleSize(void)2532 	virtual deUint32		getShaderGroupHandleSize					(void)	{ return m_rayTracingPipelineProperties.shaderGroupHandleSize;						};
getMaxRecursionDepth(void)2533 	virtual deUint32		getMaxRecursionDepth						(void)	{ return m_rayTracingPipelineProperties.maxRayRecursionDepth;						};
getMaxShaderGroupStride(void)2534 	virtual deUint32		getMaxShaderGroupStride						(void)	{ return m_rayTracingPipelineProperties.maxShaderGroupStride;						};
getShaderGroupBaseAlignment(void)2535 	virtual deUint32		getShaderGroupBaseAlignment					(void)	{ return m_rayTracingPipelineProperties.shaderGroupBaseAlignment;					};
getMaxGeometryCount(void)2536 	virtual deUint64		getMaxGeometryCount							(void)	{ return m_accelerationStructureProperties.maxGeometryCount;						};
getMaxInstanceCount(void)2537 	virtual deUint64		getMaxInstanceCount							(void)	{ return m_accelerationStructureProperties.maxInstanceCount;						};
getMaxPrimitiveCount(void)2538 	virtual deUint64		getMaxPrimitiveCount						(void)	{ return m_accelerationStructureProperties.maxPrimitiveCount;						};
getMaxDescriptorSetAccelerationStructures(void)2539 	virtual deUint32		getMaxDescriptorSetAccelerationStructures	(void)	{ return m_accelerationStructureProperties.maxDescriptorSetAccelerationStructures;	};
getMaxRayDispatchInvocationCount(void)2540 	deUint32				getMaxRayDispatchInvocationCount			(void)	{ return m_rayTracingPipelineProperties.maxRayDispatchInvocationCount;				};
getMaxRayHitAttributeSize(void)2541 	deUint32				getMaxRayHitAttributeSize					(void)	{ return m_rayTracingPipelineProperties.maxRayHitAttributeSize;						};
2542 
2543 protected:
2544 	VkPhysicalDeviceAccelerationStructurePropertiesKHR	m_accelerationStructureProperties;
2545 	VkPhysicalDeviceRayTracingPipelinePropertiesKHR		m_rayTracingPipelineProperties;
2546 };
2547 
~RayTracingPropertiesKHR()2548 RayTracingPropertiesKHR::~RayTracingPropertiesKHR ()
2549 {
2550 }
2551 
RayTracingPropertiesKHR(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)2552 RayTracingPropertiesKHR::RayTracingPropertiesKHR (const InstanceInterface&	vki,
2553 												  const VkPhysicalDevice	physicalDevice)
2554 	: RayTracingProperties	(vki, physicalDevice)
2555 {
2556 	m_accelerationStructureProperties	= getPhysicalDeviceExtensionProperties(vki, physicalDevice);
2557 	m_rayTracingPipelineProperties		= getPhysicalDeviceExtensionProperties(vki, physicalDevice);
2558 }
2559 
makeRayTracingProperties(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)2560 de::MovePtr<RayTracingProperties> makeRayTracingProperties (const InstanceInterface&	vki,
2561 															const VkPhysicalDevice		physicalDevice)
2562 {
2563 	return de::MovePtr<RayTracingProperties>(new RayTracingPropertiesKHR(vki, physicalDevice));
2564 }
2565 
cmdTraceRaysKHR(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const VkStridedDeviceAddressRegionKHR * raygenShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * missShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * hitShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * callableShaderBindingTableRegion,deUint32 width,deUint32 height,deUint32 depth)2566 static inline void cmdTraceRaysKHR (const DeviceInterface&					vk,
2567 									VkCommandBuffer							commandBuffer,
2568 									const VkStridedDeviceAddressRegionKHR*	raygenShaderBindingTableRegion,
2569 									const VkStridedDeviceAddressRegionKHR*	missShaderBindingTableRegion,
2570 									const VkStridedDeviceAddressRegionKHR*	hitShaderBindingTableRegion,
2571 									const VkStridedDeviceAddressRegionKHR*	callableShaderBindingTableRegion,
2572 									deUint32								width,
2573 									deUint32								height,
2574 									deUint32								depth)
2575 {
2576 	return vk.cmdTraceRaysKHR(commandBuffer,
2577 							  raygenShaderBindingTableRegion,
2578 							  missShaderBindingTableRegion,
2579 							  hitShaderBindingTableRegion,
2580 							  callableShaderBindingTableRegion,
2581 							  width,
2582 							  height,
2583 							  depth);
2584 }
2585 
2586 
cmdTraceRays(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const VkStridedDeviceAddressRegionKHR * raygenShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * missShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * hitShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * callableShaderBindingTableRegion,deUint32 width,deUint32 height,deUint32 depth)2587 void cmdTraceRays (const DeviceInterface&					vk,
2588 				   VkCommandBuffer							commandBuffer,
2589 				   const VkStridedDeviceAddressRegionKHR*	raygenShaderBindingTableRegion,
2590 				   const VkStridedDeviceAddressRegionKHR*	missShaderBindingTableRegion,
2591 				   const VkStridedDeviceAddressRegionKHR*	hitShaderBindingTableRegion,
2592 				   const VkStridedDeviceAddressRegionKHR*	callableShaderBindingTableRegion,
2593 				   deUint32									width,
2594 				   deUint32									height,
2595 				   deUint32									depth)
2596 {
2597 	DE_ASSERT(raygenShaderBindingTableRegion	!= DE_NULL);
2598 	DE_ASSERT(missShaderBindingTableRegion		!= DE_NULL);
2599 	DE_ASSERT(hitShaderBindingTableRegion		!= DE_NULL);
2600 	DE_ASSERT(callableShaderBindingTableRegion	!= DE_NULL);
2601 
2602 	return cmdTraceRaysKHR(vk,
2603 						   commandBuffer,
2604 						   raygenShaderBindingTableRegion,
2605 						   missShaderBindingTableRegion,
2606 						   hitShaderBindingTableRegion,
2607 						   callableShaderBindingTableRegion,
2608 						   width,
2609 						   height,
2610 						   depth);
2611 }
2612 
cmdTraceRaysIndirectKHR(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const VkStridedDeviceAddressRegionKHR * raygenShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * missShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * hitShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * callableShaderBindingTableRegion,VkDeviceAddress indirectDeviceAddress)2613 static inline void cmdTraceRaysIndirectKHR (const DeviceInterface&					vk,
2614 											VkCommandBuffer							commandBuffer,
2615 											const VkStridedDeviceAddressRegionKHR*	raygenShaderBindingTableRegion,
2616 											const VkStridedDeviceAddressRegionKHR*	missShaderBindingTableRegion,
2617 											const VkStridedDeviceAddressRegionKHR*	hitShaderBindingTableRegion,
2618 											const VkStridedDeviceAddressRegionKHR*	callableShaderBindingTableRegion,
2619 											VkDeviceAddress							indirectDeviceAddress )
2620 {
2621 	DE_ASSERT(raygenShaderBindingTableRegion	!= DE_NULL);
2622 	DE_ASSERT(missShaderBindingTableRegion		!= DE_NULL);
2623 	DE_ASSERT(hitShaderBindingTableRegion		!= DE_NULL);
2624 	DE_ASSERT(callableShaderBindingTableRegion	!= DE_NULL);
2625 	DE_ASSERT(indirectDeviceAddress				!= 0);
2626 
2627 	return vk.cmdTraceRaysIndirectKHR(commandBuffer,
2628 									  raygenShaderBindingTableRegion,
2629 									  missShaderBindingTableRegion,
2630 									  hitShaderBindingTableRegion,
2631 									  callableShaderBindingTableRegion,
2632 									  indirectDeviceAddress);
2633 }
2634 
cmdTraceRaysIndirect(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const VkStridedDeviceAddressRegionKHR * raygenShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * missShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * hitShaderBindingTableRegion,const VkStridedDeviceAddressRegionKHR * callableShaderBindingTableRegion,VkDeviceAddress indirectDeviceAddress)2635 void cmdTraceRaysIndirect (const DeviceInterface&					vk,
2636 						   VkCommandBuffer							commandBuffer,
2637 						   const VkStridedDeviceAddressRegionKHR*	raygenShaderBindingTableRegion,
2638 						   const VkStridedDeviceAddressRegionKHR*	missShaderBindingTableRegion,
2639 						   const VkStridedDeviceAddressRegionKHR*	hitShaderBindingTableRegion,
2640 						   const VkStridedDeviceAddressRegionKHR*	callableShaderBindingTableRegion,
2641 						   VkDeviceAddress							indirectDeviceAddress)
2642 {
2643 	return cmdTraceRaysIndirectKHR(vk,
2644 								   commandBuffer,
2645 								   raygenShaderBindingTableRegion,
2646 								   missShaderBindingTableRegion,
2647 								   hitShaderBindingTableRegion,
2648 								   callableShaderBindingTableRegion,
2649 								   indirectDeviceAddress);
2650 }
2651 
2652 } // vk
2653