• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
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 Ray Tracing Capture/Replay tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayTracingCaptureReplayTests.hpp"
25 
26 #include <set>
27 #include "vkDefs.hpp"
28 
29 #include "vktTestCase.hpp"
30 #include "vktTestGroupUtil.hpp"
31 #include "vktCustomInstancesDevices.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBufferWithMemory.hpp"
37 #include "vkImageWithMemory.hpp"
38 #include "vkTypeUtil.hpp"
39 
40 #include "vkRayTracingUtil.hpp"
41 
42 #include "tcuCommandLine.hpp"
43 
44 namespace vkt
45 {
46 namespace RayTracing
47 {
48 namespace
49 {
50 using namespace vk;
51 using namespace vkt;
52 
53 static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
54 												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
55 												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
56 												| VK_SHADER_STAGE_MISS_BIT_KHR
57 												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
58 												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
59 
60 static const deUint32	RTCR_DEFAULT_SIZE = 8u;
61 static const deUint32	RTCR_SHADER_COUNT = 4u;
62 
63 enum SBTReplayTestType
64 {
65 	TEST_ACCELERATION_STRUCTURES,
66 	TEST_PIPELINE_SINGLE,
67 	TEST_PIPELINE_AFTER,
68 	TEST_PIPELINE_BEFORE
69 };
70 
71 enum ASOperationTarget
72 {
73 	OT_NONE,
74 	OT_TOP_ACCELERATION,
75 	OT_BOTTOM_ACCELERATION
76 };
77 
78 enum ASOperationType
79 {
80 	OP_NONE,
81 	OP_COPY,
82 	OP_COMPACT,
83 	OP_SERIALIZE
84 };
85 
86 enum ASBottomTestType
87 {
88 	BTT_TRIANGLES,
89 	BTT_AABBS
90 };
91 
92 enum ASTopTestType
93 {
94 	TTT_IDENTICAL_INSTANCES,
95 	TTT_DIFFERENT_INSTANCES
96 };
97 
98 struct TestParams;
99 
100 struct PipelineOutput
101 {
102 	Move<VkPipeline>				pipeline;
103 	de::MovePtr<BufferWithMemory>	raygenShaderBindingTable;
104 	de::MovePtr<BufferWithMemory>	missShaderBindingTable;
105 	de::MovePtr<BufferWithMemory>	hitShaderBindingTable;
106 	Move<VkDescriptorSet>			descriptorSet;
107 	de::MovePtr<BufferWithMemory>	uniformBuffer;
108 
109 	VkStridedDeviceAddressRegionKHR	raygenShaderBindingTableRegion;
110 	VkStridedDeviceAddressRegionKHR	missShaderBindingTableRegion;
111 	VkStridedDeviceAddressRegionKHR	hitShaderBindingTableRegion;
112 	VkStridedDeviceAddressRegionKHR	callableShaderBindingTableRegion;
113 };
114 
115 struct PipelineData
116 {
PipelineDatavkt::RayTracing::__anona5ceb9bd0111::PipelineData117 	PipelineData(Allocator& alloc)
118 		: allocator(alloc)
119 	{}
120 	VkDescriptorSetLayout			descriptorSetLayout;
121 	VkDescriptorPool				descriptorPool;
122 	VkPipelineLayout				pipelineLayout;
123 	Allocator&						allocator;
124 	PipelineOutput					pipelines[2];
125 };
126 
127 class TestConfiguration
128 {
129 public:
130 	virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(Context&							context,
131 																												 TestParams&						testParams) = 0;
132 	virtual de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure		(Context&							context,
133 																												 TestParams&						testParams,
134 																												 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) = 0;
135 	virtual void															initRayTracingShaders				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
136 																												 Context&							context,
137 																												 const DeviceInterface&				vkd,
138 																												 const VkDevice						device,
139 																												 TestParams&						testParams,
140 																												 bool								replay) = 0;
141 	virtual void															initShaderBindingTables				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
142 																												 Context&							context,
143 																												 const DeviceInterface&				vkd,
144 																												 const VkDevice						device,
145 																												 TestParams&						testParams,
146 																												 deUint32							shaderGroupHandleSize,
147 																												 deUint32							shaderGroupBaseAlignment,
148 																												 PipelineData&						pipelineData,
149 																												 bool								replay) = 0;
150 	virtual bool															verifyImage							(const std::vector<deUint32>&		captureResults,
151 																												 const std::vector<deUint32>&		replayResults,
152 																												 Context&							context,
153 																												 TestParams&						testParams) = 0;
154 	virtual VkFormat														getResultImageFormat				() = 0;
155 	virtual size_t															getResultImageFormatSize			() = 0;
156 	virtual VkClearValue													getClearValue						() = 0;
157 };
158 
159 struct TestParams
160 {
161 	SBTReplayTestType							testType;			// SBT
162 	ASOperationTarget							operationTarget;	// AS
163 	ASOperationType								operationType;		// AS
164 	vk::VkAccelerationStructureBuildTypeKHR		buildType;			// AS
165 	ASBottomTestType							bottomType;			// AS
166 	ASTopTestType								topType;			// AS
167 	deUint32									width;
168 	deUint32									height;
169 	de::SharedPtr<TestConfiguration>			testConfiguration;
170 };
171 
getShaderGroupSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)172 deUint32 getShaderGroupSize (const InstanceInterface&	vki,
173 							 const VkPhysicalDevice		physicalDevice)
174 {
175 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
176 
177 	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
178 	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
179 }
180 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)181 deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
182 									  const VkPhysicalDevice	physicalDevice)
183 {
184 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
185 
186 	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
187 	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
188 }
189 
makeImageCreateInfo(deUint32 width,deUint32 height,deUint32 depth,VkFormat format)190 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
191 {
192 	const VkImageCreateInfo			imageCreateInfo			=
193 	{
194 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,																// VkStructureType			sType;
195 		DE_NULL,																							// const void*				pNext;
196 		(VkImageCreateFlags)0u,																				// VkImageCreateFlags		flags;
197 		VK_IMAGE_TYPE_3D,																					// VkImageType				imageType;
198 		format,																								// VkFormat					format;
199 		makeExtent3D(width, height, depth),																	// VkExtent3D				extent;
200 		1u,																									// deUint32					mipLevels;
201 		1u,																									// deUint32					arrayLayers;
202 		VK_SAMPLE_COUNT_1_BIT,																				// VkSampleCountFlagBits	samples;
203 		VK_IMAGE_TILING_OPTIMAL,																			// VkImageTiling			tiling;
204 		VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,		// VkImageUsageFlags		usage;
205 		VK_SHARING_MODE_EXCLUSIVE,																			// VkSharingMode			sharingMode;
206 		0u,																									// deUint32					queueFamilyIndexCount;
207 		DE_NULL,																							// const deUint32*			pQueueFamilyIndices;
208 		VK_IMAGE_LAYOUT_UNDEFINED																			// VkImageLayout			initialLayout;
209 	};
210 
211 	return imageCreateInfo;
212 }
213 
makeQueryPool(const DeviceInterface & vk,const VkDevice device,const VkQueryType queryType,deUint32 queryCount)214 Move<VkQueryPool> makeQueryPool(const DeviceInterface&		vk,
215 								const VkDevice				device,
216 								const VkQueryType			queryType,
217 								deUint32					queryCount)
218 {
219 	const VkQueryPoolCreateInfo				queryPoolCreateInfo =
220 	{
221 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,		// sType
222 		DE_NULL,										// pNext
223 		(VkQueryPoolCreateFlags)0,						// flags
224 		queryType,										// queryType
225 		queryCount,										// queryCount
226 		0u,												// pipelineStatistics
227 	};
228 	return createQueryPool(vk, device, &queryPoolCreateInfo);
229 }
230 
getAccelerationStructureDeviceAddress(const DeviceInterface & vk,const VkDevice device,VkAccelerationStructureKHR accelerationStructure)231 VkDeviceAddress getAccelerationStructureDeviceAddress (const DeviceInterface&						vk,
232 													   const VkDevice								device,
233 													   VkAccelerationStructureKHR					accelerationStructure)
234 {
235 	const VkAccelerationStructureDeviceAddressInfoKHR addressInfo =
236 	{
237 		VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType               sType;
238 		DE_NULL,															// const void*                   pNext;
239 		accelerationStructure												// VkAccelerationStructureKHR    accelerationStructure
240 	};
241 	return vk.getAccelerationStructureDeviceAddressKHR(device, &addressInfo);
242 }
243 
244 class TestShaderBindingTablesConfiguration : public TestConfiguration
245 {
246 public:
247 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(Context&							context,
248 																										 TestParams&						testParams) override;
249 	de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure		(Context&							context,
250 																										 TestParams&						testParams,
251 																										 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) override;
252 	void															initRayTracingShaders				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
253 																										 Context&							context,
254 																										 const DeviceInterface&				vkd,
255 																										 const VkDevice						device,
256 																										 TestParams&						testParams,
257 																										 bool								replay) override;
258 	void															initShaderBindingTables				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
259 																										 Context&							context,
260 																										 const DeviceInterface&				vkd,
261 																										 const VkDevice						device,
262 																										 TestParams&						testParams,
263 																										 deUint32							shaderGroupHandleSize,
264 																										 deUint32							shaderGroupBaseAlignment,
265 																										 PipelineData&						pipelineData,
266 																										 bool								replay) override;
267 	bool															verifyImage							(const std::vector<deUint32>&		captureResults,
268 																										 const std::vector<deUint32>&		replayResults,
269 																										 Context&							context,
270 																										 TestParams&						testParams) override;
271 	VkFormat														getResultImageFormat				() override;
272 	size_t															getResultImageFormatSize			() override;
273 	VkClearValue													getClearValue						() override;
274 protected:
275 	VkDeviceAddress													sbtSavedRaygenAddress	= 0u;
276 	VkDeviceAddress													sbtSavedMissAddress		= 0u;
277 	VkDeviceAddress													sbtSavedHitAddress		= 0u;
278 };
279 
initBottomAccelerationStructures(Context & context,TestParams & testParams)280 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > TestShaderBindingTablesConfiguration::initBottomAccelerationStructures (Context&					context,
281 																																	  TestParams&				testParams)
282 {
283 	DE_UNREF(context);
284 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	result;
285 
286 	tcu::Vec3 v0(0.0, 1.0, 0.0);
287 	tcu::Vec3 v1(0.0, 0.0, 0.0);
288 	tcu::Vec3 v2(1.0, 1.0, 0.0);
289 	tcu::Vec3 v3(1.0, 0.0, 0.0);
290 
291 	for (deUint32 y = 0; y < testParams.height; ++y)
292 	for (deUint32 x = 0; x < testParams.width; ++x)
293 	{
294 		// let's build a chessboard of geometries
295 		if (((x + y) % 2) == 0)
296 			continue;
297 		tcu::Vec3 xyz((float)x, (float)y, 0.0f);
298 		std::vector<tcu::Vec3>	geometryData;
299 
300 		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
301 		bottomLevelAccelerationStructure->setGeometryCount(1u);
302 
303 		geometryData.push_back(xyz + v0);
304 		geometryData.push_back(xyz + v1);
305 		geometryData.push_back(xyz + v2);
306 		geometryData.push_back(xyz + v2);
307 		geometryData.push_back(xyz + v1);
308 		geometryData.push_back(xyz + v3);
309 
310 		bottomLevelAccelerationStructure->addGeometry(geometryData, true);
311 		result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
312 	}
313 
314 	return result;
315 }
316 
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)317 de::MovePtr<TopLevelAccelerationStructure> TestShaderBindingTablesConfiguration::initTopAccelerationStructure (Context&					context,
318 																											   TestParams&				testParams,
319 																											   std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures)
320 {
321 	DE_UNREF(context);
322 	deUint32 instanceCount = testParams.width * testParams.height / 2;
323 
324 	de::MovePtr<TopLevelAccelerationStructure>	result = makeTopLevelAccelerationStructure();
325 	result->setInstanceCount(instanceCount);
326 
327 	deUint32				currentInstanceIndex = 0;
328 	VkTransformMatrixKHR	identityMatrix = { { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f } } };
329 
330 	for (deUint32 y = 0; y < testParams.height; ++y)
331 	{
332 		deUint32 shaderOffset = y % RTCR_SHADER_COUNT;
333 		for (deUint32 x = 0; x < testParams.width; ++x)
334 		{
335 			if (((x + y) % 2) == 0)
336 				continue;
337 			result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++], identityMatrix, 0, 0xFF, shaderOffset);
338 		}
339 	}
340 
341 	return result;
342 }
343 
initRayTracingShaders(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,Context & context,const DeviceInterface & vkd,const VkDevice device,TestParams & testParams,bool replay)344 void TestShaderBindingTablesConfiguration::initRayTracingShaders (de::MovePtr<RayTracingPipeline>&		rayTracingPipeline,
345 																  Context&								context,
346 																  const DeviceInterface&				vkd,
347 																  const VkDevice						device,
348 																  TestParams&							testParams,
349 																  bool									replay)
350 {
351 	DE_UNREF(testParams);
352 	DE_UNREF(replay);
353 	rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
354 	rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss"), 0), 1);
355 	for (deUint32 shaderNdx = 0; shaderNdx < RTCR_SHADER_COUNT; ++shaderNdx)
356 	{
357 		std::stringstream shaderName;
358 		shaderName << "chit" << shaderNdx;
359 		rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(shaderName.str()), 0), 2 + shaderNdx);
360 	}
361 }
362 
initShaderBindingTables(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,Context & context,const DeviceInterface & vkd,const VkDevice device,TestParams & testParams,deUint32 shaderGroupHandleSize,deUint32 shaderGroupBaseAlignment,PipelineData & pipelineData,bool replay)363 void TestShaderBindingTablesConfiguration::initShaderBindingTables (de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
364 																	Context&							context,
365 																	const DeviceInterface&				vkd,
366 																	const VkDevice						device,
367 																	TestParams&							testParams,
368 																	deUint32							shaderGroupHandleSize,
369 																	deUint32							shaderGroupBaseAlignment,
370 																	PipelineData&						pipelineData,
371 																	bool								replay)
372 {
373 	DE_UNREF(context);
374 	const VkBufferCreateInfo				uniformBufferCreateInfo		= makeBufferCreateInfo(sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
375 
376 	if (!replay) // capture phase
377 	{
378 		pipelineData.pipelines[0].pipeline								= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
379 		pipelineData.pipelines[0].raygenShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1, VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, MemoryRequirement::DeviceAddress, 0u);
380 		pipelineData.pipelines[0].missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1, VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, MemoryRequirement::DeviceAddress, 0u);
381 		pipelineData.pipelines[0].hitShaderBindingTable					= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, RTCR_SHADER_COUNT, VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, MemoryRequirement::DeviceAddress, 0u);
382 		pipelineData.pipelines[0].descriptorSet							= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
383 		pipelineData.pipelines[0].uniformBuffer							= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
384 		pipelineData.pipelines[0].raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
385 		pipelineData.pipelines[0].missShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
386 		pipelineData.pipelines[0].hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, RTCR_SHADER_COUNT * shaderGroupHandleSize);
387 		pipelineData.pipelines[0].callableShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
388 
389 		// capture SBT addresses
390 		VkBufferDeviceAddressInfo	deviceAddressInfo	=
391 		{
392 			VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,	//VkStructureType    sType;
393 			DE_NULL,										//const void*        pNext;
394 			DE_NULL											//VkBuffer           buffer;
395 		};
396 		deviceAddressInfo.buffer										= pipelineData.pipelines[0].raygenShaderBindingTable->get();
397 		sbtSavedRaygenAddress											= vkd.getBufferOpaqueCaptureAddress( device, &deviceAddressInfo);
398 		deviceAddressInfo.buffer										= pipelineData.pipelines[0].missShaderBindingTable->get();
399 		sbtSavedMissAddress												= vkd.getBufferOpaqueCaptureAddress( device, &deviceAddressInfo);
400 		deviceAddressInfo.buffer										= pipelineData.pipelines[0].hitShaderBindingTable->get();
401 		sbtSavedHitAddress												= vkd.getBufferOpaqueCaptureAddress( device, &deviceAddressInfo);
402 	}
403 	else // replay phase
404 	{
405 		switch (testParams.testType)
406 		{
407 		case TEST_PIPELINE_SINGLE:
408 			pipelineData.pipelines[0].pipeline							= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
409 			pipelineData.pipelines[0].raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1, 0u, 0u, MemoryRequirement::Any, sbtSavedRaygenAddress);
410 			pipelineData.pipelines[0].missShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1, 0u, 0u, MemoryRequirement::Any, sbtSavedMissAddress);
411 			pipelineData.pipelines[0].hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, RTCR_SHADER_COUNT, 0u, 0u, MemoryRequirement::Any, sbtSavedHitAddress);
412 			pipelineData.pipelines[0].descriptorSet						= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
413 			pipelineData.pipelines[0].uniformBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
414 			pipelineData.pipelines[0].raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
415 			pipelineData.pipelines[0].missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
416 			pipelineData.pipelines[0].hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, RTCR_SHADER_COUNT * shaderGroupHandleSize);
417 			pipelineData.pipelines[0].callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
418 
419 			break;
420 		case TEST_PIPELINE_AFTER:
421 			pipelineData.pipelines[0].pipeline							= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
422 			pipelineData.pipelines[0].raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1, 0u, 0u, MemoryRequirement::Any, sbtSavedRaygenAddress);
423 			pipelineData.pipelines[0].missShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1, 0u, 0u, MemoryRequirement::Any, sbtSavedMissAddress);
424 			pipelineData.pipelines[0].hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, RTCR_SHADER_COUNT, 0u, 0u, MemoryRequirement::Any, sbtSavedHitAddress);
425 			pipelineData.pipelines[0].descriptorSet						= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
426 			pipelineData.pipelines[0].uniformBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
427 			pipelineData.pipelines[0].raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
428 			pipelineData.pipelines[0].missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
429 			pipelineData.pipelines[0].hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, RTCR_SHADER_COUNT * shaderGroupHandleSize);
430 			pipelineData.pipelines[0].callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
431 
432 			pipelineData.pipelines[1].pipeline							= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
433 			pipelineData.pipelines[1].raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[1].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1, 0u, 0u, MemoryRequirement::Any, 0u);
434 			pipelineData.pipelines[1].missShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[1].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1, 0u, 0u, MemoryRequirement::Any, 0u);
435 			pipelineData.pipelines[1].hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[1].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, RTCR_SHADER_COUNT, 0u, 0u, MemoryRequirement::Any, 0u);
436 			pipelineData.pipelines[1].descriptorSet						= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
437 			pipelineData.pipelines[1].uniformBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
438 			pipelineData.pipelines[1].raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[1].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
439 			pipelineData.pipelines[1].missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[1].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
440 			pipelineData.pipelines[1].hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[1].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, RTCR_SHADER_COUNT * shaderGroupHandleSize);
441 			pipelineData.pipelines[1].callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
442 
443 			break;
444 		case TEST_PIPELINE_BEFORE:
445 			pipelineData.pipelines[0].pipeline							= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
446 			pipelineData.pipelines[0].raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1, 0u, 0u, MemoryRequirement::Any, 0u);
447 			pipelineData.pipelines[0].missShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1, 0u, 0u, MemoryRequirement::Any, 0u);
448 			pipelineData.pipelines[0].hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, RTCR_SHADER_COUNT, 0u, 0u, MemoryRequirement::Any, 0u);
449 			pipelineData.pipelines[0].descriptorSet						= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
450 			pipelineData.pipelines[0].uniformBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
451 			pipelineData.pipelines[0].raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
452 			pipelineData.pipelines[0].missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
453 			pipelineData.pipelines[0].hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, RTCR_SHADER_COUNT * shaderGroupHandleSize);
454 			pipelineData.pipelines[0].callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
455 
456 			pipelineData.pipelines[1].pipeline							= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
457 			pipelineData.pipelines[1].raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[1].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1, 0u, 0u, MemoryRequirement::Any, sbtSavedRaygenAddress);
458 			pipelineData.pipelines[1].missShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[1].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1, 0u, 0u, MemoryRequirement::Any, sbtSavedMissAddress);
459 			pipelineData.pipelines[1].hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[1].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, RTCR_SHADER_COUNT, 0u, 0u, MemoryRequirement::Any, sbtSavedHitAddress);
460 			pipelineData.pipelines[1].descriptorSet						= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
461 			pipelineData.pipelines[1].uniformBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
462 			pipelineData.pipelines[1].raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[1].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
463 			pipelineData.pipelines[1].missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[1].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
464 			pipelineData.pipelines[1].hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[1].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, RTCR_SHADER_COUNT * shaderGroupHandleSize);
465 			pipelineData.pipelines[1].callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
466 			break;
467 		default:
468 			TCU_THROW(InternalError, "Wrong test type");
469 		}
470 	}
471 }
472 
verifyImage(const std::vector<deUint32> & captureResults,const std::vector<deUint32> & replayResults,Context & context,TestParams & testParams)473 bool TestShaderBindingTablesConfiguration::verifyImage (const std::vector<deUint32>&		captureResults,
474 														const std::vector<deUint32>&		replayResults,
475 														Context&							context,
476 														TestParams&							testParams)
477 {
478 	DE_UNREF(context);
479 
480 	deUint32							pipelineCount	= (testParams.testType == TEST_PIPELINE_SINGLE) ? 1u : 2u;
481 	deUint32							imageSize		= testParams.height * testParams.width;
482 	deUint32							failures		= 0;
483 
484 	// verify results - each test case should generate checkerboard pattern
485 	for (deUint32 pipelineNdx = 0; pipelineNdx < pipelineCount; ++pipelineNdx)
486 	for (deUint32 pos = 0; pos < imageSize; ++pos)
487 	{
488 		if (captureResults[pos] != replayResults[pipelineNdx*imageSize + pos])
489 			failures++;
490 	}
491 	return failures == 0;
492 }
493 
getResultImageFormat()494 VkFormat TestShaderBindingTablesConfiguration::getResultImageFormat ()
495 {
496 	return VK_FORMAT_R32_UINT;
497 }
498 
getResultImageFormatSize()499 size_t TestShaderBindingTablesConfiguration::getResultImageFormatSize ()
500 {
501 	return sizeof(deUint32);
502 }
503 
getClearValue()504 VkClearValue TestShaderBindingTablesConfiguration::getClearValue ()
505 {
506 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
507 }
508 
509 class TestAccelerationStructuresConfiguration : public TestConfiguration
510 {
511 public:
512 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(Context&							context,
513 																										 TestParams&						testParams) override;
514 	de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure		(Context&							context,
515 																										 TestParams&						testParams,
516 																										 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) override;
517 	void															initRayTracingShaders				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
518 																										 Context&							context,
519 																										 const DeviceInterface&				vkd,
520 																										 const VkDevice						device,
521 																										 TestParams&						testParams,
522 																										 bool								replay) override;
523 	void															initShaderBindingTables				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
524 																										 Context&							context,
525 																										 const DeviceInterface&				vkd,
526 																										 const VkDevice						device,
527 																										 TestParams&						testParams,
528 																										 deUint32							shaderGroupHandleSize,
529 																										 deUint32							shaderGroupBaseAlignment,
530 																										 PipelineData&						pipelineData,
531 																										 bool								replay) override;
532 	bool															verifyImage							(const std::vector<deUint32>&		captureResults,
533 																										 const std::vector<deUint32>&		replayResults,
534 																										 Context&							context,
535 																										 TestParams&						testParams) override;
536 	VkFormat														getResultImageFormat				() override;
537 	size_t															getResultImageFormatSize			() override;
538 	VkClearValue													getClearValue						() override;
539 protected:
540 	VkDeviceAddress													sbtSavedRaygenAddress	= 0u;
541 	VkDeviceAddress													sbtSavedMissAddress		= 0u;
542 	VkDeviceAddress													sbtSavedHitAddress		= 0u;
543 };
544 
initBottomAccelerationStructures(Context & context,TestParams & testParams)545 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> TestAccelerationStructuresConfiguration::initBottomAccelerationStructures (Context&				context,
546 																																		 TestParams&			testParams)
547 {
548 	DE_UNREF(context);
549 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	result;
550 
551 	tcu::Vec3 v0(0.0, 1.0, 0.0);
552 	tcu::Vec3 v1(0.0, 0.0, 0.0);
553 	tcu::Vec3 v2(1.0, 1.0, 0.0);
554 	tcu::Vec3 v3(1.0, 0.0, 0.0);
555 
556 	if (testParams.topType == TTT_DIFFERENT_INSTANCES)
557 	{
558 		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
559 		bottomLevelAccelerationStructure->setGeometryCount(1u);
560 		de::SharedPtr<RaytracedGeometryBase> geometry;
561 		if (testParams.bottomType == BTT_TRIANGLES)
562 		{
563 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
564 			geometry->addVertex(v0);
565 			geometry->addVertex(v1);
566 			geometry->addVertex(v2);
567 			geometry->addVertex(v2);
568 			geometry->addVertex(v1);
569 			geometry->addVertex(v3);
570 		}
571 		else // m_data.bottomType == BTT_AABBS
572 		{
573 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
574 			geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
575 			geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
576 		}
577 
578 		bottomLevelAccelerationStructure->addGeometry(geometry);
579 		result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
580 	}
581 	else // m_data.topTestType == TTT_IDENTICAL_INSTANCES
582 	{
583 		// triangle and aabb tests use geometries/aabbs with different vertex positions and the same identity matrix in each instance data
584 		for (deUint32 y = 0; y < testParams.height; ++y)
585 			for (deUint32 x = 0; x < testParams.width; ++x)
586 			{
587 				// let's build a chessboard of geometries
588 				if (((x + y) % 2) == 0)
589 					continue;
590 				tcu::Vec3 xyz((float)x, (float)y, 0.0f);
591 
592 				de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
593 				bottomLevelAccelerationStructure->setGeometryCount(1u);
594 
595 				de::SharedPtr<RaytracedGeometryBase> geometry;
596 				if (testParams.bottomType == BTT_TRIANGLES)
597 				{
598 					geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
599 					geometry->addVertex(xyz + v0);
600 					geometry->addVertex(xyz + v1);
601 					geometry->addVertex(xyz + v2);
602 					geometry->addVertex(xyz + v2);
603 					geometry->addVertex(xyz + v1);
604 					geometry->addVertex(xyz + v3);
605 				}
606 				else // testParams.bottomTestType == BTT_AABBS
607 				{
608 					geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
609 					geometry->addVertex(xyz + tcu::Vec3(0.0f, 0.0f, -0.1f));
610 					geometry->addVertex(xyz + tcu::Vec3(1.0f, 1.0f, 0.1f));
611 				}
612 
613 				bottomLevelAccelerationStructure->addGeometry(geometry);
614 				result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
615 			}
616 	}
617 
618 	return result;
619 }
620 
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)621 de::MovePtr<TopLevelAccelerationStructure> TestAccelerationStructuresConfiguration::initTopAccelerationStructure (Context&					context,
622 																												  TestParams&				testParams,
623 																												  std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures)
624 {
625 	DE_UNREF(context);
626 
627 	deUint32 instanceCount = testParams.width * testParams.height / 2;
628 
629 	de::MovePtr<TopLevelAccelerationStructure>	result = makeTopLevelAccelerationStructure();
630 	result->setInstanceCount(instanceCount);
631 
632 	if (testParams.topType == TTT_DIFFERENT_INSTANCES)
633 	{
634 
635 		for (deUint32 y = 0; y < testParams.height; ++y)
636 		for (deUint32 x = 0; x < testParams.width; ++x)
637 		{
638 			if (((x + y) % 2) == 0)
639 				continue;
640 			const VkTransformMatrixKHR			transformMatrixKHR =
641 			{
642 				{								//  float	matrix[3][4];
643 					{ 1.0f, 0.0f, 0.0f, (float)x },
644 					{ 0.0f, 1.0f, 0.0f, (float)y },
645 					{ 0.0f, 0.0f, 1.0f, 0.0f },
646 				}
647 			};
648 			result->addInstance(bottomLevelAccelerationStructures[0], transformMatrixKHR);
649 		}
650 	}
651 	else // testParams.topType == TTT_IDENTICAL_INSTANCES
652 	{
653 		deUint32 currentInstanceIndex = 0;
654 
655 		for (deUint32 y = 0; y < testParams.height; ++y)
656 		for (deUint32 x = 0; x < testParams.width; ++x)
657 		{
658 			if (((x + y) % 2) == 0)
659 				continue;
660 			result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++]);
661 		}
662 	}
663 
664 	return result;
665 }
666 
initRayTracingShaders(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,Context & context,const DeviceInterface & vkd,const VkDevice device,TestParams & testParams,bool replay)667 void TestAccelerationStructuresConfiguration::initRayTracingShaders (de::MovePtr<RayTracingPipeline>&		rayTracingPipeline,
668 																	 Context&								context,
669 																	 const DeviceInterface&					vkd,
670 																	 const VkDevice							device,
671 																	 TestParams&							testParams,
672 																	 bool									replay)
673 {
674 	DE_UNREF(testParams);
675 	DE_UNREF(replay);
676 	rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"),  0), 0);
677 	rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get("chit1"),  0), 1);
678 	rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get("chit1"),  0), 2);
679 	rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get("isect"), 0), 2);
680 	rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,			createShaderModule(vkd, device, context.getBinaryCollection().get("miss"),  0), 3);
681 
682 }
683 
initShaderBindingTables(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,Context & context,const DeviceInterface & vkd,const VkDevice device,TestParams & testParams,deUint32 shaderGroupHandleSize,deUint32 shaderGroupBaseAlignment,PipelineData & pipelineData,bool replay)684 void TestAccelerationStructuresConfiguration::initShaderBindingTables (de::MovePtr<RayTracingPipeline>&		rayTracingPipeline,
685 																	   Context&								context,
686 																	   const DeviceInterface&				vkd,
687 																	   const VkDevice						device,
688 																	   TestParams&							testParams,
689 																	   deUint32								shaderGroupHandleSize,
690 																	   deUint32								shaderGroupBaseAlignment,
691 																	   PipelineData&						pipelineData,
692 																	   bool									replay)
693 {
694 	DE_UNREF(context);
695 	DE_UNREF(replay);
696 	const VkBufferCreateInfo				uniformBufferCreateInfo		= makeBufferCreateInfo(sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
697 
698 	pipelineData.pipelines[0].pipeline									= rayTracingPipeline->createPipeline(vkd, device, pipelineData.pipelineLayout);
699 	pipelineData.pipelines[0].raygenShaderBindingTable					= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 );
700 	if(testParams.bottomType == BTT_AABBS)
701 		pipelineData.pipelines[0].hitShaderBindingTable					= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1 );
702 	else // testParams.bottomType == BTT_TRIANGLES
703 		pipelineData.pipelines[0].hitShaderBindingTable					= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1 );
704 	pipelineData.pipelines[0].missShaderBindingTable					= rayTracingPipeline->createShaderBindingTable(vkd, device, *(pipelineData.pipelines[0].pipeline), pipelineData.allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1 );
705 	pipelineData.pipelines[0].descriptorSet								= makeDescriptorSet(vkd, device, pipelineData.descriptorPool, pipelineData.descriptorSetLayout);
706 	pipelineData.pipelines[0].uniformBuffer								= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, pipelineData.allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
707 	pipelineData.pipelines[0].raygenShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
708 	pipelineData.pipelines[0].missShaderBindingTableRegion				= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
709 	pipelineData.pipelines[0].hitShaderBindingTableRegion				= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, pipelineData.pipelines[0].hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
710 	pipelineData.pipelines[0].callableShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
711 
712 }
713 
verifyImage(const std::vector<deUint32> & captureResults,const std::vector<deUint32> & replayResults,Context & context,TestParams & testParams)714 bool TestAccelerationStructuresConfiguration::verifyImage (const std::vector<deUint32>&		captureResults,
715 														   const std::vector<deUint32>&		replayResults,
716 														   Context&							context,
717 														   TestParams&						testParams)
718 {
719 	DE_UNREF(context);
720 
721 	deUint32							imageSize		= testParams.height * testParams.width;
722 	deUint32							failures		= 0;
723 
724 	// verify results - each test case should generate checkerboard pattern
725 	for (deUint32 pos = 0; pos < imageSize; ++pos)
726 	{
727 		if (captureResults[pos] != replayResults[pos])
728 			failures++;
729 	}
730 	return failures == 0;
731 }
732 
getResultImageFormat()733 VkFormat TestAccelerationStructuresConfiguration::getResultImageFormat ()
734 {
735 	return VK_FORMAT_R32_UINT;
736 }
737 
getResultImageFormatSize()738 size_t TestAccelerationStructuresConfiguration::getResultImageFormatSize ()
739 {
740 	return sizeof(deUint32);
741 }
742 
getClearValue()743 VkClearValue TestAccelerationStructuresConfiguration::getClearValue ()
744 {
745 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
746 }
747 
748 class RayTracingCaptureReplayTestCase : public TestCase
749 {
750 	public:
751 							RayTracingCaptureReplayTestCase				(tcu::TestContext& context, const char* name, const TestParams& data);
752 							~RayTracingCaptureReplayTestCase			(void);
753 
754 	virtual void			checkSupport								(Context& context) const;
755 	virtual	void			initPrograms								(SourceCollections& programCollection) const;
756 	virtual TestInstance*	createInstance								(Context& context) const;
757 private:
758 	TestParams				m_data;
759 };
760 
761 class RayTracingCaptureReplayTestInstance : public TestInstance
762 {
763 public:
764 																	RayTracingCaptureReplayTestInstance		(Context& context, const TestParams& data);
765 																	~RayTracingCaptureReplayTestInstance	(void);
766 	tcu::TestStatus													iterate									(void);
767 
768 protected:
769 	std::vector<deUint32>											runTest									(bool replay);
770 private:
771 	TestParams														m_data;
772 	std::vector<VkDeviceAddress>									buildBLASAddresses;
773 	std::vector<VkDeviceAddress>									copyBLASAddresses;
774 	VkDeviceAddress													buildTLASAddress;
775 	VkDeviceAddress													copyTLASAddress;
776 };
777 
RayTracingCaptureReplayTestCase(tcu::TestContext & context,const char * name,const TestParams & data)778 RayTracingCaptureReplayTestCase::RayTracingCaptureReplayTestCase (tcu::TestContext& context, const char* name, const TestParams& data)
779 	: vkt::TestCase	(context, name)
780 	, m_data		(data)
781 {
782 }
783 
~RayTracingCaptureReplayTestCase(void)784 RayTracingCaptureReplayTestCase::~RayTracingCaptureReplayTestCase	(void)
785 {
786 }
787 
checkSupport(Context & context) const788 void RayTracingCaptureReplayTestCase::checkSupport(Context& context) const
789 {
790 	context.requireDeviceFunctionality("VK_KHR_buffer_device_address");
791 	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
792 	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
793 
794 	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR		= context.getRayTracingPipelineFeatures();
795 	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
796 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
797 
798 	if (m_data.testType == TEST_PIPELINE_BEFORE && rayTracingPipelineFeaturesKHR.rayTracingPipelineShaderGroupHandleCaptureReplayMixed == DE_FALSE)
799 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipelineShaderGroupHandleCaptureReplayMixed");
800 
801 	if (m_data.testType != TEST_ACCELERATION_STRUCTURES && rayTracingPipelineFeaturesKHR.rayTracingPipelineShaderGroupHandleCaptureReplay == DE_FALSE)
802 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipelineShaderGroupHandleCaptureReplay");
803 
804 	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
805 	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
806 		TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
807 
808 	if (m_data.testType == TEST_ACCELERATION_STRUCTURES && accelerationStructureFeaturesKHR.accelerationStructureCaptureReplay == DE_FALSE)
809 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureCaptureReplay");
810 
811 	if (m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE)
812 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands");
813 
814 	const VkPhysicalDeviceBufferDeviceAddressFeatures&		bufferDeviceAddressFeatures = context.getBufferDeviceAddressFeatures();
815 
816 	if (bufferDeviceAddressFeatures.bufferDeviceAddressCaptureReplay == DE_FALSE)
817 		TCU_THROW(NotSupportedError, "Requires bufferDeviceAddressFeatures.bufferDeviceAddressCaptureReplay");
818 }
819 
initPrograms(SourceCollections & programCollection) const820 void RayTracingCaptureReplayTestCase::initPrograms (SourceCollections& programCollection) const
821 {
822 	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
823 	{
824 		std::stringstream css;
825 		css <<
826 			"#version 460 core\n"
827 			"#extension GL_EXT_ray_tracing : require\n"
828 			"layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
829 			"layout(set = 0, binding = 0) uniform UniformParams\n"
830 			"{\n"
831 			"  uint targetLayer;\n"
832 			"} uniformParams;\n"
833 			"layout(r32ui, set = 0, binding = 1) uniform uimage3D result;\n"
834 			"layout(set = 0, binding = 2) uniform accelerationStructureEXT topLevelAS;\n"
835 			"\n"
836 			"void main()\n"
837 			"{\n"
838 			"  float tmin     = 0.0;\n"
839 			"  float tmax     = 1.0;\n"
840 			"  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, 0.5);\n"
841 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
842 			"  hitValue       = uvec4(0,0,0,0);\n"
843 			"  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
844 			"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, uniformParams.targetLayer), hitValue);\n"
845 			"}\n";
846 		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
847 	}
848 
849 	for (deUint32 shaderNdx = 0; shaderNdx < RTCR_SHADER_COUNT; ++shaderNdx)
850 	{
851 		deUint32 colorValue = 2 * (shaderNdx + 1);
852 		std::stringstream css;
853 		css <<
854 			"#version 460 core\n"
855 			"#extension GL_EXT_ray_tracing : require\n"
856 			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
857 			"void main()\n"
858 			"{\n"
859 			"  hitValue = uvec4(" << colorValue << ",0,0,1);\n"
860 			"}\n";
861 		std::stringstream shaderName;
862 		shaderName << "chit" << shaderNdx;
863 
864 		programCollection.glslSources.add(shaderName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
865 	}
866 
867 	{
868 		std::stringstream css;
869 		css <<
870 			"#version 460 core\n"
871 			"#extension GL_EXT_ray_tracing : require\n"
872 			"hitAttributeEXT uvec4 hitAttribute;\n"
873 			"void main()\n"
874 			"{\n"
875 			"  hitAttribute = uvec4(0,0,0,0);\n"
876 			"  reportIntersectionEXT(0.5f, 0);\n"
877 			"}\n";
878 
879 		programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
880 	}
881 
882 	{
883 		std::stringstream css;
884 		css <<
885 			"#version 460 core\n"
886 			"#extension GL_EXT_ray_tracing : require\n"
887 			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
888 			"void main()\n"
889 			"{\n"
890 			"  hitValue = uvec4(1,0,0,1);\n"
891 			"}\n";
892 
893 		programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
894 	}
895 }
896 
createInstance(Context & context) const897 TestInstance* RayTracingCaptureReplayTestCase::createInstance (Context& context) const
898 {
899 	return new RayTracingCaptureReplayTestInstance(context, m_data);
900 }
901 
RayTracingCaptureReplayTestInstance(Context & context,const TestParams & data)902 RayTracingCaptureReplayTestInstance::RayTracingCaptureReplayTestInstance (Context& context, const TestParams& data)
903 	: vkt::TestInstance		(context)
904 	, m_data				(data)
905 {
906 }
907 
~RayTracingCaptureReplayTestInstance(void)908 RayTracingCaptureReplayTestInstance::~RayTracingCaptureReplayTestInstance (void)
909 {
910 }
911 
runTest(bool replay)912 std::vector<deUint32> RayTracingCaptureReplayTestInstance::runTest(bool replay)
913 {
914 	const auto&	vki					= m_context.getInstanceInterface();
915 	const auto	physicalDevice		= m_context.getPhysicalDevice();
916 	const auto&	vkd					= m_context.getDeviceInterface();
917 	const auto	device				= m_context.getDevice();
918 	auto		allocator			= &m_context.getDefaultAllocator();
919 	const auto	queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
920 	const auto	queue				= m_context.getUniversalQueue();
921 
922 	// Create common pipeline layout for all raytracing pipelines
923 	const Move<VkDescriptorSetLayout>		descriptorSetLayout					= DescriptorSetLayoutBuilder()
924 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ALL_RAY_TRACING_STAGES)
925 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
926 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
927 																					.build(vkd, device);
928 	deUint32								pipelineCount						= (!replay || ( m_data.testType == TEST_PIPELINE_SINGLE) || (m_data.testType == TEST_ACCELERATION_STRUCTURES)) ? 1u : 2u;
929 	const Move<VkDescriptorPool>			descriptorPool						= DescriptorPoolBuilder()
930 																						.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pipelineCount)
931 																						.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, pipelineCount)
932 																						.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, pipelineCount)
933 																						.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, pipelineCount);
934 	const Move<VkPipelineLayout>			pipelineLayout						= makePipelineLayout(vkd, device, descriptorSetLayout.get());
935 
936 	// All pipelines will be using the same set of shaders and shader groups.
937 	// Single RayTracingPipeline object will be enough to define it
938 	de::MovePtr<RayTracingPipeline>			rayTracingPipeline					= de::newMovePtr<RayTracingPipeline>();
939 	m_data.testConfiguration->initRayTracingShaders(rayTracingPipeline, m_context, vkd, device, m_data, replay);
940 
941 	// Capture phase ( replay==false ):
942 	// - TEST_ACCELERATION_STRUCTURES:
943 	//   - build/copy/compact/serialize structure, record addresses
944 	// - TEST_PIPELINE_SINGLE:
945 	// - TEST_PIPELINE_AFTER:
946 	// - TEST_PIPELINE_BEFORE:
947 	//   - single pipeline records addresses and fills test data
948 	// Replay phase ( replay==true ):
949 	// - TEST_ACCELERATION_STRUCTURES:
950 	//   - build/copy/compact/serialize structure with addresses captured previously
951 	// - TEST_PIPELINE_SINGLE:
952 	//   - single pipeline with addresses captured previously - writes into first image layer
953 	// - TEST_PIPELINE_AFTER:
954 	//   - first pipeline with addresses captured previously - writes into first image layer
955 	//   - second pipeline created without captured addresses - writes into second image layer
956 	// - TEST_PIPELINE_BEFORE:
957 	//   - first pipeline created without captured addresses - writes into first image layer
958 	//   - second pipeline with addresses captured previously - writes into second image layer
959 	//
960 	// Comparing results in all tests: all layers must be identical to the layer from capture phase
961 
962 	PipelineData							pipelineData(*allocator);
963 	pipelineData.pipelineLayout													= *pipelineLayout;
964 	pipelineData.descriptorSetLayout											= *descriptorSetLayout;
965 	pipelineData.descriptorPool													= *descriptorPool;
966 	const deUint32							shaderGroupHandleSize				= getShaderGroupSize(vki, physicalDevice);
967 	const deUint32							shaderGroupBaseAlignment			= getShaderGroupBaseAlignment(vki, physicalDevice);
968 	m_data.testConfiguration->initShaderBindingTables(rayTracingPipeline, m_context, vkd, device, m_data, shaderGroupHandleSize, shaderGroupBaseAlignment, pipelineData, replay);
969 
970 	const VkFormat							imageFormat							= m_data.testConfiguration->getResultImageFormat();
971 	const VkImageCreateInfo					imageCreateInfo						= makeImageCreateInfo(m_data.width, m_data.height, pipelineCount, imageFormat);
972 	const VkImageSubresourceRange			imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
973 	const de::MovePtr<ImageWithMemory>		image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, *allocator, imageCreateInfo, MemoryRequirement::Any));
974 	const Move<VkImageView>					imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
975 	const VkDescriptorImageInfo				descriptorImageInfo					= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
976 
977 	const deUint32							pixelCount							= m_data.width * m_data.height * pipelineCount;
978 	const VkBufferCreateInfo				resultBufferCreateInfo				= makeBufferCreateInfo(pixelCount*m_data.testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
979 	const VkImageSubresourceLayers			resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
980 	const VkBufferImageCopy					resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, pipelineCount), resultBufferImageSubresourceLayers);
981 	de::MovePtr<BufferWithMemory>			resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, *allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
982 
983 	const Move<VkCommandPool>				cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
984 	const Move<VkCommandBuffer>				cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
985 
986 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	bottomLevelAccelerationStructures;
987 	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructure;
988 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	bottomLevelAccelerationStructureCopies;
989 	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructureCopy;
990 	std::vector<de::SharedPtr<SerialStorage>>						bottomSerialized;
991 	std::vector<de::SharedPtr<SerialStorage>>						topSerialized;
992 	Move<VkQueryPool>												m_queryPoolCompact;
993 	Move<VkQueryPool>												m_queryPoolSerial;
994 
995 	beginCommandBuffer(vkd, *cmdBuffer, 0u);
996 	{
997 		const VkImageMemoryBarrier			preImageBarrier						= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
998 																				VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
999 																				**image, imageSubresourceRange);
1000 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1001 		const VkClearValue					clearValue							= m_data.testConfiguration->getClearValue();
1002 		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1003 		const VkImageMemoryBarrier			postImageBarrier					= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1004 																				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1005 																				**image, imageSubresourceRange);
1006 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1007 
1008 		// build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures )
1009 		bool									bottomCompact		= m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
1010 		bool									bottomSerial		= m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
1011 		bottomLevelAccelerationStructures							= m_data.testConfiguration->initBottomAccelerationStructures(m_context, m_data);
1012 		VkBuildAccelerationStructureFlagsKHR	allowCompactionFlag	= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
1013 		VkBuildAccelerationStructureFlagsKHR	emptyCompactionFlag	= VkBuildAccelerationStructureFlagsKHR(0);
1014 		VkBuildAccelerationStructureFlagsKHR	bottomBuildFlags	= (bottomCompact ? allowCompactionFlag : emptyCompactionFlag);
1015 		std::vector<VkAccelerationStructureKHR>	accelerationStructureHandles;
1016 		std::vector<VkDeviceSize>				bottomBlasCompactSize;
1017 		std::vector<VkDeviceSize>				bottomBlasSerialSize;
1018 
1019 		for (size_t idx=0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1020 		{
1021 			bottomLevelAccelerationStructures[idx]->setBuildFlags	(bottomBuildFlags);
1022 			bottomLevelAccelerationStructures[idx]->setBuildType	(m_data.buildType);
1023 			VkDeviceAddress	deviceAddress							= ( m_data.testType == TEST_ACCELERATION_STRUCTURES && replay ) ? buildBLASAddresses[idx] : 0u;
1024 			if ( m_data.testType == TEST_ACCELERATION_STRUCTURES && replay )
1025 				bottomLevelAccelerationStructures[idx]->setCreateFlags	( VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1026 			bottomLevelAccelerationStructures[idx]->createAndBuild	(vkd, device, *cmdBuffer, *allocator, deviceAddress);
1027 			accelerationStructureHandles.push_back					(*(bottomLevelAccelerationStructures[idx]->getPtr()));
1028 			if (m_data.testType == TEST_ACCELERATION_STRUCTURES && !replay)
1029 				buildBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructures[idx]->getPtr())));
1030 		}
1031 
1032 		if (m_data.operationType == OP_COMPACT)
1033 		{
1034 			deUint32 queryCount	= (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
1035 			if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1036 				m_queryPoolCompact	= makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount);
1037 			if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
1038 				queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize);
1039 		}
1040 		if (m_data.operationType == OP_SERIALIZE)
1041 		{
1042 			deUint32 queryCount	= (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
1043 			if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1044 				m_queryPoolSerial	= makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
1045 			if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
1046 				queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize);
1047 		}
1048 
1049 		// if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
1050 		if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial))
1051 		{
1052 			endCommandBuffer(vkd, *cmdBuffer);
1053 
1054 			submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1055 
1056 			if (bottomCompact)
1057 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(bottomBlasCompactSize.size()), sizeof(VkDeviceSize) * bottomBlasCompactSize.size(), bottomBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
1058 			if (bottomSerial)
1059 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(bottomBlasSerialSize.size()), sizeof(VkDeviceSize) * bottomBlasSerialSize.size(), bottomBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
1060 
1061 			vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1062 			beginCommandBuffer(vkd, *cmdBuffer, 0u);
1063 		}
1064 
1065 		auto bottomLevelAccelerationStructuresPtr								= &bottomLevelAccelerationStructures;
1066 		if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION)
1067 		{
1068 			switch (m_data.operationType)
1069 			{
1070 			case OP_COPY:
1071 			{
1072 				for (size_t idx = 0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1073 				{
1074 					de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
1075 					asCopy->setBuildType(m_data.buildType);
1076 					VkDeviceAddress	deviceAddress = replay ? copyBLASAddresses[idx] : 0u;
1077 					if (replay)
1078 						asCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1079 					asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, bottomLevelAccelerationStructures[idx].get(), 0u, deviceAddress);
1080 					bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
1081 					if (!replay)
1082 						copyBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructureCopies[idx]->getPtr())));
1083 				}
1084 				break;
1085 			}
1086 			case OP_COMPACT:
1087 			{
1088 				for (size_t idx = 0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1089 				{
1090 					de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
1091 					asCopy->setBuildType(m_data.buildType);
1092 					VkDeviceAddress	deviceAddress = replay ? copyBLASAddresses[idx] : 0u;
1093 					if (replay)
1094 						asCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1095 					asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, bottomLevelAccelerationStructures[idx].get(), bottomBlasCompactSize[idx], deviceAddress);
1096 					bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
1097 					if (!replay)
1098 						copyBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructureCopies[idx]->getPtr())));
1099 				}
1100 				break;
1101 			}
1102 			case OP_SERIALIZE:
1103 			{
1104 				for (size_t idx = 0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1105 				{
1106 					de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, *allocator, m_data.buildType, bottomBlasSerialSize[idx]));
1107 					bottomLevelAccelerationStructures[idx]->serialize(vkd, device, *cmdBuffer, storage.get());
1108 					bottomSerialized.push_back(storage);
1109 
1110 					if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1111 					{
1112 						endCommandBuffer(vkd, *cmdBuffer);
1113 
1114 						submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1115 
1116 						vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1117 						beginCommandBuffer(vkd, *cmdBuffer, 0u);
1118 					}
1119 
1120 					de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
1121 					asCopy->setBuildType(m_data.buildType);
1122 					VkDeviceAddress	deviceAddress = replay ? copyBLASAddresses[idx] : 0u;
1123 					if (replay)
1124 						asCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1125 					asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, *allocator, storage.get(), deviceAddress);
1126 					bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
1127 					if (!replay)
1128 						copyBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructureCopies[idx]->getPtr())));
1129 				}
1130 				break;
1131 			}
1132 			default:
1133 				DE_ASSERT(DE_FALSE);
1134 			}
1135 			bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies;
1136 		}
1137 
1138 		// build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures )
1139 		bool									topCompact			= m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION;
1140 		bool									topSerial			= m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION;
1141 		VkBuildAccelerationStructureFlagsKHR	topBuildFlags		= (topCompact ? allowCompactionFlag : emptyCompactionFlag);
1142 		std::vector<VkAccelerationStructureKHR> topLevelStructureHandles;
1143 		std::vector<VkDeviceSize>				topBlasCompactSize;
1144 		std::vector<VkDeviceSize>				topBlasSerialSize;
1145 
1146 		topLevelAccelerationStructure								= m_data.testConfiguration->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr);
1147 		topLevelAccelerationStructure->setBuildFlags				(topBuildFlags);
1148 		topLevelAccelerationStructure->setBuildType					(m_data.buildType);
1149 		VkDeviceAddress							deviceAddressBuild	= ( m_data.testType == TEST_ACCELERATION_STRUCTURES && replay ) ? buildTLASAddress : 0u;
1150 		if (m_data.testType == TEST_ACCELERATION_STRUCTURES && replay)
1151 			topLevelAccelerationStructure->setCreateFlags			(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1152 		topLevelAccelerationStructure->createAndBuild				(vkd, device, *cmdBuffer, *allocator, deviceAddressBuild);
1153 		topLevelStructureHandles.push_back							(*(topLevelAccelerationStructure->getPtr()));
1154 		if (m_data.testType == TEST_ACCELERATION_STRUCTURES && !replay)
1155 			buildTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructure->getPtr()));
1156 
1157 		if (topCompact)
1158 			queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize);
1159 		if (topSerial)
1160 			queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize);
1161 
1162 		// if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
1163 		if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial))
1164 		{
1165 			endCommandBuffer(vkd, *cmdBuffer);
1166 
1167 			submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1168 
1169 			if (topCompact)
1170 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(topBlasCompactSize.size()), sizeof(VkDeviceSize) * topBlasCompactSize.size(), topBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
1171 			if (topSerial)
1172 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(topBlasSerialSize.size()), sizeof(VkDeviceSize) * topBlasSerialSize.size(), topBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
1173 
1174 			vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1175 			beginCommandBuffer(vkd, *cmdBuffer, 0u);
1176 		}
1177 
1178 		const TopLevelAccelerationStructure*			topLevelRayTracedPtr	= topLevelAccelerationStructure.get();
1179 		if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION)
1180 		{
1181 			switch (m_data.operationType)
1182 			{
1183 				case OP_COPY:
1184 				{
1185 					topLevelAccelerationStructureCopy				= makeTopLevelAccelerationStructure();
1186 					topLevelAccelerationStructureCopy->setBuildType	(m_data.buildType);
1187 					VkDeviceAddress			deviceAddress			= replay ? copyTLASAddress : 0u;
1188 					if(replay)
1189 						topLevelAccelerationStructureCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1190 					topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, topLevelAccelerationStructure.get(), 0u, deviceAddress);
1191 					if (!replay)
1192 						copyTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructureCopy->getPtr()));
1193 					break;
1194 				}
1195 				case OP_COMPACT:
1196 				{
1197 					topLevelAccelerationStructureCopy				= makeTopLevelAccelerationStructure();
1198 					topLevelAccelerationStructureCopy->setBuildType	(m_data.buildType);
1199 					VkDeviceAddress			deviceAddress			= replay ? copyTLASAddress : 0u;
1200 					if(replay)
1201 						topLevelAccelerationStructureCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1202 					topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], deviceAddress);
1203 					if (!replay)
1204 						copyTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructureCopy->getPtr()));
1205 					break;
1206 				}
1207 				case OP_SERIALIZE:
1208 				{
1209 					de::SharedPtr<SerialStorage> storage( new SerialStorage(vkd, device, *allocator, m_data.buildType, topBlasSerialSize[0]));
1210 					topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get());
1211 					topSerialized.push_back(storage);
1212 
1213 					if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1214 					{
1215 						endCommandBuffer(vkd, *cmdBuffer);
1216 
1217 						submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1218 
1219 						vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1220 						beginCommandBuffer(vkd, *cmdBuffer, 0u);
1221 					}
1222 
1223 					topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
1224 					topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
1225 					VkDeviceAddress			deviceAddress			= replay ? copyTLASAddress : 0u;
1226 					if(replay)
1227 						topLevelAccelerationStructureCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1228 					topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, *allocator, storage.get(), deviceAddress);
1229 					if (!replay)
1230 						copyTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructureCopy->getPtr()));
1231 					break;
1232 				}
1233 				default:
1234 					DE_ASSERT(DE_FALSE);
1235 			}
1236 			topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get();
1237 		}
1238 
1239 		// copy layer index into uniform buffer
1240 		for (deUint32 i = 0; i < pipelineCount; ++i)
1241 		{
1242 			deMemcpy(pipelineData.pipelines[i].uniformBuffer->getAllocation().getHostPtr(), &i, sizeof(deUint32));
1243 			flushMappedMemoryRange(vkd, device, pipelineData.pipelines[i].uniformBuffer->getAllocation().getMemory(), pipelineData.pipelines[i].uniformBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1244 		}
1245 
1246 		const VkMemoryBarrier				preTraceMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
1247 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, &preTraceMemoryBarrier);
1248 
1249 		VkWriteDescriptorSetAccelerationStructureKHR							accelerationStructureWriteDescriptorSet	=
1250 		{
1251 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1252 			DE_NULL,															//  const void*							pNext;
1253 			1u,																	//  deUint32							accelerationStructureCount;
1254 			topLevelRayTracedPtr->getPtr()										//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1255 		};
1256 
1257 		for( deUint32 i=0; i<pipelineCount; ++i )
1258 		{
1259 			VkDescriptorBufferInfo	uniformBufferInfo = makeDescriptorBufferInfo(pipelineData.pipelines[i].uniformBuffer->get(), 0ull, sizeof(deUint32));
1260 
1261 			DescriptorSetUpdateBuilder()
1262 				.writeSingle(*(pipelineData.pipelines[i].descriptorSet), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferInfo)
1263 				.writeSingle(*(pipelineData.pipelines[i].descriptorSet), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
1264 				.writeSingle(*(pipelineData.pipelines[i].descriptorSet), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1265 				.update(vkd, device);
1266 
1267 			vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &(pipelineData.pipelines[i].descriptorSet.get()), 0, DE_NULL);
1268 
1269 			vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *(pipelineData.pipelines[i].pipeline));
1270 
1271 			cmdTraceRays(vkd,
1272 				*cmdBuffer,
1273 				&(pipelineData.pipelines[i].raygenShaderBindingTableRegion),
1274 				&(pipelineData.pipelines[i].missShaderBindingTableRegion),
1275 				&(pipelineData.pipelines[i].hitShaderBindingTableRegion),
1276 				&(pipelineData.pipelines[i].callableShaderBindingTableRegion),
1277 				m_data.width, m_data.height, 1);
1278 		}
1279 
1280 		const VkMemoryBarrier													postTraceMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1281 		const VkMemoryBarrier													postCopyMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1282 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
1283 
1284 		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
1285 
1286 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1287 	}
1288 	endCommandBuffer(vkd, *cmdBuffer);
1289 
1290 	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1291 
1292 	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), pixelCount * sizeof(deUint32));
1293 
1294 	std::vector<deUint32> result(pixelCount);
1295 	deMemcpy(result.data(), resultBuffer->getAllocation().getHostPtr(), pixelCount * sizeof(deUint32));
1296 	return result;
1297 }
1298 
iterate(void)1299 tcu::TestStatus RayTracingCaptureReplayTestInstance::iterate (void)
1300 {
1301 	// run test capturing different elements
1302 	const std::vector<deUint32>	captureResults		= runTest(false);
1303 
1304 	// run test that replays different elements
1305 	const std::vector<deUint32>	replayResults		= runTest(true);
1306 
1307 	if (!m_data.testConfiguration->verifyImage(captureResults, replayResults, m_context, m_data))
1308 		return tcu::TestStatus::fail("Fail");
1309 	return tcu::TestStatus::pass("Pass");
1310 }
1311 
1312 }	// anonymous
1313 
addReplayShaderBindingTablesTests(tcu::TestCaseGroup * group)1314 void addReplayShaderBindingTablesTests(tcu::TestCaseGroup* group)
1315 {
1316 	struct
1317 	{
1318 		SBTReplayTestType	testType;
1319 		const char*			name;
1320 	} testTypes[] =
1321 	{
1322 		// Capture-replay scenario with single captured pipeline
1323 		{ TEST_PIPELINE_SINGLE,		"pipeline_single"},
1324 		// Not captured pipeline created after captured one
1325 		{ TEST_PIPELINE_AFTER	,	"pipeline_after_captured"},
1326 		// Not captured pipeline created before captured one
1327 		{ TEST_PIPELINE_BEFORE,		"pipeline_before_captured"},
1328 	};
1329 
1330 	for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
1331 	{
1332 		TestParams testParams
1333 		{
1334 			testTypes[testTypeNdx].testType,
1335 			OT_NONE,
1336 			OP_NONE,
1337 			VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
1338 			BTT_TRIANGLES,
1339 			TTT_IDENTICAL_INSTANCES,
1340 			RTCR_DEFAULT_SIZE,
1341 			RTCR_DEFAULT_SIZE,
1342 			de::SharedPtr<TestConfiguration>(new TestShaderBindingTablesConfiguration())
1343 		};
1344 		group->addChild(new RayTracingCaptureReplayTestCase(group->getTestContext(), testTypes[testTypeNdx].name, testParams));
1345 	}
1346 }
1347 
addReplayAccelerationStruturesTests(tcu::TestCaseGroup * group)1348 void addReplayAccelerationStruturesTests(tcu::TestCaseGroup* group)
1349 {
1350 	struct
1351 	{
1352 		ASOperationType										operationType;
1353 		const char*											name;
1354 	} operationTypes[] =
1355 	{
1356 		{ OP_NONE,											"building"		},
1357 		{ OP_COPY,											"copy"			},
1358 		{ OP_COMPACT,										"compaction"	},
1359 		{ OP_SERIALIZE,										"serialization"	},
1360 	};
1361 
1362 	struct
1363 	{
1364 		vk::VkAccelerationStructureBuildTypeKHR				buildType;
1365 		const char*											name;
1366 	} buildTypes[] =
1367 	{
1368 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,	"cpu_built"	},
1369 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,	"gpu_built"	},
1370 	};
1371 
1372 	struct
1373 	{
1374 		ASOperationTarget									operationTarget;
1375 		const char*											name;
1376 	} operationTargets[] =
1377 	{
1378 		{ OT_TOP_ACCELERATION,								"top_acceleration_structure"		},
1379 		{ OT_BOTTOM_ACCELERATION,							"bottom_acceleration_structure"	},
1380 	};
1381 
1382 	struct
1383 	{
1384 		ASBottomTestType									testType;
1385 		const char*											name;
1386 	} bottomTestTypes[] =
1387 	{
1388 		{ BTT_TRIANGLES,									"triangles" },
1389 		{ BTT_AABBS,										"aabbs" },
1390 	};
1391 
1392 	for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx)
1393 	{
1394 		de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name));
1395 
1396 		for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
1397 		{
1398 			de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
1399 
1400 			for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets); ++operationTargetNdx)
1401 			{
1402 				de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name));
1403 
1404 				for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
1405 				{
1406 					ASTopTestType topTest = (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ? TTT_DIFFERENT_INSTANCES : TTT_IDENTICAL_INSTANCES;
1407 
1408 					TestParams testParams
1409 					{
1410 						TEST_ACCELERATION_STRUCTURES,
1411 						operationTargets[operationTargetNdx].operationTarget,
1412 						operationTypes[operationTypeNdx].operationType,
1413 						buildTypes[buildTypeNdx].buildType,
1414 						bottomTestTypes[testTypeNdx].testType,
1415 						topTest,
1416 						RTCR_DEFAULT_SIZE,
1417 						RTCR_DEFAULT_SIZE,
1418 						de::SharedPtr<TestConfiguration>(new TestAccelerationStructuresConfiguration())
1419 					};
1420 					operationTargetGroup->addChild(new RayTracingCaptureReplayTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, testParams));
1421 				}
1422 				buildGroup->addChild(operationTargetGroup.release());
1423 			}
1424 			operationTypeGroup->addChild(buildGroup.release());
1425 		}
1426 		group->addChild(operationTypeGroup.release());
1427 	}
1428 }
1429 
createCaptureReplayTests(tcu::TestContext & testCtx)1430 tcu::TestCaseGroup*	createCaptureReplayTests(tcu::TestContext& testCtx)
1431 {
1432 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "capture_replay"));
1433 
1434 	// Test replaying shader binding tables
1435 	addTestGroup(group.get(), "shader_binding_tables", addReplayShaderBindingTablesTests);
1436 	// Test replaying acceleration structure
1437 	addTestGroup(group.get(), "acceleration_structures", addReplayAccelerationStruturesTests);
1438 
1439 	return group.release();
1440 }
1441 
1442 }	// RayTracing
1443 
1444 }	// vkt
1445