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::__anon42e00cfd0111::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.getBufferDeviceAddress( device, &deviceAddressInfo);
398 deviceAddressInfo.buffer = pipelineData.pipelines[0].missShaderBindingTable->get();
399 sbtSavedMissAddress = vkd.getBufferDeviceAddress( device, &deviceAddressInfo);
400 deviceAddressInfo.buffer = pipelineData.pipelines[0].hitShaderBindingTable->get();
401 sbtSavedHitAddress = vkd.getBufferDeviceAddress( 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 char* desc, 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 char * desc,const TestParams & data)778 RayTracingCaptureReplayTestCase::RayTracingCaptureReplayTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data)
779 : vkt::TestCase (context, name, desc)
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
removeExtensions(const std::vector<std::string> & a,const std::vector<const char * > & b)897 std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
898 {
899 std::vector<std::string> res;
900 std::set<std::string> removeExts (b.begin(), b.end());
901
902 for (std::vector<std::string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
903 {
904 if (!de::contains(removeExts, *aIter))
905 res.push_back(*aIter);
906 }
907 return res;
908 }
909
createInstance(Context & context) const910 TestInstance* RayTracingCaptureReplayTestCase::createInstance (Context& context) const
911 {
912 return new RayTracingCaptureReplayTestInstance(context, m_data);
913 }
914
RayTracingCaptureReplayTestInstance(Context & context,const TestParams & data)915 RayTracingCaptureReplayTestInstance::RayTracingCaptureReplayTestInstance (Context& context, const TestParams& data)
916 : vkt::TestInstance (context)
917 , m_data (data)
918 {
919 }
920
~RayTracingCaptureReplayTestInstance(void)921 RayTracingCaptureReplayTestInstance::~RayTracingCaptureReplayTestInstance (void)
922 {
923 }
924
runTest(bool replay)925 std::vector<deUint32> RayTracingCaptureReplayTestInstance::runTest(bool replay)
926 {
927 const deUint32 NO_MATCH_FOUND = ~((deUint32)0);
928
929 // For this test we need to create separate device with ray tracing features and buffer device address features enabled
930 const PlatformInterface& vkp = m_context.getPlatformInterface();
931 const InstanceInterface& vki = m_context.getInstanceInterface();
932 const VkInstance instance = m_context.getInstance();
933 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
934 const auto validationEnabled = m_context.getTestContext().getCommandLine().isValidationEnabled();
935
936 VkQueue queue = DE_NULL;
937 deUint32 queueFamilyIndex = NO_MATCH_FOUND;
938
939 std::vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
940 for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
941 {
942 if (queueFamilyProperties[queueNdx].queueFlags & ( VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT ))
943 {
944 if (queueFamilyIndex == NO_MATCH_FOUND)
945 queueFamilyIndex = queueNdx;
946 }
947 }
948 if (queueFamilyIndex == NO_MATCH_FOUND)
949 TCU_THROW(NotSupportedError, "Could not create queue");
950
951 const float queuePriority = 1.0f;
952 VkDeviceQueueCreateInfo queueInfo;
953 deMemset(&queueInfo, 0, sizeof(queueInfo));
954 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
955 queueInfo.pNext = DE_NULL;
956 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
957 queueInfo.queueFamilyIndex = queueFamilyIndex;
958 queueInfo.queueCount = 1;
959 queueInfo.pQueuePriorities = &queuePriority;
960
961 VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingFeaturesKHR;
962 rayTracingFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
963 rayTracingFeaturesKHR.pNext = DE_NULL;
964
965 VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeaturesKHR;
966 accelerationStructureFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
967 accelerationStructureFeaturesKHR.pNext = &rayTracingFeaturesKHR;
968
969 VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures;
970 bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
971 bufferDeviceAddressFeatures.pNext = &accelerationStructureFeaturesKHR;
972
973 VkPhysicalDeviceFeatures2 deviceFeatures2;
974 deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
975 deviceFeatures2.pNext = &bufferDeviceAddressFeatures;
976 vki.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);
977
978 // skip core device extensions according to API version
979 std::vector<const char*> coreExtensions;
980 getCoreDeviceExtensions(m_context.getUsedApiVersion(), coreExtensions);
981 std::vector<std::string> nonCoreDeviceExtensions (removeExtensions(m_context.getDeviceExtensions(), coreExtensions));
982 std::vector<const char*> nonCoreDeviceExtensionsC;
983
984 // ppEnabledExtensionNames must not contain both VK_KHR_buffer_device_address and VK_EXT_buffer_device_address
985 if ( ( de::contains(begin(coreExtensions), end(coreExtensions), "VK_KHR_buffer_device_address") ||
986 de::contains(begin(nonCoreDeviceExtensions), end(nonCoreDeviceExtensions), "VK_KHR_buffer_device_address") ) &&
987 de::contains(begin(nonCoreDeviceExtensions), end(nonCoreDeviceExtensions), "VK_EXT_buffer_device_address") )
988 std::for_each(begin(nonCoreDeviceExtensions), end(nonCoreDeviceExtensions), [&nonCoreDeviceExtensionsC](const std::string& text) { if (text != "VK_EXT_buffer_device_address") nonCoreDeviceExtensionsC.push_back(text.c_str()); });
989 else
990 std::for_each(begin(nonCoreDeviceExtensions), end(nonCoreDeviceExtensions), [&nonCoreDeviceExtensionsC](const std::string& text) { nonCoreDeviceExtensionsC.push_back(text.c_str()); });
991
992 VkDeviceCreateInfo deviceInfo;
993 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
994 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
995 deviceInfo.pNext = &deviceFeatures2;
996 deviceInfo.enabledExtensionCount = deUint32(nonCoreDeviceExtensionsC.size());
997 deviceInfo.ppEnabledExtensionNames = nonCoreDeviceExtensionsC.data();
998 deviceInfo.enabledLayerCount = 0u;
999 deviceInfo.ppEnabledLayerNames = DE_NULL;
1000 deviceInfo.pEnabledFeatures = DE_NULL;
1001 deviceInfo.queueCreateInfoCount = 1;
1002 deviceInfo.pQueueCreateInfos = &queueInfo;
1003 Move<VkDevice> testDevice = createCustomDevice(validationEnabled, vkp, m_context.getInstance(), vki, physicalDevice, &deviceInfo);
1004 VkDevice device = *testDevice;
1005 DeviceDriver vkd (vkp, instance, device);
1006
1007 vkd.getDeviceQueue(device, queueFamilyIndex, 0, &queue);
1008
1009 // create memory allocator for new VkDevice
1010 VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physicalDevice);
1011 de::UniquePtr<vk::Allocator> allocator (new SimpleAllocator(vkd, device, memoryProperties));
1012
1013 // Create common pipeline layout for all raytracing pipelines
1014 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
1015 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ALL_RAY_TRACING_STAGES)
1016 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1017 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1018 .build(vkd, device);
1019 deUint32 pipelineCount = (!replay || ( m_data.testType == TEST_PIPELINE_SINGLE) || (m_data.testType == TEST_ACCELERATION_STRUCTURES)) ? 1u : 2u;
1020 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
1021 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pipelineCount)
1022 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, pipelineCount)
1023 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, pipelineCount)
1024 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, pipelineCount);
1025 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
1026
1027 // All pipelines will be using the same set of shaders and shader groups.
1028 // Single RayTracingPipeline object will be enough to define it
1029 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1030 m_data.testConfiguration->initRayTracingShaders(rayTracingPipeline, m_context, vkd, device, m_data, replay);
1031
1032 // Capture phase ( replay==false ):
1033 // - TEST_ACCELERATION_STRUCTURES:
1034 // - build/copy/compact/serialize structure, record addresses
1035 // - TEST_PIPELINE_SINGLE:
1036 // - TEST_PIPELINE_AFTER:
1037 // - TEST_PIPELINE_BEFORE:
1038 // - single pipeline records addresses and fills test data
1039 // Replay phase ( replay==true ):
1040 // - TEST_ACCELERATION_STRUCTURES:
1041 // - build/copy/compact/serialize structure with addresses captured previously
1042 // - TEST_PIPELINE_SINGLE:
1043 // - single pipeline with addresses captured previously - writes into first image layer
1044 // - TEST_PIPELINE_AFTER:
1045 // - first pipeline with addresses captured previously - writes into first image layer
1046 // - second pipeline created without captured addresses - writes into second image layer
1047 // - TEST_PIPELINE_BEFORE:
1048 // - first pipeline created without captured addresses - writes into first image layer
1049 // - second pipeline with addresses captured previously - writes into second image layer
1050 //
1051 // Comparing results in all tests: all layers must be identical to the layer from capture phase
1052
1053 PipelineData pipelineData(*allocator);
1054 pipelineData.pipelineLayout = *pipelineLayout;
1055 pipelineData.descriptorSetLayout = *descriptorSetLayout;
1056 pipelineData.descriptorPool = *descriptorPool;
1057 const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
1058 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1059 m_data.testConfiguration->initShaderBindingTables(rayTracingPipeline, m_context, vkd, device, m_data, shaderGroupHandleSize, shaderGroupBaseAlignment, pipelineData, replay);
1060
1061 const VkFormat imageFormat = m_data.testConfiguration->getResultImageFormat();
1062 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, pipelineCount, imageFormat);
1063 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
1064 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, *allocator, imageCreateInfo, MemoryRequirement::Any));
1065 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
1066 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1067
1068 const deUint32 pixelCount = m_data.width * m_data.height * pipelineCount;
1069 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(pixelCount*m_data.testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1070 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1071 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, pipelineCount), resultBufferImageSubresourceLayers);
1072 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, *allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
1073
1074 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
1075 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1076
1077 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures;
1078 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
1079 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructureCopies;
1080 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructureCopy;
1081 std::vector<de::SharedPtr<SerialStorage>> bottomSerialized;
1082 std::vector<de::SharedPtr<SerialStorage>> topSerialized;
1083 Move<VkQueryPool> m_queryPoolCompact;
1084 Move<VkQueryPool> m_queryPoolSerial;
1085
1086 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1087 {
1088 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1089 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1090 **image, imageSubresourceRange);
1091 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1092 const VkClearValue clearValue = m_data.testConfiguration->getClearValue();
1093 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1094 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1095 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1096 **image, imageSubresourceRange);
1097 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1098
1099 // build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures )
1100 bool bottomCompact = m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
1101 bool bottomSerial = m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
1102 bottomLevelAccelerationStructures = m_data.testConfiguration->initBottomAccelerationStructures(m_context, m_data);
1103 VkBuildAccelerationStructureFlagsKHR allowCompactionFlag = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
1104 VkBuildAccelerationStructureFlagsKHR emptyCompactionFlag = VkBuildAccelerationStructureFlagsKHR(0);
1105 VkBuildAccelerationStructureFlagsKHR bottomBuildFlags = (bottomCompact ? allowCompactionFlag : emptyCompactionFlag);
1106 std::vector<VkAccelerationStructureKHR> accelerationStructureHandles;
1107 std::vector<VkDeviceSize> bottomBlasCompactSize;
1108 std::vector<VkDeviceSize> bottomBlasSerialSize;
1109
1110 for (size_t idx=0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1111 {
1112 bottomLevelAccelerationStructures[idx]->setBuildFlags (bottomBuildFlags);
1113 bottomLevelAccelerationStructures[idx]->setBuildType (m_data.buildType);
1114 VkDeviceAddress deviceAddress = ( m_data.testType == TEST_ACCELERATION_STRUCTURES && replay ) ? buildBLASAddresses[idx] : 0u;
1115 if ( m_data.testType == TEST_ACCELERATION_STRUCTURES && replay )
1116 bottomLevelAccelerationStructures[idx]->setCreateFlags ( VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1117 bottomLevelAccelerationStructures[idx]->createAndBuild (vkd, device, *cmdBuffer, *allocator, deviceAddress);
1118 accelerationStructureHandles.push_back (*(bottomLevelAccelerationStructures[idx]->getPtr()));
1119 if (m_data.testType == TEST_ACCELERATION_STRUCTURES && !replay)
1120 buildBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructures[idx]->getPtr())));
1121 }
1122
1123 if (m_data.operationType == OP_COMPACT)
1124 {
1125 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
1126 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1127 m_queryPoolCompact = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount);
1128 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
1129 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize);
1130 }
1131 if (m_data.operationType == OP_SERIALIZE)
1132 {
1133 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
1134 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1135 m_queryPoolSerial = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
1136 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
1137 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize);
1138 }
1139
1140 // 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
1141 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial))
1142 {
1143 endCommandBuffer(vkd, *cmdBuffer);
1144
1145 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1146
1147 if (bottomCompact)
1148 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));
1149 if (bottomSerial)
1150 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));
1151
1152 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1153 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1154 }
1155
1156 auto bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructures;
1157 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION)
1158 {
1159 switch (m_data.operationType)
1160 {
1161 case OP_COPY:
1162 {
1163 for (size_t idx = 0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1164 {
1165 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
1166 asCopy->setBuildType(m_data.buildType);
1167 VkDeviceAddress deviceAddress = replay ? copyBLASAddresses[idx] : 0u;
1168 if (replay)
1169 asCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1170 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, bottomLevelAccelerationStructures[idx].get(), 0u, deviceAddress);
1171 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
1172 if (!replay)
1173 copyBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructureCopies[idx]->getPtr())));
1174 }
1175 break;
1176 }
1177 case OP_COMPACT:
1178 {
1179 for (size_t idx = 0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1180 {
1181 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
1182 asCopy->setBuildType(m_data.buildType);
1183 VkDeviceAddress deviceAddress = replay ? copyBLASAddresses[idx] : 0u;
1184 if (replay)
1185 asCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1186 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, bottomLevelAccelerationStructures[idx].get(), bottomBlasCompactSize[idx], deviceAddress);
1187 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
1188 if (!replay)
1189 copyBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructureCopies[idx]->getPtr())));
1190 }
1191 break;
1192 }
1193 case OP_SERIALIZE:
1194 {
1195 for (size_t idx = 0; idx < bottomLevelAccelerationStructures.size(); ++idx)
1196 {
1197 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, *allocator, m_data.buildType, bottomBlasSerialSize[idx]));
1198 bottomLevelAccelerationStructures[idx]->serialize(vkd, device, *cmdBuffer, storage.get());
1199 bottomSerialized.push_back(storage);
1200
1201 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1202 {
1203 endCommandBuffer(vkd, *cmdBuffer);
1204
1205 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1206
1207 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1208 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1209 }
1210
1211 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
1212 asCopy->setBuildType(m_data.buildType);
1213 VkDeviceAddress deviceAddress = replay ? copyBLASAddresses[idx] : 0u;
1214 if (replay)
1215 asCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1216 asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, *allocator, storage.get(), deviceAddress);
1217 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
1218 if (!replay)
1219 copyBLASAddresses.push_back(getAccelerationStructureDeviceAddress(vkd, device, *(bottomLevelAccelerationStructureCopies[idx]->getPtr())));
1220 }
1221 break;
1222 }
1223 default:
1224 DE_ASSERT(DE_FALSE);
1225 }
1226 bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies;
1227 }
1228
1229 // build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures )
1230 bool topCompact = m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION;
1231 bool topSerial = m_data.testType == TEST_ACCELERATION_STRUCTURES && m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION;
1232 VkBuildAccelerationStructureFlagsKHR topBuildFlags = (topCompact ? allowCompactionFlag : emptyCompactionFlag);
1233 std::vector<VkAccelerationStructureKHR> topLevelStructureHandles;
1234 std::vector<VkDeviceSize> topBlasCompactSize;
1235 std::vector<VkDeviceSize> topBlasSerialSize;
1236
1237 topLevelAccelerationStructure = m_data.testConfiguration->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr);
1238 topLevelAccelerationStructure->setBuildFlags (topBuildFlags);
1239 topLevelAccelerationStructure->setBuildType (m_data.buildType);
1240 VkDeviceAddress deviceAddressBuild = ( m_data.testType == TEST_ACCELERATION_STRUCTURES && replay ) ? buildTLASAddress : 0u;
1241 if (m_data.testType == TEST_ACCELERATION_STRUCTURES && replay)
1242 topLevelAccelerationStructure->setCreateFlags (VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1243 topLevelAccelerationStructure->createAndBuild (vkd, device, *cmdBuffer, *allocator, deviceAddressBuild);
1244 topLevelStructureHandles.push_back (*(topLevelAccelerationStructure->getPtr()));
1245 if (m_data.testType == TEST_ACCELERATION_STRUCTURES && !replay)
1246 buildTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructure->getPtr()));
1247
1248 if (topCompact)
1249 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize);
1250 if (topSerial)
1251 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize);
1252
1253 // 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
1254 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial))
1255 {
1256 endCommandBuffer(vkd, *cmdBuffer);
1257
1258 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1259
1260 if (topCompact)
1261 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));
1262 if (topSerial)
1263 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));
1264
1265 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1266 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1267 }
1268
1269 const TopLevelAccelerationStructure* topLevelRayTracedPtr = topLevelAccelerationStructure.get();
1270 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION)
1271 {
1272 switch (m_data.operationType)
1273 {
1274 case OP_COPY:
1275 {
1276 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
1277 topLevelAccelerationStructureCopy->setBuildType (m_data.buildType);
1278 VkDeviceAddress deviceAddress = replay ? copyTLASAddress : 0u;
1279 if(replay)
1280 topLevelAccelerationStructureCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1281 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, topLevelAccelerationStructure.get(), 0u, deviceAddress);
1282 if (!replay)
1283 copyTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructureCopy->getPtr()));
1284 break;
1285 }
1286 case OP_COMPACT:
1287 {
1288 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
1289 topLevelAccelerationStructureCopy->setBuildType (m_data.buildType);
1290 VkDeviceAddress deviceAddress = replay ? copyTLASAddress : 0u;
1291 if(replay)
1292 topLevelAccelerationStructureCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1293 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, *allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], deviceAddress);
1294 if (!replay)
1295 copyTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructureCopy->getPtr()));
1296 break;
1297 }
1298 case OP_SERIALIZE:
1299 {
1300 de::SharedPtr<SerialStorage> storage( new SerialStorage(vkd, device, *allocator, m_data.buildType, topBlasSerialSize[0]));
1301 topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get());
1302 topSerialized.push_back(storage);
1303
1304 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
1305 {
1306 endCommandBuffer(vkd, *cmdBuffer);
1307
1308 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1309
1310 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
1311 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1312 }
1313
1314 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
1315 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
1316 VkDeviceAddress deviceAddress = replay ? copyTLASAddress : 0u;
1317 if(replay)
1318 topLevelAccelerationStructureCopy->setCreateFlags(VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR);
1319 topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, *allocator, storage.get(), deviceAddress);
1320 if (!replay)
1321 copyTLASAddress = getAccelerationStructureDeviceAddress(vkd, device, *(topLevelAccelerationStructureCopy->getPtr()));
1322 break;
1323 }
1324 default:
1325 DE_ASSERT(DE_FALSE);
1326 }
1327 topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get();
1328 }
1329
1330 // copy layer index into uniform buffer
1331 for (deUint32 i = 0; i < pipelineCount; ++i)
1332 {
1333 deMemcpy(pipelineData.pipelines[i].uniformBuffer->getAllocation().getHostPtr(), &i, sizeof(deUint32));
1334 flushMappedMemoryRange(vkd, device, pipelineData.pipelines[i].uniformBuffer->getAllocation().getMemory(), pipelineData.pipelines[i].uniformBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1335 }
1336
1337 const VkMemoryBarrier preTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
1338 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, &preTraceMemoryBarrier);
1339
1340 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1341 {
1342 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1343 DE_NULL, // const void* pNext;
1344 1u, // deUint32 accelerationStructureCount;
1345 topLevelRayTracedPtr->getPtr() // const VkAccelerationStructureKHR* pAccelerationStructures;
1346 };
1347
1348 for( deUint32 i=0; i<pipelineCount; ++i )
1349 {
1350 VkDescriptorBufferInfo uniformBufferInfo = makeDescriptorBufferInfo(pipelineData.pipelines[i].uniformBuffer->get(), 0ull, sizeof(deUint32));
1351
1352 DescriptorSetUpdateBuilder()
1353 .writeSingle(*(pipelineData.pipelines[i].descriptorSet), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferInfo)
1354 .writeSingle(*(pipelineData.pipelines[i].descriptorSet), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
1355 .writeSingle(*(pipelineData.pipelines[i].descriptorSet), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1356 .update(vkd, device);
1357
1358 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &(pipelineData.pipelines[i].descriptorSet.get()), 0, DE_NULL);
1359
1360 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *(pipelineData.pipelines[i].pipeline));
1361
1362 cmdTraceRays(vkd,
1363 *cmdBuffer,
1364 &(pipelineData.pipelines[i].raygenShaderBindingTableRegion),
1365 &(pipelineData.pipelines[i].missShaderBindingTableRegion),
1366 &(pipelineData.pipelines[i].hitShaderBindingTableRegion),
1367 &(pipelineData.pipelines[i].callableShaderBindingTableRegion),
1368 m_data.width, m_data.height, 1);
1369 }
1370
1371 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1372 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1373 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
1374
1375 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
1376
1377 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1378 }
1379 endCommandBuffer(vkd, *cmdBuffer);
1380
1381 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1382
1383 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), pixelCount * sizeof(deUint32));
1384
1385 std::vector<deUint32> result(pixelCount);
1386 deMemcpy(result.data(), resultBuffer->getAllocation().getHostPtr(), pixelCount * sizeof(deUint32));
1387 return result;
1388 }
1389
iterate(void)1390 tcu::TestStatus RayTracingCaptureReplayTestInstance::iterate (void)
1391 {
1392 // run test capturing different elements
1393 const std::vector<deUint32> captureResults = runTest(false);
1394
1395 // run test that replays different elements
1396 const std::vector<deUint32> replayResults = runTest(true);
1397
1398 if (!m_data.testConfiguration->verifyImage(captureResults, replayResults, m_context, m_data))
1399 return tcu::TestStatus::fail("Fail");
1400 return tcu::TestStatus::pass("Pass");
1401 }
1402
1403 } // anonymous
1404
addReplayShaderBindingTablesTests(tcu::TestCaseGroup * group)1405 void addReplayShaderBindingTablesTests(tcu::TestCaseGroup* group)
1406 {
1407 struct
1408 {
1409 SBTReplayTestType testType;
1410 const char* name;
1411 const char* description;
1412 } testTypes[] =
1413 {
1414 { TEST_PIPELINE_SINGLE, "pipeline_single", "Capture-replay scenario with single captured pipeline" },
1415 { TEST_PIPELINE_AFTER , "pipeline_after_captured", "Not captured pipeline created after captured one" },
1416 { TEST_PIPELINE_BEFORE, "pipeline_before_captured", "Not captured pipeline created before captured one" },
1417 };
1418
1419 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
1420 {
1421 TestParams testParams
1422 {
1423 testTypes[testTypeNdx].testType,
1424 OT_NONE,
1425 OP_NONE,
1426 VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
1427 BTT_TRIANGLES,
1428 TTT_IDENTICAL_INSTANCES,
1429 RTCR_DEFAULT_SIZE,
1430 RTCR_DEFAULT_SIZE,
1431 de::SharedPtr<TestConfiguration>(new TestShaderBindingTablesConfiguration())
1432 };
1433 group->addChild(new RayTracingCaptureReplayTestCase(group->getTestContext(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, testParams));
1434 }
1435 }
1436
addReplayAccelerationStruturesTests(tcu::TestCaseGroup * group)1437 void addReplayAccelerationStruturesTests(tcu::TestCaseGroup* group)
1438 {
1439 struct
1440 {
1441 ASOperationType operationType;
1442 const char* name;
1443 } operationTypes[] =
1444 {
1445 { OP_NONE, "building" },
1446 { OP_COPY, "copy" },
1447 { OP_COMPACT, "compaction" },
1448 { OP_SERIALIZE, "serialization" },
1449 };
1450
1451 struct
1452 {
1453 vk::VkAccelerationStructureBuildTypeKHR buildType;
1454 const char* name;
1455 } buildTypes[] =
1456 {
1457 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
1458 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
1459 };
1460
1461 struct
1462 {
1463 ASOperationTarget operationTarget;
1464 const char* name;
1465 } operationTargets[] =
1466 {
1467 { OT_TOP_ACCELERATION, "top_acceleration_structure" },
1468 { OT_BOTTOM_ACCELERATION, "bottom_acceleration_structure" },
1469 };
1470
1471 struct
1472 {
1473 ASBottomTestType testType;
1474 const char* name;
1475 } bottomTestTypes[] =
1476 {
1477 { BTT_TRIANGLES, "triangles" },
1478 { BTT_AABBS, "aabbs" },
1479 };
1480
1481 for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx)
1482 {
1483 de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name, ""));
1484
1485 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
1486 {
1487 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
1488
1489 for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets); ++operationTargetNdx)
1490 {
1491 de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name, ""));
1492
1493 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
1494 {
1495 ASTopTestType topTest = (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ? TTT_DIFFERENT_INSTANCES : TTT_IDENTICAL_INSTANCES;
1496
1497 TestParams testParams
1498 {
1499 TEST_ACCELERATION_STRUCTURES,
1500 operationTargets[operationTargetNdx].operationTarget,
1501 operationTypes[operationTypeNdx].operationType,
1502 buildTypes[buildTypeNdx].buildType,
1503 bottomTestTypes[testTypeNdx].testType,
1504 topTest,
1505 RTCR_DEFAULT_SIZE,
1506 RTCR_DEFAULT_SIZE,
1507 de::SharedPtr<TestConfiguration>(new TestAccelerationStructuresConfiguration())
1508 };
1509 operationTargetGroup->addChild(new RayTracingCaptureReplayTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, "", testParams));
1510 }
1511 buildGroup->addChild(operationTargetGroup.release());
1512 }
1513 operationTypeGroup->addChild(buildGroup.release());
1514 }
1515 group->addChild(operationTypeGroup.release());
1516 }
1517 }
1518
createCaptureReplayTests(tcu::TestContext & testCtx)1519 tcu::TestCaseGroup* createCaptureReplayTests(tcu::TestContext& testCtx)
1520 {
1521 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "capture_replay", "Capture-replay capabilities"));
1522
1523 addTestGroup(group.get(), "shader_binding_tables", "Test replaying shader binding tables", addReplayShaderBindingTablesTests);
1524 addTestGroup(group.get(), "acceleration_structures", "Test replaying acceleration structure", addReplayAccelerationStruturesTests);
1525
1526 return group.release();
1527 }
1528
1529 } // RayTracing
1530
1531 } // vkt
1532