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