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