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 Acceleration Structure Null Handle Tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRayTracingNullASTests.hpp"
25
26 #include "vkDefs.hpp"
27
28 #include "vktTestCase.hpp"
29 #include "vktCustomInstancesDevices.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkBarrierUtil.hpp"
34 #include "vkBufferWithMemory.hpp"
35 #include "vkImageWithMemory.hpp"
36 #include "vkTypeUtil.hpp"
37
38 #include "vkRayTracingUtil.hpp"
39
40 #include "tcuCommandLine.hpp"
41
42 #include "deClock.h"
43
44 namespace vkt
45 {
46 namespace RayTracing
47 {
48 namespace
49 {
50 using namespace vk;
51 using namespace std;
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 struct CaseDef
58 {
59 uint32_t width;
60 uint32_t height;
61 };
62
63 enum ShaderGroups
64 {
65 FIRST_GROUP = 0,
66 RAYGEN_GROUP = FIRST_GROUP,
67 MISS_GROUP,
68 HIT_GROUP,
69 GROUP_COUNT
70 };
71
getShaderGroupSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)72 uint32_t getShaderGroupSize(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
73 {
74 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
75
76 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
77 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
78 }
79
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)80 uint32_t getShaderGroupBaseAlignment(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
81 {
82 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
83
84 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
85 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
86 }
87
makePipeline(const DeviceInterface & vkd,const VkDevice device,vk::BinaryCollection & collection,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,VkPipelineLayout pipelineLayout,const uint32_t raygenGroup,const uint32_t missGroup,const uint32_t hitGroup)88 Move<VkPipeline> makePipeline(const DeviceInterface &vkd, const VkDevice device, vk::BinaryCollection &collection,
89 de::MovePtr<RayTracingPipeline> &rayTracingPipeline, VkPipelineLayout pipelineLayout,
90 const uint32_t raygenGroup, const uint32_t missGroup, const uint32_t hitGroup)
91 {
92 Move<VkShaderModule> raygenShader = createShaderModule(vkd, device, collection.get("rgen"), 0);
93 Move<VkShaderModule> hitShader = createShaderModule(vkd, device, collection.get("ahit"), 0);
94 Move<VkShaderModule> missShader = createShaderModule(vkd, device, collection.get("miss"), 0);
95 Move<VkShaderModule> intersectionShader = createShaderModule(vkd, device, collection.get("sect"), 0);
96
97 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, raygenShader, raygenGroup);
98 rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, hitShader, hitGroup);
99 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, missShader, missGroup);
100 rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, intersectionShader, hitGroup);
101
102 Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout);
103
104 return pipeline;
105 }
106
makeImageCreateInfo(uint32_t width,uint32_t height,VkFormat format)107 VkImageCreateInfo makeImageCreateInfo(uint32_t width, uint32_t height, VkFormat format)
108 {
109 const VkImageUsageFlags usage =
110 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
111 const VkImageCreateInfo imageCreateInfo = {
112 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
113 DE_NULL, // const void* pNext;
114 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
115 VK_IMAGE_TYPE_2D, // VkImageType imageType;
116 format, // VkFormat format;
117 makeExtent3D(width, height, 1u), // VkExtent3D extent;
118 1u, // uint32_t mipLevels;
119 1u, // uint32_t arrayLayers;
120 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
121 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
122 usage, // VkImageUsageFlags usage;
123 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
124 0u, // uint32_t queueFamilyIndexCount;
125 DE_NULL, // const uint32_t* pQueueFamilyIndices;
126 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
127 };
128
129 return imageCreateInfo;
130 }
131
132 struct TestDeviceFeatures
133 {
134 VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features;
135 VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingPipelineFeatures;
136 VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures;
137 VkPhysicalDeviceBufferDeviceAddressFeaturesKHR deviceAddressFeatures;
138 VkPhysicalDeviceFeatures2 deviceFeatures;
139
linkStructuresvkt::RayTracing::__anone37731020111::TestDeviceFeatures140 void linkStructures()
141 {
142 robustness2Features.pNext = nullptr;
143 rayTracingPipelineFeatures.pNext = &robustness2Features;
144 accelerationStructureFeatures.pNext = &rayTracingPipelineFeatures;
145 deviceAddressFeatures.pNext = &accelerationStructureFeatures;
146 deviceFeatures.pNext = &deviceAddressFeatures;
147 }
148
TestDeviceFeaturesvkt::RayTracing::__anone37731020111::TestDeviceFeatures149 TestDeviceFeatures(const InstanceInterface &vki, VkPhysicalDevice physicalDevice)
150 {
151 robustness2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
152 rayTracingPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
153 accelerationStructureFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
154 deviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
155 deviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
156
157 linkStructures();
158 vki.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);
159 }
160 };
161
162 struct DeviceHelper
163 {
164 Move<VkDevice> device;
165 de::MovePtr<DeviceDriver> vkd;
166 uint32_t queueFamilyIndex;
167 VkQueue queue;
168 de::MovePtr<SimpleAllocator> allocator;
169
DeviceHelpervkt::RayTracing::__anone37731020111::DeviceHelper170 DeviceHelper(Context &context)
171 {
172 const auto &vkp = context.getPlatformInterface();
173 const auto &vki = context.getInstanceInterface();
174 const auto instance = context.getInstance();
175 const auto physicalDevice = context.getPhysicalDevice();
176 const auto queuePriority = 1.0f;
177
178 // Queue index first.
179 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
180
181 // Get device features (these have already been checked in the test case).
182 TestDeviceFeatures features(vki, physicalDevice);
183 features.linkStructures();
184
185 // Make sure uneeded robustness features are disabled.
186 features.deviceFeatures.features.robustBufferAccess = VK_FALSE;
187 features.robustness2Features.robustBufferAccess2 = VK_FALSE;
188 features.robustness2Features.robustImageAccess2 = VK_FALSE;
189
190 const VkDeviceQueueCreateInfo queueInfo = {
191 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
192 nullptr, // const void* pNext;
193 0u, // VkDeviceQueueCreateFlags flags;
194 queueFamilyIndex, // uint32_t queueFamilyIndex;
195 1u, // uint32_t queueCount;
196 &queuePriority, // const float* pQueuePriorities;
197 };
198
199 // Required extensions.
200 std::vector<const char *> requiredExtensions;
201 requiredExtensions.push_back("VK_KHR_ray_tracing_pipeline");
202 requiredExtensions.push_back("VK_KHR_acceleration_structure");
203 requiredExtensions.push_back("VK_KHR_buffer_device_address");
204 requiredExtensions.push_back("VK_KHR_deferred_host_operations");
205 requiredExtensions.push_back("VK_EXT_descriptor_indexing");
206 requiredExtensions.push_back("VK_KHR_spirv_1_4");
207 requiredExtensions.push_back("VK_KHR_shader_float_controls");
208 requiredExtensions.push_back("VK_EXT_robustness2");
209
210 const VkDeviceCreateInfo createInfo = {
211 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
212 features.deviceFeatures.pNext, // const void* pNext;
213 0u, // VkDeviceCreateFlags flags;
214 1u, // uint32_t queueCreateInfoCount;
215 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
216 0u, // uint32_t enabledLayerCount;
217 nullptr, // const char* const* ppEnabledLayerNames;
218 static_cast<uint32_t>(requiredExtensions.size()), // uint32_t enabledExtensionCount;
219 requiredExtensions.data(), // const char* const* ppEnabledExtensionNames;
220 &features.deviceFeatures.features, // const VkPhysicalDeviceFeatures* pEnabledFeatures;
221 };
222
223 // Create custom device and related objects.
224 device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki,
225 physicalDevice, &createInfo);
226 vkd = de::MovePtr<DeviceDriver>(new DeviceDriver(vkp, instance, device.get(), context.getUsedApiVersion(),
227 context.getTestContext().getCommandLine()));
228 queue = getDeviceQueue(*vkd, *device, queueFamilyIndex, 0u);
229 allocator = de::MovePtr<SimpleAllocator>(
230 new SimpleAllocator(*vkd, device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
231 }
232 };
233
234 class RayTracingBuildTestInstance : public TestInstance
235 {
236 public:
237 RayTracingBuildTestInstance(Context &context, const CaseDef &data);
238 ~RayTracingBuildTestInstance(void);
239 tcu::TestStatus iterate(void);
240
241 protected:
242 uint32_t validateBuffer(de::MovePtr<BufferWithMemory> buffer);
243 de::MovePtr<BufferWithMemory> runTest(DeviceHelper &deviceHelper);
244
245 private:
246 CaseDef m_data;
247 };
248
RayTracingBuildTestInstance(Context & context,const CaseDef & data)249 RayTracingBuildTestInstance::RayTracingBuildTestInstance(Context &context, const CaseDef &data)
250 : vkt::TestInstance(context)
251 , m_data(data)
252 {
253 }
254
~RayTracingBuildTestInstance(void)255 RayTracingBuildTestInstance::~RayTracingBuildTestInstance(void)
256 {
257 }
258
259 class RayTracingTestCase : public TestCase
260 {
261 public:
262 RayTracingTestCase(tcu::TestContext &context, const char *name, const CaseDef data);
263 ~RayTracingTestCase(void);
264
265 virtual void initPrograms(SourceCollections &programCollection) const;
266 virtual TestInstance *createInstance(Context &context) const;
267 virtual void checkSupport(Context &context) const;
268
269 private:
270 CaseDef m_data;
271 };
272
RayTracingTestCase(tcu::TestContext & context,const char * name,const CaseDef data)273 RayTracingTestCase::RayTracingTestCase(tcu::TestContext &context, const char *name, const CaseDef data)
274 : vkt::TestCase(context, name)
275 , m_data(data)
276 {
277 }
278
~RayTracingTestCase(void)279 RayTracingTestCase::~RayTracingTestCase(void)
280 {
281 }
282
checkSupport(Context & context) const283 void RayTracingTestCase::checkSupport(Context &context) const
284 {
285 const auto &vki = context.getInstanceInterface();
286 const auto physicalDevice = context.getPhysicalDevice();
287
288 if (!context.isDeviceFunctionalitySupported("VK_KHR_ray_tracing_pipeline"))
289 TCU_THROW(NotSupportedError, "VK_KHR_ray_tracing_pipeline not supported");
290
291 // VK_KHR_acceleration_structure is required by VK_KHR_ray_tracing_pipeline.
292 if (!context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
293 TCU_FAIL("VK_KHR_acceleration_structure not supported but VK_KHR_ray_tracing_pipeline supported");
294
295 // VK_KHR_deferred_host_operations is required by VK_KHR_ray_tracing_pipeline.
296 if (!context.isDeviceFunctionalitySupported("VK_KHR_deferred_host_operations"))
297 TCU_FAIL("VK_KHR_deferred_host_operations not supported but VK_KHR_ray_tracing_pipeline supported");
298
299 // VK_KHR_buffer_device_address is required by VK_KHR_acceleration_structure.
300 if (!context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
301 TCU_FAIL("VK_KHR_buffer_device_address not supported but VK_KHR_acceleration_structure supported");
302
303 if (!context.isDeviceFunctionalitySupported("VK_EXT_robustness2"))
304 TCU_THROW(NotSupportedError, "VK_EXT_robustness2 not supported");
305
306 // Required extensions supported: check features.
307 TestDeviceFeatures testFeatures(vki, physicalDevice);
308
309 if (!testFeatures.rayTracingPipelineFeatures.rayTracingPipeline)
310 TCU_THROW(NotSupportedError, "Ray tracing pipelines not supported");
311
312 if (!testFeatures.robustness2Features.nullDescriptor)
313 TCU_THROW(NotSupportedError, "Null descriptors not supported");
314 }
315
initPrograms(SourceCollections & programCollection) const316 void RayTracingTestCase::initPrograms(SourceCollections &programCollection) const
317 {
318 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
319
320 programCollection.glslSources.add("rgen")
321 << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
322
323 {
324 std::stringstream css;
325 css << "#version 460 core\n"
326 "#extension GL_EXT_nonuniform_qualifier : enable\n"
327 "#extension GL_EXT_ray_tracing : require\n"
328 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
329 "hitAttributeEXT vec3 hitAttribute;\n"
330 "void main()\n"
331 "{\n"
332 " reportIntersectionEXT(1.0f, 0);\n"
333 " uvec4 color = uvec4(1,0,0,1);\n"
334 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
335 "}\n";
336
337 programCollection.glslSources.add("sect")
338 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
339 }
340
341 {
342 std::stringstream css;
343 css << "#version 460 core\n"
344 "#extension GL_EXT_nonuniform_qualifier : enable\n"
345 "#extension GL_EXT_ray_tracing : require\n"
346 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
347 "hitAttributeEXT vec3 attribs;\n"
348 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
349 "void main()\n"
350 "{\n"
351 " uvec4 color = uvec4(2,0,0,1);\n"
352 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
353 "}\n";
354
355 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
356 }
357
358 {
359 std::stringstream css;
360 css << "#version 460 core\n"
361 "#extension GL_EXT_nonuniform_qualifier : enable\n"
362 "#extension GL_EXT_ray_tracing : require\n"
363 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
364 "hitAttributeEXT vec3 attribs;\n"
365 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
366 "void main()\n"
367 "{\n"
368 " uvec4 color = uvec4(3,0,0,1);\n"
369 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
370 "}\n";
371
372 programCollection.glslSources.add("chit")
373 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
374 }
375
376 {
377 std::stringstream css;
378 css << "#version 460 core\n"
379 "#extension GL_EXT_nonuniform_qualifier : enable\n"
380 "#extension GL_EXT_ray_tracing : require\n"
381 "layout(location = 0) rayPayloadInEXT vec3 unusedPayload;\n"
382 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
383 "void main()\n"
384 "{\n"
385 " uvec4 color = uvec4(4,0,0,1);\n"
386 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
387 "}\n";
388
389 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
390 }
391 }
392
createInstance(Context & context) const393 TestInstance *RayTracingTestCase::createInstance(Context &context) const
394 {
395 return new RayTracingBuildTestInstance(context, m_data);
396 }
397
runTest(DeviceHelper & deviceHelper)398 de::MovePtr<BufferWithMemory> RayTracingBuildTestInstance::runTest(DeviceHelper &deviceHelper)
399 {
400 const InstanceInterface &vki = m_context.getInstanceInterface();
401 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
402 const DeviceDriver &vkd = *deviceHelper.vkd;
403 const VkDevice device = *deviceHelper.device;
404 const uint32_t queueFamilyIndex = deviceHelper.queueFamilyIndex;
405 const VkQueue queue = deviceHelper.queue;
406 SimpleAllocator &allocator = *deviceHelper.allocator;
407 const VkFormat format = VK_FORMAT_R32_UINT;
408 const uint32_t pixelCount = m_data.width * m_data.height;
409 const uint32_t shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
410 const uint32_t shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
411
412 const Move<VkDescriptorSetLayout> descriptorSetLayout =
413 DescriptorSetLayoutBuilder()
414 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
415 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
416 .build(vkd, device);
417 const Move<VkDescriptorPool> descriptorPool =
418 DescriptorPoolBuilder()
419 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
420 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
421 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
422 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
423 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
424 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
425 const Move<VkCommandBuffer> cmdBuffer =
426 allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
427
428 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
429 const Move<VkPipeline> pipeline = makePipeline(vkd, device, m_context.getBinaryCollection(), rayTracingPipeline,
430 *pipelineLayout, RAYGEN_GROUP, MISS_GROUP, HIT_GROUP);
431 const de::MovePtr<BufferWithMemory> raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
432 vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, RAYGEN_GROUP, 1u);
433 const de::MovePtr<BufferWithMemory> missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
434 vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, MISS_GROUP, 1u);
435 const de::MovePtr<BufferWithMemory> hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
436 vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, HIT_GROUP, 1u);
437
438 const VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion =
439 makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0),
440 shaderGroupHandleSize, shaderGroupHandleSize);
441 const VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion =
442 makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0),
443 shaderGroupHandleSize, shaderGroupHandleSize);
444 const VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion =
445 makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0),
446 shaderGroupHandleSize, shaderGroupHandleSize);
447 const VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion =
448 makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
449
450 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, format);
451 const VkImageSubresourceRange imageSubresourceRange =
452 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
453 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(
454 new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
455 const Move<VkImageView> imageView =
456 makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_2D, format, imageSubresourceRange);
457
458 const VkBufferCreateInfo bufferCreateInfo =
459 makeBufferCreateInfo(pixelCount * sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
460 const VkImageSubresourceLayers bufferImageSubresourceLayers =
461 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
462 const VkBufferImageCopy bufferImageRegion =
463 makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 1u), bufferImageSubresourceLayers);
464 de::MovePtr<BufferWithMemory> buffer = de::MovePtr<BufferWithMemory>(
465 new BufferWithMemory(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
466
467 const VkDescriptorImageInfo descriptorImageInfo =
468 makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
469
470 const VkImageMemoryBarrier preImageBarrier =
471 makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
472 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
473 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(
474 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
475 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
476 const VkMemoryBarrier postTraceMemoryBarrier =
477 makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
478 const VkMemoryBarrier postCopyMemoryBarrier =
479 makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
480 const VkClearValue clearValue = makeClearValueColorU32(5u, 5u, 5u, 255u);
481 const VkAccelerationStructureKHR topLevelAccelerationStructure = DE_NULL;
482
483 beginCommandBuffer(vkd, *cmdBuffer, 0u);
484 {
485 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
486 VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
487 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1,
488 &imageSubresourceRange);
489 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
490 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, &postImageBarrier);
491
492 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
493 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
494 DE_NULL, // const void* pNext;
495 1u, // uint32_t accelerationStructureCount;
496 &topLevelAccelerationStructure, // const VkAccelerationStructureKHR* pAccelerationStructures;
497 };
498
499 DescriptorSetUpdateBuilder()
500 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
501 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
502 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
503 VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
504 .update(vkd, device);
505
506 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1,
507 &descriptorSet.get(), 0, DE_NULL);
508
509 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
510
511 cmdTraceRays(vkd, *cmdBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion,
512 &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, m_data.width, m_data.height, 1);
513
514 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
515 VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
516
517 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **buffer, 1u, &bufferImageRegion);
518
519 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
520 &postCopyMemoryBarrier);
521 }
522 endCommandBuffer(vkd, *cmdBuffer);
523
524 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
525
526 invalidateMappedMemoryRange(vkd, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(),
527 pixelCount * sizeof(uint32_t));
528
529 return buffer;
530 }
531
validateBuffer(de::MovePtr<BufferWithMemory> buffer)532 uint32_t RayTracingBuildTestInstance::validateBuffer(de::MovePtr<BufferWithMemory> buffer)
533 {
534 const uint32_t *bufferPtr = (uint32_t *)buffer->getAllocation().getHostPtr();
535 const uint32_t expectedValue = 4;
536 uint32_t failures = 0;
537 uint32_t pos = 0;
538
539 for (uint32_t y = 0; y < m_data.height; ++y)
540 for (uint32_t x = 0; x < m_data.width; ++x)
541 {
542 if (bufferPtr[pos] != expectedValue)
543 failures++;
544
545 ++pos;
546 }
547
548 return failures;
549 }
550
iterate(void)551 tcu::TestStatus RayTracingBuildTestInstance::iterate(void)
552 {
553 DeviceHelper deviceHelper(m_context);
554 de::MovePtr<BufferWithMemory> buffer = runTest(deviceHelper);
555 const uint32_t failures = validateBuffer(buffer);
556
557 if (failures == 0)
558 return tcu::TestStatus::pass("Pass");
559 else
560 return tcu::TestStatus::fail("failures=" + de::toString(failures));
561 }
562
563 } // namespace
564
createNullAccelerationStructureTests(tcu::TestContext & testCtx)565 tcu::TestCaseGroup *createNullAccelerationStructureTests(tcu::TestContext &testCtx)
566 {
567 // Null Acceleration Structure is accepted as 'always miss' case
568 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "null_as"));
569
570 const CaseDef caseDef = {
571 8, // uint32_t width;
572 8, // uint32_t height;
573 };
574 group->addChild(new RayTracingTestCase(testCtx, "test", caseDef));
575
576 return group.release();
577 }
578
579 } // namespace RayTracing
580 } // namespace vkt
581