1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 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 binding tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktBindingDescriptorUpdateASTests.hpp"
25
26 #include "vkDefs.hpp"
27
28 #include "vktTestCase.hpp"
29 #include "vktTestGroupUtil.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 #include "vkImageUtil.hpp"
38 #include "deRandom.hpp"
39 #include "tcuTexture.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "tcuCommandLine.hpp"
44
45 #include "vkRayTracingUtil.hpp"
46
47 namespace vkt
48 {
49 namespace BindingModel
50 {
51 namespace
52 {
53 using namespace vk;
54 using namespace vkt;
55
56 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
57 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
58 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
59 | VK_SHADER_STAGE_MISS_BIT_KHR
60 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
61 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
62
63 enum TestType
64 {
65 TEST_TYPE_USING_RAY_QUERY = 0,
66 TEST_TYPE_USING_RAY_TRACING,
67 };
68
69 enum UpdateMethod
70 {
71 UPDATE_METHOD_NORMAL = 0, //!< use vkUpdateDescriptorSets vkUpdateDescriptorSets
72 UPDATE_METHOD_WITH_TEMPLATE, //!< use descriptor update templates vkUpdateDescriptorSetWithTemplate
73 UPDATE_METHOD_WITH_PUSH, //!< use push descriptor updates vkCmdPushDescriptorSetKHR
74 UPDATE_METHOD_WITH_PUSH_TEMPLATE, //!< use push descriptor update templates vkCmdPushDescriptorSetWithTemplateKHR
75
76 UPDATE_METHOD_LAST
77 };
78
79 const deUint32 TEST_WIDTH = 16u;
80 const deUint32 TEST_HEIGHT = 16u;
81 const deUint32 FIXED_POINT_DIVISOR = 1024 * 1024;
82 const float PLAIN_Z0 = 2.0f;
83 const float PLAIN_Z1 = 4.0f;
84
85 struct TestParams;
86
87 typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams);
88 typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams);
89 typedef const std::string (*ShaderBodyTextFunc)(const TestParams& testParams);
90
91 struct TestParams
92 {
93 deUint32 width;
94 deUint32 height;
95 deUint32 depth;
96 TestType testType;
97 UpdateMethod updateMethod;
98 VkShaderStageFlagBits stage;
99 VkFormat format;
100 CheckSupportFunc pipelineCheckSupport;
101 InitProgramsFunc pipelineInitPrograms;
102 ShaderBodyTextFunc testConfigShaderBodyText;
103 };
104
105
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)106 static deUint32 getShaderGroupHandleSize (const InstanceInterface& vki,
107 const VkPhysicalDevice physicalDevice)
108 {
109 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
110
111 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
112
113 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
114 }
115
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)116 static deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
117 const VkPhysicalDevice physicalDevice)
118 {
119 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
120
121 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
122
123 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
124 }
125
getVkBuffer(const de::MovePtr<BufferWithMemory> & buffer)126 static VkBuffer getVkBuffer (const de::MovePtr<BufferWithMemory>& buffer)
127 {
128 VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get();
129
130 return result;
131 }
132
makeStridedDeviceAddressRegion(const DeviceInterface & vkd,const VkDevice device,VkBuffer buffer,deUint32 stride,deUint32 count)133 static VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, deUint32 stride, deUint32 count)
134 {
135 if (buffer == DE_NULL)
136 {
137 return makeStridedDeviceAddressRegionKHR(0, 0, 0);
138 }
139 else
140 {
141 return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), stride, stride * count);
142 }
143 }
144
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout0,const VkDescriptorSetLayout descriptorSetLayout1,const VkDescriptorSetLayout descriptorSetLayoutOpt=DE_NULL)145 static Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
146 const VkDevice device,
147 const VkDescriptorSetLayout descriptorSetLayout0,
148 const VkDescriptorSetLayout descriptorSetLayout1,
149 const VkDescriptorSetLayout descriptorSetLayoutOpt = DE_NULL)
150 {
151 std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
152
153 descriptorSetLayouts.push_back(descriptorSetLayout0);
154 descriptorSetLayouts.push_back(descriptorSetLayout1);
155
156 if (descriptorSetLayoutOpt != DE_NULL)
157 descriptorSetLayouts.push_back(descriptorSetLayoutOpt);
158
159 return makePipelineLayout(vk, device, (deUint32)descriptorSetLayouts.size(), descriptorSetLayouts.data());
160 }
161
makeWriteDescriptorSetAccelerationStructureKHR(const VkAccelerationStructureKHR * accelerationStructureKHR)162 static VkWriteDescriptorSetAccelerationStructureKHR makeWriteDescriptorSetAccelerationStructureKHR (const VkAccelerationStructureKHR* accelerationStructureKHR)
163 {
164 const VkWriteDescriptorSetAccelerationStructureKHR result =
165 {
166 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
167 DE_NULL, // const void* pNext;
168 1u, // deUint32 accelerationStructureCount;
169 accelerationStructureKHR // const VkAccelerationStructureKHR* pAccelerationStructures;
170 };
171
172 return result;
173 }
174
isPushUpdateMethod(const UpdateMethod updateMethod)175 static bool isPushUpdateMethod (const UpdateMethod updateMethod)
176 {
177 switch (updateMethod)
178 {
179 case UPDATE_METHOD_NORMAL: return false;
180 case UPDATE_METHOD_WITH_TEMPLATE: return false;
181 case UPDATE_METHOD_WITH_PUSH: return true;
182 case UPDATE_METHOD_WITH_PUSH_TEMPLATE: return true;
183 default: TCU_THROW(InternalError, "Unknown update method");
184 }
185 }
186
isTemplateUpdateMethod(const UpdateMethod updateMethod)187 static bool isTemplateUpdateMethod (const UpdateMethod updateMethod)
188 {
189 switch (updateMethod)
190 {
191 case UPDATE_METHOD_NORMAL: return false;
192 case UPDATE_METHOD_WITH_TEMPLATE: return true;
193 case UPDATE_METHOD_WITH_PUSH: return false;
194 case UPDATE_METHOD_WITH_PUSH_TEMPLATE: return true;
195 default: TCU_THROW(InternalError, "Unknown update method");
196 }
197 }
198
makeDescriptorSet(const DeviceInterface & vki,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout,UpdateMethod updateMethod)199 static Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vki,
200 const VkDevice device,
201 const VkDescriptorPool descriptorPool,
202 const VkDescriptorSetLayout setLayout,
203 UpdateMethod updateMethod)
204 {
205 const bool pushUpdateMethod = isPushUpdateMethod(updateMethod);
206 Move<VkDescriptorSet> descriptorSet = pushUpdateMethod
207 ? vk::Move<vk::VkDescriptorSet>()
208 : vk::makeDescriptorSet(vki, device, descriptorPool, setLayout, DE_NULL);
209
210 return descriptorSet;
211 }
212
makeImageCreateInfo(VkFormat format,deUint32 width,deUint32 height,deUint32 depth,VkImageType imageType=VK_IMAGE_TYPE_3D,VkImageUsageFlags usageFlags=VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)213 static VkImageCreateInfo makeImageCreateInfo (VkFormat format,
214 deUint32 width,
215 deUint32 height,
216 deUint32 depth,
217 VkImageType imageType = VK_IMAGE_TYPE_3D,
218 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
219 {
220 const VkImageCreateInfo imageCreateInfo =
221 {
222 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
223 DE_NULL, // const void* pNext;
224 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
225 imageType, // VkImageType imageType;
226 format, // VkFormat format;
227 makeExtent3D(width, height, depth), // VkExtent3D extent;
228 1u, // deUint32 mipLevels;
229 1u, // deUint32 arrayLayers;
230 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
231 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
232 usageFlags, // VkImageUsageFlags usage;
233 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
234 0u, // deUint32 queueFamilyIndexCount;
235 DE_NULL, // const deUint32* pQueueFamilyIndices;
236 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
237 };
238
239 return imageCreateInfo;
240 }
241
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule)242 static Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
243 const VkDevice device,
244 const VkPipelineLayout pipelineLayout,
245 const VkShaderModule shaderModule)
246 {
247 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
248 {
249 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
250 DE_NULL, // const void* pNext;
251 0u, // VkPipelineShaderStageCreateFlags flags;
252 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
253 shaderModule, // VkShaderModule module;
254 "main", // const char* pName;
255 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
256 };
257 const VkComputePipelineCreateInfo pipelineCreateInfo =
258 {
259 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
260 DE_NULL, // const void* pNext;
261 0u, // VkPipelineCreateFlags flags;
262 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage;
263 pipelineLayout, // VkPipelineLayout layout;
264 DE_NULL, // VkPipeline basePipelineHandle;
265 0, // deInt32 basePipelineIndex;
266 };
267
268 return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
269 }
270
getMissPassthrough(void)271 static const std::string getMissPassthrough (void)
272 {
273 std::ostringstream src;
274
275 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
276 << "#extension GL_EXT_ray_tracing : require\n"
277 << "\n"
278 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
279 << "\n"
280 << "void main()\n"
281 << "{\n"
282 << "}\n";
283
284 return src.str();
285 }
286
getHitPassthrough(void)287 static const std::string getHitPassthrough (void)
288 {
289 std::ostringstream src;
290
291 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
292 << "#extension GL_EXT_ray_tracing : require\n"
293 << "hitAttributeEXT vec3 attribs;\n"
294 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
295 << "\n"
296 << "void main()\n"
297 << "{\n"
298 << "}\n";
299
300 return src.str();
301 }
302
getGraphicsPassthrough(void)303 static const std::string getGraphicsPassthrough (void)
304 {
305 std::ostringstream src;
306
307 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
308 << "\n"
309 << "void main(void)\n"
310 << "{\n"
311 << "}\n";
312
313 return src.str();
314 }
315
getVertexPassthrough(void)316 static const std::string getVertexPassthrough (void)
317 {
318 std::ostringstream src;
319
320 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
321 << "\n"
322 << "layout(location = 0) in vec4 in_position;\n"
323 << "\n"
324 << "void main(void)\n"
325 << "{\n"
326 << " gl_Position = in_position;\n"
327 << "}\n";
328
329 return src.str();
330 }
331
getDescriptorSetLayoutCreateFlags(const UpdateMethod updateMethod)332 static VkDescriptorSetLayoutCreateFlags getDescriptorSetLayoutCreateFlags(const UpdateMethod updateMethod)
333 {
334 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
335
336 if (updateMethod == UPDATE_METHOD_WITH_PUSH_TEMPLATE || updateMethod == UPDATE_METHOD_WITH_PUSH)
337 {
338 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
339 }
340
341 return extraFlags;
342 }
343
344 class BindingAcceleratioStructureTestInstance : public TestInstance
345 {
346 public:
347 BindingAcceleratioStructureTestInstance (Context& context,
348 const TestParams& testParams);
~BindingAcceleratioStructureTestInstance()349 virtual ~BindingAcceleratioStructureTestInstance () {}
350 virtual tcu::TestStatus iterate (void);
351
352 protected:
353 virtual void initPipeline (void) = 0;
354 virtual deUint32 getExtraAccelerationDescriptorCount (void) = 0;
355 virtual VkShaderStageFlags getShaderStageFlags (void) = 0;
356 virtual VkPipelineBindPoint getPipelineBindPoint (void) = 0;
357
358 virtual void fillCommandBuffer (VkCommandBuffer commandBuffer) = 0;
359
360 virtual const VkAccelerationStructureKHR* createAccelerationStructures (Context& context,
361 TestParams& testParams);
362 virtual void buildAccelerationStructures (Context& context,
363 TestParams& testParams,
364 VkCommandBuffer commandBuffer);
365 virtual bool verify (BufferWithMemory* resultBuffer,
366 Context& context,
367 TestParams& testParams);
368
369 TestParams m_testParams;
370
371 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> m_bottomAccelerationStructures;
372 de::SharedPtr<TopLevelAccelerationStructure> m_topAccelerationStructure;
373
374 Move<VkDescriptorPool> m_descriptorPool;
375
376 Move<VkDescriptorSetLayout> m_descriptorSetLayoutImg;
377 Move<VkDescriptorSet> m_descriptorSetImg;
378
379 Move<VkDescriptorSetLayout> m_descriptorSetLayoutAS;
380 Move<VkDescriptorSet> m_descriptorSetAS;
381
382 Move<VkPipelineLayout> m_pipelineLayout;
383 Move<VkPipeline> m_pipeline;
384
385 Move<VkDescriptorUpdateTemplate> m_updateTemplate;
386 };
387
BindingAcceleratioStructureTestInstance(Context & context,const TestParams & testParams)388 BindingAcceleratioStructureTestInstance::BindingAcceleratioStructureTestInstance (Context& context, const TestParams& testParams)
389 : TestInstance (context)
390 , m_testParams (testParams)
391 , m_bottomAccelerationStructures ()
392 , m_topAccelerationStructure ()
393 , m_descriptorPool ()
394 , m_descriptorSetLayoutImg ()
395 , m_descriptorSetImg ()
396 , m_descriptorSetLayoutAS ()
397 , m_descriptorSetAS ()
398 , m_pipelineLayout ()
399 , m_pipeline ()
400 , m_updateTemplate ()
401 {
402 }
403
iterate(void)404 tcu::TestStatus BindingAcceleratioStructureTestInstance::iterate (void)
405 {
406 const DeviceInterface& vkd = m_context.getDeviceInterface();
407 const VkDevice device = m_context.getDevice();
408 const VkQueue queue = m_context.getUniversalQueue();
409 Allocator& allocator = m_context.getDefaultAllocator();
410 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
411 const bool templateUpdateMethod = isTemplateUpdateMethod(m_testParams.updateMethod);
412 const bool pushUpdateMethod = isPushUpdateMethod(m_testParams.updateMethod);
413
414 const deUint32 width = m_testParams.width;
415 const deUint32 height = m_testParams.height;
416 const deUint32 depth = m_testParams.depth;
417 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_testParams.format, width, height, depth);
418 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
419 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
420 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_testParams.format, imageSubresourceRange);
421
422 const deUint32 pixelSize = mapVkFormat(m_testParams.format).getPixelSize();
423 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
424 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
425 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
426 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
427 const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
428
429 const Move<VkCommandPool> commandPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
430 const Move<VkCommandBuffer> commandBuffer = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
431 const VkAccelerationStructureKHR* topAccelerationStructurePtr = createAccelerationStructures(m_context, m_testParams);
432 const VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure = makeWriteDescriptorSetAccelerationStructureKHR(topAccelerationStructurePtr);
433 const deUint32 accelerationStructureDescriptorCount = 1 + getExtraAccelerationDescriptorCount();
434 deUint32 updateCount = 0;
435
436 m_descriptorPool = DescriptorPoolBuilder()
437 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
438 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, accelerationStructureDescriptorCount)
439 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u + accelerationStructureDescriptorCount);
440
441 m_descriptorSetLayoutImg = DescriptorSetLayoutBuilder()
442 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, getShaderStageFlags())
443 .build(vkd, device);
444 m_descriptorSetImg = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutImg);
445
446 DescriptorSetUpdateBuilder()
447 .writeSingle(*m_descriptorSetImg, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
448 .update(vkd, device);
449
450 m_descriptorSetLayoutAS = DescriptorSetLayoutBuilder()
451 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, getShaderStageFlags())
452 .build(vkd, device, getDescriptorSetLayoutCreateFlags(m_testParams.updateMethod));
453 m_descriptorSetAS = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutAS, m_testParams.updateMethod);
454
455 initPipeline();
456
457 if (m_testParams.updateMethod == UPDATE_METHOD_NORMAL)
458 {
459 DescriptorSetUpdateBuilder()
460 .writeSingle(*m_descriptorSetAS, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeDescriptorSetAccelerationStructure)
461 .update(vkd, device);
462
463 updateCount++;
464 }
465
466 if (templateUpdateMethod)
467 {
468 const VkDescriptorUpdateTemplateType updateTemplateType = isPushUpdateMethod(m_testParams.updateMethod)
469 ? VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR
470 : VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET;
471 const VkDescriptorUpdateTemplateEntry updateTemplateEntry =
472 {
473 0, // deUint32 dstBinding;
474 0, // deUint32 dstArrayElement;
475 1, // deUint32 descriptorCount;
476 VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, // VkDescriptorType descriptorType;
477 0, // deUintptr offset;
478 0, // deUintptr stride;
479 };
480 const VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
481 {
482 VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR, // VkStructureType sType;
483 DE_NULL, // const void* pNext;
484 0, // VkDescriptorUpdateTemplateCreateFlags flags;
485 1, // deUint32 descriptorUpdateEntryCount;
486 &updateTemplateEntry, // const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries;
487 updateTemplateType, // VkDescriptorUpdateTemplateType templateType;
488 *m_descriptorSetLayoutAS, // VkDescriptorSetLayout descriptorSetLayout;
489 getPipelineBindPoint(), // VkPipelineBindPoint pipelineBindPoint;
490 *m_pipelineLayout, // VkPipelineLayout pipelineLayout;
491 0, // deUint32 set;
492 };
493
494 m_updateTemplate = vk::createDescriptorUpdateTemplate(vkd, device, &templateCreateInfo);
495
496 if (!pushUpdateMethod)
497 {
498 vkd.updateDescriptorSetWithTemplate(device, *m_descriptorSetAS, *m_updateTemplate, topAccelerationStructurePtr);
499
500 updateCount++;
501 }
502 }
503
504 beginCommandBuffer(vkd, *commandBuffer, 0u);
505 {
506 {
507 const VkClearValue clearValue = makeClearValueColorU32(0u, 0u, 0u, 0u);
508 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
509 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
510
511 cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
512 vkd.cmdClearColorImage(*commandBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
513 cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
514
515 vkd.cmdBindDescriptorSets(*commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 1, 1, &m_descriptorSetImg.get(), 0, DE_NULL);
516 }
517
518 switch (m_testParams.updateMethod)
519 {
520 case UPDATE_METHOD_NORMAL: // fallthrough
521 case UPDATE_METHOD_WITH_TEMPLATE:
522 {
523 vkd.cmdBindDescriptorSets(*commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 0, 1, &m_descriptorSetAS.get(), 0, DE_NULL);
524
525 break;
526 }
527
528 case UPDATE_METHOD_WITH_PUSH:
529 {
530 DescriptorSetUpdateBuilder()
531 .writeSingle(*m_descriptorSetAS, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeDescriptorSetAccelerationStructure)
532 .updateWithPush(vkd, *commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 0, 0, 1);
533
534 updateCount++;
535
536 break;
537 }
538
539 case UPDATE_METHOD_WITH_PUSH_TEMPLATE:
540 {
541 vkd.cmdPushDescriptorSetWithTemplateKHR(*commandBuffer, *m_updateTemplate, *m_pipelineLayout, 0, topAccelerationStructurePtr);
542
543 updateCount++;
544
545 break;
546 }
547
548 default: TCU_THROW(InternalError, "Unknown update method");
549 }
550
551 {
552 const VkMemoryBarrier preTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
553 const VkPipelineStageFlags dstStageFlags = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
554
555 buildAccelerationStructures(m_context, m_testParams, *commandBuffer);
556
557 cmdPipelineMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, dstStageFlags, &preTraceMemoryBarrier);
558 }
559
560 fillCommandBuffer(*commandBuffer);
561
562 {
563 const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
564
565 cmdPipelineMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
566 }
567
568 vkd.cmdCopyImageToBuffer(*commandBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
569 }
570 endCommandBuffer(vkd, *commandBuffer);
571
572 if (updateCount != 1)
573 TCU_THROW(InternalError, "Invalid descriptor update");
574
575 submitCommandsAndWait(vkd, device, queue, commandBuffer.get());
576
577 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
578
579 if (verify(resultBuffer.get(), m_context, m_testParams))
580 return tcu::TestStatus::pass("Pass");
581 else
582 return tcu::TestStatus::fail("Fail");
583 }
584
createAccelerationStructures(Context & context,TestParams & testParams)585 const VkAccelerationStructureKHR* BindingAcceleratioStructureTestInstance::createAccelerationStructures (Context& context,
586 TestParams& testParams)
587 {
588 DE_UNREF(testParams);
589
590 const DeviceInterface& vkd = context.getDeviceInterface();
591 const VkDevice device = context.getDevice();
592 Allocator& allocator = context.getDefaultAllocator();
593 de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
594 de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
595 std::vector<tcu::Vec3> geometryData;
596
597 // Generate in-plain square starting at (0,0,PLAIN_Z0) and ending at (1,1,PLAIN_Z1).
598 // Vertices 1,0 and 0,1 by Z axis are in the middle between PLAIN_Z0 and PLAIN_Z1
599 geometryData.push_back(tcu::Vec3(0.0f, 0.0f, PLAIN_Z0));
600 geometryData.push_back(tcu::Vec3(1.0f, 0.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
601 geometryData.push_back(tcu::Vec3(0.0f, 1.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
602 geometryData.push_back(tcu::Vec3(1.0f, 1.0f, PLAIN_Z1));
603 geometryData.push_back(tcu::Vec3(0.0f, 1.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
604 geometryData.push_back(tcu::Vec3(1.0f, 0.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
605
606 rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
607 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true);
608 rayQueryBottomLevelAccelerationStructure->create(vkd, device, allocator, 0);
609 m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
610
611 m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
612 m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
613 m_topAccelerationStructure->create(vkd, device, allocator);
614
615 return m_topAccelerationStructure.get()->getPtr();
616 }
617
buildAccelerationStructures(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer)618 void BindingAcceleratioStructureTestInstance::buildAccelerationStructures (Context& context,
619 TestParams& testParams,
620 VkCommandBuffer commandBuffer)
621 {
622 DE_UNREF(testParams);
623
624 const DeviceInterface& vkd = context.getDeviceInterface();
625 const VkDevice device = context.getDevice();
626
627 for (size_t blStructNdx = 0; blStructNdx < m_bottomAccelerationStructures.size(); ++blStructNdx)
628 m_bottomAccelerationStructures[blStructNdx]->build(vkd, device, commandBuffer);
629
630 m_topAccelerationStructure->build(vkd, device, commandBuffer);
631 }
632
verify(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)633 bool BindingAcceleratioStructureTestInstance::verify (BufferWithMemory* resultBuffer,
634 Context& context,
635 TestParams& testParams)
636 {
637 tcu::TestLog& log = context.getTestContext().getLog();
638 const deUint32 width = testParams.width;
639 const deUint32 height = testParams.height;
640 const deInt32* retrieved = (deInt32*)resultBuffer->getAllocation().getHostPtr();
641 deUint32 failures = 0;
642 deUint32 pos = 0;
643 std::vector<deInt32> expected;
644
645 expected.reserve(width * height);
646
647 for (deUint32 y = 0; y < height; ++y)
648 {
649 const float expectedY = deFloatMix(PLAIN_Z0, PLAIN_Z1, (0.5f + float(y)) / float(height));
650
651 for (deUint32 x = 0; x < width; ++x)
652 {
653 const float expectedX = deFloatMix(PLAIN_Z0, PLAIN_Z1, (0.5f + float(x)) / float(width));
654 const deInt32 expectedV = deInt32(float(FIXED_POINT_DIVISOR / 2) * (expectedX + expectedY));
655
656 expected.push_back(expectedV);
657 }
658 }
659
660 for (deUint32 y = 0; y < height; ++y)
661 for (deUint32 x = 0; x < width; ++x)
662 {
663 if (retrieved[pos] != expected[pos])
664 {
665 failures++;
666
667 if (failures < 10)
668 {
669 const deInt32 expectedValue = expected[pos];
670 const deInt32 retrievedValue = retrieved[pos];
671
672 log << tcu::TestLog::Message
673 << "At (" << x <<"," << y << ") "
674 << "expected " << std::fixed << std::setprecision(6) << std::setw(8) << float(expectedValue) / float(FIXED_POINT_DIVISOR) << " (" << expectedValue << ") "
675 << "retrieved " << std::fixed << std::setprecision(6) << std::setw(8) << float(retrievedValue) / float(FIXED_POINT_DIVISOR) << " (" << retrievedValue << ") "
676 << tcu::TestLog::EndMessage;
677 }
678 }
679
680 pos++;
681 }
682
683 if (failures != 0)
684 {
685 for (deUint32 dumpNdx = 0; dumpNdx < 2; ++dumpNdx)
686 {
687 const deInt32* data = (dumpNdx == 0) ? expected.data() : retrieved;
688 const char* dataName = (dumpNdx == 0) ? "Expected" : "Retrieved";
689 std::ostringstream css;
690
691 pos = 0;
692
693 for (deUint32 y = 0; y < height; ++y)
694 {
695 for (deUint32 x = 0; x < width; ++x)
696 {
697 if (expected[pos] != retrieved[pos])
698 css << std::fixed << std::setprecision(6) << std::setw(8) << float(data[pos]) / float(FIXED_POINT_DIVISOR) << ",";
699 else
700 css << "________,";
701
702 pos++;
703 }
704
705 css << std::endl;
706 }
707
708 log << tcu::TestLog::Message << dataName << ":" << tcu::TestLog::EndMessage;
709 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
710 }
711 }
712
713 return (failures == 0);
714 }
715
716
717 class BindingAcceleratioStructureGraphicsTestInstance : public BindingAcceleratioStructureTestInstance
718 {
719 public:
720 static void checkSupport (Context& context,
721 const TestParams& testParams);
722 static void initPrograms (SourceCollections& programCollection,
723 const TestParams& testParams);
724
725 BindingAcceleratioStructureGraphicsTestInstance (Context& context,
726 const TestParams& testParams);
~BindingAcceleratioStructureGraphicsTestInstance()727 virtual ~BindingAcceleratioStructureGraphicsTestInstance () {}
728
729 protected:
730 virtual void initPipeline (void) override;
731 virtual void fillCommandBuffer (VkCommandBuffer commandBuffer) override;
732
733 void initVertexBuffer (void);
734 Move<VkPipeline> makeGraphicsPipeline (void);
735
getExtraAccelerationDescriptorCount(void)736 virtual deUint32 getExtraAccelerationDescriptorCount (void) override { return 0; }
getShaderStageFlags(void)737 virtual VkShaderStageFlags getShaderStageFlags (void) override { return VK_SHADER_STAGE_ALL_GRAPHICS; }
getPipelineBindPoint(void)738 virtual VkPipelineBindPoint getPipelineBindPoint (void) override { return VK_PIPELINE_BIND_POINT_GRAPHICS; }
739
740 VkFormat m_framebufferFormat;
741 Move<VkImage> m_framebufferImage;
742 de::MovePtr<Allocation> m_framebufferImageAlloc;
743 Move<VkImageView> m_framebufferAttachment;
744
745 Move<VkShaderModule> m_vertShaderModule;
746 Move<VkShaderModule> m_geomShaderModule;
747 Move<VkShaderModule> m_tescShaderModule;
748 Move<VkShaderModule> m_teseShaderModule;
749 Move<VkShaderModule> m_fragShaderModule;
750
751 Move<VkRenderPass> m_renderPass;
752 Move<VkFramebuffer> m_framebuffer;
753
754 deUint32 m_vertexCount;
755 Move<VkBuffer> m_vertexBuffer;
756 de::MovePtr<Allocation> m_vertexBufferAlloc;
757 };
758
BindingAcceleratioStructureGraphicsTestInstance(Context & context,const TestParams & testParams)759 BindingAcceleratioStructureGraphicsTestInstance::BindingAcceleratioStructureGraphicsTestInstance (Context& context,
760 const TestParams& testParams)
761 : BindingAcceleratioStructureTestInstance (context, testParams)
762 , m_framebufferFormat (VK_FORMAT_R8G8B8A8_UNORM)
763 , m_framebufferImage ()
764 , m_framebufferImageAlloc ()
765 , m_framebufferAttachment ()
766 , m_vertShaderModule ()
767 , m_geomShaderModule ()
768 , m_tescShaderModule ()
769 , m_teseShaderModule ()
770 , m_fragShaderModule ()
771 , m_renderPass ()
772 , m_framebuffer ()
773 , m_vertexCount (0)
774 , m_vertexBuffer ()
775 , m_vertexBufferAlloc ()
776 {
777 }
778
checkSupport(Context & context,const TestParams & testParams)779 void BindingAcceleratioStructureGraphicsTestInstance::checkSupport (Context& context,
780 const TestParams& testParams)
781 {
782 switch (testParams.stage)
783 {
784 case VK_SHADER_STAGE_VERTEX_BIT:
785 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
786 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
787 case VK_SHADER_STAGE_GEOMETRY_BIT:
788 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
789 break;
790 default:
791 break;
792 }
793
794 switch (testParams.stage)
795 {
796 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
797 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
798 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
799 break;
800 case VK_SHADER_STAGE_GEOMETRY_BIT:
801 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
802 break;
803 default:
804 break;
805 }
806 }
807
initPrograms(SourceCollections & programCollection,const TestParams & testParams)808 void BindingAcceleratioStructureGraphicsTestInstance::initPrograms (SourceCollections& programCollection,
809 const TestParams& testParams)
810 {
811 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
812 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
813
814 switch (testParams.stage)
815 {
816 case VK_SHADER_STAGE_VERTEX_BIT:
817 {
818 {
819 std::ostringstream src;
820 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
821 << "#extension GL_EXT_ray_query : require\n"
822 << "#extension GL_EXT_ray_tracing : require\n"
823 << "\n"
824 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
825 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
826 << "\n"
827 << "void testFunc(ivec3 pos, ivec3 size)\n"
828 << "{\n"
829 << testShaderBody
830 << "}\n"
831 << "\n"
832 << "void main(void)\n"
833 << "{\n"
834 << " const int posId = int(gl_VertexIndex / 3);\n"
835 << " const int vertId = int(gl_VertexIndex % 3);\n"
836 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
837 << " const ivec3 pos = ivec3(posId % size.x, posId / size.x, 0);\n"
838 << "\n"
839 << " if (vertId == 0)\n"
840 << " {\n"
841 << " testFunc(pos, size);\n"
842 << " }\n"
843 << "}\n";
844
845 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
846 }
847
848 programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;
849
850 break;
851 }
852
853 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
854 {
855 {
856 std::ostringstream src;
857 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
858 << "\n"
859 << "layout(location = 0) in vec4 in_position;\n"
860 << "out gl_PerVertex\n"
861 << "{\n"
862 << " vec4 gl_Position;\n"
863 << "};\n"
864 << "\n"
865 << "void main(void)\n"
866 << "{\n"
867 << " gl_Position = in_position;\n"
868 << "}\n";
869
870 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
871 }
872
873 {
874 std::ostringstream src;
875 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
876 << "#extension GL_EXT_tessellation_shader : require\n"
877 << "#extension GL_EXT_ray_query : require\n"
878 << "\n"
879 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
880 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
881 << "\n"
882 << "in gl_PerVertex\n"
883 << "{\n"
884 << " vec4 gl_Position;\n"
885 << "} gl_in[];\n"
886 << "layout(vertices = 3) out;\n"
887 << "out gl_PerVertex\n"
888 << "{\n"
889 << " vec4 gl_Position;\n"
890 << "} gl_out[];\n"
891 << "\n"
892 << "void testFunc(ivec3 pos, ivec3 size)\n"
893 << "{\n"
894 << testShaderBody
895 << "}\n"
896 << "\n"
897 << "void main(void)\n"
898 << "{\n"
899 << "\n"
900 << " if (gl_InvocationID == 0)\n"
901 << " {\n"
902 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
903 << " int index = int(gl_in[gl_InvocationID].gl_Position.z);\n"
904 << " int x = index % size.x;\n"
905 << " int y = index / size.y;\n"
906 << " const ivec3 pos = ivec3(x, y, 0);\n"
907 << " testFunc(pos, size);\n"
908 << " }\n"
909 << "\n"
910 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
911 << " gl_TessLevelInner[0] = 1;\n"
912 << " gl_TessLevelInner[1] = 1;\n"
913 << " gl_TessLevelOuter[gl_InvocationID] = 1;\n"
914 << "}\n";
915
916 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
917 }
918
919 {
920 std::ostringstream src;
921 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
922 << "#extension GL_EXT_tessellation_shader : require\n"
923 << "layout(triangles, equal_spacing, ccw) in;\n"
924 << "\n"
925 << "in gl_PerVertex\n"
926 << "{\n"
927 << " vec4 gl_Position;\n"
928 << "} gl_in[];\n"
929 << "\n"
930 << "void main(void)\n"
931 << "{\n"
932 << " gl_Position = gl_in[0].gl_Position;\n"
933 << "}\n";
934
935 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
936 }
937
938 break;
939 }
940
941 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
942 {
943 {
944 std::ostringstream src;
945 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
946 << "\n"
947 << "layout(location = 0) in vec4 in_position;\n"
948 << "out gl_PerVertex"
949 << "{\n"
950 << " vec4 gl_Position;\n"
951 << "};\n"
952 << "\n"
953 << "void main(void)\n"
954 << "{\n"
955 << " gl_Position = in_position;\n"
956 << "}\n";
957
958 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
959 }
960
961 {
962 std::ostringstream src;
963 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
964 << "#extension GL_EXT_tessellation_shader : require\n"
965 << "\n"
966 << "in gl_PerVertex\n"
967 << "{\n"
968 << " vec4 gl_Position;\n"
969 << "} gl_in[];\n"
970 << "layout(vertices = 3) out;\n"
971 << "out gl_PerVertex\n"
972 << "{\n"
973 << " vec4 gl_Position;\n"
974 << "} gl_out[];\n"
975 << "\n"
976 << "void main(void)\n"
977 << "{\n"
978 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
979 << " gl_TessLevelInner[0] = 1;\n"
980 << " gl_TessLevelInner[1] = 1;\n"
981 << " gl_TessLevelOuter[gl_InvocationID] = 1;\n"
982 << "}\n";
983
984 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
985 }
986
987 {
988 std::ostringstream src;
989 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
990 << "#extension GL_EXT_tessellation_shader : require\n"
991 << "#extension GL_EXT_ray_query : require\n"
992 << "\n"
993 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
994 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
995 << "\n"
996 << "layout(triangles, equal_spacing, ccw) in;\n"
997 << "in gl_PerVertex\n"
998 << "{\n"
999 << " vec4 gl_Position;\n"
1000 << "} gl_in[];\n"
1001 << "\n"
1002 << "void testFunc(ivec3 pos, ivec3 size)\n"
1003 << "{\n"
1004 << testShaderBody
1005 << "}\n"
1006 << "\n"
1007 << "void main(void)\n"
1008 << "{\n"
1009 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
1010 << " int index = int(gl_in[0].gl_Position.z);\n"
1011 << " int x = index % size.x;\n"
1012 << " int y = index / size.y;\n"
1013 << " const ivec3 pos = ivec3(x, y, 0);\n"
1014 << " testFunc(pos, size);\n"
1015 << " gl_Position = gl_in[0].gl_Position;\n"
1016 << "}\n";
1017
1018 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
1019 }
1020
1021 break;
1022 }
1023
1024 case VK_SHADER_STAGE_GEOMETRY_BIT:
1025 {
1026 programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
1027
1028 {
1029 std::ostringstream src;
1030 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1031 << "#extension GL_EXT_ray_query : require\n"
1032 << "\n"
1033 << "layout(triangles) in;\n"
1034 << "layout(points, max_vertices = 1) out;\n"
1035 << "\n"
1036 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1037 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1038 << "\n"
1039 << "void testFunc(ivec3 pos, ivec3 size)\n"
1040 << "{\n"
1041 << testShaderBody
1042 << "}\n"
1043 << "\n"
1044 << "void main(void)\n"
1045 << "{\n"
1046 << " const int posId = int(gl_PrimitiveIDIn);\n"
1047 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
1048 << " const ivec3 pos = ivec3(posId % size.x, posId / size.x, 0);\n"
1049 << "\n"
1050 << " testFunc(pos, size);\n"
1051 << " gl_PointSize = 1.0;\n"
1052 << "}\n";
1053
1054 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str()) << buildOptions;
1055 }
1056
1057 break;
1058 }
1059
1060 case VK_SHADER_STAGE_FRAGMENT_BIT:
1061 {
1062 programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
1063
1064 {
1065 std::ostringstream src;
1066 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1067 << "#extension GL_EXT_ray_query : require\n"
1068 << "\n"
1069 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1070 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1071 << "\n"
1072 << "void testFunc(ivec3 pos, ivec3 size)\n"
1073 << "{\n"
1074 << testShaderBody
1075 << "}\n"
1076 << "\n"
1077 << "void main(void)\n"
1078 << "{\n"
1079 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
1080 << " const ivec3 pos = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
1081 << "\n"
1082 << " testFunc(pos, size);\n"
1083 << "}\n";
1084
1085 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
1086 }
1087
1088 break;
1089 }
1090
1091 default:
1092 TCU_THROW(InternalError, "Unknown stage");
1093 }
1094 }
1095
initVertexBuffer(void)1096 void BindingAcceleratioStructureGraphicsTestInstance::initVertexBuffer (void)
1097 {
1098 const DeviceInterface& vkd = m_context.getDeviceInterface();
1099 const VkDevice device = m_context.getDevice();
1100 const deUint32 width = m_testParams.width;
1101 const deUint32 height = m_testParams.height;
1102 Allocator& allocator = m_context.getDefaultAllocator();
1103 std::vector<tcu::Vec4> vertices;
1104
1105 switch (m_testParams.stage)
1106 {
1107 case VK_SHADER_STAGE_VERTEX_BIT:
1108 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1109 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1110 case VK_SHADER_STAGE_GEOMETRY_BIT:
1111 {
1112 float z = 0.0f;
1113
1114 vertices.reserve(3 * height * width);
1115
1116 for (deUint32 y = 0; y < height; ++y)
1117 for (deUint32 x = 0; x < width; ++x)
1118 {
1119 const float x0 = float(x + 0) / float(width);
1120 const float y0 = float(y + 0) / float(height);
1121 const float x1 = float(x + 1) / float(width);
1122 const float y1 = float(y + 1) / float(height);
1123 const float xm = (x0 + x1) / 2.0f;
1124 const float ym = (y0 + y1) / 2.0f;
1125
1126 vertices.push_back(tcu::Vec4(x0, y0, z, 1.0f));
1127 vertices.push_back(tcu::Vec4(xm, y1, z, 1.0f));
1128 vertices.push_back(tcu::Vec4(x1, ym, z, 1.0f));
1129
1130 z += 1.f;
1131 }
1132
1133 break;
1134 }
1135
1136 case VK_SHADER_STAGE_FRAGMENT_BIT:
1137 {
1138 const float z = 1.0f;
1139 const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, 1.0f);
1140 const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, 1.0f);
1141 const tcu::Vec4 c = tcu::Vec4(-1.0f, +1.0f, z, 1.0f);
1142 const tcu::Vec4 d = tcu::Vec4(+1.0f, +1.0f, z, 1.0f);
1143
1144 vertices.push_back(a);
1145 vertices.push_back(b);
1146 vertices.push_back(c);
1147
1148 vertices.push_back(b);
1149 vertices.push_back(c);
1150 vertices.push_back(d);
1151
1152 break;
1153 }
1154
1155 default:
1156 TCU_THROW(InternalError, "Unknown stage");
1157
1158 }
1159
1160 // Initialize vertex buffer
1161 {
1162 const VkDeviceSize vertexBufferSize = sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
1163 const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1164
1165 m_vertexCount = static_cast<deUint32>(vertices.size());
1166 m_vertexBuffer = createBuffer(vkd, device, &vertexBufferCreateInfo);
1167 m_vertexBufferAlloc = bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
1168
1169 deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
1170 flushAlloc(vkd, device, *m_vertexBufferAlloc);
1171 }
1172 }
1173
makeGraphicsPipeline(void)1174 Move<VkPipeline> BindingAcceleratioStructureGraphicsTestInstance::makeGraphicsPipeline (void)
1175 {
1176 const DeviceInterface& vkd = m_context.getDeviceInterface();
1177 const VkDevice device = m_context.getDevice();
1178 const bool tessStageTest = (m_testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
1179 const VkPrimitiveTopology topology = tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1180 const deUint32 patchControlPoints = tessStageTest ? 3 : 0;
1181 const std::vector<VkViewport> viewports (1, makeViewport(m_testParams.width, m_testParams.height));
1182 const std::vector<VkRect2D> scissors (1, makeRect2D(m_testParams.width, m_testParams.height));
1183
1184 return vk::makeGraphicsPipeline (vkd,
1185 device,
1186 *m_pipelineLayout,
1187 *m_vertShaderModule,
1188 *m_tescShaderModule,
1189 *m_teseShaderModule,
1190 *m_geomShaderModule,
1191 *m_fragShaderModule,
1192 *m_renderPass,
1193 viewports,
1194 scissors,
1195 topology,
1196 0,
1197 patchControlPoints);
1198 }
1199
initPipeline(void)1200 void BindingAcceleratioStructureGraphicsTestInstance::initPipeline (void)
1201 {
1202 const DeviceInterface& vkd = m_context.getDeviceInterface();
1203 const VkDevice device = m_context.getDevice();
1204 Allocator& allocator = m_context.getDefaultAllocator();
1205 vk::BinaryCollection& collection = m_context.getBinaryCollection();
1206 VkShaderStageFlags shaders = static_cast<VkShaderStageFlags>(0);
1207 deUint32 shaderCount = 0;
1208
1209 if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT;
1210 if (collection.contains("geom")) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
1211 if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
1212 if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
1213 if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
1214
1215 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1216 shaderCount++;
1217
1218 if (shaderCount != (deUint32)dePop32(shaders))
1219 TCU_THROW(InternalError, "Unused shaders detected in the collection");
1220
1221 if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT)) m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
1222 if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT)) m_geomShaderModule = createShaderModule(vkd, device, collection.get("geom"), 0);
1223 if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)) m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
1224 if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
1225 if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT)) m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
1226
1227 m_framebufferImage = makeImage (vkd, device, makeImageCreateInfo(m_framebufferFormat, m_testParams.width, m_testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
1228 m_framebufferImageAlloc = bindImage (vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
1229 m_framebufferAttachment = makeImageView (vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
1230 m_renderPass = makeRenderPass (vkd, device, m_framebufferFormat);
1231 m_framebuffer = makeFramebuffer (vkd, device, *m_renderPass, *m_framebufferAttachment, m_testParams.width, m_testParams.height);
1232 m_pipelineLayout = makePipelineLayout (vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get());
1233 m_pipeline = makeGraphicsPipeline ();
1234
1235 initVertexBuffer();
1236 }
1237
fillCommandBuffer(VkCommandBuffer commandBuffer)1238 void BindingAcceleratioStructureGraphicsTestInstance::fillCommandBuffer (VkCommandBuffer commandBuffer)
1239 {
1240 const DeviceInterface& vkd = m_context.getDeviceInterface();
1241 const VkDeviceSize vertexBufferOffset = 0;
1242
1243 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1244 vkd.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
1245
1246 beginRenderPass(vkd, commandBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_testParams.width, m_testParams.height), tcu::UVec4());
1247
1248 vkd.cmdDraw(commandBuffer, m_vertexCount, 1u, 0u, 0u);
1249
1250 endRenderPass(vkd, commandBuffer);
1251 }
1252
1253 class BindingAcceleratioStructureComputeTestInstance : public BindingAcceleratioStructureTestInstance
1254 {
1255 public:
1256 BindingAcceleratioStructureComputeTestInstance (Context& context,
1257 const TestParams& testParams);
1258
~BindingAcceleratioStructureComputeTestInstance()1259 virtual ~BindingAcceleratioStructureComputeTestInstance () {}
1260
1261 static void checkSupport (Context& context,
1262 const TestParams& testParams);
1263 static void initPrograms (SourceCollections& programCollection,
1264 const TestParams& testParams);
1265
1266 protected:
1267 virtual void initPipeline (void) override;
1268 virtual void fillCommandBuffer (VkCommandBuffer commandBuffer) override;
1269
getExtraAccelerationDescriptorCount(void)1270 virtual deUint32 getExtraAccelerationDescriptorCount (void) override { return 0; }
getShaderStageFlags(void)1271 virtual VkShaderStageFlags getShaderStageFlags (void) override { return VK_SHADER_STAGE_COMPUTE_BIT; }
getPipelineBindPoint(void)1272 virtual VkPipelineBindPoint getPipelineBindPoint (void) override { return VK_PIPELINE_BIND_POINT_COMPUTE; }
1273
1274 Move<VkShaderModule> m_shaderModule;
1275 };
1276
BindingAcceleratioStructureComputeTestInstance(Context & context,const TestParams & testParams)1277 BindingAcceleratioStructureComputeTestInstance::BindingAcceleratioStructureComputeTestInstance (Context& context,
1278 const TestParams& testParams)
1279 : BindingAcceleratioStructureTestInstance (context, testParams)
1280 , m_shaderModule ()
1281 {
1282 }
1283
checkSupport(Context & context,const TestParams & testParams)1284 void BindingAcceleratioStructureComputeTestInstance::checkSupport (Context& context,
1285 const TestParams& testParams)
1286 {
1287 DE_UNREF(context);
1288 DE_UNREF(testParams);
1289 }
1290
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1291 void BindingAcceleratioStructureComputeTestInstance::initPrograms (SourceCollections& programCollection,
1292 const TestParams& testParams)
1293 {
1294 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1295 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
1296 const std::string testBody =
1297 " ivec3 pos = ivec3(gl_WorkGroupID);\n"
1298 " ivec3 size = ivec3(gl_NumWorkGroups);\n"
1299 + testShaderBody;
1300
1301 switch (testParams.stage)
1302 {
1303 case VK_SHADER_STAGE_COMPUTE_BIT:
1304 {
1305 std::stringstream css;
1306 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1307 << "#extension GL_EXT_ray_query : require\n"
1308 << "\n"
1309 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1310 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1311 << "\n"
1312 << "void main()\n"
1313 << "{\n"
1314 << testBody
1315 << "}\n";
1316
1317 programCollection.glslSources.add("comp") << glu::ComputeSource(css.str()) << buildOptions;
1318
1319 break;
1320 }
1321
1322 default:
1323 TCU_THROW(InternalError, "Unknown stage");
1324 }
1325 }
1326
initPipeline(void)1327 void BindingAcceleratioStructureComputeTestInstance::initPipeline (void)
1328 {
1329 const DeviceInterface& vkd = m_context.getDeviceInterface();
1330 const VkDevice device = m_context.getDevice();
1331 vk::BinaryCollection& collection = m_context.getBinaryCollection();
1332
1333 m_shaderModule = createShaderModule(vkd, device, collection.get("comp"), 0);
1334 m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get());
1335 m_pipeline = makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
1336 }
1337
fillCommandBuffer(VkCommandBuffer commandBuffer)1338 void BindingAcceleratioStructureComputeTestInstance::fillCommandBuffer (VkCommandBuffer commandBuffer)
1339 {
1340 const DeviceInterface& vkd = m_context.getDeviceInterface();
1341
1342 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
1343
1344 vkd.cmdDispatch(commandBuffer, m_testParams.width, m_testParams.height, 1);
1345 }
1346
1347 class BindingAcceleratioStructureRayTracingTestInstance : public BindingAcceleratioStructureTestInstance
1348 {
1349 public:
1350 BindingAcceleratioStructureRayTracingTestInstance (Context& context,
1351 const TestParams& testParams);
~BindingAcceleratioStructureRayTracingTestInstance()1352 virtual ~BindingAcceleratioStructureRayTracingTestInstance () {}
1353
1354 static void checkSupport (Context& context,
1355 const TestParams& testParams);
1356 static void initPrograms (SourceCollections& programCollection,
1357 const TestParams& testParams);
1358
1359 protected:
1360 virtual void initPipeline (void) override;
1361 virtual void fillCommandBuffer (VkCommandBuffer commandBuffer) override;
1362
1363 de::MovePtr<BufferWithMemory> createShaderBindingTable (const InstanceInterface& vki,
1364 const DeviceInterface& vkd,
1365 const VkDevice device,
1366 const VkPhysicalDevice physicalDevice,
1367 const VkPipeline pipeline,
1368 Allocator& allocator,
1369 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1370 const deUint32 group);
1371
getExtraAccelerationDescriptorCount(void)1372 virtual deUint32 getExtraAccelerationDescriptorCount (void) override { return 1; }
getShaderStageFlags(void)1373 virtual VkShaderStageFlags getShaderStageFlags (void) override { return ALL_RAY_TRACING_STAGES; }
getPipelineBindPoint(void)1374 virtual VkPipelineBindPoint getPipelineBindPoint (void) override { return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; }
1375
1376 deUint32 m_shaders;
1377 deUint32 m_raygenShaderGroup;
1378 deUint32 m_missShaderGroup;
1379 deUint32 m_hitShaderGroup;
1380 deUint32 m_callableShaderGroup;
1381 deUint32 m_shaderGroupCount;
1382
1383 Move<VkDescriptorSetLayout> m_descriptorSetLayoutSvc;
1384 Move<VkDescriptorSet> m_descriptorSetSvc;
1385
1386 de::MovePtr<RayTracingPipeline> m_rayTracingPipeline;
1387
1388 de::MovePtr<BufferWithMemory> m_raygenShaderBindingTable;
1389 de::MovePtr<BufferWithMemory> m_hitShaderBindingTable;
1390 de::MovePtr<BufferWithMemory> m_missShaderBindingTable;
1391 de::MovePtr<BufferWithMemory> m_callableShaderBindingTable;
1392
1393 VkStridedDeviceAddressRegionKHR m_raygenShaderBindingTableRegion;
1394 VkStridedDeviceAddressRegionKHR m_missShaderBindingTableRegion;
1395 VkStridedDeviceAddressRegionKHR m_hitShaderBindingTableRegion;
1396 VkStridedDeviceAddressRegionKHR m_callableShaderBindingTableRegion;
1397
1398 de::SharedPtr<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructure;
1399 de::SharedPtr<TopLevelAccelerationStructure> m_topLevelAccelerationStructure;
1400 };
1401
BindingAcceleratioStructureRayTracingTestInstance(Context & context,const TestParams & testParams)1402 BindingAcceleratioStructureRayTracingTestInstance::BindingAcceleratioStructureRayTracingTestInstance (Context& context,
1403 const TestParams& testParams)
1404 : BindingAcceleratioStructureTestInstance (context, testParams)
1405 , m_shaders (0)
1406 , m_raygenShaderGroup (~0u)
1407 , m_missShaderGroup (~0u)
1408 , m_hitShaderGroup (~0u)
1409 , m_callableShaderGroup (~0u)
1410 , m_shaderGroupCount (0)
1411
1412 , m_descriptorSetLayoutSvc ()
1413 , m_descriptorSetSvc ()
1414
1415 , m_rayTracingPipeline ()
1416
1417 , m_raygenShaderBindingTable ()
1418 , m_hitShaderBindingTable ()
1419 , m_missShaderBindingTable ()
1420 , m_callableShaderBindingTable ()
1421
1422 , m_raygenShaderBindingTableRegion ()
1423 , m_missShaderBindingTableRegion ()
1424 , m_hitShaderBindingTableRegion ()
1425 , m_callableShaderBindingTableRegion ()
1426
1427 , m_bottomLevelAccelerationStructure ()
1428 , m_topLevelAccelerationStructure ()
1429 {
1430 }
1431
checkSupport(Context & context,const TestParams & testParams)1432 void BindingAcceleratioStructureRayTracingTestInstance::checkSupport (Context& context,
1433 const TestParams& testParams)
1434 {
1435 DE_UNREF(testParams);
1436
1437 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1438
1439 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1440
1441 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1442 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1443 }
1444
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1445 void BindingAcceleratioStructureRayTracingTestInstance::initPrograms (SourceCollections& programCollection,
1446 const TestParams& testParams)
1447 {
1448 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1449 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
1450 const std::string testBody =
1451 " ivec3 pos = ivec3(gl_LaunchIDEXT);\n"
1452 " ivec3 size = ivec3(gl_LaunchSizeEXT);\n"
1453 + testShaderBody;
1454 const std::string commonRayGenerationShader =
1455 std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
1456 "#extension GL_EXT_ray_tracing : require\n"
1457 "\n"
1458 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1459 "layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1460 "\n"
1461 "void main()\n"
1462 "{\n"
1463 " uint rayFlags = 0;\n"
1464 " uint cullMask = 0xFF;\n"
1465 " float tmin = 0.0;\n"
1466 " float tmax = 9.0;\n"
1467 " vec3 origin = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
1468 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1469 " traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1470 "}\n";
1471
1472 switch (testParams.stage)
1473 {
1474 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1475 {
1476 std::stringstream css;
1477 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1478 << "#extension GL_EXT_ray_tracing : require\n"
1479 << "#extension GL_EXT_ray_query : require\n"
1480 << "\n"
1481 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1482 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1483 << "\n"
1484 << "void main()\n"
1485 << "{\n"
1486 << testBody
1487 << "}\n";
1488
1489 programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str()) << buildOptions;
1490
1491 break;
1492 }
1493
1494 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1495 {
1496 programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1497
1498 {
1499 std::stringstream css;
1500 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1501 << "#extension GL_EXT_ray_tracing : require\n"
1502 << "#extension GL_EXT_ray_query : require\n"
1503 << "\n"
1504 << "hitAttributeEXT vec3 attribs;\n"
1505 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1506 << "\n"
1507 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1508 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1509 << "\n"
1510 << "void main()\n"
1511 << "{\n"
1512 << testBody
1513 << "}\n";
1514
1515 programCollection.glslSources.add("ahit") << glu::AnyHitSource(css.str()) << buildOptions;
1516 }
1517
1518 programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1519 programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1520
1521 break;
1522 }
1523
1524 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1525 {
1526 programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1527
1528 {
1529 std::stringstream css;
1530 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1531 << "#extension GL_EXT_ray_tracing : require\n"
1532 << "#extension GL_EXT_ray_query : require\n"
1533 << "\n"
1534 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1535 << "hitAttributeEXT vec3 attribs;\n"
1536 << "\n"
1537 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1538 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1539 << "\n"
1540 << "void main()\n"
1541 << "{\n"
1542 << testBody
1543 << "}\n";
1544
1545 programCollection.glslSources.add("chit") << glu::ClosestHitSource(css.str()) << buildOptions;
1546 }
1547
1548 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1549 programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1550
1551 break;
1552 }
1553
1554 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1555 {
1556 programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1557
1558 {
1559 std::stringstream css;
1560 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1561 << "#extension GL_EXT_ray_tracing : require\n"
1562 << "#extension GL_EXT_ray_query : require\n"
1563 << "hitAttributeEXT vec3 hitAttribute;\n"
1564 << "\n"
1565 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1566 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1567 << "\n"
1568 << "void main()\n"
1569 << "{\n"
1570 << testBody
1571 << " hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1572 << " reportIntersectionEXT(1.0f, 0);\n"
1573 << "}\n";
1574
1575 programCollection.glslSources.add("sect") << glu::IntersectionSource(css.str()) << buildOptions;
1576 }
1577
1578 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1579 programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1580 programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1581
1582 break;
1583 }
1584
1585 case VK_SHADER_STAGE_MISS_BIT_KHR:
1586 {
1587 programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1588
1589 {
1590 std::stringstream css;
1591 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1592 << "#extension GL_EXT_ray_tracing : require\n"
1593 << "#extension GL_EXT_ray_query : require\n"
1594 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1595 << "\n"
1596 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1597 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1598 << "\n"
1599 << "void main()\n"
1600 << "{\n"
1601 << testBody
1602 << "}\n";
1603
1604 programCollection.glslSources.add("miss") << glu::MissSource(css.str()) << buildOptions;
1605 }
1606
1607 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1608 programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1609
1610 break;
1611 }
1612
1613 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1614 {
1615 {
1616 std::stringstream css;
1617 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1618 << "#extension GL_EXT_ray_tracing : require\n"
1619 << "#extension GL_EXT_ray_query : require\n"
1620 << "\n"
1621 << "layout(location = 0) callableDataEXT float dummy;"
1622 << "layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1623 << "\n"
1624 << "void main()\n"
1625 << "{\n"
1626 << " executeCallableEXT(0, 0);\n"
1627 << "}\n";
1628
1629 programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str()) << buildOptions;
1630 }
1631
1632 {
1633 std::stringstream css;
1634 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1635 << "#extension GL_EXT_ray_tracing : require\n"
1636 << "#extension GL_EXT_ray_query : require\n"
1637 << "layout(location = 0) callableDataInEXT float dummy;"
1638 << "\n"
1639 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1640 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1641 << "\n"
1642 << "void main()\n"
1643 << "{\n"
1644 << testBody
1645 << "}\n";
1646
1647 programCollection.glslSources.add("call") << glu::CallableSource(css.str()) << buildOptions;
1648 }
1649
1650 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1651 programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1652 programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1653
1654 break;
1655 }
1656
1657 default:
1658 TCU_THROW(InternalError, "Unknown stage");
1659 }
1660 }
1661
initPipeline(void)1662 void BindingAcceleratioStructureRayTracingTestInstance::initPipeline (void)
1663 {
1664 const InstanceInterface& vki = m_context.getInstanceInterface();
1665 const DeviceInterface& vkd = m_context.getDeviceInterface();
1666 const VkDevice device = m_context.getDevice();
1667 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1668 vk::BinaryCollection& collection = m_context.getBinaryCollection();
1669 Allocator& allocator = m_context.getDefaultAllocator();
1670 const deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1671 const VkShaderStageFlags hitStages = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1672 deUint32 shaderCount = 0;
1673
1674 m_shaderGroupCount = 0;
1675
1676 if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
1677 if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
1678 if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
1679 if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
1680 if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1681 if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1682
1683 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1684 shaderCount++;
1685
1686 if (shaderCount != (deUint32)dePop32(m_shaders))
1687 TCU_THROW(InternalError, "Unused shaders detected in the collection");
1688
1689 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1690 m_raygenShaderGroup = m_shaderGroupCount++;
1691
1692 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1693 m_missShaderGroup = m_shaderGroupCount++;
1694
1695 if (0 != (m_shaders & hitStages))
1696 m_hitShaderGroup = m_shaderGroupCount++;
1697
1698 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1699 m_callableShaderGroup = m_shaderGroupCount++;
1700
1701 m_rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1702
1703 m_descriptorSetLayoutSvc = DescriptorSetLayoutBuilder()
1704 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1705 .build(vkd, device);
1706 m_descriptorSetSvc = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutSvc);
1707
1708 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR , createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
1709 if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
1710 if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
1711 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR , createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
1712 if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR , createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
1713 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR , createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup);
1714
1715 m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get(), m_descriptorSetLayoutSvc.get());
1716 m_pipeline = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
1717
1718 m_raygenShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup);
1719 m_missShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup);
1720 m_hitShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup);
1721 m_callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup);
1722
1723 m_raygenShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable), shaderGroupHandleSize, 1);
1724 m_missShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable), shaderGroupHandleSize, 1);
1725 m_hitShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable), shaderGroupHandleSize, 1);
1726 m_callableShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable), shaderGroupHandleSize, 1);
1727 }
1728
fillCommandBuffer(VkCommandBuffer commandBuffer)1729 void BindingAcceleratioStructureRayTracingTestInstance::fillCommandBuffer (VkCommandBuffer commandBuffer)
1730 {
1731 const DeviceInterface& vkd = m_context.getDeviceInterface();
1732 const VkDevice device = m_context.getDevice();
1733 Allocator& allocator = m_context.getDefaultAllocator();
1734 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1735 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1736
1737 m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
1738 m_bottomLevelAccelerationStructure->setDefaultGeometryData(m_testParams.stage);
1739 m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1740
1741 m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
1742 m_topLevelAccelerationStructure->setInstanceCount(1);
1743 m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
1744 m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1745
1746 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = m_topLevelAccelerationStructure.get();
1747 const VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = makeWriteDescriptorSetAccelerationStructureKHR(topLevelAccelerationStructurePtr->getPtr());
1748
1749 DescriptorSetUpdateBuilder()
1750 .writeSingle(*m_descriptorSetSvc, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1751 .update(vkd, device);
1752
1753 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 2, 1, &m_descriptorSetSvc.get(), 0, DE_NULL);
1754
1755 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
1756
1757 cmdTraceRays(vkd,
1758 commandBuffer,
1759 &m_raygenShaderBindingTableRegion,
1760 &m_missShaderBindingTableRegion,
1761 &m_hitShaderBindingTableRegion,
1762 &m_callableShaderBindingTableRegion,
1763 m_testParams.width, m_testParams.height, 1);
1764 }
1765
createShaderBindingTable(const InstanceInterface & vki,const DeviceInterface & vkd,const VkDevice device,const VkPhysicalDevice physicalDevice,const VkPipeline pipeline,Allocator & allocator,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,const deUint32 group)1766 de::MovePtr<BufferWithMemory> BindingAcceleratioStructureRayTracingTestInstance::createShaderBindingTable (const InstanceInterface& vki,
1767 const DeviceInterface& vkd,
1768 const VkDevice device,
1769 const VkPhysicalDevice physicalDevice,
1770 const VkPipeline pipeline,
1771 Allocator& allocator,
1772 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1773 const deUint32 group)
1774 {
1775 de::MovePtr<BufferWithMemory> shaderBindingTable;
1776
1777 if (group < m_shaderGroupCount)
1778 {
1779 const deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1780 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1781
1782 shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1783 }
1784
1785 return shaderBindingTable;
1786 }
1787
1788
1789 class BindingAcceleratioStructureRayTracingRayTracingTestInstance : public BindingAcceleratioStructureTestInstance
1790 {
1791 public:
1792 BindingAcceleratioStructureRayTracingRayTracingTestInstance (Context& context,
1793 const TestParams& testParams);
~BindingAcceleratioStructureRayTracingRayTracingTestInstance()1794 virtual ~BindingAcceleratioStructureRayTracingRayTracingTestInstance () {}
1795
1796 static void checkSupport (Context& context,
1797 const TestParams& testParams);
1798 static void initPrograms (SourceCollections& programCollection,
1799 const TestParams& testParams);
1800
1801 protected:
1802 virtual void initPipeline (void) override;
1803 virtual void fillCommandBuffer (VkCommandBuffer commandBuffer) override;
1804
1805 void calcShaderGroup (deUint32& shaderGroupCounter,
1806 const VkShaderStageFlags shaders1,
1807 const VkShaderStageFlags shaders2,
1808 const VkShaderStageFlags shaderStageFlags,
1809 deUint32& shaderGroup,
1810 deUint32& shaderGroupCount) const;
1811
1812
1813 de::MovePtr<BufferWithMemory> createShaderBindingTable (const InstanceInterface& vki,
1814 const DeviceInterface& vkd,
1815 const VkDevice device,
1816 const VkPhysicalDevice physicalDevice,
1817 const VkPipeline pipeline,
1818 Allocator& allocator,
1819 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1820 const deUint32 group,
1821 const deUint32 groupCount = 1);
1822
getExtraAccelerationDescriptorCount(void)1823 virtual deUint32 getExtraAccelerationDescriptorCount (void) override { return 1; }
getShaderStageFlags(void)1824 virtual VkShaderStageFlags getShaderStageFlags (void) override { return ALL_RAY_TRACING_STAGES; }
getPipelineBindPoint(void)1825 virtual VkPipelineBindPoint getPipelineBindPoint (void) override { return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; }
1826
1827 deUint32 m_shaders;
1828 deUint32 m_raygenShaderGroup;
1829 deUint32 m_missShaderGroup;
1830 deUint32 m_hitShaderGroup;
1831 deUint32 m_callableShaderGroup;
1832 deUint32 m_shaderGroupCount;
1833
1834 Move<VkDescriptorSetLayout> m_descriptorSetLayoutSvc;
1835 Move<VkDescriptorSet> m_descriptorSetSvc;
1836
1837 de::MovePtr<RayTracingPipeline> m_rayTracingPipeline;
1838
1839 de::MovePtr<BufferWithMemory> m_raygenShaderBindingTable;
1840 de::MovePtr<BufferWithMemory> m_hitShaderBindingTable;
1841 de::MovePtr<BufferWithMemory> m_missShaderBindingTable;
1842 de::MovePtr<BufferWithMemory> m_callableShaderBindingTable;
1843
1844 VkStridedDeviceAddressRegionKHR m_raygenShaderBindingTableRegion;
1845 VkStridedDeviceAddressRegionKHR m_missShaderBindingTableRegion;
1846 VkStridedDeviceAddressRegionKHR m_hitShaderBindingTableRegion;
1847 VkStridedDeviceAddressRegionKHR m_callableShaderBindingTableRegion;
1848
1849 de::SharedPtr<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructure;
1850 de::SharedPtr<TopLevelAccelerationStructure> m_topLevelAccelerationStructure;
1851 };
1852
BindingAcceleratioStructureRayTracingRayTracingTestInstance(Context & context,const TestParams & testParams)1853 BindingAcceleratioStructureRayTracingRayTracingTestInstance::BindingAcceleratioStructureRayTracingRayTracingTestInstance (Context& context,
1854 const TestParams& testParams)
1855 : BindingAcceleratioStructureTestInstance (context, testParams)
1856 , m_shaders (0)
1857 , m_raygenShaderGroup (~0u)
1858 , m_missShaderGroup (~0u)
1859 , m_hitShaderGroup (~0u)
1860 , m_callableShaderGroup (~0u)
1861 , m_shaderGroupCount (0)
1862
1863 , m_descriptorSetLayoutSvc ()
1864 , m_descriptorSetSvc ()
1865
1866 , m_rayTracingPipeline ()
1867
1868 , m_raygenShaderBindingTable ()
1869 , m_hitShaderBindingTable ()
1870 , m_missShaderBindingTable ()
1871 , m_callableShaderBindingTable ()
1872
1873 , m_raygenShaderBindingTableRegion ()
1874 , m_missShaderBindingTableRegion ()
1875 , m_hitShaderBindingTableRegion ()
1876 , m_callableShaderBindingTableRegion ()
1877
1878 , m_bottomLevelAccelerationStructure ()
1879 , m_topLevelAccelerationStructure ()
1880 {
1881 }
1882
checkSupport(Context & context,const TestParams & testParams)1883 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::checkSupport (Context& context,
1884 const TestParams& testParams)
1885 {
1886 DE_UNREF(testParams);
1887
1888 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1889
1890 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1891
1892 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1893 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1894 }
1895
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1896 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPrograms (SourceCollections& programCollection,
1897 const TestParams& testParams)
1898 {
1899 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1900 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
1901 const std::string testBody =
1902 " ivec3 pos = ivec3(gl_LaunchIDEXT);\n"
1903 " ivec3 size = ivec3(gl_LaunchSizeEXT);\n"
1904 + testShaderBody;
1905 const std::string testOutClosestHitShader =
1906 std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
1907 "#extension GL_EXT_ray_tracing : require\n"
1908 "\n"
1909 "hitAttributeEXT vec3 attribs;\n"
1910 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1911 "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1912 "\n"
1913 "void main()\n"
1914 "{\n"
1915 + testBody +
1916 "}\n";
1917 const std::string testInShaderFragment =
1918 " uint rayFlags = 0;\n"
1919 " uint cullMask = 0xFF;\n"
1920 " float tmin = 0.0;\n"
1921 " float tmax = 9.0;\n"
1922 " vec3 origin = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
1923 " vec3 direct = vec3(0.0, 0.0, 1.0);\n"
1924 "\n"
1925 " traceRayEXT(topLevelAS, rayFlags, cullMask, 1, 0, 1, origin, tmin, direct, tmax, 0);\n";
1926 const std::string commonRayGenerationShader =
1927 std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
1928 "#extension GL_EXT_ray_tracing : require\n"
1929 "\n"
1930 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1931 "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1932 "layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1933 "\n"
1934 "void main()\n"
1935 "{\n"
1936 " uint rayFlags = 0;\n"
1937 " uint cullMask = 0xFF;\n"
1938 " float tmin = 0.0;\n"
1939 " float tmax = 9.0;\n"
1940 " vec3 origin = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
1941 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1942 "\n"
1943 " traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1944 "}\n";
1945
1946 programCollection.glslSources.add("chit0") << glu::ClosestHitSource(testOutClosestHitShader) << buildOptions;
1947 programCollection.glslSources.add("ahit0") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1948 programCollection.glslSources.add("miss0") << glu::MissSource(getMissPassthrough()) << buildOptions;
1949
1950 switch (testParams.stage)
1951 {
1952 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1953 {
1954 {
1955 std::stringstream css;
1956 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1957 << "#extension GL_EXT_ray_tracing : require\n"
1958 << "\n"
1959 << "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1960 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1961 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1962 << "\n"
1963 << "void main()\n"
1964 << "{\n"
1965 << testInShaderFragment
1966 << "}\n";
1967
1968 programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str()) << buildOptions;
1969 }
1970
1971 programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1972 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1973 programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1974
1975 break;
1976 }
1977
1978 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1979 {
1980 programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1981
1982 {
1983 std::stringstream css;
1984 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1985 << "#extension GL_EXT_ray_tracing : require\n"
1986 << "\n"
1987 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1988 << "hitAttributeEXT vec3 attribs;\n"
1989 << "\n"
1990 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1991 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1992 << "\n"
1993 << "void main()\n"
1994 << "{\n"
1995 << testInShaderFragment
1996 << "}\n";
1997
1998 programCollection.glslSources.add("chit") << glu::ClosestHitSource(css.str()) << buildOptions;
1999 }
2000
2001 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
2002 programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
2003
2004 break;
2005 }
2006
2007 case VK_SHADER_STAGE_MISS_BIT_KHR:
2008 {
2009 programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
2010
2011 {
2012 std::stringstream css;
2013 css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
2014 << "#extension GL_EXT_ray_tracing : require\n"
2015 << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
2016 << "\n"
2017 << "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
2018 << "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
2019 << "\n"
2020 << "void main()\n"
2021 << "{\n"
2022 << testInShaderFragment
2023 << "}\n";
2024
2025 programCollection.glslSources.add("miss") << glu::MissSource(css.str()) << buildOptions;
2026 }
2027
2028 programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
2029 programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
2030
2031 break;
2032 }
2033
2034 default:
2035 TCU_THROW(InternalError, "Unknown stage");
2036 }
2037 }
2038
calcShaderGroup(deUint32 & shaderGroupCounter,const VkShaderStageFlags shaders1,const VkShaderStageFlags shaders2,const VkShaderStageFlags shaderStageFlags,deUint32 & shaderGroup,deUint32 & shaderGroupCount) const2039 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::calcShaderGroup (deUint32& shaderGroupCounter,
2040 const VkShaderStageFlags shaders1,
2041 const VkShaderStageFlags shaders2,
2042 const VkShaderStageFlags shaderStageFlags,
2043 deUint32& shaderGroup,
2044 deUint32& shaderGroupCount) const
2045 {
2046 const deUint32 shader1Count = ((shaders1 & shaderStageFlags) != 0) ? 1 : 0;
2047 const deUint32 shader2Count = ((shaders2 & shaderStageFlags) != 0) ? 1 : 0;
2048
2049 shaderGroupCount = shader1Count + shader2Count;
2050
2051 if (shaderGroupCount != 0)
2052 {
2053 shaderGroup = shaderGroupCounter;
2054 shaderGroupCounter += shaderGroupCount;
2055 }
2056 }
2057
initPipeline(void)2058 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPipeline (void)
2059 {
2060 const InstanceInterface& vki = m_context.getInstanceInterface();
2061 const DeviceInterface& vkd = m_context.getDeviceInterface();
2062 const VkDevice device = m_context.getDevice();
2063 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
2064 vk::BinaryCollection& collection = m_context.getBinaryCollection();
2065 Allocator& allocator = m_context.getDefaultAllocator();
2066 const deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
2067 const VkShaderStageFlags hitStages = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
2068 deUint32 shaderCount = 0;
2069 VkShaderStageFlags shaders0 = static_cast<VkShaderStageFlags>(0);
2070 deUint32 raygenShaderGroupCount = 0;
2071 deUint32 hitShaderGroupCount = 0;
2072 deUint32 missShaderGroupCount = 0;
2073
2074 if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
2075 if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
2076 if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2077 if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
2078
2079 if (collection.contains("ahit0")) shaders0 |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
2080 if (collection.contains("chit0")) shaders0 |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2081 if (collection.contains("miss0")) shaders0 |= VK_SHADER_STAGE_MISS_BIT_KHR;
2082
2083 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
2084 shaderCount++;
2085
2086 if (shaderCount != (deUint32)(dePop32(m_shaders) + dePop32(shaders0)))
2087 TCU_THROW(InternalError, "Unused shaders detected in the collection");
2088
2089 calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, VK_SHADER_STAGE_RAYGEN_BIT_KHR, m_raygenShaderGroup, raygenShaderGroupCount);
2090 calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, VK_SHADER_STAGE_MISS_BIT_KHR, m_missShaderGroup, missShaderGroupCount);
2091 calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, hitStages, m_hitShaderGroup, hitShaderGroupCount);
2092
2093 m_rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2094
2095 m_descriptorSetLayoutSvc = DescriptorSetLayoutBuilder()
2096 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
2097 .build(vkd, device);
2098 m_descriptorSetSvc = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutSvc);
2099
2100 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR , createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
2101 if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
2102 if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
2103 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR , createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
2104
2105 // The "chit" and "miss" cases both generate more rays from their shaders.
2106 if (m_testParams.testType == TEST_TYPE_USING_RAY_TRACING && (m_testParams.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR || m_testParams.stage == VK_SHADER_STAGE_MISS_BIT_KHR))
2107 m_rayTracingPipeline->setMaxRecursionDepth(2u);
2108
2109 if (0 != (shaders0 & VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("ahit0"), 0), m_hitShaderGroup + 1);
2110 if (0 != (shaders0 & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("chit0"), 0), m_hitShaderGroup + 1);
2111 if (0 != (shaders0 & VK_SHADER_STAGE_MISS_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR , createShaderModule(vkd, device, collection.get("miss0"), 0), m_missShaderGroup + 1);
2112
2113 m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get(), m_descriptorSetLayoutSvc.get());
2114 m_pipeline = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
2115
2116 m_raygenShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup, raygenShaderGroupCount);
2117 m_missShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup, missShaderGroupCount);
2118 m_hitShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup, hitShaderGroupCount);
2119
2120 m_raygenShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable), shaderGroupHandleSize, raygenShaderGroupCount);
2121 m_missShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable), shaderGroupHandleSize, missShaderGroupCount);
2122 m_hitShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable), shaderGroupHandleSize, hitShaderGroupCount);
2123 m_callableShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, DE_NULL, 0, 0);
2124 }
2125
fillCommandBuffer(VkCommandBuffer commandBuffer)2126 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::fillCommandBuffer (VkCommandBuffer commandBuffer)
2127 {
2128 const DeviceInterface& vkd = m_context.getDeviceInterface();
2129 const VkDevice device = m_context.getDevice();
2130 Allocator& allocator = m_context.getDefaultAllocator();
2131 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2132 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2133
2134 m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
2135 m_bottomLevelAccelerationStructure->setDefaultGeometryData(m_testParams.stage);
2136 m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
2137
2138 m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
2139 m_topLevelAccelerationStructure->setInstanceCount(1);
2140 m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
2141 m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
2142
2143 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = m_topLevelAccelerationStructure.get();
2144 const VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = makeWriteDescriptorSetAccelerationStructureKHR(topLevelAccelerationStructurePtr->getPtr());
2145
2146 DescriptorSetUpdateBuilder()
2147 .writeSingle(*m_descriptorSetSvc, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
2148 .update(vkd, device);
2149
2150 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 2, 1, &m_descriptorSetSvc.get(), 0, DE_NULL);
2151
2152 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
2153
2154 cmdTraceRays(vkd,
2155 commandBuffer,
2156 &m_raygenShaderBindingTableRegion,
2157 &m_missShaderBindingTableRegion,
2158 &m_hitShaderBindingTableRegion,
2159 &m_callableShaderBindingTableRegion,
2160 m_testParams.width, m_testParams.height, 1);
2161 }
2162
createShaderBindingTable(const InstanceInterface & vki,const DeviceInterface & vkd,const VkDevice device,const VkPhysicalDevice physicalDevice,const VkPipeline pipeline,Allocator & allocator,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,const deUint32 group,const deUint32 groupCount)2163 de::MovePtr<BufferWithMemory> BindingAcceleratioStructureRayTracingRayTracingTestInstance::createShaderBindingTable (const InstanceInterface& vki,
2164 const DeviceInterface& vkd,
2165 const VkDevice device,
2166 const VkPhysicalDevice physicalDevice,
2167 const VkPipeline pipeline,
2168 Allocator& allocator,
2169 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
2170 const deUint32 group,
2171 const deUint32 groupCount)
2172 {
2173 de::MovePtr<BufferWithMemory> shaderBindingTable;
2174
2175 if (group < m_shaderGroupCount)
2176 {
2177 const deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
2178 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
2179
2180 shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, groupCount);
2181 }
2182
2183 return shaderBindingTable;
2184 }
2185
2186
getRayQueryShaderBodyText(const TestParams & testParams)2187 const std::string getRayQueryShaderBodyText (const TestParams& testParams)
2188 {
2189 DE_UNREF(testParams);
2190
2191 const std::string result =
2192 " const float mult = " + de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
2193 " uint rayFlags = 0;\n"
2194 " uint cullMask = 0xFF;\n"
2195 " float tmin = 0.0;\n"
2196 " float tmax = 9.0;\n"
2197 " vec3 origin = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2198 " vec3 direct = vec3(0.0, 0.0, 1.0);\n"
2199 " int value = 0;\n"
2200 " rayQueryEXT rayQuery;\n"
2201 "\n"
2202 " rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2203 "\n"
2204 " while(rayQueryProceedEXT(rayQuery))\n"
2205 " {\n"
2206 " if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2207 " {\n"
2208 " const float t = rayQueryGetIntersectionTEXT(rayQuery, false);"
2209 "\n"
2210 " value = int(round(mult * t));\n"
2211 " }\n"
2212 " }\n"
2213 "\n"
2214 " imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2215
2216 return result;
2217 }
2218
getRayTracingShaderBodyText(const TestParams & testParams)2219 const std::string getRayTracingShaderBodyText (const TestParams& testParams)
2220 {
2221 DE_UNREF(testParams);
2222
2223 const std::string result =
2224 " const float mult = " + de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
2225 " int value = int(round(mult * gl_HitTEXT));\n"
2226 "\n"
2227 " imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2228
2229 return result;
2230 }
2231
2232 class BindingAccelerationStructureTestCase : public TestCase
2233 {
2234 public:
2235 BindingAccelerationStructureTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams testParams);
2236 ~BindingAccelerationStructureTestCase (void);
2237
2238 virtual void checkSupport (Context& context) const;
2239 virtual void initPrograms (SourceCollections& programCollection) const;
2240 virtual TestInstance* createInstance (Context& context) const;
2241
2242 private:
2243 TestParams m_testParams;
2244 };
2245
BindingAccelerationStructureTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams testParams)2246 BindingAccelerationStructureTestCase::BindingAccelerationStructureTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams testParams)
2247 : vkt::TestCase (context, name, desc)
2248 , m_testParams (testParams)
2249 {
2250 }
2251
~BindingAccelerationStructureTestCase(void)2252 BindingAccelerationStructureTestCase::~BindingAccelerationStructureTestCase (void)
2253 {
2254 }
2255
checkSupport(Context & context) const2256 void BindingAccelerationStructureTestCase::checkSupport (Context& context) const
2257 {
2258 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
2259
2260 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
2261 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
2262 TCU_THROW(TestError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
2263
2264 switch (m_testParams.testType)
2265 {
2266 case TEST_TYPE_USING_RAY_QUERY:
2267 {
2268 context.requireDeviceFunctionality("VK_KHR_ray_query");
2269
2270 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures();
2271
2272 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
2273 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
2274
2275 break;
2276 }
2277
2278 case TEST_TYPE_USING_RAY_TRACING:
2279 {
2280 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
2281
2282 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
2283
2284 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
2285 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
2286
2287 break;
2288 }
2289
2290 default:
2291 TCU_THROW(InternalError, "Unknown test type");
2292 }
2293
2294 switch (m_testParams.updateMethod)
2295 {
2296 case UPDATE_METHOD_NORMAL:
2297 {
2298 break;
2299 }
2300
2301 case UPDATE_METHOD_WITH_TEMPLATE:
2302 {
2303 context.requireDeviceFunctionality("VK_KHR_descriptor_update_template");
2304
2305 break;
2306 }
2307
2308 case UPDATE_METHOD_WITH_PUSH:
2309 {
2310 context.requireDeviceFunctionality("VK_KHR_push_descriptor");
2311
2312 break;
2313 }
2314
2315 case UPDATE_METHOD_WITH_PUSH_TEMPLATE:
2316 {
2317 context.requireDeviceFunctionality("VK_KHR_push_descriptor");
2318 context.requireDeviceFunctionality("VK_KHR_descriptor_update_template");
2319
2320 break;
2321 }
2322
2323 default:
2324 TCU_THROW(InternalError, "Unknown update method");
2325 }
2326
2327 m_testParams.pipelineCheckSupport(context, m_testParams);
2328 }
2329
createInstance(Context & context) const2330 TestInstance* BindingAccelerationStructureTestCase::createInstance (Context& context) const
2331 {
2332 switch (m_testParams.testType)
2333 {
2334 case TEST_TYPE_USING_RAY_QUERY:
2335 {
2336 switch (m_testParams.stage)
2337 {
2338 case VK_SHADER_STAGE_VERTEX_BIT:
2339 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2340 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2341 case VK_SHADER_STAGE_GEOMETRY_BIT:
2342 case VK_SHADER_STAGE_FRAGMENT_BIT:
2343 {
2344 return new BindingAcceleratioStructureGraphicsTestInstance(context, m_testParams);
2345 }
2346
2347 case VK_SHADER_STAGE_COMPUTE_BIT:
2348 {
2349 return new BindingAcceleratioStructureComputeTestInstance(context, m_testParams);
2350 }
2351
2352 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2353 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2354 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2355 case VK_SHADER_STAGE_MISS_BIT_KHR:
2356 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2357 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2358 {
2359 return new BindingAcceleratioStructureRayTracingTestInstance(context, m_testParams);
2360 }
2361
2362 default:
2363 TCU_THROW(InternalError, "Unknown shader stage");
2364 }
2365 }
2366
2367 case TEST_TYPE_USING_RAY_TRACING:
2368 {
2369 return new BindingAcceleratioStructureRayTracingRayTracingTestInstance(context, m_testParams);
2370 }
2371
2372 default:
2373 TCU_THROW(InternalError, "Unknown shader stage");
2374 }
2375 }
2376
initPrograms(SourceCollections & programCollection) const2377 void BindingAccelerationStructureTestCase::initPrograms (SourceCollections& programCollection) const
2378 {
2379 m_testParams.pipelineInitPrograms(programCollection, m_testParams);
2380 }
2381
getPipelineRayQueryCheckSupport(const VkShaderStageFlagBits stage)2382 static inline CheckSupportFunc getPipelineRayQueryCheckSupport (const VkShaderStageFlagBits stage)
2383 {
2384 switch (stage)
2385 {
2386 case VK_SHADER_STAGE_VERTEX_BIT:
2387 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2388 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2389 case VK_SHADER_STAGE_GEOMETRY_BIT:
2390 case VK_SHADER_STAGE_FRAGMENT_BIT:
2391 return BindingAcceleratioStructureGraphicsTestInstance::checkSupport;
2392
2393 case VK_SHADER_STAGE_COMPUTE_BIT:
2394 return BindingAcceleratioStructureComputeTestInstance::checkSupport;
2395
2396 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2397 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2398 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2399 case VK_SHADER_STAGE_MISS_BIT_KHR:
2400 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2401 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2402 return BindingAcceleratioStructureRayTracingTestInstance::checkSupport;
2403
2404 default:
2405 TCU_THROW(InternalError, "Unknown shader stage");
2406 }
2407 }
2408
getPipelineRayTracingCheckSupport(const VkShaderStageFlagBits stage)2409 static inline CheckSupportFunc getPipelineRayTracingCheckSupport (const VkShaderStageFlagBits stage)
2410 {
2411 DE_UNREF(stage);
2412
2413 return BindingAcceleratioStructureRayTracingRayTracingTestInstance::checkSupport;
2414 }
2415
getPipelineRayQueryInitPrograms(const VkShaderStageFlagBits stage)2416 static inline InitProgramsFunc getPipelineRayQueryInitPrograms (const VkShaderStageFlagBits stage)
2417 {
2418 switch (stage)
2419 {
2420 case VK_SHADER_STAGE_VERTEX_BIT:
2421 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2422 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2423 case VK_SHADER_STAGE_GEOMETRY_BIT:
2424 case VK_SHADER_STAGE_FRAGMENT_BIT:
2425 return BindingAcceleratioStructureGraphicsTestInstance::initPrograms;
2426
2427 case VK_SHADER_STAGE_COMPUTE_BIT:
2428 return BindingAcceleratioStructureComputeTestInstance::initPrograms;
2429
2430 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2431 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2432 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2433 case VK_SHADER_STAGE_MISS_BIT_KHR:
2434 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2435 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2436 return BindingAcceleratioStructureRayTracingTestInstance::initPrograms;
2437
2438 default:
2439 TCU_THROW(InternalError, "Unknown shader stage");
2440 }
2441 }
2442
getPipelineRayTracingInitPrograms(const VkShaderStageFlagBits stage)2443 static inline InitProgramsFunc getPipelineRayTracingInitPrograms (const VkShaderStageFlagBits stage)
2444 {
2445 DE_UNREF(stage);
2446
2447 return BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPrograms;
2448 }
2449
getShaderBodyTextFunc(const TestType testType)2450 static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType)
2451 {
2452 switch (testType)
2453 {
2454 case TEST_TYPE_USING_RAY_QUERY: return getRayQueryShaderBodyText;
2455 case TEST_TYPE_USING_RAY_TRACING: return getRayTracingShaderBodyText;
2456 default: TCU_THROW(InternalError, "Unknown test type");
2457 }
2458 }
2459
2460 } // anonymous
2461
createDescriptorUpdateASTests(tcu::TestContext & testCtx)2462 tcu::TestCaseGroup* createDescriptorUpdateASTests (tcu::TestContext& testCtx)
2463 {
2464 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "acceleration_structure", "Tests acceleration structure descriptor updates"));
2465
2466 const struct TestTypes
2467 {
2468 TestType testType;
2469 const char* name;
2470 }
2471 testTypes[] =
2472 {
2473 { TEST_TYPE_USING_RAY_QUERY, "ray_query" },
2474 { TEST_TYPE_USING_RAY_TRACING, "ray_tracing" },
2475 };
2476 const struct UpdateMethods
2477 {
2478 const UpdateMethod method;
2479 const char* name;
2480 const char* description;
2481 }
2482 updateMethods[] =
2483 {
2484 { UPDATE_METHOD_NORMAL, "regular", "Use regular descriptor updates" },
2485 { UPDATE_METHOD_WITH_TEMPLATE, "with_template", "Use descriptor update templates" },
2486 { UPDATE_METHOD_WITH_PUSH, "with_push", "Use push descriptor updates" },
2487 { UPDATE_METHOD_WITH_PUSH_TEMPLATE, "with_push_template", "Use push descriptor update templates" },
2488 };
2489 const struct PipelineStages
2490 {
2491 VkShaderStageFlagBits stage;
2492 const char* name;
2493 const bool rayTracing;
2494 }
2495 pipelineStages[] =
2496 {
2497 { VK_SHADER_STAGE_VERTEX_BIT, "vert", false },
2498 { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc", false },
2499 { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese", false },
2500 { VK_SHADER_STAGE_GEOMETRY_BIT, "geom", false },
2501 { VK_SHADER_STAGE_FRAGMENT_BIT, "frag", false },
2502 { VK_SHADER_STAGE_COMPUTE_BIT, "comp", false },
2503 { VK_SHADER_STAGE_RAYGEN_BIT_KHR, "rgen", true },
2504 { VK_SHADER_STAGE_ANY_HIT_BIT_KHR, "ahit", false },
2505 { VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, "chit", true },
2506 { VK_SHADER_STAGE_MISS_BIT_KHR, "miss", true },
2507 { VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "sect", false },
2508 { VK_SHADER_STAGE_CALLABLE_BIT_KHR, "call", false },
2509 };
2510
2511 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
2512 {
2513 de::MovePtr<tcu::TestCaseGroup> testTypeGroup (new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
2514 const TestType testType = testTypes[testTypeNdx].testType;
2515 const ShaderBodyTextFunc shaderBodyTextFunc = getShaderBodyTextFunc(testType);
2516 const deUint32 imageDepth = 1;
2517
2518 for (size_t updateMethodsNdx = 0; updateMethodsNdx < DE_LENGTH_OF_ARRAY(updateMethods); ++updateMethodsNdx)
2519 {
2520 de::MovePtr<tcu::TestCaseGroup> updateMethodsGroup (new tcu::TestCaseGroup(group->getTestContext(), updateMethods[updateMethodsNdx].name, updateMethods[updateMethodsNdx].description));
2521 const UpdateMethod updateMethod = updateMethods[updateMethodsNdx].method;
2522
2523 for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
2524 {
2525 const VkShaderStageFlagBits stage = pipelineStages[pipelineStageNdx].stage;
2526 const CheckSupportFunc pipelineCheckSupport = (testType == TEST_TYPE_USING_RAY_QUERY)
2527 ? getPipelineRayQueryCheckSupport(stage)
2528 : getPipelineRayTracingCheckSupport(stage);
2529 const InitProgramsFunc pipelineInitPrograms = (testType == TEST_TYPE_USING_RAY_QUERY)
2530 ? getPipelineRayQueryInitPrograms(stage)
2531 : getPipelineRayTracingInitPrograms(stage);
2532
2533 if (testType == TEST_TYPE_USING_RAY_TRACING && !pipelineStages[pipelineStageNdx].rayTracing)
2534 continue;
2535
2536 const TestParams testParams =
2537 {
2538 TEST_WIDTH, // deUint32 width;
2539 TEST_HEIGHT, // deUint32 height;
2540 imageDepth, // deUint32 depth;
2541 testType, // TestType testType;
2542 updateMethod, // UpdateMethod updateMethod;
2543 stage, // VkShaderStageFlagBits stage;
2544 VK_FORMAT_R32_SINT, // VkFormat format;
2545 pipelineCheckSupport, // CheckSupportFunc pipelineCheckSupport;
2546 pipelineInitPrograms, // InitProgramsFunc pipelineInitPrograms;
2547 shaderBodyTextFunc, // ShaderTestTextFunc testConfigShaderBodyText;
2548 };
2549
2550 updateMethodsGroup->addChild(new BindingAccelerationStructureTestCase(group->getTestContext(), pipelineStages[pipelineStageNdx].name, "", testParams));
2551 }
2552
2553 testTypeGroup->addChild(updateMethodsGroup.release());
2554 }
2555
2556 group->addChild(testTypeGroup.release());
2557 }
2558
2559 return group.release();
2560 }
2561
2562 } // RayQuery
2563 } // vkt
2564