1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2020 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Testing acceleration structures in ray query extension
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRayQueryAccelerationStructuresTests.hpp"
25
26 #include <array>
27 #include <set>
28 #include <limits>
29
30 #include "vkDefs.hpp"
31 #include "deClock.h"
32 #include "vktTestCase.hpp"
33 #include "vktTestGroupUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkBarrierUtil.hpp"
38 #include "vkBufferWithMemory.hpp"
39 #include "vkImageWithMemory.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkRayTracingUtil.hpp"
43 #include "deRandom.hpp"
44 #include "tcuTexture.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuImageCompare.hpp"
48 #include "tcuFloat.hpp"
49 #include "deModularCounter.hpp"
50
51 namespace vkt
52 {
53 namespace RayQuery
54 {
55 namespace
56 {
57 using namespace vk;
58 using namespace vkt;
59
60 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
61 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
62 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
63 | VK_SHADER_STAGE_MISS_BIT_KHR
64 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
65 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
66
67 enum ShaderSourcePipeline
68 {
69 SSP_GRAPHICS_PIPELINE,
70 SSP_COMPUTE_PIPELINE,
71 SSP_RAY_TRACING_PIPELINE
72 };
73
74 enum ShaderSourceType
75 {
76 SST_VERTEX_SHADER,
77 SST_TESSELATION_CONTROL_SHADER,
78 SST_TESSELATION_EVALUATION_SHADER,
79 SST_GEOMETRY_SHADER,
80 SST_FRAGMENT_SHADER,
81 SST_COMPUTE_SHADER,
82 SST_RAY_GENERATION_SHADER,
83 SST_INTERSECTION_SHADER,
84 SST_ANY_HIT_SHADER,
85 SST_CLOSEST_HIT_SHADER,
86 SST_MISS_SHADER,
87 SST_CALLABLE_SHADER,
88 };
89
90 enum ShaderTestType
91 {
92 STT_GENERATE_INTERSECTION = 0,
93 STT_SKIP_INTERSECTION = 1,
94 };
95
96 enum class BottomTestType
97 {
98 TRIANGLES = 0,
99 AABBS = 1,
100 };
101
102 enum class TopTestType
103 {
104 IDENTICAL_INSTANCES,
105 DIFFERENT_INSTANCES,
106 UPDATED_INSTANCES
107 };
108
109 enum OperationTarget
110 {
111 OT_NONE,
112 OT_TOP_ACCELERATION,
113 OT_BOTTOM_ACCELERATION
114 };
115
116 enum OperationType
117 {
118 OP_NONE,
119 OP_COPY,
120 OP_COMPACT,
121 OP_SERIALIZE,
122 OP_UPDATE,
123 OP_UPDATE_IN_PLACE
124 };
125
126 enum class InstanceCullFlags
127 {
128 NONE,
129 CULL_DISABLE,
130 COUNTERCLOCKWISE,
131 ALL,
132 };
133
134 enum class EmptyAccelerationStructureCase
135 {
136 NOT_EMPTY = 0,
137 INACTIVE_TRIANGLES = 1,
138 INACTIVE_INSTANCES = 2,
139 NO_GEOMETRIES_BOTTOM = 3, // geometryCount zero when building.
140 NO_PRIMITIVES_BOTTOM = 4, // primitiveCount zero when building.
141 NO_PRIMITIVES_TOP = 5, // primitiveCount zero when building.
142 };
143
144 const deUint32 TEST_WIDTH = 8;
145 const deUint32 TEST_HEIGHT = 8;
146
147 struct TestParams;
148
149 class TestConfiguration
150 {
151 public:
152 virtual ~TestConfiguration ();
153 virtual void initConfiguration (Context& context,
154 TestParams& testParams) = 0;
155 virtual void fillCommandBuffer (Context& context,
156 TestParams& testParams,
157 VkCommandBuffer commandBuffer,
158 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
159 const VkDescriptorImageInfo& resultImageInfo) = 0;
160 virtual bool verifyImage (BufferWithMemory* resultBuffer,
161 Context& context,
162 TestParams& testParams) = 0;
163 virtual VkFormat getResultImageFormat () = 0;
164 virtual size_t getResultImageFormatSize () = 0;
165 virtual VkClearValue getClearValue () = 0;
166 };
167
~TestConfiguration()168 TestConfiguration::~TestConfiguration()
169 {
170 }
171
172 class SceneBuilder
173 {
174 public:
175 virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (Context& context,
176 TestParams& testParams) = 0;
177 virtual de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (Context& context,
178 TestParams& testParams,
179 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) = 0;
180 };
181
182 struct TestParams
183 {
184 ShaderSourceType shaderSourceType;
185 ShaderSourcePipeline shaderSourcePipeline;
186 vk::VkAccelerationStructureBuildTypeKHR buildType; // are we making AS on CPU or GPU
187 VkFormat vertexFormat;
188 bool padVertices;
189 VkIndexType indexType;
190 BottomTestType bottomTestType; // what kind of geometry is stored in bottom AS
191 InstanceCullFlags cullFlags; // Flags for instances, if needed.
192 bool bottomUsesAOP; // does bottom AS use arrays, or arrays of pointers
193 bool bottomGeneric; // Bottom created as generic AS type.
194 bool bottomUnboundedCreation; // Bottom created with unbounded buffer memory.
195 TopTestType topTestType; // If instances are identical then bottom geometries must have different vertices/aabbs
196 bool topUsesAOP; // does top AS use arrays, or arrays of pointers
197 bool topGeneric; // Top created as generic AS type.
198 bool topUnboundedCreation; // Top created with unbounded buffer memory.
199 VkBuildAccelerationStructureFlagsKHR buildFlags;
200 OperationTarget operationTarget;
201 OperationType operationType;
202 deUint32 width;
203 deUint32 height;
204 deUint32 workerThreadsCount;
205 EmptyAccelerationStructureCase emptyASCase;
206 };
207
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)208 deUint32 getShaderGroupHandleSize (const InstanceInterface& vki,
209 const VkPhysicalDevice physicalDevice)
210 {
211 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
212
213 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
214 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
215 }
216
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)217 deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
218 const VkPhysicalDevice physicalDevice)
219 {
220 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
221
222 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
223 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
224 }
225
makeImageCreateInfo(deUint32 width,deUint32 height,deUint32 depth,VkFormat format)226 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
227 {
228 const VkImageCreateInfo imageCreateInfo =
229 {
230 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
231 DE_NULL, // const void* pNext;
232 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
233 VK_IMAGE_TYPE_3D, // VkImageType imageType;
234 format, // VkFormat format;
235 makeExtent3D(width, height, depth), // VkExtent3D extent;
236 1u, // deUint32 mipLevels;
237 1u, // deUint32 arrayLayers;
238 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
239 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
240 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
241 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
242 0u, // deUint32 queueFamilyIndexCount;
243 DE_NULL, // const deUint32* pQueueFamilyIndices;
244 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
245 };
246
247 return imageCreateInfo;
248 }
249
makeQueryPool(const DeviceInterface & vk,const VkDevice device,const VkQueryType queryType,deUint32 queryCount)250 Move<VkQueryPool> makeQueryPool(const DeviceInterface& vk,
251 const VkDevice device,
252 const VkQueryType queryType,
253 deUint32 queryCount)
254 {
255 const VkQueryPoolCreateInfo queryPoolCreateInfo =
256 {
257 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType
258 DE_NULL, // pNext
259 (VkQueryPoolCreateFlags)0, // flags
260 queryType, // queryType
261 queryCount, // queryCount
262 0u, // pipelineStatistics
263 };
264 return createQueryPool(vk, device, &queryPoolCreateInfo);
265 }
266
267
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,std::vector<de::SharedPtr<Move<VkShaderModule>>> & shaderModules,std::vector<VkPipelineShaderStageCreateInfo> & shaderCreateInfos,VkShaderStageFlagBits stage,const std::string & externalNamePart,const std::string & internalNamePart)268 bool registerShaderModule (const DeviceInterface& vkd,
269 const VkDevice device,
270 Context& context,
271 std::vector<de::SharedPtr<Move<VkShaderModule>>>& shaderModules,
272 std::vector<VkPipelineShaderStageCreateInfo>& shaderCreateInfos,
273 VkShaderStageFlagBits stage,
274 const std::string& externalNamePart,
275 const std::string& internalNamePart)
276 {
277 char fullShaderName[40];
278 snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
279 std::string fsn = fullShaderName;
280 if (fsn.empty())
281 return false;
282
283 shaderModules.push_back(makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0)));
284
285 shaderCreateInfos.push_back(
286 {
287 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
288 DE_NULL,
289 (VkPipelineShaderStageCreateFlags)0,
290 stage, // stage
291 shaderModules.back()->get(), // shader
292 "main",
293 DE_NULL, // pSpecializationInfo
294 });
295
296 return true;
297 }
298
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,RayTracingPipeline & rayTracingPipeline,VkShaderStageFlagBits shaderStage,const std::string & externalNamePart,const std::string & internalNamePart,deUint32 groupIndex)299 bool registerShaderModule (const DeviceInterface& vkd,
300 const VkDevice device,
301 Context& context,
302 RayTracingPipeline& rayTracingPipeline,
303 VkShaderStageFlagBits shaderStage,
304 const std::string& externalNamePart,
305 const std::string& internalNamePart,
306 deUint32 groupIndex)
307 {
308 char fullShaderName[40];
309 snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
310 std::string fsn = fullShaderName;
311 if (fsn.empty())
312 return false;
313 Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0);
314 if (*shaderModule == DE_NULL)
315 return false;
316 rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex);
317 return true;
318 }
319
getCullFlags(InstanceCullFlags flags)320 VkGeometryInstanceFlagsKHR getCullFlags (InstanceCullFlags flags)
321 {
322 VkGeometryInstanceFlagsKHR cullFlags = 0u;
323
324 if (flags == InstanceCullFlags::CULL_DISABLE || flags == InstanceCullFlags::ALL)
325 cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
326
327 if (flags == InstanceCullFlags::COUNTERCLOCKWISE || flags == InstanceCullFlags::ALL)
328 cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR;
329
330 return cullFlags;
331 }
332
333 class GraphicsConfiguration : public TestConfiguration
334 {
335 public:
336 virtual ~GraphicsConfiguration ();
337 void initConfiguration (Context& context,
338 TestParams& testParams) override;
339 void fillCommandBuffer (Context& context,
340 TestParams& testParams,
341 VkCommandBuffer commandBuffer,
342 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
343 const VkDescriptorImageInfo& resultImageInfo) override;
344 bool verifyImage (BufferWithMemory* resultBuffer,
345 Context& context,
346 TestParams& testParams) override;
347 VkFormat getResultImageFormat () override;
348 size_t getResultImageFormatSize () override;
349 VkClearValue getClearValue () override;
350 protected:
351 Move<VkDescriptorSetLayout> descriptorSetLayout;
352 Move<VkDescriptorPool> descriptorPool;
353 Move<VkDescriptorSet> descriptorSet;
354 Move<VkPipelineLayout> pipelineLayout;
355 Move<VkRenderPass> renderPass;
356 Move<VkFramebuffer> framebuffer;
357 std::vector<de::SharedPtr<Move<VkShaderModule> > > shaderModules;
358 Move<VkPipeline> pipeline;
359 std::vector<tcu::Vec3> vertices;
360 Move<VkBuffer> vertexBuffer;
361 de::MovePtr<Allocation> vertexAlloc;
362 };
363
~GraphicsConfiguration()364 GraphicsConfiguration::~GraphicsConfiguration()
365 {
366 shaderModules.clear();
367 }
368
initConfiguration(Context & context,TestParams & testParams)369 void GraphicsConfiguration::initConfiguration (Context& context,
370 TestParams& testParams)
371 {
372 const DeviceInterface& vkd = context.getDeviceInterface();
373 const VkDevice device = context.getDevice();
374 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
375 Allocator& allocator = context.getDefaultAllocator();
376
377 descriptorSetLayout = DescriptorSetLayoutBuilder()
378 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
379 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
380 .build(vkd, device);
381 descriptorPool = DescriptorPoolBuilder()
382 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
383 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
384 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
385 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
386 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
387
388 std::vector<std::string> rayQueryTestName;
389 rayQueryTestName.push_back("as_triangle");
390 rayQueryTestName.push_back("as_aabb");
391
392 const std::map<ShaderSourceType,std::vector<std::string>> shaderNames =
393 {
394 //idx: 0 1 2 3 4
395 //shader: vert, tesc, tese, geom, frag,
396 { SST_VERTEX_SHADER, { "vert_%s", "", "", "", "", } },
397 { SST_TESSELATION_CONTROL_SHADER, { "vert", "tesc_%s", "tese", "", "", } },
398 { SST_TESSELATION_EVALUATION_SHADER, { "vert", "tesc", "tese_%s", "", "", } },
399 { SST_GEOMETRY_SHADER, { "vert_vid", "", "", "geom_%s", "", } },
400 { SST_FRAGMENT_SHADER, { "vert", "", "", "", "frag_%s", } },
401 };
402
403 auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
404 if(shaderNameIt == end(shaderNames))
405 TCU_THROW(InternalError, "Wrong shader source type");
406
407 std::vector<VkPipelineShaderStageCreateInfo> shaderCreateInfos;
408 bool tescX, teseX, fragX;
409 const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType);
410 registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_VERTEX_BIT, shaderNameIt->second[0], rayQueryTestName[bottomTestTypeIdx]);
411 tescX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, shaderNameIt->second[1], rayQueryTestName[bottomTestTypeIdx]);
412 teseX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, shaderNameIt->second[2], rayQueryTestName[bottomTestTypeIdx]);
413 registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_GEOMETRY_BIT, shaderNameIt->second[3], rayQueryTestName[bottomTestTypeIdx]);
414 fragX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_FRAGMENT_BIT, shaderNameIt->second[4], rayQueryTestName[bottomTestTypeIdx]);
415
416 const vk::VkSubpassDescription subpassDesc =
417 {
418 (vk::VkSubpassDescriptionFlags)0,
419 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
420 0u, // inputCount
421 DE_NULL, // pInputAttachments
422 0u, // colorCount
423 DE_NULL, // pColorAttachments
424 DE_NULL, // pResolveAttachments
425 DE_NULL, // depthStencilAttachment
426 0u, // preserveCount
427 DE_NULL, // pPreserveAttachments
428 };
429 const vk::VkRenderPassCreateInfo renderPassParams =
430 {
431 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
432 DE_NULL, // pNext
433 (vk::VkRenderPassCreateFlags)0,
434 0u, // attachmentCount
435 DE_NULL, // pAttachments
436 1u, // subpassCount
437 &subpassDesc, // pSubpasses
438 0u, // dependencyCount
439 DE_NULL, // pDependencies
440 };
441
442 renderPass = createRenderPass(vkd, device, &renderPassParams);
443
444 const vk::VkFramebufferCreateInfo framebufferParams =
445 {
446 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
447 DE_NULL, // pNext
448 (vk::VkFramebufferCreateFlags)0,
449 *renderPass, // renderPass
450 0u, // attachmentCount
451 DE_NULL, // pAttachments
452 testParams.width, // width
453 testParams.height, // height
454 1u, // layers
455 };
456
457 framebuffer = createFramebuffer(vkd, device, &framebufferParams);
458
459 VkPrimitiveTopology testTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
460 tcu::Vec3 v0(0.0f, 0.0f, 0.0f);
461 tcu::Vec3 v1(float(testParams.width) - 1.0f, 0.0f, 0.0f);
462 tcu::Vec3 v2(0.0f, float(testParams.height) - 1.0f, 0.0f);
463 tcu::Vec3 v3(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0f);
464
465 switch (testParams.shaderSourceType)
466 {
467 case SST_TESSELATION_CONTROL_SHADER:
468 case SST_TESSELATION_EVALUATION_SHADER:
469 testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
470 vertices.push_back(v0);
471 vertices.push_back(v1);
472 vertices.push_back(v2);
473 vertices.push_back(v1);
474 vertices.push_back(v3);
475 vertices.push_back(v2);
476 break;
477 case SST_VERTEX_SHADER:
478 case SST_GEOMETRY_SHADER:
479 vertices.push_back(v0);
480 vertices.push_back(v1);
481 vertices.push_back(v2);
482 vertices.push_back(v3);
483 break;
484 case SST_FRAGMENT_SHADER:
485 vertices.push_back( tcu::Vec3(-1.0f, 1.0f, 0.0f) );
486 vertices.push_back( tcu::Vec3(-1.0f, -1.0f, 0.0f) );
487 vertices.push_back( tcu::Vec3( 1.0f, 1.0f, 0.0f) );
488 vertices.push_back( tcu::Vec3( 1.0f, -1.0f, 0.0f) );
489 break;
490 default:
491 TCU_THROW(InternalError, "Wrong shader source type");
492 }
493
494 const VkVertexInputBindingDescription vertexInputBindingDescription =
495 {
496 0u, // uint32_t binding;
497 sizeof(tcu::Vec3), // uint32_t stride;
498 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
499 };
500
501 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
502 {
503 0u, // uint32_t location;
504 0u, // uint32_t binding;
505 VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
506 0u, // uint32_t offset;
507 };
508
509 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
510 {
511 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
512 DE_NULL, // const void* pNext;
513 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
514 1u, // deUint32 vertexBindingDescriptionCount;
515 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
516 1u, // deUint32 vertexAttributeDescriptionCount;
517 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
518 };
519
520 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
521 {
522 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
523 DE_NULL, // const void* pNext;
524 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
525 testTopology, // VkPrimitiveTopology topology;
526 VK_FALSE // VkBool32 primitiveRestartEnable;
527 };
528
529 const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo =
530 {
531 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
532 DE_NULL, // const void* pNext;
533 VkPipelineTessellationStateCreateFlags(0u), // VkPipelineTessellationStateCreateFlags flags;
534 3u // deUint32 patchControlPoints;
535 };
536
537 VkViewport viewport = makeViewport(testParams.width, testParams.height);
538 VkRect2D scissor = makeRect2D(testParams.width, testParams.height);
539
540 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
541 {
542 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
543 DE_NULL, // const void* pNext
544 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
545 1u, // deUint32 viewportCount
546 &viewport, // const VkViewport* pViewports
547 1u, // deUint32 scissorCount
548 &scissor // const VkRect2D* pScissors
549 };
550
551 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
552 {
553 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
554 DE_NULL, // const void* pNext;
555 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
556 VK_FALSE, // VkBool32 depthClampEnable;
557 fragX ? VK_FALSE : VK_TRUE, // VkBool32 rasterizerDiscardEnable;
558 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
559 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
560 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
561 VK_FALSE, // VkBool32 depthBiasEnable;
562 0.0f, // float depthBiasConstantFactor;
563 0.0f, // float depthBiasClamp;
564 0.0f, // float depthBiasSlopeFactor;
565 1.0f // float lineWidth;
566 };
567
568 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
569 {
570 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
571 DE_NULL, // const void* pNext;
572 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
573 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
574 VK_FALSE, // VkBool32 sampleShadingEnable;
575 0.0f, // float minSampleShading;
576 DE_NULL, // const VkSampleMask* pSampleMask;
577 VK_FALSE, // VkBool32 alphaToCoverageEnable;
578 VK_FALSE // VkBool32 alphaToOneEnable;
579 };
580
581 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
582 {
583 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
584 DE_NULL, // const void* pNext;
585 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
586 DE_FALSE, // VkBool32 logicOpEnable;
587 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp;
588 0, // deUint32 attachmentCount;
589 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments;
590 { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4];
591 };
592
593 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
594 {
595 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
596 DE_NULL, // const void* pNext;
597 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
598 static_cast<deUint32>(shaderCreateInfos.size()), // deUint32 stageCount;
599 shaderCreateInfos.data(), // const VkPipelineShaderStageCreateInfo* pStages;
600 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
601 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
602 (tescX||teseX) ? &tessellationStateCreateInfo : DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
603 fragX ? &viewportStateCreateInfo : DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState;
604 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
605 fragX ? &multisampleStateCreateInfo : DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
606 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
607 fragX ? &colorBlendStateCreateInfo : DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
608 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
609 pipelineLayout.get(), // VkPipelineLayout layout;
610 renderPass.get(), // VkRenderPass renderPass;
611 0u, // deUint32 subpass;
612 DE_NULL, // VkPipeline basePipelineHandle;
613 0 // int basePipelineIndex;
614 };
615
616 pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo);
617
618 const VkBufferCreateInfo vertexBufferParams =
619 {
620 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
621 DE_NULL, // const void* pNext;
622 0u, // VkBufferCreateFlags flags;
623 VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()), // VkDeviceSize size;
624 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
625 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
626 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
627 1u, // deUint32 queueFamilyIndexCount;
628 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
629 };
630
631 vertexBuffer = createBuffer(vkd, device, &vertexBufferParams);
632 vertexAlloc = allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible);
633 VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
634
635 // Upload vertex data
636 deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3));
637 flushAlloc(vkd, device, *vertexAlloc);
638 }
639
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)640 void GraphicsConfiguration::fillCommandBuffer (Context& context,
641 TestParams& testParams,
642 VkCommandBuffer commandBuffer,
643 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
644 const VkDescriptorImageInfo& resultImageInfo)
645 {
646 const DeviceInterface& vkd = context.getDeviceInterface();
647 const VkDevice device = context.getDevice();
648
649 DescriptorSetUpdateBuilder()
650 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
651 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
652 .update(vkd, device);
653
654 const VkRenderPassBeginInfo renderPassBeginInfo =
655 {
656 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
657 DE_NULL, // const void* pNext;
658 *renderPass, // VkRenderPass renderPass;
659 *framebuffer, // VkFramebuffer framebuffer;
660 makeRect2D(testParams.width, testParams.height), // VkRect2D renderArea;
661 0u, // uint32_t clearValueCount;
662 DE_NULL // const VkClearValue* pClearValues;
663 };
664 VkDeviceSize vertexBufferOffset = 0u;
665
666 vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
667 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
668 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
669 vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
670 vkd.cmdDraw(commandBuffer, deUint32(vertices.size()), 1, 0, 0);
671 vkd.cmdEndRenderPass(commandBuffer);
672 }
673
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)674 bool GraphicsConfiguration::verifyImage (BufferWithMemory* resultBuffer,
675 Context& context,
676 TestParams& testParams)
677 {
678 // create result image
679 const bool allMiss = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
680 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
681 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
682
683 // create reference image
684 std::vector<deUint32> reference(testParams.width * testParams.height * 2);
685 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
686
687 std::vector<std::vector<deUint32>> primitives =
688 {
689 {0, 1, 2},
690 {1, 3, 2}
691 };
692
693 tcu::UVec4 hitValue0 = tcu::UVec4(1, 0, 0, 0);
694 tcu::UVec4 hitValue1 = tcu::UVec4(1, 0, 0, 0);
695 tcu::UVec4 missValue = tcu::UVec4(0, 0, 0, 0);
696 tcu::UVec4 clearValue = tcu::UVec4(0xFF, 0, 0, 0);
697
698 switch (testParams.shaderSourceType)
699 {
700 case SST_VERTEX_SHADER:
701 tcu::clear(referenceAccess, clearValue);
702 for (deUint32 vertexNdx = 0; vertexNdx < 4; ++vertexNdx)
703 {
704 if (!allMiss && (vertexNdx == 1 || vertexNdx == 2))
705 {
706 referenceAccess.setPixel(hitValue0, vertexNdx, 0, 0);
707 referenceAccess.setPixel(hitValue1, vertexNdx, 0, 1);
708 }
709 else
710 {
711 referenceAccess.setPixel(missValue, vertexNdx, 0, 0);
712 referenceAccess.setPixel(missValue, vertexNdx, 0, 1);
713 }
714 }
715 break;
716 case SST_TESSELATION_EVALUATION_SHADER:
717 case SST_TESSELATION_CONTROL_SHADER:
718 case SST_GEOMETRY_SHADER:
719 tcu::clear(referenceAccess, clearValue);
720 for (deUint32 primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx)
721 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
722 {
723 deUint32 vNdx = primitives[primitiveNdx][vertexNdx];
724 if (!allMiss && (vNdx==1 || vNdx==2))
725 {
726 referenceAccess.setPixel(hitValue0, primitiveNdx, vertexNdx, 0);
727 referenceAccess.setPixel(hitValue1, primitiveNdx, vertexNdx, 1);
728 }
729 else
730 {
731 referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 0);
732 referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 1);
733 }
734 }
735 break;
736 case SST_FRAGMENT_SHADER:
737 tcu::clear(referenceAccess, missValue);
738 for (deUint32 y = 0; y < testParams.height; ++y)
739 for (deUint32 x = 0; x < testParams.width; ++x)
740 {
741 if (allMiss || ((x + y) % 2) == 0)
742 continue;
743
744 referenceAccess.setPixel(hitValue0, x, y, 0);
745 referenceAccess.setPixel(hitValue1, x, y, 1);
746 }
747 break;
748 default:
749 TCU_THROW(InternalError, "Wrong shader source type");
750 }
751
752 // compare result and reference
753 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
754 }
755
getResultImageFormat()756 VkFormat GraphicsConfiguration::getResultImageFormat ()
757 {
758 return VK_FORMAT_R32_UINT;
759 }
760
getResultImageFormatSize()761 size_t GraphicsConfiguration::getResultImageFormatSize ()
762 {
763 return sizeof(deUint32);
764 }
765
getClearValue()766 VkClearValue GraphicsConfiguration::getClearValue ()
767 {
768 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
769 }
770
771 class ComputeConfiguration : public TestConfiguration
772 {
773 public:
774 virtual ~ComputeConfiguration ();
775 void initConfiguration (Context& context,
776 TestParams& testParams) override;
777 void fillCommandBuffer (Context& context,
778 TestParams& testParams,
779 VkCommandBuffer commandBuffer,
780 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
781 const VkDescriptorImageInfo& resultImageInfo) override;
782 bool verifyImage (BufferWithMemory* resultBuffer,
783 Context& context,
784 TestParams& testParams) override;
785 VkFormat getResultImageFormat () override;
786 size_t getResultImageFormatSize () override;
787 VkClearValue getClearValue () override;
788 protected:
789 Move<VkDescriptorSetLayout> descriptorSetLayout;
790 Move<VkDescriptorPool> descriptorPool;
791 Move<VkDescriptorSet> descriptorSet;
792 Move<VkPipelineLayout> pipelineLayout;
793 Move<VkShaderModule> shaderModule;
794 Move<VkPipeline> pipeline;
795 };
796
~ComputeConfiguration()797 ComputeConfiguration::~ComputeConfiguration()
798 {
799 }
800
initConfiguration(Context & context,TestParams & testParams)801 void ComputeConfiguration::initConfiguration (Context& context,
802 TestParams& testParams)
803 {
804 const DeviceInterface& vkd = context.getDeviceInterface();
805 const VkDevice device = context.getDevice();
806
807 descriptorSetLayout = DescriptorSetLayoutBuilder()
808 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
809 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
810 .build(vkd, device);
811 descriptorPool = DescriptorPoolBuilder()
812 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
813 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
814 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
815 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
816 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
817
818 std::vector<std::string> rayQueryTestName;
819 rayQueryTestName.push_back("comp_as_triangle");
820 rayQueryTestName.push_back("comp_as_aabb");
821
822 const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType);
823 shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[bottomTestTypeIdx]), 0u);
824 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
825 {
826 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
827 DE_NULL, // const void* pNext;
828 0u, // VkPipelineShaderStageCreateFlags flags;
829 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
830 *shaderModule, // VkShaderModule module;
831 "main", // const char* pName;
832 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
833 };
834 const VkComputePipelineCreateInfo pipelineCreateInfo =
835 {
836 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
837 DE_NULL, // const void* pNext;
838 0u, // VkPipelineCreateFlags flags;
839 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage;
840 *pipelineLayout, // VkPipelineLayout layout;
841 DE_NULL, // VkPipeline basePipelineHandle;
842 0, // deInt32 basePipelineIndex;
843 };
844
845 pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
846 }
847
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)848 void ComputeConfiguration::fillCommandBuffer (Context& context,
849 TestParams& testParams,
850 VkCommandBuffer commandBuffer,
851 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
852 const VkDescriptorImageInfo& resultImageInfo)
853 {
854 const DeviceInterface& vkd = context.getDeviceInterface();
855 const VkDevice device = context.getDevice();
856
857 DescriptorSetUpdateBuilder()
858 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
859 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
860 .update(vkd, device);
861
862 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
863
864 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
865
866 vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1);
867 }
868
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)869 bool ComputeConfiguration::verifyImage (BufferWithMemory* resultBuffer,
870 Context& context,
871 TestParams& testParams)
872 {
873 // create result image
874 const bool allMiss = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
875 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
876 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
877
878 // create reference image
879 std::vector<deUint32> reference(testParams.width * testParams.height * 2);
880 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
881
882 tcu::UVec4 hitValue0 = tcu::UVec4(1, 0, 0, 0);
883 tcu::UVec4 hitValue1 = tcu::UVec4(1, 0, 0, 0);
884 tcu::UVec4 missValue = tcu::UVec4(0, 0, 0, 0);
885
886 tcu::clear(referenceAccess, missValue);
887
888 for (deUint32 y = 0; y < testParams.height; ++y)
889 for (deUint32 x = 0; x < testParams.width; ++x)
890 {
891 if (allMiss || ((x + y) % 2) == 0)
892 continue;
893
894 referenceAccess.setPixel(hitValue0, x, y, 0);
895 referenceAccess.setPixel(hitValue1, x, y, 1);
896 }
897
898 // compare result and reference
899 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
900 }
901
getResultImageFormat()902 VkFormat ComputeConfiguration::getResultImageFormat ()
903 {
904 return VK_FORMAT_R32_UINT;
905 }
906
getResultImageFormatSize()907 size_t ComputeConfiguration::getResultImageFormatSize ()
908 {
909 return sizeof(deUint32);
910 }
911
getClearValue()912 VkClearValue ComputeConfiguration::getClearValue ()
913 {
914 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
915 }
916
917 class RayTracingConfiguration : public TestConfiguration
918 {
919 public:
920 virtual ~RayTracingConfiguration ();
921 void initConfiguration (Context& context,
922 TestParams& testParams) override;
923 void fillCommandBuffer (Context& context,
924 TestParams& testParams,
925 VkCommandBuffer commandBuffer,
926 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
927 const VkDescriptorImageInfo& resultImageInfo) override;
928 bool verifyImage (BufferWithMemory* resultBuffer,
929 Context& context,
930 TestParams& testParams) override;
931 VkFormat getResultImageFormat () override;
932 size_t getResultImageFormatSize () override;
933 VkClearValue getClearValue () override;
934 protected:
935 Move<VkDescriptorSetLayout> descriptorSetLayout;
936 Move<VkDescriptorPool> descriptorPool;
937 Move<VkDescriptorSet> descriptorSet;
938 Move<VkPipelineLayout> pipelineLayout;
939
940 de::MovePtr<RayTracingPipeline> rayTracingPipeline;
941 Move<VkPipeline> rtPipeline;
942
943 de::MovePtr<BufferWithMemory> raygenShaderBindingTable;
944 de::MovePtr<BufferWithMemory> hitShaderBindingTable;
945 de::MovePtr<BufferWithMemory> missShaderBindingTable;
946 de::MovePtr<BufferWithMemory> callableShaderBindingTable;
947
948 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelAccelerationStructures;
949 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
950 };
951
~RayTracingConfiguration()952 RayTracingConfiguration::~RayTracingConfiguration()
953 {
954 }
955
initConfiguration(Context & context,TestParams & testParams)956 void RayTracingConfiguration::initConfiguration (Context& context,
957 TestParams& testParams)
958 {
959 const InstanceInterface& vki = context.getInstanceInterface();
960 const DeviceInterface& vkd = context.getDeviceInterface();
961 const VkDevice device = context.getDevice();
962 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
963 Allocator& allocator = context.getDefaultAllocator();
964
965 descriptorSetLayout = DescriptorSetLayoutBuilder()
966 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
967 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
968 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
969 .build(vkd, device);
970 descriptorPool = DescriptorPoolBuilder()
971 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
972 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
973 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
974 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
975 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
976 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
977
978 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
979
980 const std::map<ShaderSourceType,std::vector<std::string>> shaderNames =
981 {
982 //idx: 0 1 2 3 4 5
983 //shader: rgen, isect, ahit, chit, miss, call
984 //group: 0 1 1 1 2 3
985 { SST_RAY_GENERATION_SHADER, { "rgen_%s", "", "", "", "", "" } },
986 { SST_INTERSECTION_SHADER, { "rgen", "isect_%s", "", "chit_isect", "miss", "" } },
987 { SST_ANY_HIT_SHADER, { "rgen", "isect", "ahit_%s", "", "miss", "" } },
988 { SST_CLOSEST_HIT_SHADER, { "rgen", "isect", "", "chit_%s", "miss", "" } },
989 { SST_MISS_SHADER, { "rgen", "isect", "", "chit", "miss_%s", "" } },
990 { SST_CALLABLE_SHADER, { "rgen_call", "", "", "chit", "miss", "call_%s" } },
991 };
992
993 std::vector<std::string> rayQueryTestName;
994 rayQueryTestName.push_back("as_triangle");
995 rayQueryTestName.push_back("as_aabb");
996
997 auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
998 if(shaderNameIt == end(shaderNames))
999 TCU_THROW(InternalError, "Wrong shader source type");
1000
1001 bool rgenX, isectX, ahitX, chitX, missX, callX;
1002 const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType);
1003 rgenX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_RAYGEN_BIT_KHR, shaderNameIt->second[0], rayQueryTestName[bottomTestTypeIdx], 0);
1004 if (testParams.shaderSourceType == SST_INTERSECTION_SHADER)
1005 isectX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_INTERSECTION_BIT_KHR, shaderNameIt->second[1], rayQueryTestName[bottomTestTypeIdx], 1);
1006 else
1007 isectX = false;
1008 ahitX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_ANY_HIT_BIT_KHR, shaderNameIt->second[2], rayQueryTestName[bottomTestTypeIdx], 1);
1009 chitX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, shaderNameIt->second[3], rayQueryTestName[bottomTestTypeIdx], 1);
1010 missX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_MISS_BIT_KHR, shaderNameIt->second[4], rayQueryTestName[bottomTestTypeIdx], 2);
1011 callX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CALLABLE_BIT_KHR, shaderNameIt->second[5], rayQueryTestName[bottomTestTypeIdx], 3);
1012 bool hitX = isectX || ahitX || chitX;
1013
1014 rtPipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
1015
1016 deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1017 deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1018
1019 if (rgenX) raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
1020 if (hitX) hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1021 if (missX) missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
1022 if (callX) callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
1023 }
1024
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)1025 void RayTracingConfiguration::fillCommandBuffer (Context& context,
1026 TestParams& testParams,
1027 VkCommandBuffer commandBuffer,
1028 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
1029 const VkDescriptorImageInfo& resultImageInfo)
1030 {
1031 const InstanceInterface& vki = context.getInstanceInterface();
1032 const DeviceInterface& vkd = context.getDeviceInterface();
1033 const VkDevice device = context.getDevice();
1034 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1035 Allocator& allocator = context.getDefaultAllocator();
1036
1037 {
1038 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1039 bottomLevelAccelerationStructure->setGeometryCount(1);
1040
1041 de::SharedPtr<RaytracedGeometryBase> geometry;
1042 if (testParams.shaderSourceType != SST_INTERSECTION_SHADER)
1043 {
1044 tcu::Vec3 v0(0.0f, float(testParams.height), 0.0f);
1045 tcu::Vec3 v1(0.0f, 0.0f, 0.0f);
1046 tcu::Vec3 v2(float(testParams.width), float(testParams.height), 0.0f);
1047 tcu::Vec3 v3(float(testParams.width), 0.0f, 0.0f);
1048 tcu::Vec3 missOffset(0.0f, 0.0f, 0.0f);
1049 if (testParams.shaderSourceType == SST_MISS_SHADER)
1050 missOffset = tcu::Vec3(1.0f + float(testParams.width), 0.0f, 0.0f);
1051
1052 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1053 geometry->addVertex(v0 + missOffset);
1054 geometry->addVertex(v1 + missOffset);
1055 geometry->addVertex(v2 + missOffset);
1056 geometry->addVertex(v2 + missOffset);
1057 geometry->addVertex(v1 + missOffset);
1058 geometry->addVertex(v3 + missOffset);
1059 }
1060 else // testParams.shaderSourceType == SST_INTERSECTION_SHADER
1061 {
1062 tcu::Vec3 v0(0.0f, 0.0f, -0.1f);
1063 tcu::Vec3 v1(float(testParams.width), float(testParams.height), 0.1f);
1064
1065 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1066 geometry->addVertex(v0);
1067 geometry->addVertex(v1);
1068 }
1069 bottomLevelAccelerationStructure->addGeometry(geometry);
1070 bottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1071
1072 for (auto& blas : bottomLevelAccelerationStructures)
1073 blas->createAndBuild(vkd, device, commandBuffer, allocator);
1074 }
1075
1076 topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1077 topLevelAccelerationStructure->setInstanceCount(1);
1078 topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]);
1079 topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1080
1081 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
1082 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1083 {
1084 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1085 DE_NULL, // const void* pNext;
1086 1u, // deUint32 accelerationStructureCount;
1087 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
1088 };
1089
1090 DescriptorSetUpdateBuilder()
1091 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1092 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1093 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1094 .update(vkd, device);
1095
1096 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1097
1098 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline);
1099
1100 deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1101 VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = raygenShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1102 VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = hitShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1103 VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = missShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1104 VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = callableShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1105
1106 cmdTraceRays(vkd,
1107 commandBuffer,
1108 &raygenShaderBindingTableRegion,
1109 &missShaderBindingTableRegion,
1110 &hitShaderBindingTableRegion,
1111 &callableShaderBindingTableRegion,
1112 testParams.width, testParams.height, 1);
1113 }
1114
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1115 bool RayTracingConfiguration::verifyImage (BufferWithMemory* resultBuffer,
1116 Context& context,
1117 TestParams& testParams)
1118 {
1119 // create result image
1120 const bool allMiss = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
1121 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
1122 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
1123
1124 // create reference image
1125 std::vector<deUint32> reference(testParams.width * testParams.height * 2);
1126 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
1127
1128 tcu::UVec4 missValue (0, 0, 0, 0);
1129 tcu::UVec4 hitValue (1, 0, 0, 0);
1130
1131 for (deUint32 y = 0; y < testParams.height; ++y)
1132 for (deUint32 x = 0; x < testParams.width; ++x)
1133 {
1134 if (allMiss || ((x + y) % 2) == 0)
1135 {
1136 referenceAccess.setPixel(missValue, x, y, 0);
1137 referenceAccess.setPixel(missValue, x, y, 1);
1138 }
1139 else
1140 {
1141 referenceAccess.setPixel(hitValue, x, y, 0);
1142 referenceAccess.setPixel(hitValue, x, y, 1);
1143 }
1144 }
1145
1146 // compare result and reference
1147 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
1148 }
1149
getResultImageFormat()1150 VkFormat RayTracingConfiguration::getResultImageFormat ()
1151 {
1152 return VK_FORMAT_R32_UINT;
1153 }
1154
getResultImageFormatSize()1155 size_t RayTracingConfiguration::getResultImageFormatSize ()
1156 {
1157 return sizeof(deUint32);
1158 }
1159
getClearValue()1160 VkClearValue RayTracingConfiguration::getClearValue ()
1161 {
1162 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1163 }
1164
createTestConfiguration(const ShaderSourcePipeline & shaderSourcePipeline)1165 de::SharedPtr<TestConfiguration> createTestConfiguration(const ShaderSourcePipeline& shaderSourcePipeline)
1166 {
1167 switch (shaderSourcePipeline)
1168 {
1169 case SSP_GRAPHICS_PIPELINE:
1170 return de::SharedPtr<TestConfiguration>(new GraphicsConfiguration());
1171 case SSP_COMPUTE_PIPELINE:
1172 return de::SharedPtr<TestConfiguration>(new ComputeConfiguration());
1173 case SSP_RAY_TRACING_PIPELINE:
1174 return de::SharedPtr<TestConfiguration>(new RayTracingConfiguration());
1175 default:
1176 TCU_THROW(InternalError, "Wrong shader source pipeline");
1177 }
1178 return de::SharedPtr<TestConfiguration>();
1179 }
1180
1181 class CheckerboardSceneBuilder : public SceneBuilder
1182 {
1183 public:
1184 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (Context& context,
1185 TestParams& testParams) override;
1186 de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (Context& context,
1187 TestParams& testParams,
1188 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) override;
1189 };
1190
initBottomAccelerationStructures(Context & context,TestParams & testParams)1191 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> CheckerboardSceneBuilder::initBottomAccelerationStructures (Context& context,
1192 TestParams& testParams)
1193 {
1194 DE_UNREF(context);
1195
1196 // Cull flags can only be used with triangles.
1197 DE_ASSERT(testParams.cullFlags == InstanceCullFlags::NONE || testParams.bottomTestType == BottomTestType::TRIANGLES);
1198
1199 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > result;
1200
1201 const auto instanceFlags = getCullFlags(testParams.cullFlags);
1202
1203 tcu::Vec3 v0(0.0, 1.0, 0.0);
1204 tcu::Vec3 v1(0.0, 0.0, 0.0);
1205 tcu::Vec3 v2(1.0, 1.0, 0.0);
1206 tcu::Vec3 v3(1.0, 0.0, 0.0);
1207
1208 // Different vertex configurations of a triangle whose parameter x is set to NaN during inactive_triangles tests
1209 const bool nanConfig[4][4] =
1210 {
1211 { true, true, true, true },
1212 { false, true, true, false },
1213 { false, false, true, false },
1214 { false, true, false, false },
1215 };
1216
1217 unsigned int geometryCount = testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES ? 4U : 1U;
1218
1219 if (testParams.topTestType == TopTestType::DIFFERENT_INSTANCES)
1220 {
1221 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1222 bottomLevelAccelerationStructure->setGeometryCount(1u);
1223 de::SharedPtr<RaytracedGeometryBase> geometry;
1224 if (testParams.bottomTestType == BottomTestType::TRIANGLES)
1225 {
1226 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1227 if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1228 {
1229 if (instanceFlags == 0u)
1230 {
1231 geometry->addVertex(v0);
1232 geometry->addVertex(v1);
1233 geometry->addVertex(v2);
1234 geometry->addVertex(v2);
1235 geometry->addVertex(v1);
1236 geometry->addVertex(v3);
1237 }
1238 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1239 {
1240 geometry->addVertex(v2);
1241 geometry->addVertex(v1);
1242 geometry->addVertex(v0);
1243 geometry->addVertex(v3);
1244 geometry->addVertex(v1);
1245 geometry->addVertex(v2);
1246 }
1247 }
1248 else // m_data.indexType != VK_INDEX_TYPE_NONE_KHR
1249 {
1250 geometry->addVertex(v0);
1251 geometry->addVertex(v1);
1252 geometry->addVertex(v2);
1253 geometry->addVertex(v3);
1254
1255 if (instanceFlags == 0u)
1256 {
1257 geometry->addIndex(0);
1258 geometry->addIndex(1);
1259 geometry->addIndex(2);
1260 geometry->addIndex(2);
1261 geometry->addIndex(1);
1262 geometry->addIndex(3);
1263 }
1264 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1265 {
1266 geometry->addIndex(2);
1267 geometry->addIndex(1);
1268 geometry->addIndex(0);
1269 geometry->addIndex(3);
1270 geometry->addIndex(1);
1271 geometry->addIndex(2);
1272 }
1273
1274 }
1275 }
1276 else // m_data.bottomTestType == BTT_AABBS
1277 {
1278 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1279
1280 if (!testParams.padVertices)
1281 {
1282 // Single AABB.
1283 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1284 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1285 }
1286 else
1287 {
1288 // Multiple AABBs covering the same space.
1289 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1290 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, 0.1f));
1291
1292 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, -0.1f));
1293 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1294
1295 geometry->addVertex(tcu::Vec3(0.0f, 0.5f, -0.1f));
1296 geometry->addVertex(tcu::Vec3(0.5f, 1.0f, 0.1f));
1297
1298 geometry->addVertex(tcu::Vec3(0.5f, 0.0f, -0.1f));
1299 geometry->addVertex(tcu::Vec3(1.0f, 0.5f, 0.1f));
1300 }
1301 }
1302
1303 bottomLevelAccelerationStructure->addGeometry(geometry);
1304 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1305 }
1306 else // m_data.topTestType == TTT_IDENTICAL_INSTANCES
1307 {
1308 tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat);
1309 tcu::Vec3 scale ( 1.0f, 1.0f, 1.0f );
1310 if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1311 scale = tcu::Vec3(1.0f / float(testParams.width), 1.0f / float(testParams.height), 1.0f);
1312
1313 // triangle and aabb tests use geometries/aabbs with different vertex positions and the same identity matrix in each instance data
1314 for (deUint32 y = 0; y < testParams.height; ++y)
1315 for (deUint32 x = 0; x < testParams.width; ++x)
1316 {
1317 // let's build a chessboard of geometries
1318 if (((x + y) % 2) == 0)
1319 continue;
1320 tcu::Vec3 xyz((float)x, (float)y, 0.0f);
1321
1322 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1323 bottomLevelAccelerationStructure->setGeometryCount(geometryCount);
1324
1325 if (testParams.bottomTestType == BottomTestType::TRIANGLES)
1326 {
1327 for (unsigned int i = 0; i < geometryCount; i++)
1328 {
1329 de::SharedPtr<RaytracedGeometryBase> geometry;
1330 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1331
1332 if (testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES)
1333 {
1334 const auto nanValue = tcu::Float32::nan().asFloat();
1335
1336 if (nanConfig[i][0])
1337 v0.x() = nanValue;
1338 if (nanConfig[i][1])
1339 v1.x() = nanValue;
1340 if (nanConfig[i][2])
1341 v2.x() = nanValue;
1342 if (nanConfig[i][3])
1343 v3.x() = nanValue;
1344 }
1345
1346 if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1347 {
1348 if (instanceFlags == 0u)
1349 {
1350 geometry->addVertex(scale * (xyz + v0));
1351 geometry->addVertex(scale * (xyz + v1));
1352 geometry->addVertex(scale * (xyz + v2));
1353 geometry->addVertex(scale * (xyz + v2));
1354 geometry->addVertex(scale * (xyz + v1));
1355 geometry->addVertex(scale * (xyz + v3));
1356 }
1357 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1358 {
1359 geometry->addVertex(scale * (xyz + v2));
1360 geometry->addVertex(scale * (xyz + v1));
1361 geometry->addVertex(scale * (xyz + v0));
1362 geometry->addVertex(scale * (xyz + v3));
1363 geometry->addVertex(scale * (xyz + v1));
1364 geometry->addVertex(scale * (xyz + v2));
1365 }
1366 }
1367
1368 else
1369 {
1370 geometry->addVertex(scale * (xyz + v0));
1371 geometry->addVertex(scale * (xyz + v1));
1372 geometry->addVertex(scale * (xyz + v2));
1373 geometry->addVertex(scale * (xyz + v3));
1374
1375 if (instanceFlags == 0u)
1376 {
1377 geometry->addIndex(0);
1378 geometry->addIndex(1);
1379 geometry->addIndex(2);
1380 geometry->addIndex(2);
1381 geometry->addIndex(1);
1382 geometry->addIndex(3);
1383 }
1384 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1385 {
1386 geometry->addIndex(2);
1387 geometry->addIndex(1);
1388 geometry->addIndex(0);
1389 geometry->addIndex(3);
1390 geometry->addIndex(1);
1391 geometry->addIndex(2);
1392 }
1393 }
1394
1395 bottomLevelAccelerationStructure->addGeometry(geometry);
1396 }
1397 }
1398 else // testParams.bottomTestType == BTT_AABBS
1399 {
1400 de::SharedPtr<RaytracedGeometryBase> geometry;
1401 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1402
1403 if (!testParams.padVertices)
1404 {
1405 // Single AABB.
1406 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1407 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1408 }
1409 else
1410 {
1411 // Multiple AABBs covering the same space.
1412 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1413 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, 0.1f)));
1414
1415 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, -0.1f)));
1416 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1417
1418 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.5f, -0.1f)));
1419 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 1.0f, 0.1f)));
1420
1421 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.0f, -0.1f)));
1422 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 0.5f, 0.1f)));
1423 }
1424
1425 bottomLevelAccelerationStructure->addGeometry(geometry);
1426 }
1427
1428 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1429 }
1430 }
1431
1432 return result;
1433 }
1434
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)1435 de::MovePtr<TopLevelAccelerationStructure> CheckerboardSceneBuilder::initTopAccelerationStructure (Context& context,
1436 TestParams& testParams,
1437 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
1438 {
1439 DE_UNREF(context);
1440
1441 const auto instanceCount = testParams.width * testParams.height / 2u;
1442 const auto instanceFlags = getCullFlags(testParams.cullFlags);
1443
1444 de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure();
1445 result->setInstanceCount(instanceCount);
1446
1447 if (testParams.topTestType == TopTestType::DIFFERENT_INSTANCES)
1448 {
1449
1450 for (deUint32 y = 0; y < testParams.height; ++y)
1451 for (deUint32 x = 0; x < testParams.width; ++x)
1452 {
1453 if (((x + y) % 2) == 0)
1454 continue;
1455 const VkTransformMatrixKHR transformMatrixKHR =
1456 {
1457 { // float matrix[3][4];
1458 { 1.0f, 0.0f, 0.0f, (float)x },
1459 { 0.0f, 1.0f, 0.0f, (float)y },
1460 { 0.0f, 0.0f, 1.0f, 0.0f },
1461 }
1462 };
1463 result->addInstance(bottomLevelAccelerationStructures[0], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags);
1464 }
1465 }
1466 else // testParams.topTestType == TTT_IDENTICAL_INSTANCES
1467 {
1468 tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat);
1469 tcu::Vec3 scale ( 1.0f, 1.0f, 1.0f );
1470 if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1471 scale = tcu::Vec3(float(testParams.width), float(testParams.height), 1.0f);
1472
1473 const VkTransformMatrixKHR transformMatrixKHR =
1474 {
1475 { // float matrix[3][4];
1476 { scale.x(), 0.0f, 0.0f, 0.0f },
1477 { 0.0f, scale.y(), 0.0f, 0.0f },
1478 { 0.0f, 0.0f, scale.z(), 0.0f },
1479 }
1480 };
1481
1482 deUint32 currentInstanceIndex = 0;
1483
1484 for (deUint32 y = 0; y < testParams.height; ++y)
1485 for (deUint32 x = 0; x < testParams.width; ++x)
1486 {
1487 if (((x + y) % 2) == 0)
1488 continue;
1489 result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags);
1490 }
1491 }
1492
1493 return result;
1494 }
1495
commonASTestsCheckSupport(Context & context)1496 void commonASTestsCheckSupport(Context& context)
1497 {
1498 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1499 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1500 context.requireDeviceFunctionality("VK_KHR_ray_query");
1501
1502 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures();
1503 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
1504 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1505
1506 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1507 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
1508 TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1509 }
1510
1511 class RayQueryASBasicTestCase : public TestCase
1512 {
1513 public:
1514 RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const TestParams& data);
1515 ~RayQueryASBasicTestCase (void);
1516
1517 virtual void checkSupport (Context& context) const;
1518 virtual void initPrograms (SourceCollections& programCollection) const;
1519 virtual TestInstance* createInstance (Context& context) const;
1520 protected:
1521 TestParams m_data;
1522 };
1523
1524 class RayQueryASFuncArgTestCase : public RayQueryASBasicTestCase
1525 {
1526 public:
1527 RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const TestParams& data);
~RayQueryASFuncArgTestCase(void)1528 ~RayQueryASFuncArgTestCase (void) {}
1529
1530 virtual void initPrograms (SourceCollections& programCollection) const;
1531 };
1532
1533 class RayQueryASBasicTestInstance : public TestInstance
1534 {
1535 public:
1536 RayQueryASBasicTestInstance (Context& context,
1537 const TestParams& data);
1538 ~RayQueryASBasicTestInstance (void);
1539 tcu::TestStatus iterate (void);
1540 protected:
1541 bool iterateNoWorkers (void);
1542 bool iterateWithWorkers (void);
1543 de::MovePtr<BufferWithMemory> runTest (TestConfiguration* testConfiguration,
1544 SceneBuilder* sceneBuilder,
1545 const deUint32 workerThreadsCount);
1546
1547
1548 private:
1549 TestParams m_data;
1550 };
1551
RayQueryASBasicTestCase(tcu::TestContext & context,const char * name,const TestParams & data)1552 RayQueryASBasicTestCase::RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const TestParams& data)
1553 : vkt::TestCase (context, name)
1554 , m_data (data)
1555 {
1556 }
1557
~RayQueryASBasicTestCase(void)1558 RayQueryASBasicTestCase::~RayQueryASBasicTestCase (void)
1559 {
1560 }
1561
checkSupport(Context & context) const1562 void RayQueryASBasicTestCase::checkSupport (Context& context) const
1563 {
1564 commonASTestsCheckSupport(context);
1565
1566 const VkPhysicalDeviceFeatures2& features2 = context.getDeviceFeatures2();
1567
1568 if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1569 m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1570 features2.features.tessellationShader == DE_FALSE )
1571 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1572
1573 if (m_data.shaderSourceType == SST_GEOMETRY_SHADER &&
1574 features2.features.geometryShader == DE_FALSE )
1575 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1576
1577 if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER ||
1578 m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1579 m_data.shaderSourceType == SST_ANY_HIT_SHADER ||
1580 m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1581 m_data.shaderSourceType == SST_MISS_SHADER ||
1582 m_data.shaderSourceType == SST_CALLABLE_SHADER)
1583 {
1584 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1585
1586 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1587
1588 if(rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
1589 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1590 }
1591
1592 switch (m_data.shaderSourceType)
1593 {
1594 case SST_VERTEX_SHADER:
1595 case SST_TESSELATION_CONTROL_SHADER:
1596 case SST_TESSELATION_EVALUATION_SHADER:
1597 case SST_GEOMETRY_SHADER:
1598 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1599 break;
1600 default:
1601 break;
1602 }
1603
1604 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1605 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE)
1606 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands");
1607
1608 // Check supported vertex format.
1609 checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.vertexFormat);
1610 }
1611
initPrograms(SourceCollections & programCollection) const1612 void RayQueryASBasicTestCase::initPrograms (SourceCollections& programCollection) const
1613 {
1614 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1615
1616 // create parts of programs responsible for test execution
1617 std::vector<std::string> rayQueryTest;
1618 std::vector<std::string> rayQueryTestName;
1619 rayQueryTestName.push_back("as_triangle");
1620 rayQueryTestName.push_back("as_aabb");
1621
1622 {
1623 std::stringstream css;
1624 css <<
1625 " float tmin = 0.0;\n"
1626 " float tmax = 1.0;\n"
1627 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1628 " rayQueryEXT rq;\n"
1629 " rayQueryInitializeEXT(rq, rqTopLevelAS, " << ((m_data.cullFlags == InstanceCullFlags::NONE) ? "0" : "gl_RayFlagsCullBackFacingTrianglesEXT") << ", 0xFF, origin, tmin, direct, tmax);\n"
1630 " if(rayQueryProceedEXT(rq))\n"
1631 " {\n"
1632 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1633 " {\n"
1634 " hitValue.y = 1;\n"
1635 " hitValue.x = 1;\n"
1636 " }\n"
1637 " }\n";
1638 rayQueryTest.push_back(css.str());
1639 }
1640 {
1641 std::stringstream css;
1642 css <<
1643 " float tmin = 0.0;\n"
1644 " float tmax = 1.0;\n"
1645 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1646 " rayQueryEXT rq;\n"
1647 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1648 " if(rayQueryProceedEXT(rq))\n"
1649 " {\n"
1650 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1651 " {\n"
1652 " hitValue.y = 1;\n"
1653 " hitValue.x = 1;\n"
1654 " }\n"
1655 " }\n";
1656 rayQueryTest.push_back(css.str());
1657 }
1658
1659 const auto bottomTestTypeIdx = static_cast<int>(m_data.bottomTestType);
1660
1661 // create all programs
1662 if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1663 {
1664 {
1665 std::stringstream css;
1666 css <<
1667 "#version 460 core\n"
1668 "layout (location = 0) in vec3 position;\n"
1669 "out gl_PerVertex\n"
1670 "{\n"
1671 " vec4 gl_Position;\n"
1672 "};\n"
1673 "void main()\n"
1674 "{\n"
1675 " gl_Position = vec4(position, 1.0);\n"
1676 "}\n";
1677 programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions;
1678 }
1679
1680 {
1681 std::stringstream css;
1682 css <<
1683 "#version 460 core\n"
1684 "layout (location = 0) in vec3 position;\n"
1685 "out gl_PerVertex\n"
1686 "{\n"
1687 " vec4 gl_Position;\n"
1688 "};\n"
1689 "layout(location = 0) out int vertexIndex;\n"
1690 "void main()\n"
1691 "{\n"
1692 " gl_Position = vec4(position, 1.0);\n"
1693 " vertexIndex = gl_VertexIndex;\n"
1694 "}\n";
1695 programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str()) << buildOptions;
1696 }
1697
1698 {
1699 std::stringstream css;
1700 css <<
1701 "#version 460 core\n"
1702 "#extension GL_EXT_ray_query : require\n"
1703 "layout (location = 0) in vec3 position;\n"
1704 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1705 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1706 "void main()\n"
1707 "{\n"
1708 " vec3 origin = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n"
1709 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1710 rayQueryTest[bottomTestTypeIdx] <<
1711 " imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1712 " imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1713 " gl_Position = vec4(position,1);\n"
1714 "}\n";
1715 std::stringstream cssName;
1716 cssName << "vert_" << rayQueryTestName[bottomTestTypeIdx];
1717
1718 programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1719 }
1720
1721 {
1722 std::stringstream css;
1723 css <<
1724 "#version 460 core\n"
1725 "#extension GL_EXT_tessellation_shader : require\n"
1726 "in gl_PerVertex {\n"
1727 " vec4 gl_Position;\n"
1728 "} gl_in[];\n"
1729 "layout(vertices = 3) out;\n"
1730 "void main (void)\n"
1731 "{\n"
1732 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1733 " gl_TessLevelInner[0] = 1;\n"
1734 " gl_TessLevelOuter[0] = 1;\n"
1735 " gl_TessLevelOuter[1] = 1;\n"
1736 " gl_TessLevelOuter[2] = 1;\n"
1737 "}\n";
1738 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions;
1739 }
1740
1741 {
1742 std::stringstream css;
1743 css <<
1744 "#version 460 core\n"
1745 "#extension GL_EXT_tessellation_shader : require\n"
1746 "#extension GL_EXT_ray_query : require\n"
1747 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1748 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1749 "in gl_PerVertex {\n"
1750 " vec4 gl_Position;\n"
1751 "} gl_in[];\n"
1752 "layout(vertices = 3) out;\n"
1753 "void main (void)\n"
1754 "{\n"
1755 " vec3 origin = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n"
1756 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1757 rayQueryTest[bottomTestTypeIdx] <<
1758 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1759 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1760 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1761 " gl_TessLevelInner[0] = 1;\n"
1762 " gl_TessLevelOuter[0] = 1;\n"
1763 " gl_TessLevelOuter[1] = 1;\n"
1764 " gl_TessLevelOuter[2] = 1;\n"
1765 "}\n";
1766 std::stringstream cssName;
1767 cssName << "tesc_" << rayQueryTestName[bottomTestTypeIdx];
1768
1769 programCollection.glslSources.add(cssName.str()) << glu::TessellationControlSource(css.str()) << buildOptions;
1770 }
1771
1772 {
1773 std::stringstream css;
1774 css <<
1775 "#version 460 core\n"
1776 "#extension GL_EXT_tessellation_shader : require\n"
1777 "#extension GL_EXT_ray_query : require\n"
1778 "layout(triangles, equal_spacing, ccw) in;\n"
1779 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1780 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1781 "void main (void)\n"
1782 "{\n"
1783 " for (int i = 0; i < 3; ++i)\n"
1784 " {\n"
1785 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1786 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1787 rayQueryTest[bottomTestTypeIdx] <<
1788 " imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1789 " imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1790 " }\n"
1791 " gl_Position = gl_in[0].gl_Position;\n"
1792 "}\n";
1793 std::stringstream cssName;
1794 cssName << "tese_" << rayQueryTestName[bottomTestTypeIdx];
1795
1796 programCollection.glslSources.add(cssName.str()) << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1797 }
1798
1799 {
1800 std::stringstream css;
1801 css <<
1802 "#version 460 core\n"
1803 "#extension GL_EXT_tessellation_shader : require\n"
1804 "layout(triangles, equal_spacing, ccw) in;\n"
1805 "void main (void)\n"
1806 "{\n"
1807 " gl_Position = gl_in[0].gl_Position;\n"
1808 "}\n";
1809
1810 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1811 }
1812
1813 {
1814 std::stringstream css;
1815 css <<
1816 "#version 460 core\n"
1817 "#extension GL_EXT_ray_query : require\n"
1818 "layout(triangles) in;\n"
1819 "layout (triangle_strip, max_vertices = 4) out;\n"
1820 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1821 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1822 "\n"
1823 "in gl_PerVertex {\n"
1824 " vec4 gl_Position;\n"
1825 "} gl_in[];\n"
1826 "layout(location = 0) in int vertexIndex[];\n"
1827 "out gl_PerVertex {\n"
1828 " vec4 gl_Position;\n"
1829 "};\n"
1830 "void main (void)\n"
1831 "{\n"
1832 " // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n"
1833 " // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n"
1834 " // smallest vertex index value.\n"
1835 " int minVertexIndex = 10000;"
1836 " int firstVertex;"
1837 " for (int i = 0; i < gl_in.length(); ++i)\n"
1838 " {\n"
1839 " if (minVertexIndex > vertexIndex[i])\n"
1840 " {\n"
1841 " minVertexIndex = vertexIndex[i];\n"
1842 " firstVertex = i;\n"
1843 " }\n"
1844 " }\n"
1845 " for (int j = 0; j < gl_in.length(); ++j)\n"
1846 " {\n"
1847 " // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n"
1848 " // always iterated starting from the smallest vertex index, as found above.\n"
1849 " int i = (firstVertex + j) % gl_in.length();\n"
1850 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1851 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1852 rayQueryTest[bottomTestTypeIdx] <<
1853 " imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1854 " imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1855 " gl_Position = gl_in[i].gl_Position;\n"
1856 " EmitVertex();\n"
1857 " }\n"
1858 " EndPrimitive();\n"
1859 "}\n";
1860 std::stringstream cssName;
1861 cssName << "geom_" << rayQueryTestName[bottomTestTypeIdx];
1862
1863 programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1864 }
1865
1866 {
1867 std::stringstream css;
1868 css <<
1869 "#version 460 core\n"
1870 "#extension GL_EXT_ray_query : require\n"
1871 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1872 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1873 "void main()\n"
1874 "{\n"
1875 " vec3 origin = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n"
1876 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1877 rayQueryTest[bottomTestTypeIdx] <<
1878 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1879 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1880 "}\n";
1881 std::stringstream cssName;
1882 cssName << "frag_" << rayQueryTestName[bottomTestTypeIdx];
1883
1884 programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1885 }
1886 }
1887 else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1888 {
1889 {
1890 std::stringstream css;
1891 css <<
1892 "#version 460 core\n"
1893 "#extension GL_EXT_ray_query : require\n"
1894 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1895 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1896 "void main()\n"
1897 "{\n"
1898 " vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);\n"
1899 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1900 rayQueryTest[bottomTestTypeIdx] <<
1901 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1902 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1903 "}\n";
1904 std::stringstream cssName;
1905 cssName << "comp_" << rayQueryTestName[bottomTestTypeIdx];
1906
1907 programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1908 }
1909 }
1910 else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1911 {
1912 {
1913 std::stringstream css;
1914 css <<
1915 "#version 460 core\n"
1916 "#extension GL_EXT_ray_tracing : require\n"
1917 "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1918 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1919 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1920 "void main()\n"
1921 "{\n"
1922 " float tmin = 0.0;\n"
1923 " float tmax = 1.0;\n"
1924 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1925 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1926 " hitValue = uvec4(0,0,0,0);\n"
1927 " traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1928 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1929 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1930 "}\n";
1931 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1932 }
1933
1934 {
1935 std::stringstream css;
1936 css <<
1937 "#version 460 core\n"
1938 "#extension GL_EXT_ray_tracing : require\n"
1939 "#extension GL_EXT_ray_query : require\n"
1940 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1941 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1942 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1943 "void main()\n"
1944 "{\n"
1945 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1946 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1947 rayQueryTest[bottomTestTypeIdx] <<
1948 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1949 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1950 "}\n";
1951 std::stringstream cssName;
1952 cssName << "rgen_" << rayQueryTestName[bottomTestTypeIdx];
1953
1954 programCollection.glslSources.add(cssName.str()) << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1955 }
1956
1957 {
1958 std::stringstream css;
1959 css <<
1960 "#version 460 core\n"
1961 "#extension GL_EXT_ray_tracing : require\n"
1962 "struct CallValue\n{\n"
1963 " vec3 origin;\n"
1964 " uvec4 hitValue;\n"
1965 "};\n"
1966 "layout(location = 0) callableDataEXT CallValue param;\n"
1967 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1968 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1969 "void main()\n"
1970 "{\n"
1971 " param.origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1972 " param.hitValue = uvec4(0, 0, 0, 0);\n"
1973 " executeCallableEXT(0, 0);\n"
1974 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
1975 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
1976 "}\n";
1977 programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1978 }
1979
1980 {
1981 std::stringstream css;
1982 css <<
1983 "#version 460 core\n"
1984 "#extension GL_EXT_ray_tracing : require\n"
1985 "hitAttributeEXT uvec4 hitValue;\n"
1986 "void main()\n"
1987 "{\n"
1988 " reportIntersectionEXT(0.5f, 0);\n"
1989 "}\n";
1990
1991 programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1992 }
1993
1994 {
1995 std::stringstream css;
1996 css <<
1997 "#version 460 core\n"
1998 "#extension GL_EXT_ray_tracing : require\n"
1999 "#extension GL_EXT_ray_query : require\n"
2000 "hitAttributeEXT uvec4 hitValue;\n"
2001 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2002 "void main()\n"
2003 "{\n"
2004 " vec3 origin = gl_WorldRayOriginEXT;\n"
2005 " hitValue = uvec4(0,0,0,0);\n" <<
2006 rayQueryTest[bottomTestTypeIdx] <<
2007 " reportIntersectionEXT(0.5f, 0);\n"
2008 "}\n";
2009 std::stringstream cssName;
2010 cssName << "isect_" << rayQueryTestName[bottomTestTypeIdx];
2011
2012 programCollection.glslSources.add(cssName.str()) << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
2013 }
2014
2015 {
2016 std::stringstream css;
2017 css <<
2018 "#version 460 core\n"
2019 "#extension GL_EXT_ray_tracing : require\n"
2020 "#extension GL_EXT_ray_query : require\n"
2021 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2022 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2023 "void main()\n"
2024 "{\n"
2025 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
2026 rayQueryTest[bottomTestTypeIdx] <<
2027 "}\n";
2028 std::stringstream cssName;
2029 cssName << "ahit_" << rayQueryTestName[bottomTestTypeIdx];
2030
2031 programCollection.glslSources.add(cssName.str()) << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2032 }
2033
2034 {
2035 std::stringstream css;
2036 css <<
2037 "#version 460 core\n"
2038 "#extension GL_EXT_ray_tracing : require\n"
2039 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2040 "void main()\n"
2041 "{\n"
2042 " hitValue.y = 3;\n"
2043 "}\n";
2044
2045 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2046 }
2047
2048 {
2049 std::stringstream css;
2050 css <<
2051 "#version 460 core\n"
2052 "#extension GL_EXT_ray_tracing : require\n"
2053 "#extension GL_EXT_ray_query : require\n"
2054 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2055 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2056 "void main()\n"
2057 "{\n"
2058 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
2059 rayQueryTest[bottomTestTypeIdx] <<
2060 "}\n";
2061 std::stringstream cssName;
2062 cssName << "chit_" << rayQueryTestName[bottomTestTypeIdx];
2063
2064 programCollection.glslSources.add(cssName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2065 }
2066
2067 {
2068 std::stringstream css;
2069 css <<
2070 "#version 460 core\n"
2071 "#extension GL_EXT_ray_tracing : require\n"
2072 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2073 "hitAttributeEXT uvec4 hitAttrib;\n"
2074 "void main()\n"
2075 "{\n"
2076 " hitValue = hitAttrib;\n"
2077 "}\n";
2078
2079 programCollection.glslSources.add("chit_isect") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2080 }
2081
2082 {
2083 std::stringstream css;
2084 css <<
2085 "#version 460 core\n"
2086 "#extension GL_EXT_ray_tracing : require\n"
2087 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2088 "void main()\n"
2089 "{\n"
2090 " hitValue.x = 4;\n"
2091 "}\n";
2092
2093 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2094 }
2095
2096 {
2097 std::stringstream css;
2098 css <<
2099 "#version 460 core\n"
2100 "#extension GL_EXT_ray_tracing : require\n"
2101 "#extension GL_EXT_ray_query : require\n"
2102 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2103 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2104 "void main()\n"
2105 "{\n"
2106 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
2107 rayQueryTest[bottomTestTypeIdx] <<
2108 "}\n";
2109 std::stringstream cssName;
2110 cssName << "miss_" << rayQueryTestName[bottomTestTypeIdx];
2111
2112 programCollection.glslSources.add(cssName.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2113 }
2114
2115 {
2116 std::stringstream css;
2117 css <<
2118 "#version 460 core\n"
2119 "#extension GL_EXT_ray_tracing : require\n"
2120 "#extension GL_EXT_ray_query : require\n"
2121 "struct CallValue\n{\n"
2122 " vec3 origin;\n"
2123 " uvec4 hitValue;\n"
2124 "};\n"
2125 "layout(location = 0) callableDataInEXT CallValue result;\n"
2126 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2127 "void main()\n"
2128 "{\n"
2129 " vec3 origin = result.origin;\n"
2130 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
2131 rayQueryTest[bottomTestTypeIdx] <<
2132 " result.hitValue = hitValue;\n"
2133 "}\n";
2134 std::stringstream cssName;
2135 cssName << "call_" << rayQueryTestName[bottomTestTypeIdx];
2136
2137 programCollection.glslSources.add(cssName.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
2138 }
2139 }
2140 }
2141
createInstance(Context & context) const2142 TestInstance* RayQueryASBasicTestCase::createInstance (Context& context) const
2143 {
2144 return new RayQueryASBasicTestInstance(context, m_data);
2145 }
2146
RayQueryASFuncArgTestCase(tcu::TestContext & context,const char * name,const TestParams & data)2147 RayQueryASFuncArgTestCase::RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const TestParams& data)
2148 : RayQueryASBasicTestCase (context, name, data)
2149 {
2150 }
2151
initPrograms(SourceCollections & programCollection) const2152 void RayQueryASFuncArgTestCase::initPrograms (SourceCollections& programCollection) const
2153 {
2154 const vk::SpirVAsmBuildOptions spvBuildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2155
2156 DE_ASSERT(m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE);
2157 DE_ASSERT(m_data.bottomTestType == BottomTestType::TRIANGLES);
2158
2159 // The SPIR-V assembly shader below is based on the following GLSL code.
2160 // In it, rayQueryInitializeBottomWrapper has been modified to take a
2161 // bare AS as the second argument, instead of a pointer.
2162 //
2163 // #version 460 core
2164 // #extension GL_EXT_ray_query : require
2165 // layout(r32ui, set = 0, binding = 0) uniform uimage3D result;
2166 // layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;
2167 //
2168 // void rayQueryInitializeBottomWrapper(rayQueryEXT rayQuery,
2169 // accelerationStructureEXT topLevel,
2170 // uint rayFlags, uint cullMask, vec3 origin,
2171 // float tMin, vec3 direction, float tMax)
2172 // {
2173 // rayQueryInitializeEXT(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2174 // }
2175 //
2176 // void rayQueryInitializeTopWrapper(rayQueryEXT rayQuery,
2177 // accelerationStructureEXT topLevel,
2178 // uint rayFlags, uint cullMask, vec3 origin,
2179 // float tMin, vec3 direction, float tMax)
2180 // {
2181 // rayQueryInitializeBottomWrapper(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2182 // }
2183 //
2184 // void main()
2185 // {
2186 // vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);
2187 // uvec4 hitValue = uvec4(0,0,0,0);
2188 // float tmin = 0.0;
2189 // float tmax = 1.0;
2190 // vec3 direct = vec3(0.0, 0.0, -1.0);
2191 // rayQueryEXT rq;
2192 // rayQueryInitializeTopWrapper(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);
2193 // if(rayQueryProceedEXT(rq))
2194 // {
2195 // if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)
2196 // {
2197 // hitValue.y = 1;
2198 // hitValue.x = 1;
2199 // }
2200 // }
2201 // imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));
2202 // imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));
2203 // }
2204
2205 std::stringstream css;
2206 css
2207 << "; SPIR-V\n"
2208 << "; Version: 1.4\n"
2209 << "; Generator: Khronos Glslang Reference Front End; 10\n"
2210 << "; Bound: 139\n"
2211 << "; Schema: 0\n"
2212 << "OpCapability Shader\n"
2213 << "OpCapability RayQueryKHR\n"
2214 << "OpExtension \"SPV_KHR_ray_query\"\n"
2215 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
2216 << "OpMemoryModel Logical GLSL450\n"
2217 << "OpEntryPoint GLCompute %4 \"main\" %60 %86 %114\n"
2218 << "OpExecutionMode %4 LocalSize 1 1 1\n"
2219 << "OpDecorate %60 BuiltIn GlobalInvocationId\n"
2220 << "OpDecorate %86 DescriptorSet 0\n"
2221 << "OpDecorate %86 Binding 1\n"
2222 << "OpDecorate %114 DescriptorSet 0\n"
2223 << "OpDecorate %114 Binding 0\n"
2224 << "%2 = OpTypeVoid\n"
2225 << "%3 = OpTypeFunction %2\n"
2226
2227 // Bare query type
2228 << "%6 = OpTypeRayQueryKHR\n"
2229
2230 // Pointer to query.
2231 << "%7 = OpTypePointer Function %6\n"
2232
2233 // Bare AS type.
2234 << "%8 = OpTypeAccelerationStructureKHR\n"
2235
2236 // Pointer to AS.
2237 << "%9 = OpTypePointer UniformConstant %8\n"
2238
2239 << "%10 = OpTypeInt 32 0\n"
2240 << "%11 = OpTypePointer Function %10\n"
2241 << "%12 = OpTypeFloat 32\n"
2242 << "%13 = OpTypeVector %12 3\n"
2243 << "%14 = OpTypePointer Function %13\n"
2244 << "%15 = OpTypePointer Function %12\n"
2245
2246 // This is the function type for rayQueryInitializeTopWrapper and the old rayQueryInitializeBottomWrapper.
2247 << "%16 = OpTypeFunction %2 %7 %9 %11 %11 %14 %15 %14 %15\n"
2248
2249 // This is the new function type for the modified rayQueryInitializeBottomWrapper that uses a bare AS.
2250 //<< "%16b = OpTypeFunction %2 %6 %8 %11 %11 %14 %15 %14 %15\n"
2251 << "%16b = OpTypeFunction %2 %7 %8 %11 %11 %14 %15 %14 %15\n"
2252
2253 << "%58 = OpTypeVector %10 3\n"
2254 << "%59 = OpTypePointer Input %58\n"
2255 << "%60 = OpVariable %59 Input\n"
2256 << "%61 = OpConstant %10 0\n"
2257 << "%62 = OpTypePointer Input %10\n"
2258 << "%66 = OpConstant %12 0.5\n"
2259 << "%68 = OpConstant %10 1\n"
2260 << "%74 = OpTypeVector %10 4\n"
2261 << "%75 = OpTypePointer Function %74\n"
2262 << "%77 = OpConstantComposite %74 %61 %61 %61 %61\n"
2263 << "%79 = OpConstant %12 0\n"
2264 << "%81 = OpConstant %12 1\n"
2265 << "%83 = OpConstant %12 -1\n"
2266 << "%84 = OpConstantComposite %13 %79 %79 %83\n"
2267 << "%86 = OpVariable %9 UniformConstant\n"
2268 << "%87 = OpConstant %10 255\n"
2269 << "%99 = OpTypeBool\n"
2270 << "%103 = OpConstantFalse %99\n"
2271 << "%104 = OpTypeInt 32 1\n"
2272 << "%105 = OpConstant %104 0\n"
2273 << "%112 = OpTypeImage %10 3D 0 0 0 2 R32ui\n"
2274 << "%113 = OpTypePointer UniformConstant %112\n"
2275 << "%114 = OpVariable %113 UniformConstant\n"
2276 << "%116 = OpTypeVector %10 2\n"
2277 << "%119 = OpTypeVector %104 2\n"
2278 << "%121 = OpTypeVector %104 3\n"
2279 << "%132 = OpConstant %104 1\n"
2280
2281 // This is main().
2282 << "%4 = OpFunction %2 None %3\n"
2283 << "%5 = OpLabel\n"
2284 << "%57 = OpVariable %14 Function\n"
2285 << "%76 = OpVariable %75 Function\n"
2286 << "%78 = OpVariable %15 Function\n"
2287 << "%80 = OpVariable %15 Function\n"
2288 << "%82 = OpVariable %14 Function\n"
2289 << "%85 = OpVariable %7 Function\n"
2290 << "%88 = OpVariable %11 Function\n"
2291 << "%89 = OpVariable %11 Function\n"
2292 << "%90 = OpVariable %14 Function\n"
2293 << "%92 = OpVariable %15 Function\n"
2294 << "%94 = OpVariable %14 Function\n"
2295 << "%96 = OpVariable %15 Function\n"
2296 << "%63 = OpAccessChain %62 %60 %61\n"
2297 << "%64 = OpLoad %10 %63\n"
2298 << "%65 = OpConvertUToF %12 %64\n"
2299 << "%67 = OpFAdd %12 %65 %66\n"
2300 << "%69 = OpAccessChain %62 %60 %68\n"
2301 << "%70 = OpLoad %10 %69\n"
2302 << "%71 = OpConvertUToF %12 %70\n"
2303 << "%72 = OpFAdd %12 %71 %66\n"
2304 << "%73 = OpCompositeConstruct %13 %67 %72 %66\n"
2305 << "OpStore %57 %73\n"
2306 << "OpStore %76 %77\n"
2307 << "OpStore %78 %79\n"
2308 << "OpStore %80 %81\n"
2309 << "OpStore %82 %84\n"
2310 << "OpStore %88 %61\n"
2311 << "OpStore %89 %87\n"
2312 << "%91 = OpLoad %13 %57\n"
2313 << "OpStore %90 %91\n"
2314 << "%93 = OpLoad %12 %78\n"
2315 << "OpStore %92 %93\n"
2316 << "%95 = OpLoad %13 %82\n"
2317 << "OpStore %94 %95\n"
2318 << "%97 = OpLoad %12 %80\n"
2319 << "OpStore %96 %97\n"
2320 << "%98 = OpFunctionCall %2 %35 %85 %86 %88 %89 %90 %92 %94 %96\n"
2321 << "%100 = OpRayQueryProceedKHR %99 %85\n"
2322 << "OpSelectionMerge %102 None\n"
2323 << "OpBranchConditional %100 %101 %102\n"
2324 << "%101 = OpLabel\n"
2325 << "%106 = OpRayQueryGetIntersectionTypeKHR %10 %85 %105\n"
2326 << "%107 = OpIEqual %99 %106 %61\n"
2327 << "OpSelectionMerge %109 None\n"
2328 << "OpBranchConditional %107 %108 %109\n"
2329 << "%108 = OpLabel\n"
2330 << "%110 = OpAccessChain %11 %76 %68\n"
2331 << "OpStore %110 %68\n"
2332 << "%111 = OpAccessChain %11 %76 %61\n"
2333 << "OpStore %111 %68\n"
2334 << "OpBranch %109\n"
2335 << "%109 = OpLabel\n"
2336 << "OpBranch %102\n"
2337 << "%102 = OpLabel\n"
2338 << "%115 = OpLoad %112 %114\n"
2339 << "%117 = OpLoad %58 %60\n"
2340 << "%118 = OpVectorShuffle %116 %117 %117 0 1\n"
2341 << "%120 = OpBitcast %119 %118\n"
2342 << "%122 = OpCompositeExtract %104 %120 0\n"
2343 << "%123 = OpCompositeExtract %104 %120 1\n"
2344 << "%124 = OpCompositeConstruct %121 %122 %123 %105\n"
2345 << "%125 = OpAccessChain %11 %76 %61\n"
2346 << "%126 = OpLoad %10 %125\n"
2347 << "%127 = OpCompositeConstruct %74 %126 %61 %61 %61\n"
2348 << "OpImageWrite %115 %124 %127 ZeroExtend\n"
2349 << "%128 = OpLoad %112 %114\n"
2350 << "%129 = OpLoad %58 %60\n"
2351 << "%130 = OpVectorShuffle %116 %129 %129 0 1\n"
2352 << "%131 = OpBitcast %119 %130\n"
2353 << "%133 = OpCompositeExtract %104 %131 0\n"
2354 << "%134 = OpCompositeExtract %104 %131 1\n"
2355 << "%135 = OpCompositeConstruct %121 %133 %134 %132\n"
2356 << "%136 = OpAccessChain %11 %76 %68\n"
2357 << "%137 = OpLoad %10 %136\n"
2358 << "%138 = OpCompositeConstruct %74 %137 %61 %61 %61\n"
2359 << "OpImageWrite %128 %135 %138 ZeroExtend\n"
2360 << "OpReturn\n"
2361 << "OpFunctionEnd\n"
2362
2363 // This is rayQueryInitializeBottomWrapper, calling OpRayQueryInitializeKHR.
2364 // We have modified the function type so it takes bare arguments.
2365 //%25 = OpFunction %2 None %16
2366 << "%25 = OpFunction %2 None %16b\n"
2367
2368 // These is the modified parameter.
2369 << "%17 = OpFunctionParameter %7\n"
2370 //<< "%17 = OpFunctionParameter %6\n"
2371 //%18 = OpFunctionParameter %9
2372 << "%18 = OpFunctionParameter %8\n"
2373
2374 << "%19 = OpFunctionParameter %11\n"
2375 << "%20 = OpFunctionParameter %11\n"
2376 << "%21 = OpFunctionParameter %14\n"
2377 << "%22 = OpFunctionParameter %15\n"
2378 << "%23 = OpFunctionParameter %14\n"
2379 << "%24 = OpFunctionParameter %15\n"
2380 << "%26 = OpLabel\n"
2381
2382 // We no longer need to load this parameter.
2383 //%37 = OpLoad %8 %18
2384
2385 << "%38 = OpLoad %10 %19\n"
2386 << "%39 = OpLoad %10 %20\n"
2387 << "%40 = OpLoad %13 %21\n"
2388 << "%41 = OpLoad %12 %22\n"
2389 << "%42 = OpLoad %13 %23\n"
2390 << "%43 = OpLoad %12 %24\n"
2391
2392 // We call OpRayQueryInitializeKHR with bare arguments.
2393 // Note: some experimental lines to pass a bare rayQuery as the first argument have been commented out.
2394 //OpRayQueryInitializeKHR %17 %37 %38 %39 %40 %41 %42 %43
2395 << "OpRayQueryInitializeKHR %17 %18 %38 %39 %40 %41 %42 %43\n"
2396
2397 << "OpReturn\n"
2398 << "OpFunctionEnd\n"
2399
2400 // This is rayQueryInitializeTopWrapper, calling rayQueryInitializeBottomWrapper.
2401 << "%35 = OpFunction %2 None %16\n"
2402 << "%27 = OpFunctionParameter %7\n"
2403 << "%28 = OpFunctionParameter %9\n"
2404 << "%29 = OpFunctionParameter %11\n"
2405 << "%30 = OpFunctionParameter %11\n"
2406 << "%31 = OpFunctionParameter %14\n"
2407 << "%32 = OpFunctionParameter %15\n"
2408 << "%33 = OpFunctionParameter %14\n"
2409 << "%34 = OpFunctionParameter %15\n"
2410 << "%36 = OpLabel\n"
2411 << "%44 = OpVariable %11 Function\n"
2412 << "%46 = OpVariable %11 Function\n"
2413 << "%48 = OpVariable %14 Function\n"
2414 << "%50 = OpVariable %15 Function\n"
2415 << "%52 = OpVariable %14 Function\n"
2416 << "%54 = OpVariable %15 Function\n"
2417
2418 // We need to load the second argument.
2419 //<< "%27b = OpLoad %6 %27\n"
2420 << "%28b = OpLoad %8 %28\n"
2421
2422 << "%45 = OpLoad %10 %29\n"
2423 << "OpStore %44 %45\n"
2424 << "%47 = OpLoad %10 %30\n"
2425 << "OpStore %46 %47\n"
2426 << "%49 = OpLoad %13 %31\n"
2427 << "OpStore %48 %49\n"
2428 << "%51 = OpLoad %12 %32\n"
2429 << "OpStore %50 %51\n"
2430 << "%53 = OpLoad %13 %33\n"
2431 << "OpStore %52 %53\n"
2432 << "%55 = OpLoad %12 %34\n"
2433 << "OpStore %54 %55\n"
2434
2435 // We call rayQueryInitializeBottomWrapper with the loaded argument.
2436 //%56 = OpFunctionCall %2 %25 %27 %28 %44 %46 %48 %50 %52 %54
2437 //<< "%56 = OpFunctionCall %2 %25 %27b %28b %44 %46 %48 %50 %52 %54\n"
2438 << "%56 = OpFunctionCall %2 %25 %27 %28b %44 %46 %48 %50 %52 %54\n"
2439
2440 << "OpReturn\n"
2441 << "OpFunctionEnd\n"
2442 ;
2443
2444 programCollection.spirvAsmSources.add("comp_as_triangle") << spvBuildOptions << css.str();
2445 }
2446
RayQueryASBasicTestInstance(Context & context,const TestParams & data)2447 RayQueryASBasicTestInstance::RayQueryASBasicTestInstance (Context& context, const TestParams& data)
2448 : vkt::TestInstance (context)
2449 , m_data (data)
2450 {
2451 }
2452
~RayQueryASBasicTestInstance(void)2453 RayQueryASBasicTestInstance::~RayQueryASBasicTestInstance (void)
2454 {
2455 }
2456
runTest(TestConfiguration * testConfiguration,SceneBuilder * sceneBuilder,const deUint32 workerThreadsCount)2457 de::MovePtr<BufferWithMemory> RayQueryASBasicTestInstance::runTest (TestConfiguration* testConfiguration,
2458 SceneBuilder* sceneBuilder,
2459 const deUint32 workerThreadsCount)
2460 {
2461 testConfiguration->initConfiguration(m_context, m_data);
2462
2463 const DeviceInterface& vkd = m_context.getDeviceInterface();
2464 const VkDevice device = m_context.getDevice();
2465 const VkQueue queue = m_context.getUniversalQueue();
2466 Allocator& allocator = m_context.getDefaultAllocator();
2467 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2468
2469 const bool htCopy = (workerThreadsCount != 0) && (m_data.operationType == OP_COPY);
2470 const bool htSerialize = (workerThreadsCount != 0) && (m_data.operationType == OP_SERIALIZE);
2471
2472
2473 const VkFormat imageFormat = testConfiguration->getResultImageFormat();
2474 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
2475 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2476 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2477 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
2478
2479 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2480 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2481 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
2482 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
2483
2484 const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2485
2486 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
2487 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2488
2489 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures;
2490 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
2491 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructureCopies;
2492 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructureCopy;
2493 std::vector<de::SharedPtr<SerialStorage>> bottomSerialized;
2494 std::vector<de::SharedPtr<SerialStorage>> topSerialized;
2495 std::vector<VkDeviceSize> accelerationCompactedSizes;
2496 std::vector<VkDeviceSize> accelerationSerialSizes;
2497 Move<VkQueryPool> m_queryPoolCompact;
2498 Move<VkQueryPool> m_queryPoolSerial;
2499
2500 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2501 {
2502 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
2503 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2504 **image, imageSubresourceRange);
2505 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
2506
2507 const VkClearValue clearValue = testConfiguration->getClearValue();
2508 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
2509
2510 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
2511 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2512 **image, imageSubresourceRange);
2513 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
2514
2515 // build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures )
2516 bool bottomCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2517 bool bottomSerial = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2518 const bool buildWithoutGeom = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM);
2519 const bool bottomNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM);
2520 const bool topNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP);
2521 const bool inactiveInstances = (m_data.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_INSTANCES);
2522 bottomLevelAccelerationStructures = sceneBuilder->initBottomAccelerationStructures(m_context, m_data);
2523 VkBuildAccelerationStructureFlagsKHR allowCompactionFlag = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
2524 VkBuildAccelerationStructureFlagsKHR emptyCompactionFlag = VkBuildAccelerationStructureFlagsKHR(0);
2525 VkBuildAccelerationStructureFlagsKHR bottomCompactFlags = (bottomCompact ? allowCompactionFlag : emptyCompactionFlag);
2526 VkBuildAccelerationStructureFlagsKHR bottomBuildFlags = m_data.buildFlags | bottomCompactFlags;
2527 std::vector<VkAccelerationStructureKHR> accelerationStructureHandles;
2528 std::vector<VkDeviceSize> bottomBlasCompactSize;
2529 std::vector<VkDeviceSize> bottomBlasSerialSize;
2530
2531 for (auto& blas : bottomLevelAccelerationStructures)
2532 {
2533 blas->setBuildType (m_data.buildType);
2534 blas->setBuildFlags (bottomBuildFlags);
2535 blas->setUseArrayOfPointers (m_data.bottomUsesAOP);
2536 blas->setCreateGeneric (m_data.bottomGeneric);
2537 blas->setCreationBufferUnbounded (m_data.bottomUnboundedCreation);
2538 blas->setBuildWithoutGeometries (buildWithoutGeom);
2539 blas->setBuildWithoutPrimitives (bottomNoPrimitives);
2540 blas->createAndBuild (vkd, device, *cmdBuffer, allocator);
2541 accelerationStructureHandles.push_back (*(blas->getPtr()));
2542 }
2543
2544 if (m_data.operationType == OP_COMPACT)
2545 {
2546 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
2547 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2548 m_queryPoolCompact = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount);
2549 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2550 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize);
2551 }
2552 if (m_data.operationType == OP_SERIALIZE)
2553 {
2554 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
2555 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2556 m_queryPoolSerial = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
2557 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2558 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize);
2559 }
2560
2561 // if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
2562 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial))
2563 {
2564 endCommandBuffer(vkd, *cmdBuffer);
2565
2566 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2567
2568 if (bottomCompact)
2569 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(bottomBlasCompactSize.size()), sizeof(VkDeviceSize) * bottomBlasCompactSize.size(), bottomBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2570 if (bottomSerial)
2571 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(bottomBlasSerialSize.size()), sizeof(VkDeviceSize) * bottomBlasSerialSize.size(), bottomBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2572
2573 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2574 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2575 }
2576
2577 auto bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructures;
2578 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2579 {
2580 switch (m_data.operationType)
2581 {
2582 case OP_COPY:
2583 {
2584 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2585 {
2586 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2587 asCopy->setDeferredOperation(htCopy, workerThreadsCount);
2588 asCopy->setBuildType(m_data.buildType);
2589 asCopy->setBuildFlags(m_data.buildFlags);
2590 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2591 asCopy->setCreateGeneric(m_data.bottomGeneric);
2592 asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2593 asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2594 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2595 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), 0u, 0u);
2596 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2597 }
2598 break;
2599 }
2600 case OP_COMPACT:
2601 {
2602 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2603 {
2604 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2605 asCopy->setBuildType(m_data.buildType);
2606 asCopy->setBuildFlags(m_data.buildFlags);
2607 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2608 asCopy->setCreateGeneric(m_data.bottomGeneric);
2609 asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2610 asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2611 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2612 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), bottomBlasCompactSize[i], 0u);
2613 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2614 }
2615 break;
2616 }
2617 case OP_SERIALIZE:
2618 {
2619 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2620 {
2621 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, bottomBlasSerialSize[i]));
2622
2623 bottomLevelAccelerationStructures[i]->setDeferredOperation(htSerialize, workerThreadsCount);
2624 bottomLevelAccelerationStructures[i]->serialize(vkd, device, *cmdBuffer, storage.get());
2625 bottomSerialized.push_back(storage);
2626
2627 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2628 {
2629 endCommandBuffer(vkd, *cmdBuffer);
2630
2631 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2632
2633 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2634 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2635 }
2636
2637 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2638 asCopy->setBuildType(m_data.buildType);
2639 asCopy->setBuildFlags(m_data.buildFlags);
2640 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2641 asCopy->setCreateGeneric(m_data.bottomGeneric);
2642 asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2643 asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2644 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2645 asCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2646 asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2647 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2648 }
2649 break;
2650 }
2651 default:
2652 DE_ASSERT(DE_FALSE);
2653 }
2654 bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies;
2655 }
2656
2657 // build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures )
2658 bool topCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION;
2659 bool topSerial = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION;
2660 VkBuildAccelerationStructureFlagsKHR topCompactFlags = (topCompact ? allowCompactionFlag : emptyCompactionFlag);
2661 VkBuildAccelerationStructureFlagsKHR topBuildFlags = m_data.buildFlags | topCompactFlags;
2662 std::vector<VkAccelerationStructureKHR> topLevelStructureHandles;
2663 std::vector<VkDeviceSize> topBlasCompactSize;
2664 std::vector<VkDeviceSize> topBlasSerialSize;
2665
2666 topLevelAccelerationStructure = sceneBuilder->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr);
2667 topLevelAccelerationStructure->setBuildType (m_data.buildType);
2668 topLevelAccelerationStructure->setBuildFlags (topBuildFlags);
2669 topLevelAccelerationStructure->setBuildWithoutPrimitives (topNoPrimitives);
2670 topLevelAccelerationStructure->setUseArrayOfPointers (m_data.topUsesAOP);
2671 topLevelAccelerationStructure->setCreateGeneric (m_data.topGeneric);
2672 topLevelAccelerationStructure->setCreationBufferUnbounded (m_data.topUnboundedCreation);
2673 topLevelAccelerationStructure->setInactiveInstances (inactiveInstances);
2674 topLevelAccelerationStructure->createAndBuild (vkd, device, *cmdBuffer, allocator);
2675 topLevelStructureHandles.push_back (*(topLevelAccelerationStructure->getPtr()));
2676
2677 if (topCompact)
2678 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize);
2679 if (topSerial)
2680 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize);
2681
2682 // if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
2683 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial))
2684 {
2685 endCommandBuffer(vkd, *cmdBuffer);
2686
2687 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2688
2689 if (topCompact)
2690 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(topBlasCompactSize.size()), sizeof(VkDeviceSize) * topBlasCompactSize.size(), topBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2691 if (topSerial)
2692 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(topBlasSerialSize.size()), sizeof(VkDeviceSize) * topBlasSerialSize.size(), topBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2693
2694 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2695 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2696 }
2697
2698 const TopLevelAccelerationStructure* topLevelRayTracedPtr = topLevelAccelerationStructure.get();
2699 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION)
2700 {
2701 switch (m_data.operationType)
2702 {
2703 case OP_COPY:
2704 {
2705 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2706 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount);
2707 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2708 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2709 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2710 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2711 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2712 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2713 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2714 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), 0u, 0u);
2715 break;
2716 }
2717 case OP_COMPACT:
2718 {
2719 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2720 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2721 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2722 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2723 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2724 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2725 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2726 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2727 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], 0u);
2728 break;
2729 }
2730 case OP_SERIALIZE:
2731 {
2732 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, topBlasSerialSize[0]));
2733
2734 topLevelAccelerationStructure->setDeferredOperation(htSerialize, workerThreadsCount);
2735 topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get());
2736 topSerialized.push_back(storage);
2737
2738 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2739 {
2740 endCommandBuffer(vkd, *cmdBuffer);
2741
2742 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2743
2744 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2745 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2746 }
2747
2748 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2749 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2750 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2751 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2752 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2753 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2754 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2755 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2756 topLevelAccelerationStructureCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2757 topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2758 break;
2759 }
2760 case OP_UPDATE:
2761 {
2762 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2763 topLevelAccelerationStructureCopy->create(vkd, device, allocator, 0u, 0u);
2764 // Update AS based on topLevelAccelerationStructure
2765 topLevelAccelerationStructureCopy->build(vkd, device, *cmdBuffer, topLevelAccelerationStructure.get());
2766 break;
2767 }
2768 case OP_UPDATE_IN_PLACE:
2769 {
2770 // Update in place
2771 topLevelAccelerationStructure->build(vkd, device, *cmdBuffer, topLevelAccelerationStructure.get());
2772 // Make a coppy
2773 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2774 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount);
2775 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2776 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2777 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2778 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2779 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2780 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2781 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), 0u, 0u);
2782 break;
2783 }
2784 default:
2785 DE_ASSERT(DE_FALSE);
2786
2787 }
2788 topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get();
2789 }
2790
2791 const VkMemoryBarrier preTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
2792 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &preTraceMemoryBarrier);
2793
2794 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
2795 {
2796 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
2797 DE_NULL, // const void* pNext;
2798 1u, // deUint32 accelerationStructureCount;
2799 topLevelRayTracedPtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
2800 };
2801
2802 testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet, resultImageInfo);
2803
2804 const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
2805 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2806 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
2807
2808 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
2809
2810 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
2811 }
2812 endCommandBuffer(vkd, *cmdBuffer);
2813
2814 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2815
2816 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2817
2818 return resultBuffer;
2819 }
2820
iterateNoWorkers(void)2821 bool RayQueryASBasicTestInstance::iterateNoWorkers (void)
2822 {
2823 de::SharedPtr<TestConfiguration> testConfiguration = createTestConfiguration(m_data.shaderSourcePipeline);
2824 de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2825
2826 const de::MovePtr<BufferWithMemory> buffer = runTest(testConfiguration.get(), sceneBuilder.get(), 0);
2827
2828 return testConfiguration->verifyImage(buffer.get(), m_context, m_data);
2829 }
2830
iterateWithWorkers(void)2831 bool RayQueryASBasicTestInstance::iterateWithWorkers (void)
2832 {
2833 de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2834
2835 de::SharedPtr<TestConfiguration> testConfigurationS = createTestConfiguration(m_data.shaderSourcePipeline);
2836 de::MovePtr<BufferWithMemory> singleThreadBufferCPU = runTest(testConfigurationS.get(), sceneBuilder.get(), 0);
2837 const bool singleThreadValidation = testConfigurationS->verifyImage(singleThreadBufferCPU.get(), m_context, m_data);
2838 testConfigurationS.clear();
2839
2840 de::SharedPtr<TestConfiguration> testConfigurationM = createTestConfiguration(m_data.shaderSourcePipeline);
2841 de::MovePtr<BufferWithMemory> multiThreadBufferCPU = runTest(testConfigurationM.get(), sceneBuilder.get(), m_data.workerThreadsCount);
2842 const bool multiThreadValidation = testConfigurationM->verifyImage(multiThreadBufferCPU.get(), m_context, m_data);
2843 testConfigurationM.clear();
2844
2845 const deUint32 result = singleThreadValidation && multiThreadValidation;
2846
2847 return result;
2848 }
2849
iterate(void)2850 tcu::TestStatus RayQueryASBasicTestInstance::iterate(void)
2851 {
2852 bool result;
2853 if (m_data.workerThreadsCount != 0)
2854 result = iterateWithWorkers();
2855 else
2856 result = iterateNoWorkers();
2857
2858 if (result)
2859 return tcu::TestStatus::pass("Pass");
2860 else
2861 return tcu::TestStatus::fail("Fail");
2862 }
2863
2864 // Tests dynamic indexing of acceleration structures
2865 class RayQueryASDynamicIndexingTestCase : public TestCase
2866 {
2867 public:
2868 RayQueryASDynamicIndexingTestCase (tcu::TestContext& context, const char* name);
2869 ~RayQueryASDynamicIndexingTestCase (void) = default;
2870
2871 void checkSupport (Context& context) const override;
2872 void initPrograms (SourceCollections& programCollection) const override;
2873 TestInstance* createInstance (Context& context) const override;
2874 };
2875
2876 class RayQueryASDynamicIndexingTestInstance : public TestInstance
2877 {
2878 public:
2879 RayQueryASDynamicIndexingTestInstance (Context& context);
2880 ~RayQueryASDynamicIndexingTestInstance (void) = default;
2881 tcu::TestStatus iterate (void) override;
2882 };
2883
RayQueryASDynamicIndexingTestCase(tcu::TestContext & context,const char * name)2884 RayQueryASDynamicIndexingTestCase::RayQueryASDynamicIndexingTestCase(tcu::TestContext& context, const char* name)
2885 : TestCase(context, name)
2886 {
2887 }
2888
checkSupport(Context & context) const2889 void RayQueryASDynamicIndexingTestCase::checkSupport(Context& context) const
2890 {
2891 commonASTestsCheckSupport(context);
2892 context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
2893 }
2894
initPrograms(SourceCollections & programCollection) const2895 void RayQueryASDynamicIndexingTestCase::initPrograms(SourceCollections& programCollection) const
2896 {
2897 const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2898
2899 // compute shader is defined in spir-v as it requires possing pointer to TLAS that was read from ssbo;
2900 // original spir-v code was generated using following glsl code but resulting spir-v code was modiifed
2901
2902 // #version 460 core
2903 // #extension GL_EXT_ray_query : require
2904 // #extension GL_EXT_nonuniform_qualifier : enable
2905
2906 // #define ARRAY_SIZE 500
2907 // layout(set = 0, binding = 0) uniform accelerationStructureEXT tlasArray[ARRAY_SIZE];
2908 // layout(set = 0, binding = 1) readonly buffer topLevelASPointers {
2909 // uvec2 ptr[];
2910 // } tlasPointers;
2911 // layout(set = 0, binding = 2) readonly buffer topLevelASIndices {
2912 // uint idx[];
2913 // } tlasIndices;
2914 // layout(set = 0, binding = 3, std430) writeonly buffer Result {
2915 // uint value[];
2916 // } result;
2917
2918 // void main()
2919 // {
2920 // float tmin = 0.0;
2921 // float tmax = 2.0;
2922 // vec3 origin = vec3(0.25f, 0.5f, 1.0);
2923 // vec3 direction = vec3(0.0,0.0,-1.0);
2924 // uint tlasIndex = tlasIndices.idx[nonuniformEXT(gl_GlobalInvocationID.x)];
2925
2926 // rayQueryEXT rq;
2927 // rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2928 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x)], 2);
2929
2930 // if (rayQueryProceedEXT(rq))
2931 // {
2932 // if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
2933 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x)], 3);
2934 // }
2935
2936 // //rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2937 // rayQueryInitializeEXT(rq, *tlasPointers.ptr[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2938 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 2)], 5);
2939
2940 // if (rayQueryProceedEXT(rq))
2941 // {
2942 // if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
2943 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 3)], 7);
2944 // }
2945 // }
2946
2947 const std::string compSource =
2948 "OpCapability Shader\n"
2949 "OpCapability RayQueryKHR\n"
2950 "OpCapability ShaderNonUniform\n"
2951 "OpExtension \"SPV_EXT_descriptor_indexing\"\n"
2952 "OpExtension \"SPV_KHR_ray_query\"\n"
2953 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
2954 "OpMemoryModel Logical GLSL450\n"
2955 "OpEntryPoint GLCompute %4 \"main\" %var_index_ssbo %33 %var_as_arr_uni_ptr %64 %83 %var_as_pointers_ssbo\n"
2956 "OpExecutionMode %4 LocalSize 1 1 1\n"
2957 "OpDecorate %25 ArrayStride 4\n"
2958 "OpMemberDecorate %26 0 NonWritable\n"
2959 "OpMemberDecorate %26 0 Offset 0\n"
2960 "OpDecorate %26 Block\n"
2961 "OpDecorate %var_index_ssbo DescriptorSet 0\n"
2962 "OpDecorate %var_index_ssbo Binding 2\n"
2963 "OpDecorate %33 BuiltIn GlobalInvocationId\n"
2964 "OpDecorate %38 NonUniform\n"
2965 "OpDecorate %40 NonUniform\n"
2966 "OpDecorate %41 NonUniform\n"
2967 "OpDecorate %var_as_arr_uni_ptr DescriptorSet 0\n"
2968 "OpDecorate %var_as_arr_uni_ptr Binding 0\n"
2969 "OpDecorate %51 NonUniform\n"
2970 "OpDecorate %53 NonUniform\n"
2971 "OpDecorate %54 NonUniform\n"
2972 "OpDecorate %61 ArrayStride 4\n"
2973 "OpMemberDecorate %62 0 NonReadable\n"
2974 "OpMemberDecorate %62 0 Offset 0\n"
2975 "OpDecorate %62 Block\n"
2976 "OpDecorate %64 DescriptorSet 0\n"
2977 "OpDecorate %64 Binding 3\n"
2978 "OpDecorate %67 NonUniform\n"
2979 "OpDecorate %83 BuiltIn NumWorkgroups\n"
2980 "OpDecorate %87 NonUniform\n"
2981 "OpDecorate %as_index NonUniform\n"
2982 "OpDecorate %as_device_addres NonUniform\n"
2983 "OpDecorate %105 NonUniform\n"
2984 "OpDecorate %122 NonUniform\n"
2985 "OpDecorate %127 ArrayStride 8\n"
2986 "OpMemberDecorate %128 0 NonWritable\n"
2987 "OpMemberDecorate %128 0 Offset 0\n"
2988 "OpDecorate %128 Block\n"
2989 "OpDecorate %var_as_pointers_ssbo DescriptorSet 0\n"
2990 "OpDecorate %var_as_pointers_ssbo Binding 1\n"
2991 "%2 = OpTypeVoid\n"
2992 "%3 = OpTypeFunction %2\n"
2993 "%6 = OpTypeFloat 32\n"
2994 "%7 = OpTypePointer Function %6\n"
2995 "%9 = OpConstant %6 0\n"
2996 "%11 = OpConstant %6 2\n"
2997 "%12 = OpTypeVector %6 3\n"
2998 "%13 = OpTypePointer Function %12\n"
2999 "%15 = OpConstant %6 0.25\n"
3000 "%16 = OpConstant %6 0.5\n"
3001 "%17 = OpConstant %6 1\n"
3002 "%18 = OpConstantComposite %12 %15 %16 %17\n"
3003 "%20 = OpConstant %6 -1\n"
3004 "%21 = OpConstantComposite %12 %9 %9 %20\n"
3005 "%type_uint32 = OpTypeInt 32 0\n"
3006 "%23 = OpTypePointer Function %type_uint32\n"
3007 "%25 = OpTypeRuntimeArray %type_uint32\n"
3008 "%26 = OpTypeStruct %25\n"
3009 "%27 = OpTypePointer StorageBuffer %26\n"
3010 "%var_index_ssbo = OpVariable %27 StorageBuffer\n"
3011 "%29 = OpTypeInt 32 1\n"
3012 "%c_int32_0 = OpConstant %29 0\n"
3013 "%31 = OpTypeVector %type_uint32 3\n"
3014 "%32 = OpTypePointer Input %31\n"
3015 "%33 = OpVariable %32 Input\n"
3016 "%34 = OpConstant %type_uint32 0\n"
3017 "%35 = OpTypePointer Input %type_uint32\n"
3018 "%type_uint32_ssbo_ptr = OpTypePointer StorageBuffer %type_uint32\n"
3019 "%42 = OpTypeRayQueryKHR\n"
3020 "%43 = OpTypePointer Function %42\n"
3021 "%type_as = OpTypeAccelerationStructureKHR\n"
3022 "%46 = OpConstant %type_uint32 500\n"
3023 "%type_as_arr = OpTypeArray %type_as %46\n"
3024 "%type_as_arr_uni_ptr = OpTypePointer UniformConstant %type_as_arr\n"
3025 "%var_as_arr_uni_ptr = OpVariable %type_as_arr_uni_ptr UniformConstant\n"
3026 "%type_as_uni_ptr = OpTypePointer UniformConstant %type_as\n"
3027 "%55 = OpConstant %type_uint32 16\n"
3028 "%56 = OpConstant %type_uint32 255\n"
3029 "%61 = OpTypeRuntimeArray %type_uint32\n"
3030 "%62 = OpTypeStruct %61\n"
3031 "%63 = OpTypePointer StorageBuffer %62\n"
3032 "%64 = OpVariable %63 StorageBuffer\n"
3033 "%69 = OpConstant %type_uint32 2\n"
3034 "%70 = OpConstant %type_uint32 1\n"
3035 "%72 = OpTypeBool\n"
3036 "%76 = OpConstantFalse %72\n"
3037 "%83 = OpVariable %32 Input\n"
3038 "%89 = OpConstant %type_uint32 3\n"
3039 "%107 = OpConstant %type_uint32 5\n"
3040 "%124 = OpConstant %type_uint32 7\n"
3041
3042 // <changed_section>
3043 "%v2uint = OpTypeVector %type_uint32 2\n"
3044 "%127 = OpTypeRuntimeArray %v2uint\n"
3045 "%128 = OpTypeStruct %127\n"
3046 "%129 = OpTypePointer StorageBuffer %128\n"
3047 "%var_as_pointers_ssbo = OpVariable %129 StorageBuffer\n"
3048 "%type_uint64_ssbo_ptr = OpTypePointer StorageBuffer %v2uint\n"
3049 // </changed_section>
3050
3051 // void main()
3052 "%4 = OpFunction %2 None %3\n"
3053 "%5 = OpLabel\n"
3054 "%8 = OpVariable %7 Function\n"
3055 "%10 = OpVariable %7 Function\n"
3056 "%14 = OpVariable %13 Function\n"
3057 "%19 = OpVariable %13 Function\n"
3058 "%24 = OpVariable %23 Function\n"
3059 "%var_ray_query = OpVariable %43 Function\n"
3060 "OpStore %8 %9\n"
3061 "OpStore %10 %11\n"
3062 "OpStore %14 %18\n"
3063 "OpStore %19 %21\n"
3064 "%36 = OpAccessChain %35 %33 %34\n"
3065 "%37 = OpLoad %type_uint32 %36\n"
3066 "%38 = OpCopyObject %type_uint32 %37\n"
3067 "%40 = OpAccessChain %type_uint32_ssbo_ptr %var_index_ssbo %c_int32_0 %38\n"
3068 "%41 = OpLoad %type_uint32 %40\n"
3069 "OpStore %24 %41\n"
3070
3071 // rayQueryInitializeEXT using AS that was read from array
3072 "%50 = OpLoad %type_uint32 %24\n"
3073 "%51 = OpCopyObject %type_uint32 %50\n"
3074 "%53 = OpAccessChain %type_as_uni_ptr %var_as_arr_uni_ptr %51\n"
3075 "%54 = OpLoad %type_as %53\n"
3076 "%57 = OpLoad %12 %14\n"
3077 "%58 = OpLoad %6 %8\n"
3078 "%59 = OpLoad %12 %19\n"
3079 "%60 = OpLoad %6 %10\n"
3080 "OpRayQueryInitializeKHR %var_ray_query %54 %55 %56 %57 %58 %59 %60\n"
3081
3082 "%65 = OpAccessChain %35 %33 %34\n"
3083 "%66 = OpLoad %type_uint32 %65\n"
3084 "%67 = OpCopyObject %type_uint32 %66\n"
3085 "%68 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %67\n"
3086 "%71 = OpAtomicIAdd %type_uint32 %68 %70 %34 %69\n"
3087
3088 "%73 = OpRayQueryProceedKHR %72 %var_ray_query\n"
3089 "OpSelectionMerge %75 None\n"
3090 "OpBranchConditional %73 %74 %75\n"
3091 "%74 = OpLabel\n"
3092
3093 "%77 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3094 "%78 = OpIEqual %72 %77 %34\n"
3095 "OpSelectionMerge %80 None\n"
3096 "OpBranchConditional %78 %79 %80\n"
3097 "%79 = OpLabel\n"
3098 "%81 = OpAccessChain %35 %33 %34\n"
3099 "%82 = OpLoad %type_uint32 %81\n"
3100 "%84 = OpAccessChain %35 %83 %34\n"
3101 "%85 = OpLoad %type_uint32 %84\n"
3102 "%86 = OpIAdd %type_uint32 %82 %85\n"
3103 "%87 = OpCopyObject %type_uint32 %86\n"
3104 "%88 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %87\n"
3105 "%90 = OpAtomicIAdd %type_uint32 %88 %70 %34 %89\n"
3106 "OpBranch %80\n"
3107 "%80 = OpLabel\n"
3108 "OpBranch %75\n"
3109 "%75 = OpLabel\n"
3110
3111 // rayQueryInitializeEXT using pointer to AS
3112 "%91 = OpLoad %type_uint32 %24\n"
3113 "%as_index = OpCopyObject %type_uint32 %91\n"
3114
3115 // <changed_section>
3116 "%as_device_addres_ptr = OpAccessChain %type_uint64_ssbo_ptr %var_as_pointers_ssbo %c_int32_0 %as_index\n"
3117 "%as_device_addres = OpLoad %v2uint %as_device_addres_ptr\n"
3118 "%as_to_use = OpConvertUToAccelerationStructureKHR %type_as %as_device_addres\n"
3119 // </changed_section>
3120
3121 "%95 = OpLoad %12 %14\n"
3122 "%96 = OpLoad %6 %8\n"
3123 "%97 = OpLoad %12 %19\n"
3124 "%98 = OpLoad %6 %10\n"
3125 "OpRayQueryInitializeKHR %var_ray_query %as_to_use %55 %56 %95 %96 %97 %98\n"
3126
3127 "%99 = OpAccessChain %35 %33 %34\n"
3128 "%100 = OpLoad %type_uint32 %99\n"
3129 "%101 = OpAccessChain %35 %83 %34\n"
3130 "%102 = OpLoad %type_uint32 %101\n"
3131 "%103 = OpIMul %type_uint32 %102 %69\n"
3132 "%104 = OpIAdd %type_uint32 %100 %103\n"
3133 "%105 = OpCopyObject %type_uint32 %104\n"
3134 "%106 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %105\n"
3135 "%108 = OpAtomicIAdd %type_uint32 %106 %70 %34 %107\n"
3136
3137 "%109 = OpRayQueryProceedKHR %72 %var_ray_query\n"
3138 "OpSelectionMerge %111 None\n"
3139 "OpBranchConditional %109 %110 %111\n"
3140 "%110 = OpLabel\n"
3141
3142 "%112 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3143 "%113 = OpIEqual %72 %112 %34\n"
3144 "OpSelectionMerge %115 None\n"
3145 "OpBranchConditional %113 %114 %115\n"
3146 "%114 = OpLabel\n"
3147 "%116 = OpAccessChain %35 %33 %34\n"
3148 "%117 = OpLoad %type_uint32 %116\n"
3149 "%118 = OpAccessChain %35 %83 %34\n"
3150 "%119 = OpLoad %type_uint32 %118\n"
3151 "%120 = OpIMul %type_uint32 %119 %89\n"
3152 "%121 = OpIAdd %type_uint32 %117 %120\n"
3153 "%122 = OpCopyObject %type_uint32 %121\n"
3154 "%123 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %122\n"
3155 "%125 = OpAtomicIAdd %type_uint32 %123 %70 %34 %124\n"
3156 "OpBranch %115\n"
3157 "%115 = OpLabel\n"
3158 "OpBranch %111\n"
3159 "%111 = OpLabel\n"
3160 "OpReturn\n"
3161 "OpFunctionEnd\n";
3162
3163 programCollection.spirvAsmSources.add("comp") << compSource << spvBuildOptions;
3164 }
3165
createInstance(Context & context) const3166 TestInstance* RayQueryASDynamicIndexingTestCase::createInstance(Context& context) const
3167 {
3168 return new RayQueryASDynamicIndexingTestInstance(context);
3169 }
3170
3171
RayQueryASDynamicIndexingTestInstance(Context & context)3172 RayQueryASDynamicIndexingTestInstance::RayQueryASDynamicIndexingTestInstance(Context& context)
3173 : vkt::TestInstance(context)
3174 {
3175 }
3176
iterate(void)3177 tcu::TestStatus RayQueryASDynamicIndexingTestInstance::iterate(void)
3178 {
3179 const DeviceInterface& vkd = m_context.getDeviceInterface();
3180 const VkDevice device = m_context.getDevice();
3181 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3182 const VkQueue queue = m_context.getUniversalQueue();
3183 Allocator& allocator = m_context.getDefaultAllocator();
3184 const deUint32 tlasCount = 500; // changing this will require also changing shaders
3185 const deUint32 activeTlasCount = 32; // number of tlas out of <tlasCount> that will be active
3186
3187 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
3188 .addArrayBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, VK_SHADER_STAGE_COMPUTE_BIT)
3189 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // pointers to all acceleration structures
3190 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with indices of all acceleration structures
3191 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with result values
3192 .build(vkd, device);
3193
3194 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
3195 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount)
3196 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3197 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3198 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3199 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
3200 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
3201
3202 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
3203 Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);
3204 const VkComputePipelineCreateInfo pipelineCreateInfo
3205 {
3206 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
3207 DE_NULL, // const void* pNext
3208 0u, // VkPipelineCreateFlags flags
3209 { // VkPipelineShaderStageCreateInfo stage
3210 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3211 DE_NULL,
3212 (VkPipelineShaderStageCreateFlags)0,
3213 VK_SHADER_STAGE_COMPUTE_BIT,
3214 *shaderModule,
3215 "main",
3216 DE_NULL
3217 },
3218 *pipelineLayout, // VkPipelineLayout layout
3219 DE_NULL, // VkPipeline basePipelineHandle
3220 0, // deInt32 basePipelineIndex
3221 };
3222
3223 Move<VkPipeline> pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
3224
3225 const VkDeviceSize pointerBufferSize = tlasCount * sizeof(VkDeviceAddress);
3226 const VkBufferCreateInfo pointerBufferCreateInfo = makeBufferCreateInfo(pointerBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3227 de::MovePtr<BufferWithMemory> pointerBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, pointerBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress));
3228
3229 const VkDeviceSize indicesBufferSize = activeTlasCount * sizeof(deUint32);
3230 const VkBufferCreateInfo indicesBufferCreateInfo = makeBufferCreateInfo(indicesBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3231 de::MovePtr<BufferWithMemory> indicesBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, indicesBufferCreateInfo, MemoryRequirement::HostVisible));
3232
3233 const VkDeviceSize resultBufferSize = activeTlasCount * sizeof(deUint32) * 4;
3234 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(resultBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
3235 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3236
3237 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
3238 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3239
3240 de::SharedPtr<BottomLevelAccelerationStructure> blas = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
3241 std::vector<de::MovePtr<TopLevelAccelerationStructure>> tlasVect(tlasCount);
3242 std::vector<VkDeviceAddress> tlasPtrVect(tlasCount);
3243 std::vector<VkAccelerationStructureKHR> tlasVkVect;
3244
3245 // randomly scatter AS indices across the range (number of them should be equal to the max subgroup size)
3246 deRandom rnd;
3247 deRandom_init(&rnd, 123);
3248 std::set<deUint32> asIndicesSet;
3249 while (asIndicesSet.size() < activeTlasCount)
3250 asIndicesSet.insert(deRandom_getUint32(&rnd) % tlasCount);
3251
3252 // fill indices buffer
3253 deUint32 helperIndex = 0;
3254 auto& indicesBufferAlloc = indicesBuffer->getAllocation();
3255 deUint32* indicesBufferPtr = reinterpret_cast<deUint32*>(indicesBufferAlloc.getHostPtr());
3256 std::for_each(asIndicesSet.begin(), asIndicesSet.end(),
3257 [&helperIndex, indicesBufferPtr](const deUint32& index)
3258 {
3259 indicesBufferPtr[helperIndex++] = index;
3260 });
3261 vk::flushAlloc(vkd, device, indicesBufferAlloc);
3262
3263 // clear result buffer
3264 auto& resultBufferAlloc = resultBuffer->getAllocation();
3265 void* resultBufferPtr = resultBufferAlloc.getHostPtr();
3266 deMemset(resultBufferPtr, 0, static_cast<size_t>(resultBufferSize));
3267 vk::flushAlloc(vkd, device, resultBufferAlloc);
3268
3269 beginCommandBuffer(vkd, *cmdBuffer, 0u);
3270 {
3271 // build bottom level acceleration structure
3272 blas->setGeometryData(
3273 {
3274 { 0.0, 0.0, 0.0 },
3275 { 1.0, 0.0, 0.0 },
3276 { 0.0, 1.0, 0.0 },
3277 },
3278 true,
3279 0u
3280 );
3281
3282 blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3283
3284 // build top level acceleration structures
3285 for (deUint32 tlasIndex = 0; tlasIndex < tlasCount; ++tlasIndex)
3286 {
3287 auto& tlas = tlasVect[tlasIndex];
3288 tlas = makeTopLevelAccelerationStructure();
3289 tlas->setInstanceCount(1);
3290 tlas->addInstance(blas);
3291 if (!asIndicesSet.count(tlasIndex))
3292 {
3293 // tlas that are not in asIndicesSet should be empty but it is hard to do
3294 // that with current cts utils so we are marking them as inactive instead
3295 tlas->setInactiveInstances(true);
3296 }
3297 tlas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3298
3299 // get acceleration structure device address
3300 const VkAccelerationStructureDeviceAddressInfoKHR addressInfo =
3301 {
3302 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType
3303 DE_NULL, // const void* pNext
3304 *tlas->getPtr() // VkAccelerationStructureKHR accelerationStructure
3305 };
3306 VkDeviceAddress vkda = vkd.getAccelerationStructureDeviceAddressKHR(device, &addressInfo);
3307 tlasPtrVect[tlasIndex] = vkda;
3308 }
3309
3310 // fill pointer buffer
3311 vkd.cmdUpdateBuffer(*cmdBuffer, **pointerBuffer, 0, pointerBufferSize, tlasPtrVect.data());
3312
3313 // wait for data transfers
3314 const VkMemoryBarrier uploadBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
3315 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &uploadBarrier, 1u);
3316
3317 // wait for as build
3318 const VkMemoryBarrier asBuildBarrier = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
3319 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &asBuildBarrier, 1u);
3320
3321 tlasVkVect.reserve(tlasCount);
3322 for (auto& tlas : tlasVect)
3323 tlasVkVect.push_back(*tlas->getPtr());
3324
3325 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
3326 {
3327 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
3328 DE_NULL, // const void* pNext;
3329 tlasCount, // deUint32 accelerationStructureCount;
3330 tlasVkVect.data(), // const VkAccelerationStructureKHR* pAccelerationStructures;
3331 };
3332
3333 const vk::VkDescriptorBufferInfo pointerBufferInfo = makeDescriptorBufferInfo(**pointerBuffer, 0u, VK_WHOLE_SIZE);
3334 const vk::VkDescriptorBufferInfo indicesBufferInfo = makeDescriptorBufferInfo(**indicesBuffer, 0u, VK_WHOLE_SIZE);
3335 const vk::VkDescriptorBufferInfo resultInfo = makeDescriptorBufferInfo(**resultBuffer, 0u, VK_WHOLE_SIZE);
3336
3337 DescriptorSetUpdateBuilder()
3338 .writeArray (*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, &accelerationStructureWriteDescriptorSet)
3339 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &pointerBufferInfo)
3340 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indicesBufferInfo)
3341 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo)
3342 .update(vkd, device);
3343
3344 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
3345
3346 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3347
3348 vkd.cmdDispatch(*cmdBuffer, activeTlasCount, 1, 1);
3349
3350 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
3351 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
3352 }
3353 endCommandBuffer(vkd, *cmdBuffer);
3354
3355 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
3356
3357 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), resultBufferSize);
3358
3359 // verify result buffer
3360 deUint32 failures = 0;
3361 const deUint32* resultPtr = reinterpret_cast<deUint32*>(resultBuffer->getAllocation().getHostPtr());
3362 for (deUint32 index = 0; index < activeTlasCount; ++index)
3363 {
3364 failures += (resultPtr[0 * activeTlasCount + index] != 2) +
3365 (resultPtr[1 * activeTlasCount + index] != 3) +
3366 (resultPtr[2 * activeTlasCount + index] != 5) +
3367 (resultPtr[3 * activeTlasCount + index] != 7);
3368 }
3369
3370 if (failures)
3371 return tcu::TestStatus::fail(de::toString(failures) + " failures, " + de::toString(4 * activeTlasCount - failures) + " are ok");
3372 return tcu::TestStatus::pass("Pass");
3373 }
3374
3375 } // anonymous
3376
3377 /********************/
3378
addBasicBuildingTests(tcu::TestCaseGroup * group)3379 void addBasicBuildingTests(tcu::TestCaseGroup* group)
3380 {
3381 struct ShaderSourceTypeData
3382 {
3383 ShaderSourceType shaderSourceType;
3384 ShaderSourcePipeline shaderSourcePipeline;
3385 const char* name;
3386 } shaderSourceTypes[] =
3387 {
3388 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3389 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3390 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3391 };
3392
3393 struct
3394 {
3395 vk::VkAccelerationStructureBuildTypeKHR buildType;
3396 const char* name;
3397 } buildTypes[] =
3398 {
3399 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3400 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3401 };
3402
3403 struct
3404 {
3405 BottomTestType testType;
3406 bool usesAOP;
3407 const char* name;
3408 } bottomTestTypes[] =
3409 {
3410 { BottomTestType::TRIANGLES, false, "triangles" },
3411 { BottomTestType::TRIANGLES, true, "triangles_aop" },
3412 { BottomTestType::AABBS, false, "aabbs" },
3413 { BottomTestType::AABBS, true, "aabbs_aop" },
3414 };
3415
3416 struct
3417 {
3418 TopTestType testType;
3419 bool usesAOP;
3420 const char* name;
3421 } topTestTypes[] =
3422 {
3423 { TopTestType::IDENTICAL_INSTANCES, false, "identical_instances" },
3424 { TopTestType::IDENTICAL_INSTANCES, true, "identical_instances_aop" },
3425 { TopTestType::DIFFERENT_INSTANCES, false, "different_instances" },
3426 { TopTestType::DIFFERENT_INSTANCES, true, "different_instances_aop" },
3427 };
3428
3429 struct BuildFlagsData
3430 {
3431 VkBuildAccelerationStructureFlagsKHR flags;
3432 const char* name;
3433 };
3434
3435 BuildFlagsData optimizationTypes[] =
3436 {
3437 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3438 { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, "fasttrace" },
3439 { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, "fastbuild" },
3440 };
3441
3442 BuildFlagsData updateTypes[] =
3443 {
3444 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3445 { VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, "update" },
3446 };
3447
3448 BuildFlagsData compactionTypes[] =
3449 {
3450 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3451 { VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, "compaction" },
3452 };
3453
3454 BuildFlagsData lowMemoryTypes[] =
3455 {
3456 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3457 { VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, "lowmemory" },
3458 };
3459
3460 struct
3461 {
3462 bool padVertices;
3463 const char* name;
3464 } paddingType[] =
3465 {
3466 { false, "nopadding" },
3467 { true, "padded" },
3468 };
3469
3470 struct
3471 {
3472 bool topGeneric;
3473 bool bottomGeneric;
3474 const char* suffix;
3475 } createGenericParams[] =
3476 {
3477 { false, false, "" },
3478 { false, true, "_bottomgeneric" },
3479 { true, false, "_topgeneric" },
3480 { true, true, "_bothgeneric" },
3481 };
3482
3483 // In order not to create thousands of new test variants for unbound buffer memory on acceleration structure creation, we will
3484 // set these options on some of the tests.
3485 de::ModCounter32 unboundedCreationBottomCounter (3u);
3486 de::ModCounter32 unboundedCreationTopCounter (7u);
3487
3488 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3489 {
3490 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
3491
3492 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3493 {
3494 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
3495
3496 for (size_t bottomNdx = 0; bottomNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++bottomNdx)
3497 {
3498 de::MovePtr<tcu::TestCaseGroup> bottomGroup(new tcu::TestCaseGroup(group->getTestContext(), bottomTestTypes[bottomNdx].name));
3499
3500 for (size_t topNdx = 0; topNdx < DE_LENGTH_OF_ARRAY(topTestTypes); ++topNdx)
3501 {
3502 de::MovePtr<tcu::TestCaseGroup> topGroup(new tcu::TestCaseGroup(group->getTestContext(), topTestTypes[topNdx].name));
3503
3504 for (int paddingTypeIdx = 0; paddingTypeIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingTypeIdx)
3505 {
3506 de::MovePtr<tcu::TestCaseGroup> paddingTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingTypeIdx].name));
3507
3508 for (size_t optimizationNdx = 0; optimizationNdx < DE_LENGTH_OF_ARRAY(optimizationTypes); ++optimizationNdx)
3509 {
3510 for (size_t updateNdx = 0; updateNdx < DE_LENGTH_OF_ARRAY(updateTypes); ++updateNdx)
3511 {
3512 for (size_t compactionNdx = 0; compactionNdx < DE_LENGTH_OF_ARRAY(compactionTypes); ++compactionNdx)
3513 {
3514 for (size_t lowMemoryNdx = 0; lowMemoryNdx < DE_LENGTH_OF_ARRAY(lowMemoryTypes); ++lowMemoryNdx)
3515 {
3516 for (int createGenericIdx = 0; createGenericIdx < DE_LENGTH_OF_ARRAY(createGenericParams); ++createGenericIdx)
3517 {
3518 std::string testName =
3519 std::string(optimizationTypes[optimizationNdx].name) + "_" +
3520 std::string(updateTypes[updateNdx].name) + "_" +
3521 std::string(compactionTypes[compactionNdx].name) + "_" +
3522 std::string(lowMemoryTypes[lowMemoryNdx].name) +
3523 std::string(createGenericParams[createGenericIdx].suffix);
3524
3525 const bool unboundedCreationBottom = (static_cast<uint32_t>(unboundedCreationBottomCounter++) == 0u);
3526 const bool unboundedCreationTop = (static_cast<uint32_t>(unboundedCreationTopCounter++) == 0u);
3527
3528 TestParams testParams
3529 {
3530 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3531 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3532 buildTypes[buildTypeNdx].buildType,
3533 VK_FORMAT_R32G32B32_SFLOAT,
3534 paddingType[paddingTypeIdx].padVertices,
3535 VK_INDEX_TYPE_NONE_KHR,
3536 bottomTestTypes[bottomNdx].testType,
3537 InstanceCullFlags::NONE,
3538 bottomTestTypes[bottomNdx].usesAOP,
3539 createGenericParams[createGenericIdx].bottomGeneric,
3540 unboundedCreationBottom,
3541 topTestTypes[topNdx].testType,
3542 topTestTypes[topNdx].usesAOP,
3543 createGenericParams[createGenericIdx].topGeneric,
3544 unboundedCreationTop,
3545 optimizationTypes[optimizationNdx].flags | updateTypes[updateNdx].flags | compactionTypes[compactionNdx].flags | lowMemoryTypes[lowMemoryNdx].flags,
3546 OT_NONE,
3547 OP_NONE,
3548 TEST_WIDTH,
3549 TEST_HEIGHT,
3550 0u,
3551 EmptyAccelerationStructureCase::NOT_EMPTY,
3552 };
3553 paddingTypeGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), testName.c_str(), testParams));
3554 }
3555 }
3556 }
3557 }
3558 }
3559 topGroup->addChild(paddingTypeGroup.release());
3560 }
3561 bottomGroup->addChild(topGroup.release());
3562 }
3563 buildGroup->addChild(bottomGroup.release());
3564 }
3565 sourceTypeGroup->addChild(buildGroup.release());
3566 }
3567 group->addChild(sourceTypeGroup.release());
3568 }
3569 }
3570
addVertexIndexFormatsTests(tcu::TestCaseGroup * group)3571 void addVertexIndexFormatsTests(tcu::TestCaseGroup* group)
3572 {
3573 struct ShaderSourceTypeData
3574 {
3575 ShaderSourceType shaderSourceType;
3576 ShaderSourcePipeline shaderSourcePipeline;
3577 const char* name;
3578 } shaderSourceTypes[] =
3579 {
3580 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3581 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3582 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3583 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3584 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3585 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3586 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3587 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3588 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3589 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3590 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3591 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3592 };
3593
3594 struct
3595 {
3596 vk::VkAccelerationStructureBuildTypeKHR buildType;
3597 const char* name;
3598 } buildTypes[] =
3599 {
3600 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3601 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3602 };
3603
3604 const VkFormat vertexFormats[] =
3605 {
3606 // Mandatory formats.
3607 VK_FORMAT_R32G32_SFLOAT,
3608 VK_FORMAT_R32G32B32_SFLOAT,
3609 VK_FORMAT_R16G16_SFLOAT,
3610 VK_FORMAT_R16G16B16A16_SFLOAT,
3611 VK_FORMAT_R16G16_SNORM,
3612 VK_FORMAT_R16G16B16A16_SNORM,
3613
3614 // Additional formats.
3615 VK_FORMAT_R8G8_SNORM,
3616 VK_FORMAT_R8G8B8_SNORM,
3617 VK_FORMAT_R8G8B8A8_SNORM,
3618 VK_FORMAT_R16G16B16_SNORM,
3619 VK_FORMAT_R16G16B16_SFLOAT,
3620 VK_FORMAT_R32G32B32A32_SFLOAT,
3621 VK_FORMAT_R64G64_SFLOAT,
3622 VK_FORMAT_R64G64B64_SFLOAT,
3623 VK_FORMAT_R64G64B64A64_SFLOAT,
3624 };
3625
3626 struct
3627 {
3628 VkIndexType indexType;
3629 const char* name;
3630 } indexFormats[] =
3631 {
3632 { VK_INDEX_TYPE_NONE_KHR , "index_none" },
3633 { VK_INDEX_TYPE_UINT16 , "index_uint16" },
3634 { VK_INDEX_TYPE_UINT32 , "index_uint32" },
3635 };
3636
3637 struct
3638 {
3639 bool padVertices;
3640 const char* name;
3641 } paddingType[] =
3642 {
3643 { false, "nopadding" },
3644 { true, "padded" },
3645 };
3646
3647 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3648 {
3649 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
3650
3651 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3652 {
3653 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
3654
3655 for (size_t vertexFormatNdx = 0; vertexFormatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); ++vertexFormatNdx)
3656 {
3657 const auto format = vertexFormats[vertexFormatNdx];
3658 const auto formatName = getFormatSimpleName(format);
3659
3660 de::MovePtr<tcu::TestCaseGroup> vertexFormatGroup(new tcu::TestCaseGroup(group->getTestContext(), formatName.c_str()));
3661
3662 for (int paddingIdx = 0; paddingIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingIdx)
3663 {
3664 de::MovePtr<tcu::TestCaseGroup> paddingGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingIdx].name));
3665
3666 for (size_t indexFormatNdx = 0; indexFormatNdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatNdx)
3667 {
3668 TestParams testParams
3669 {
3670 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3671 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3672 buildTypes[buildTypeNdx].buildType,
3673 format,
3674 paddingType[paddingIdx].padVertices,
3675 indexFormats[indexFormatNdx].indexType,
3676 BottomTestType::TRIANGLES,
3677 InstanceCullFlags::NONE,
3678 false,
3679 false,
3680 false,
3681 TopTestType::IDENTICAL_INSTANCES,
3682 false,
3683 false,
3684 false,
3685 VkBuildAccelerationStructureFlagsKHR(0u),
3686 OT_NONE,
3687 OP_NONE,
3688 TEST_WIDTH,
3689 TEST_HEIGHT,
3690 0u,
3691 EmptyAccelerationStructureCase::NOT_EMPTY,
3692 };
3693 paddingGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), indexFormats[indexFormatNdx].name, testParams));
3694 }
3695 vertexFormatGroup->addChild(paddingGroup.release());
3696 }
3697 buildGroup->addChild(vertexFormatGroup.release());
3698 }
3699 sourceTypeGroup->addChild(buildGroup.release());
3700 }
3701 group->addChild(sourceTypeGroup.release());
3702 }
3703 }
3704
addOperationTestsImpl(tcu::TestCaseGroup * group,const deUint32 workerThreads)3705 void addOperationTestsImpl (tcu::TestCaseGroup* group, const deUint32 workerThreads)
3706 {
3707 struct ShaderSourceTypeData
3708 {
3709 ShaderSourceType shaderSourceType;
3710 ShaderSourcePipeline shaderSourcePipeline;
3711 const char* name;
3712 } shaderSourceTypes[] =
3713 {
3714 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3715 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3716 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3717 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3718 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3719 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3720 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3721 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3722 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3723 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3724 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3725 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3726 };
3727
3728 struct
3729 {
3730 OperationType operationType;
3731 const char* name;
3732 } operationTypes[] =
3733 {
3734 { OP_COPY, "copy" },
3735 { OP_COMPACT, "compaction" },
3736 { OP_SERIALIZE, "serialization" },
3737 };
3738
3739 struct
3740 {
3741 vk::VkAccelerationStructureBuildTypeKHR buildType;
3742 const char* name;
3743 } buildTypes[] =
3744 {
3745 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3746 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3747 };
3748
3749 struct
3750 {
3751 OperationTarget operationTarget;
3752 const char* name;
3753 } operationTargets[] =
3754 {
3755 { OT_TOP_ACCELERATION, "top_acceleration_structure" },
3756 { OT_BOTTOM_ACCELERATION, "bottom_acceleration_structure" },
3757 };
3758
3759 struct
3760 {
3761 BottomTestType testType;
3762 const char* name;
3763 } bottomTestTypes[] =
3764 {
3765 { BottomTestType::TRIANGLES, "triangles" },
3766 { BottomTestType::AABBS, "aabbs" },
3767 };
3768
3769 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3770 {
3771 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
3772
3773 for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx)
3774 {
3775 if (workerThreads > 0)
3776 if (operationTypes[operationTypeNdx].operationType != OP_COPY && operationTypes[operationTypeNdx].operationType != OP_SERIALIZE)
3777 continue;
3778
3779 de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name));
3780
3781 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3782 {
3783 if (workerThreads > 0 && buildTypes[buildTypeNdx].buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR)
3784 continue;
3785
3786 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
3787
3788 for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets); ++operationTargetNdx)
3789 {
3790 de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name));
3791
3792 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
3793 {
3794 TopTestType topTest = (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ? TopTestType::DIFFERENT_INSTANCES : TopTestType::IDENTICAL_INSTANCES;
3795
3796 TestParams testParams
3797 {
3798 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3799 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3800 buildTypes[buildTypeNdx].buildType,
3801 VK_FORMAT_R32G32B32_SFLOAT,
3802 false,
3803 VK_INDEX_TYPE_NONE_KHR,
3804 bottomTestTypes[testTypeNdx].testType,
3805 InstanceCullFlags::NONE,
3806 false,
3807 false,
3808 false,
3809 topTest,
3810 false,
3811 false,
3812 false,
3813 VkBuildAccelerationStructureFlagsKHR(0u),
3814 operationTargets[operationTargetNdx].operationTarget,
3815 operationTypes[operationTypeNdx].operationType,
3816 TEST_WIDTH,
3817 TEST_HEIGHT,
3818 workerThreads,
3819 EmptyAccelerationStructureCase::NOT_EMPTY,
3820 };
3821 operationTargetGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, testParams));
3822 }
3823 buildGroup->addChild(operationTargetGroup.release());
3824 }
3825 operationTypeGroup->addChild(buildGroup.release());
3826 }
3827 sourceTypeGroup->addChild(operationTypeGroup.release());
3828 }
3829 group->addChild(sourceTypeGroup.release());
3830 }
3831 }
3832
addOperationTests(tcu::TestCaseGroup * group)3833 void addOperationTests (tcu::TestCaseGroup* group)
3834 {
3835 addOperationTestsImpl(group, 0);
3836 }
3837
addHostThreadingOperationTests(tcu::TestCaseGroup * group)3838 void addHostThreadingOperationTests (tcu::TestCaseGroup* group)
3839 {
3840 const deUint32 threads[] = { 1, 2, 3, 4, 8, std::numeric_limits<deUint32>::max() };
3841
3842 for (size_t threadsNdx = 0; threadsNdx < DE_LENGTH_OF_ARRAY(threads); ++threadsNdx)
3843 {
3844 const std::string groupName = threads[threadsNdx] != std::numeric_limits<deUint32>::max()
3845 ? de::toString(threads[threadsNdx])
3846 : "max";
3847
3848 de::MovePtr<tcu::TestCaseGroup> threadGroup(new tcu::TestCaseGroup(group->getTestContext(), groupName.c_str()));
3849
3850 addOperationTestsImpl(threadGroup.get(), threads[threadsNdx]);
3851
3852 group->addChild(threadGroup.release());
3853 }
3854 }
3855
addFuncArgTests(tcu::TestCaseGroup * group)3856 void addFuncArgTests (tcu::TestCaseGroup* group)
3857 {
3858 const struct
3859 {
3860 vk::VkAccelerationStructureBuildTypeKHR buildType;
3861 const char* name;
3862 } buildTypes[] =
3863 {
3864 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3865 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3866 };
3867
3868 auto& ctx = group->getTestContext();
3869
3870 for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3871 {
3872 TestParams testParams
3873 {
3874 SST_COMPUTE_SHADER,
3875 SSP_COMPUTE_PIPELINE,
3876 buildTypes[buildTypeNdx].buildType,
3877 VK_FORMAT_R32G32B32_SFLOAT,
3878 false,
3879 VK_INDEX_TYPE_NONE_KHR,
3880 BottomTestType::TRIANGLES,
3881 InstanceCullFlags::NONE,
3882 false,
3883 false,
3884 false,
3885 TopTestType::IDENTICAL_INSTANCES,
3886 false,
3887 false,
3888 false,
3889 VkBuildAccelerationStructureFlagsKHR(0u),
3890 OT_NONE,
3891 OP_NONE,
3892 TEST_WIDTH,
3893 TEST_HEIGHT,
3894 0u,
3895 EmptyAccelerationStructureCase::NOT_EMPTY,
3896 };
3897
3898 group->addChild(new RayQueryASFuncArgTestCase(ctx, buildTypes[buildTypeNdx].name, testParams));
3899 }
3900 }
3901
addInstanceTriangleCullingTests(tcu::TestCaseGroup * group)3902 void addInstanceTriangleCullingTests (tcu::TestCaseGroup* group)
3903 {
3904 const struct
3905 {
3906 ShaderSourceType shaderSourceType;
3907 ShaderSourcePipeline shaderSourcePipeline;
3908 std::string name;
3909 } shaderSourceTypes[] =
3910 {
3911 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3912 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3913 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3914 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3915 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3916 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3917 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3918 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3919 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3920 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3921 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3922 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3923 };
3924
3925 const struct
3926 {
3927 InstanceCullFlags cullFlags;
3928 std::string name;
3929 } cullFlags[] =
3930 {
3931 { InstanceCullFlags::NONE, "noflags" },
3932 { InstanceCullFlags::COUNTERCLOCKWISE, "ccw" },
3933 { InstanceCullFlags::CULL_DISABLE, "nocull" },
3934 { InstanceCullFlags::ALL, "ccw_nocull" },
3935 };
3936
3937 const struct
3938 {
3939 TopTestType topType;
3940 std::string name;
3941 } topType[] =
3942 {
3943 { TopTestType::DIFFERENT_INSTANCES, "transformed" }, // Each instance has its own transformation matrix.
3944 { TopTestType::IDENTICAL_INSTANCES, "notransform" }, // "Identical" instances, different geometries.
3945 };
3946
3947 const struct
3948 {
3949 vk::VkAccelerationStructureBuildTypeKHR buildType;
3950 std::string name;
3951 } buildTypes[] =
3952 {
3953 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3954 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3955 };
3956
3957 const struct
3958 {
3959 VkIndexType indexType;
3960 std::string name;
3961 } indexFormats[] =
3962 {
3963 { VK_INDEX_TYPE_NONE_KHR , "index_none" },
3964 { VK_INDEX_TYPE_UINT16 , "index_uint16" },
3965 { VK_INDEX_TYPE_UINT32 , "index_uint32" },
3966 };
3967
3968 auto& ctx = group->getTestContext();
3969
3970 for (int shaderSourceIdx = 0; shaderSourceIdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceIdx)
3971 {
3972 de::MovePtr<tcu::TestCaseGroup> shaderSourceGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceIdx].name.c_str()));
3973
3974 for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
3975 {
3976 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str()));
3977
3978 for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
3979 {
3980 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str()));
3981
3982 for (int topTypeIdx = 0; topTypeIdx < DE_LENGTH_OF_ARRAY(topType); ++topTypeIdx)
3983 {
3984 for (int cullFlagsIdx = 0; cullFlagsIdx < DE_LENGTH_OF_ARRAY(cullFlags); ++cullFlagsIdx)
3985 {
3986 const std::string testName = topType[topTypeIdx].name + "_" + cullFlags[cullFlagsIdx].name;
3987
3988 TestParams testParams
3989 {
3990 shaderSourceTypes[shaderSourceIdx].shaderSourceType,
3991 shaderSourceTypes[shaderSourceIdx].shaderSourcePipeline,
3992 buildTypes[buildTypeIdx].buildType,
3993 VK_FORMAT_R32G32B32_SFLOAT,
3994 false,
3995 indexFormats[indexFormatIdx].indexType,
3996 BottomTestType::TRIANGLES,
3997 cullFlags[cullFlagsIdx].cullFlags,
3998 false,
3999 false,
4000 false,
4001 topType[topTypeIdx].topType,
4002 false,
4003 false,
4004 false,
4005 VkBuildAccelerationStructureFlagsKHR(0u),
4006 OT_NONE,
4007 OP_NONE,
4008 TEST_WIDTH,
4009 TEST_HEIGHT,
4010 0u,
4011 EmptyAccelerationStructureCase::NOT_EMPTY,
4012 };
4013 indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, testName.c_str(), testParams));
4014 }
4015 }
4016 buildTypeGroup->addChild(indexTypeGroup.release());
4017 }
4018 shaderSourceGroup->addChild(buildTypeGroup.release());
4019 }
4020 group->addChild(shaderSourceGroup.release());
4021 }
4022 }
4023
addInstanceUpdateTests(tcu::TestCaseGroup * group)4024 void addInstanceUpdateTests (tcu::TestCaseGroup* group)
4025 {
4026 const struct
4027 {
4028 vk::VkAccelerationStructureBuildTypeKHR buildType;
4029 std::string name;
4030 } buildTypes[] =
4031 {
4032 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
4033 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
4034 };
4035
4036 struct
4037 {
4038 OperationType operationType;
4039 const char* name;
4040 } operationTypes[] =
4041 {
4042 { OP_UPDATE, "update" },
4043 { OP_UPDATE_IN_PLACE, "update_in_place" },
4044 };
4045
4046 auto& ctx = group->getTestContext();
4047
4048 for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
4049 {
4050 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeNdx].name.c_str()));
4051
4052 for (int operationTypesIdx = 0; operationTypesIdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypesIdx)
4053 {
4054 TestParams testParams
4055 {
4056 SST_COMPUTE_SHADER,
4057 SSP_COMPUTE_PIPELINE,
4058 buildTypes[buildTypeNdx].buildType,
4059 VK_FORMAT_R32G32B32_SFLOAT,
4060 false,
4061 VK_INDEX_TYPE_NONE_KHR,
4062 BottomTestType::TRIANGLES,
4063 InstanceCullFlags::NONE,
4064 false,
4065 false,
4066 false,
4067 TopTestType::IDENTICAL_INSTANCES,
4068 false,
4069 false,
4070 false,
4071 VkBuildAccelerationStructureFlagsKHR(0u),
4072 OT_NONE,
4073 OP_NONE,
4074 TEST_WIDTH,
4075 TEST_HEIGHT,
4076 0u,
4077 EmptyAccelerationStructureCase::NOT_EMPTY,
4078 };
4079
4080 buildTypeGroup->addChild(new RayQueryASFuncArgTestCase(ctx, operationTypes[operationTypesIdx].name, testParams));
4081 }
4082 group->addChild(buildTypeGroup.release());
4083 }
4084 }
4085
addDynamicIndexingTests(tcu::TestCaseGroup * group)4086 void addDynamicIndexingTests(tcu::TestCaseGroup* group)
4087 {
4088 auto& ctx = group->getTestContext();
4089 group->addChild(new RayQueryASDynamicIndexingTestCase(ctx, "dynamic_indexing"));
4090 }
4091
addEmptyAccelerationStructureTests(tcu::TestCaseGroup * group)4092 void addEmptyAccelerationStructureTests (tcu::TestCaseGroup* group)
4093 {
4094 const struct
4095 {
4096 ShaderSourceType shaderSourceType;
4097 ShaderSourcePipeline shaderSourcePipeline;
4098 std::string name;
4099 } shaderSourceTypes[] =
4100 {
4101 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
4102 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
4103 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
4104 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
4105 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
4106 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
4107 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
4108 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
4109 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
4110 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
4111 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
4112 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
4113 };
4114
4115 const struct
4116 {
4117 vk::VkAccelerationStructureBuildTypeKHR buildType;
4118 std::string name;
4119 } buildTypes[] =
4120 {
4121 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
4122 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
4123 };
4124
4125 const struct
4126 {
4127 VkIndexType indexType;
4128 std::string name;
4129 } indexFormats[] =
4130 {
4131 { VK_INDEX_TYPE_NONE_KHR , "index_none" },
4132 { VK_INDEX_TYPE_UINT16 , "index_uint16" },
4133 { VK_INDEX_TYPE_UINT32 , "index_uint32" },
4134 };
4135
4136 const struct
4137 {
4138 EmptyAccelerationStructureCase emptyASCase;
4139 std::string name;
4140 } emptyCases[] =
4141 {
4142 { EmptyAccelerationStructureCase::INACTIVE_TRIANGLES, "inactive_triangles" },
4143 { EmptyAccelerationStructureCase::INACTIVE_INSTANCES, "inactive_instances" },
4144 { EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM, "no_geometries_bottom" },
4145 { EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP, "no_primitives_top" },
4146 { EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM, "no_primitives_bottom" },
4147 };
4148
4149 auto& ctx = group->getTestContext();
4150
4151 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
4152 {
4153 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceNdx].name.c_str()));
4154
4155 for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
4156 {
4157 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str()));
4158
4159 for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
4160 {
4161 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str()));
4162
4163 for (int emptyCaseIdx = 0; emptyCaseIdx < DE_LENGTH_OF_ARRAY(emptyCases); ++emptyCaseIdx)
4164 {
4165 TestParams testParams
4166 {
4167 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
4168 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
4169 buildTypes[buildTypeIdx].buildType,
4170 VK_FORMAT_R32G32B32_SFLOAT,
4171 false,
4172 indexFormats[indexFormatIdx].indexType,
4173 BottomTestType::TRIANGLES,
4174 InstanceCullFlags::NONE,
4175 false,
4176 false,
4177 false,
4178 TopTestType::IDENTICAL_INSTANCES,
4179 false,
4180 false,
4181 false,
4182 VkBuildAccelerationStructureFlagsKHR(0u),
4183 OT_NONE,
4184 OP_NONE,
4185 TEST_WIDTH,
4186 TEST_HEIGHT,
4187 0u,
4188 emptyCases[emptyCaseIdx].emptyASCase,
4189 };
4190 indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, emptyCases[emptyCaseIdx].name.c_str(), testParams));
4191 }
4192 buildTypeGroup->addChild(indexTypeGroup.release());
4193 }
4194 sourceTypeGroup->addChild(buildTypeGroup.release());
4195 }
4196 group->addChild(sourceTypeGroup.release());
4197 }
4198 }
4199
createAccelerationStructuresTests(tcu::TestContext & testCtx)4200 tcu::TestCaseGroup* createAccelerationStructuresTests(tcu::TestContext& testCtx)
4201 {
4202 // Acceleration structure tests using rayQuery feature
4203 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "acceleration_structures"));
4204
4205 // Test building AS with different build types, build flags and geometries/instances using arrays or arrays of pointers
4206 addTestGroup(group.get(), "flags", addBasicBuildingTests);
4207 // Test building AS with different vertex and index formats
4208 addTestGroup(group.get(), "format", addVertexIndexFormatsTests);
4209 // Test copying, compaction and serialization of AS
4210 addTestGroup(group.get(), "operations", addOperationTests);
4211 // Test host threading operations
4212 addTestGroup(group.get(), "host_threading", addHostThreadingOperationTests);
4213 // Test using AS as function argument using both pointers and bare values
4214 addTestGroup(group.get(), "function_argument", addFuncArgTests);
4215 // Test building AS with counterclockwise triangles and/or disabling face culling
4216 addTestGroup(group.get(), "instance_triangle_culling", addInstanceTriangleCullingTests);
4217 // Test updating instance index using both in-place and separate src/dst acceleration structures
4218 addTestGroup(group.get(), "instance_update", addInstanceUpdateTests);
4219 // Exercise dynamic indexing of acceleration structures
4220 addTestGroup(group.get(), "dynamic_indexing", addDynamicIndexingTests);
4221 // Test building empty acceleration structures using different methods
4222 addTestGroup(group.get(), "empty", addEmptyAccelerationStructureTests);
4223
4224 return group.release();
4225 }
4226
4227 } // RayQuery
4228
4229 } // vkt
4230