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