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