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