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 // Different vertex configurations of a triangle whose parameter x is set to NaN during inactive_triangles tests
1200 const bool nanConfig[4][4] =
1201 {
1202 { true, true, true, true },
1203 { false, true, true, false },
1204 { false, false, true, false },
1205 { false, true, false, false },
1206 };
1207
1208 unsigned int geometryCount = testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES ? 4U : 1U;
1209
1210 if (testParams.topTestType == TTT_DIFFERENT_INSTANCES)
1211 {
1212 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1213 bottomLevelAccelerationStructure->setGeometryCount(1u);
1214 de::SharedPtr<RaytracedGeometryBase> geometry;
1215 if (testParams.bottomTestType == BTT_TRIANGLES)
1216 {
1217 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1218 if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1219 {
1220 if (instanceFlags == 0u)
1221 {
1222 geometry->addVertex(v0);
1223 geometry->addVertex(v1);
1224 geometry->addVertex(v2);
1225 geometry->addVertex(v2);
1226 geometry->addVertex(v1);
1227 geometry->addVertex(v3);
1228 }
1229 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1230 {
1231 geometry->addVertex(v2);
1232 geometry->addVertex(v1);
1233 geometry->addVertex(v0);
1234 geometry->addVertex(v3);
1235 geometry->addVertex(v1);
1236 geometry->addVertex(v2);
1237 }
1238 }
1239 else // m_data.indexType != VK_INDEX_TYPE_NONE_KHR
1240 {
1241 geometry->addVertex(v0);
1242 geometry->addVertex(v1);
1243 geometry->addVertex(v2);
1244 geometry->addVertex(v3);
1245
1246 if (instanceFlags == 0u)
1247 {
1248 geometry->addIndex(0);
1249 geometry->addIndex(1);
1250 geometry->addIndex(2);
1251 geometry->addIndex(2);
1252 geometry->addIndex(1);
1253 geometry->addIndex(3);
1254 }
1255 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1256 {
1257 geometry->addIndex(2);
1258 geometry->addIndex(1);
1259 geometry->addIndex(0);
1260 geometry->addIndex(3);
1261 geometry->addIndex(1);
1262 geometry->addIndex(2);
1263 }
1264
1265 }
1266 }
1267 else // m_data.bottomTestType == BTT_AABBS
1268 {
1269 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1270
1271 if (!testParams.padVertices)
1272 {
1273 // Single AABB.
1274 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1275 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1276 }
1277 else
1278 {
1279 // Multiple AABBs covering the same space.
1280 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1281 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, 0.1f));
1282
1283 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, -0.1f));
1284 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1285
1286 geometry->addVertex(tcu::Vec3(0.0f, 0.5f, -0.1f));
1287 geometry->addVertex(tcu::Vec3(0.5f, 1.0f, 0.1f));
1288
1289 geometry->addVertex(tcu::Vec3(0.5f, 0.0f, -0.1f));
1290 geometry->addVertex(tcu::Vec3(1.0f, 0.5f, 0.1f));
1291 }
1292 }
1293
1294 bottomLevelAccelerationStructure->addGeometry(geometry);
1295 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1296 }
1297 else // m_data.topTestType == TTT_IDENTICAL_INSTANCES
1298 {
1299 tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat);
1300 tcu::Vec3 scale ( 1.0f, 1.0f, 1.0f );
1301 if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1302 scale = tcu::Vec3(1.0f / float(testParams.width), 1.0f / float(testParams.height), 1.0f);
1303
1304 // triangle and aabb tests use geometries/aabbs with different vertex positions and the same identity matrix in each instance data
1305 for (deUint32 y = 0; y < testParams.height; ++y)
1306 for (deUint32 x = 0; x < testParams.width; ++x)
1307 {
1308 // let's build a chessboard of geometries
1309 if (((x + y) % 2) == 0)
1310 continue;
1311 tcu::Vec3 xyz((float)x, (float)y, 0.0f);
1312
1313 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1314 bottomLevelAccelerationStructure->setGeometryCount(geometryCount);
1315
1316 if (testParams.bottomTestType == BTT_TRIANGLES)
1317 {
1318 for (unsigned int i = 0; i < geometryCount; i++)
1319 {
1320 de::SharedPtr<RaytracedGeometryBase> geometry;
1321 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1322
1323 if (testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES)
1324 {
1325 const auto nanValue = tcu::Float32::nan().asFloat();
1326
1327 if (nanConfig[i][0])
1328 v0.x() = nanValue;
1329 if (nanConfig[i][1])
1330 v1.x() = nanValue;
1331 if (nanConfig[i][2])
1332 v2.x() = nanValue;
1333 if (nanConfig[i][3])
1334 v3.x() = nanValue;
1335 }
1336
1337 if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1338 {
1339 if (instanceFlags == 0u)
1340 {
1341 geometry->addVertex(scale * (xyz + v0));
1342 geometry->addVertex(scale * (xyz + v1));
1343 geometry->addVertex(scale * (xyz + v2));
1344 geometry->addVertex(scale * (xyz + v2));
1345 geometry->addVertex(scale * (xyz + v1));
1346 geometry->addVertex(scale * (xyz + v3));
1347 }
1348 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1349 {
1350 geometry->addVertex(scale * (xyz + v2));
1351 geometry->addVertex(scale * (xyz + v1));
1352 geometry->addVertex(scale * (xyz + v0));
1353 geometry->addVertex(scale * (xyz + v3));
1354 geometry->addVertex(scale * (xyz + v1));
1355 geometry->addVertex(scale * (xyz + v2));
1356 }
1357 }
1358
1359 else
1360 {
1361 geometry->addVertex(scale * (xyz + v0));
1362 geometry->addVertex(scale * (xyz + v1));
1363 geometry->addVertex(scale * (xyz + v2));
1364 geometry->addVertex(scale * (xyz + v3));
1365
1366 if (instanceFlags == 0u)
1367 {
1368 geometry->addIndex(0);
1369 geometry->addIndex(1);
1370 geometry->addIndex(2);
1371 geometry->addIndex(2);
1372 geometry->addIndex(1);
1373 geometry->addIndex(3);
1374 }
1375 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1376 {
1377 geometry->addIndex(2);
1378 geometry->addIndex(1);
1379 geometry->addIndex(0);
1380 geometry->addIndex(3);
1381 geometry->addIndex(1);
1382 geometry->addIndex(2);
1383 }
1384 }
1385
1386 bottomLevelAccelerationStructure->addGeometry(geometry);
1387 }
1388 }
1389 else // testParams.bottomTestType == BTT_AABBS
1390 {
1391 de::SharedPtr<RaytracedGeometryBase> geometry;
1392 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1393
1394 if (!testParams.padVertices)
1395 {
1396 // Single AABB.
1397 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1398 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1399 }
1400 else
1401 {
1402 // Multiple AABBs covering the same space.
1403 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1404 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, 0.1f)));
1405
1406 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, -0.1f)));
1407 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1408
1409 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.5f, -0.1f)));
1410 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 1.0f, 0.1f)));
1411
1412 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.0f, -0.1f)));
1413 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 0.5f, 0.1f)));
1414 }
1415
1416 bottomLevelAccelerationStructure->addGeometry(geometry);
1417 }
1418
1419 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1420 }
1421 }
1422
1423 return result;
1424 }
1425
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)1426 de::MovePtr<TopLevelAccelerationStructure> CheckerboardSceneBuilder::initTopAccelerationStructure (Context& context,
1427 TestParams& testParams,
1428 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
1429 {
1430 DE_UNREF(context);
1431
1432 const auto instanceCount = testParams.width * testParams.height / 2u;
1433 const auto instanceFlags = getCullFlags(testParams.cullFlags);
1434
1435 de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure();
1436 result->setInstanceCount(instanceCount);
1437
1438 if (testParams.topTestType == TTT_DIFFERENT_INSTANCES)
1439 {
1440
1441 for (deUint32 y = 0; y < testParams.height; ++y)
1442 for (deUint32 x = 0; x < testParams.width; ++x)
1443 {
1444 if (((x + y) % 2) == 0)
1445 continue;
1446 const VkTransformMatrixKHR transformMatrixKHR =
1447 {
1448 { // float matrix[3][4];
1449 { 1.0f, 0.0f, 0.0f, (float)x },
1450 { 0.0f, 1.0f, 0.0f, (float)y },
1451 { 0.0f, 0.0f, 1.0f, 0.0f },
1452 }
1453 };
1454 result->addInstance(bottomLevelAccelerationStructures[0], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags);
1455 }
1456 }
1457 else // testParams.topTestType == TTT_IDENTICAL_INSTANCES
1458 {
1459 tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat);
1460 tcu::Vec3 scale ( 1.0f, 1.0f, 1.0f );
1461 if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1462 scale = tcu::Vec3(float(testParams.width), float(testParams.height), 1.0f);
1463
1464 const VkTransformMatrixKHR transformMatrixKHR =
1465 {
1466 { // float matrix[3][4];
1467 { scale.x(), 0.0f, 0.0f, 0.0f },
1468 { 0.0f, scale.y(), 0.0f, 0.0f },
1469 { 0.0f, 0.0f, scale.z(), 0.0f },
1470 }
1471 };
1472
1473 deUint32 currentInstanceIndex = 0;
1474
1475 for (deUint32 y = 0; y < testParams.height; ++y)
1476 for (deUint32 x = 0; x < testParams.width; ++x)
1477 {
1478 if (((x + y) % 2) == 0)
1479 continue;
1480 result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags);
1481 }
1482 }
1483
1484 return result;
1485 }
1486
commonASTestsCheckSupport(Context & context)1487 void commonASTestsCheckSupport(Context& context)
1488 {
1489 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1490 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1491 context.requireDeviceFunctionality("VK_KHR_ray_query");
1492
1493 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures();
1494 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
1495 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1496
1497 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1498 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
1499 TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1500 }
1501
1502 class RayQueryASBasicTestCase : public TestCase
1503 {
1504 public:
1505 RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data);
1506 ~RayQueryASBasicTestCase (void);
1507
1508 virtual void checkSupport (Context& context) const;
1509 virtual void initPrograms (SourceCollections& programCollection) const;
1510 virtual TestInstance* createInstance (Context& context) const;
1511 protected:
1512 TestParams m_data;
1513 };
1514
1515 class RayQueryASFuncArgTestCase : public RayQueryASBasicTestCase
1516 {
1517 public:
1518 RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data);
~RayQueryASFuncArgTestCase(void)1519 ~RayQueryASFuncArgTestCase (void) {}
1520
1521 virtual void initPrograms (SourceCollections& programCollection) const;
1522 };
1523
1524 class RayQueryASBasicTestInstance : public TestInstance
1525 {
1526 public:
1527 RayQueryASBasicTestInstance (Context& context,
1528 const TestParams& data);
1529 ~RayQueryASBasicTestInstance (void);
1530 tcu::TestStatus iterate (void);
1531 protected:
1532 bool iterateNoWorkers (void);
1533 bool iterateWithWorkers (void);
1534 de::MovePtr<BufferWithMemory> runTest (TestConfiguration* testConfiguration,
1535 SceneBuilder* sceneBuilder,
1536 const deUint32 workerThreadsCount);
1537
1538
1539 private:
1540 TestParams m_data;
1541 };
1542
RayQueryASBasicTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams & data)1543 RayQueryASBasicTestCase::RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data)
1544 : vkt::TestCase (context, name, desc)
1545 , m_data (data)
1546 {
1547 }
1548
~RayQueryASBasicTestCase(void)1549 RayQueryASBasicTestCase::~RayQueryASBasicTestCase (void)
1550 {
1551 }
1552
checkSupport(Context & context) const1553 void RayQueryASBasicTestCase::checkSupport (Context& context) const
1554 {
1555 commonASTestsCheckSupport(context);
1556
1557 const VkPhysicalDeviceFeatures2& features2 = context.getDeviceFeatures2();
1558
1559 if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1560 m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1561 features2.features.tessellationShader == DE_FALSE )
1562 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1563
1564 if (m_data.shaderSourceType == SST_GEOMETRY_SHADER &&
1565 features2.features.geometryShader == DE_FALSE )
1566 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1567
1568 if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER ||
1569 m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1570 m_data.shaderSourceType == SST_ANY_HIT_SHADER ||
1571 m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1572 m_data.shaderSourceType == SST_MISS_SHADER ||
1573 m_data.shaderSourceType == SST_CALLABLE_SHADER)
1574 {
1575 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1576
1577 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1578
1579 if(rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
1580 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1581 }
1582
1583 switch (m_data.shaderSourceType)
1584 {
1585 case SST_VERTEX_SHADER:
1586 case SST_TESSELATION_CONTROL_SHADER:
1587 case SST_TESSELATION_EVALUATION_SHADER:
1588 case SST_GEOMETRY_SHADER:
1589 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1590 break;
1591 default:
1592 break;
1593 }
1594
1595 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1596 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE)
1597 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands");
1598
1599 // Check supported vertex format.
1600 checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.vertexFormat);
1601 }
1602
initPrograms(SourceCollections & programCollection) const1603 void RayQueryASBasicTestCase::initPrograms (SourceCollections& programCollection) const
1604 {
1605 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1606
1607 // create parts of programs responsible for test execution
1608 std::vector<std::string> rayQueryTest;
1609 std::vector<std::string> rayQueryTestName;
1610 rayQueryTestName.push_back("as_triangle");
1611 rayQueryTestName.push_back("as_aabb");
1612
1613 {
1614 std::stringstream css;
1615 css <<
1616 " float tmin = 0.0;\n"
1617 " float tmax = 1.0;\n"
1618 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1619 " rayQueryEXT rq;\n"
1620 " rayQueryInitializeEXT(rq, rqTopLevelAS, " << ((m_data.cullFlags == InstanceCullFlags::NONE) ? "0" : "gl_RayFlagsCullBackFacingTrianglesEXT") << ", 0xFF, origin, tmin, direct, tmax);\n"
1621 " if(rayQueryProceedEXT(rq))\n"
1622 " {\n"
1623 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1624 " {\n"
1625 " hitValue.y = 1;\n"
1626 " hitValue.x = 1;\n"
1627 " }\n"
1628 " }\n";
1629 rayQueryTest.push_back(css.str());
1630 }
1631 {
1632 std::stringstream css;
1633 css <<
1634 " float tmin = 0.0;\n"
1635 " float tmax = 1.0;\n"
1636 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1637 " rayQueryEXT rq;\n"
1638 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1639 " if(rayQueryProceedEXT(rq))\n"
1640 " {\n"
1641 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1642 " {\n"
1643 " hitValue.y = 1;\n"
1644 " hitValue.x = 1;\n"
1645 " }\n"
1646 " }\n";
1647 rayQueryTest.push_back(css.str());
1648 }
1649
1650 // create all programs
1651 if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1652 {
1653 {
1654 std::stringstream css;
1655 css <<
1656 "#version 460 core\n"
1657 "layout (location = 0) in vec3 position;\n"
1658 "out gl_PerVertex\n"
1659 "{\n"
1660 " vec4 gl_Position;\n"
1661 "};\n"
1662 "void main()\n"
1663 "{\n"
1664 " gl_Position = vec4(position, 1.0);\n"
1665 "}\n";
1666 programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions;
1667 }
1668
1669 {
1670 std::stringstream css;
1671 css <<
1672 "#version 460 core\n"
1673 "layout (location = 0) in vec3 position;\n"
1674 "out gl_PerVertex\n"
1675 "{\n"
1676 " vec4 gl_Position;\n"
1677 "};\n"
1678 "layout(location = 0) out int vertexIndex;\n"
1679 "void main()\n"
1680 "{\n"
1681 " gl_Position = vec4(position, 1.0);\n"
1682 " vertexIndex = gl_VertexIndex;\n"
1683 "}\n";
1684 programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str()) << buildOptions;
1685 }
1686
1687 {
1688 std::stringstream css;
1689 css <<
1690 "#version 460 core\n"
1691 "#extension GL_EXT_ray_query : require\n"
1692 "layout (location = 0) in vec3 position;\n"
1693 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1694 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1695 "void main()\n"
1696 "{\n"
1697 " vec3 origin = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n"
1698 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1699 rayQueryTest[m_data.bottomTestType] <<
1700 " imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1701 " imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1702 " gl_Position = vec4(position,1);\n"
1703 "}\n";
1704 std::stringstream cssName;
1705 cssName << "vert_" << rayQueryTestName[m_data.bottomTestType];
1706
1707 programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1708 }
1709
1710 {
1711 std::stringstream css;
1712 css <<
1713 "#version 460 core\n"
1714 "#extension GL_EXT_tessellation_shader : require\n"
1715 "in gl_PerVertex {\n"
1716 " vec4 gl_Position;\n"
1717 "} gl_in[];\n"
1718 "layout(vertices = 3) out;\n"
1719 "void main (void)\n"
1720 "{\n"
1721 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1722 " gl_TessLevelInner[0] = 1;\n"
1723 " gl_TessLevelOuter[0] = 1;\n"
1724 " gl_TessLevelOuter[1] = 1;\n"
1725 " gl_TessLevelOuter[2] = 1;\n"
1726 "}\n";
1727 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions;
1728 }
1729
1730 {
1731 std::stringstream css;
1732 css <<
1733 "#version 460 core\n"
1734 "#extension GL_EXT_tessellation_shader : require\n"
1735 "#extension GL_EXT_ray_query : require\n"
1736 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1737 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1738 "in gl_PerVertex {\n"
1739 " vec4 gl_Position;\n"
1740 "} gl_in[];\n"
1741 "layout(vertices = 3) out;\n"
1742 "void main (void)\n"
1743 "{\n"
1744 " vec3 origin = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n"
1745 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1746 rayQueryTest[m_data.bottomTestType] <<
1747 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1748 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1749 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1750 " gl_TessLevelInner[0] = 1;\n"
1751 " gl_TessLevelOuter[0] = 1;\n"
1752 " gl_TessLevelOuter[1] = 1;\n"
1753 " gl_TessLevelOuter[2] = 1;\n"
1754 "}\n";
1755 std::stringstream cssName;
1756 cssName << "tesc_" << rayQueryTestName[m_data.bottomTestType];
1757
1758 programCollection.glslSources.add(cssName.str()) << glu::TessellationControlSource(css.str()) << buildOptions;
1759 }
1760
1761 {
1762 std::stringstream css;
1763 css <<
1764 "#version 460 core\n"
1765 "#extension GL_EXT_tessellation_shader : require\n"
1766 "#extension GL_EXT_ray_query : require\n"
1767 "layout(triangles, equal_spacing, ccw) in;\n"
1768 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1769 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1770 "void main (void)\n"
1771 "{\n"
1772 " for (int i = 0; i < 3; ++i)\n"
1773 " {\n"
1774 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1775 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1776 rayQueryTest[m_data.bottomTestType] <<
1777 " imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1778 " imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1779 " }\n"
1780 " gl_Position = gl_in[0].gl_Position;\n"
1781 "}\n";
1782 std::stringstream cssName;
1783 cssName << "tese_" << rayQueryTestName[m_data.bottomTestType];
1784
1785 programCollection.glslSources.add(cssName.str()) << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1786 }
1787
1788 {
1789 std::stringstream css;
1790 css <<
1791 "#version 460 core\n"
1792 "#extension GL_EXT_tessellation_shader : require\n"
1793 "layout(triangles, equal_spacing, ccw) in;\n"
1794 "void main (void)\n"
1795 "{\n"
1796 " gl_Position = gl_in[0].gl_Position;\n"
1797 "}\n";
1798
1799 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1800 }
1801
1802 {
1803 std::stringstream css;
1804 css <<
1805 "#version 460 core\n"
1806 "#extension GL_EXT_ray_query : require\n"
1807 "layout(triangles) in;\n"
1808 "layout (triangle_strip, max_vertices = 4) out;\n"
1809 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1810 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1811 "\n"
1812 "in gl_PerVertex {\n"
1813 " vec4 gl_Position;\n"
1814 "} gl_in[];\n"
1815 "layout(location = 0) in int vertexIndex[];\n"
1816 "out gl_PerVertex {\n"
1817 " vec4 gl_Position;\n"
1818 "};\n"
1819 "void main (void)\n"
1820 "{\n"
1821 " // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n"
1822 " // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n"
1823 " // smallest vertex index value.\n"
1824 " int minVertexIndex = 10000;"
1825 " int firstVertex;"
1826 " for (int i = 0; i < gl_in.length(); ++i)\n"
1827 " {\n"
1828 " if (minVertexIndex > vertexIndex[i])\n"
1829 " {\n"
1830 " minVertexIndex = vertexIndex[i];\n"
1831 " firstVertex = i;\n"
1832 " }\n"
1833 " }\n"
1834 " for (int j = 0; j < gl_in.length(); ++j)\n"
1835 " {\n"
1836 " // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n"
1837 " // always iterated starting from the smallest vertex index, as found above.\n"
1838 " int i = (firstVertex + j) % gl_in.length();\n"
1839 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1840 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1841 rayQueryTest[m_data.bottomTestType] <<
1842 " imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1843 " imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1844 " gl_Position = gl_in[i].gl_Position;\n"
1845 " EmitVertex();\n"
1846 " }\n"
1847 " EndPrimitive();\n"
1848 "}\n";
1849 std::stringstream cssName;
1850 cssName << "geom_" << rayQueryTestName[m_data.bottomTestType];
1851
1852 programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1853 }
1854
1855 {
1856 std::stringstream css;
1857 css <<
1858 "#version 460 core\n"
1859 "#extension GL_EXT_ray_query : require\n"
1860 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1861 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1862 "void main()\n"
1863 "{\n"
1864 " vec3 origin = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n"
1865 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1866 rayQueryTest[m_data.bottomTestType] <<
1867 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1868 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1869 "}\n";
1870 std::stringstream cssName;
1871 cssName << "frag_" << rayQueryTestName[m_data.bottomTestType];
1872
1873 programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1874 }
1875 }
1876 else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1877 {
1878 {
1879 std::stringstream css;
1880 css <<
1881 "#version 460 core\n"
1882 "#extension GL_EXT_ray_query : require\n"
1883 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1884 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1885 "void main()\n"
1886 "{\n"
1887 " vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);\n"
1888 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1889 rayQueryTest[m_data.bottomTestType] <<
1890 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1891 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1892 "}\n";
1893 std::stringstream cssName;
1894 cssName << "comp_" << rayQueryTestName[m_data.bottomTestType];
1895
1896 programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1897 }
1898 }
1899 else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1900 {
1901 {
1902 std::stringstream css;
1903 css <<
1904 "#version 460 core\n"
1905 "#extension GL_EXT_ray_tracing : require\n"
1906 "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1907 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1908 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1909 "void main()\n"
1910 "{\n"
1911 " float tmin = 0.0;\n"
1912 " float tmax = 1.0;\n"
1913 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1914 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1915 " hitValue = uvec4(0,0,0,0);\n"
1916 " traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1917 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1918 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1919 "}\n";
1920 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1921 }
1922
1923 {
1924 std::stringstream css;
1925 css <<
1926 "#version 460 core\n"
1927 "#extension GL_EXT_ray_tracing : require\n"
1928 "#extension GL_EXT_ray_query : require\n"
1929 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1930 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1931 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1932 "void main()\n"
1933 "{\n"
1934 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1935 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1936 rayQueryTest[m_data.bottomTestType] <<
1937 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1938 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1939 "}\n";
1940 std::stringstream cssName;
1941 cssName << "rgen_" << rayQueryTestName[m_data.bottomTestType];
1942
1943 programCollection.glslSources.add(cssName.str()) << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1944 }
1945
1946 {
1947 std::stringstream css;
1948 css <<
1949 "#version 460 core\n"
1950 "#extension GL_EXT_ray_tracing : require\n"
1951 "struct CallValue\n{\n"
1952 " vec3 origin;\n"
1953 " uvec4 hitValue;\n"
1954 "};\n"
1955 "layout(location = 0) callableDataEXT CallValue param;\n"
1956 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1957 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1958 "void main()\n"
1959 "{\n"
1960 " param.origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1961 " param.hitValue = uvec4(0, 0, 0, 0);\n"
1962 " executeCallableEXT(0, 0);\n"
1963 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
1964 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
1965 "}\n";
1966 programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1967 }
1968
1969 {
1970 std::stringstream css;
1971 css <<
1972 "#version 460 core\n"
1973 "#extension GL_EXT_ray_tracing : require\n"
1974 "hitAttributeEXT uvec4 hitValue;\n"
1975 "void main()\n"
1976 "{\n"
1977 " reportIntersectionEXT(0.5f, 0);\n"
1978 "}\n";
1979
1980 programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1981 }
1982
1983 {
1984 std::stringstream css;
1985 css <<
1986 "#version 460 core\n"
1987 "#extension GL_EXT_ray_tracing : require\n"
1988 "#extension GL_EXT_ray_query : require\n"
1989 "hitAttributeEXT uvec4 hitValue;\n"
1990 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1991 "void main()\n"
1992 "{\n"
1993 " vec3 origin = gl_WorldRayOriginEXT;\n"
1994 " hitValue = uvec4(0,0,0,0);\n" <<
1995 rayQueryTest[m_data.bottomTestType] <<
1996 " reportIntersectionEXT(0.5f, 0);\n"
1997 "}\n";
1998 std::stringstream cssName;
1999 cssName << "isect_" << rayQueryTestName[m_data.bottomTestType];
2000
2001 programCollection.glslSources.add(cssName.str()) << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
2002 }
2003
2004 {
2005 std::stringstream css;
2006 css <<
2007 "#version 460 core\n"
2008 "#extension GL_EXT_ray_tracing : require\n"
2009 "#extension GL_EXT_ray_query : require\n"
2010 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2011 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2012 "void main()\n"
2013 "{\n"
2014 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
2015 rayQueryTest[m_data.bottomTestType] <<
2016 "}\n";
2017 std::stringstream cssName;
2018 cssName << "ahit_" << rayQueryTestName[m_data.bottomTestType];
2019
2020 programCollection.glslSources.add(cssName.str()) << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2021 }
2022
2023 {
2024 std::stringstream css;
2025 css <<
2026 "#version 460 core\n"
2027 "#extension GL_EXT_ray_tracing : require\n"
2028 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2029 "void main()\n"
2030 "{\n"
2031 " hitValue.y = 3;\n"
2032 "}\n";
2033
2034 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2035 }
2036
2037 {
2038 std::stringstream css;
2039 css <<
2040 "#version 460 core\n"
2041 "#extension GL_EXT_ray_tracing : require\n"
2042 "#extension GL_EXT_ray_query : require\n"
2043 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2044 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2045 "void main()\n"
2046 "{\n"
2047 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
2048 rayQueryTest[m_data.bottomTestType] <<
2049 "}\n";
2050 std::stringstream cssName;
2051 cssName << "chit_" << rayQueryTestName[m_data.bottomTestType];
2052
2053 programCollection.glslSources.add(cssName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2054 }
2055
2056 {
2057 std::stringstream css;
2058 css <<
2059 "#version 460 core\n"
2060 "#extension GL_EXT_ray_tracing : require\n"
2061 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2062 "hitAttributeEXT uvec4 hitAttrib;\n"
2063 "void main()\n"
2064 "{\n"
2065 " hitValue = hitAttrib;\n"
2066 "}\n";
2067
2068 programCollection.glslSources.add("chit_isect") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2069 }
2070
2071 {
2072 std::stringstream css;
2073 css <<
2074 "#version 460 core\n"
2075 "#extension GL_EXT_ray_tracing : require\n"
2076 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2077 "void main()\n"
2078 "{\n"
2079 " hitValue.x = 4;\n"
2080 "}\n";
2081
2082 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2083 }
2084
2085 {
2086 std::stringstream css;
2087 css <<
2088 "#version 460 core\n"
2089 "#extension GL_EXT_ray_tracing : require\n"
2090 "#extension GL_EXT_ray_query : require\n"
2091 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2092 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2093 "void main()\n"
2094 "{\n"
2095 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
2096 rayQueryTest[m_data.bottomTestType] <<
2097 "}\n";
2098 std::stringstream cssName;
2099 cssName << "miss_" << rayQueryTestName[m_data.bottomTestType];
2100
2101 programCollection.glslSources.add(cssName.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2102 }
2103
2104 {
2105 std::stringstream css;
2106 css <<
2107 "#version 460 core\n"
2108 "#extension GL_EXT_ray_tracing : require\n"
2109 "#extension GL_EXT_ray_query : require\n"
2110 "struct CallValue\n{\n"
2111 " vec3 origin;\n"
2112 " uvec4 hitValue;\n"
2113 "};\n"
2114 "layout(location = 0) callableDataInEXT CallValue result;\n"
2115 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2116 "void main()\n"
2117 "{\n"
2118 " vec3 origin = result.origin;\n"
2119 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
2120 rayQueryTest[m_data.bottomTestType] <<
2121 " result.hitValue = hitValue;\n"
2122 "}\n";
2123 std::stringstream cssName;
2124 cssName << "call_" << rayQueryTestName[m_data.bottomTestType];
2125
2126 programCollection.glslSources.add(cssName.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
2127 }
2128 }
2129 }
2130
createInstance(Context & context) const2131 TestInstance* RayQueryASBasicTestCase::createInstance (Context& context) const
2132 {
2133 return new RayQueryASBasicTestInstance(context, m_data);
2134 }
2135
RayQueryASFuncArgTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams & data)2136 RayQueryASFuncArgTestCase::RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data)
2137 : RayQueryASBasicTestCase (context, name, desc, data)
2138 {
2139 }
2140
initPrograms(SourceCollections & programCollection) const2141 void RayQueryASFuncArgTestCase::initPrograms (SourceCollections& programCollection) const
2142 {
2143 const vk::SpirVAsmBuildOptions spvBuildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2144
2145 DE_ASSERT(m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE);
2146 DE_ASSERT(m_data.bottomTestType == BTT_TRIANGLES);
2147
2148 // The SPIR-V assembly shader below is based on the following GLSL code.
2149 // In it, rayQueryInitializeBottomWrapper has been modified to take a
2150 // bare AS as the second argument, instead of a pointer.
2151 //
2152 // #version 460 core
2153 // #extension GL_EXT_ray_query : require
2154 // layout(r32ui, set = 0, binding = 0) uniform uimage3D result;
2155 // layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;
2156 //
2157 // void rayQueryInitializeBottomWrapper(rayQueryEXT rayQuery,
2158 // accelerationStructureEXT topLevel,
2159 // uint rayFlags, uint cullMask, vec3 origin,
2160 // float tMin, vec3 direction, float tMax)
2161 // {
2162 // rayQueryInitializeEXT(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2163 // }
2164 //
2165 // void rayQueryInitializeTopWrapper(rayQueryEXT rayQuery,
2166 // accelerationStructureEXT topLevel,
2167 // uint rayFlags, uint cullMask, vec3 origin,
2168 // float tMin, vec3 direction, float tMax)
2169 // {
2170 // rayQueryInitializeBottomWrapper(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2171 // }
2172 //
2173 // void main()
2174 // {
2175 // vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);
2176 // uvec4 hitValue = uvec4(0,0,0,0);
2177 // float tmin = 0.0;
2178 // float tmax = 1.0;
2179 // vec3 direct = vec3(0.0, 0.0, -1.0);
2180 // rayQueryEXT rq;
2181 // rayQueryInitializeTopWrapper(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);
2182 // if(rayQueryProceedEXT(rq))
2183 // {
2184 // if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)
2185 // {
2186 // hitValue.y = 1;
2187 // hitValue.x = 1;
2188 // }
2189 // }
2190 // imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));
2191 // imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));
2192 // }
2193
2194 std::stringstream css;
2195 css
2196 << "; SPIR-V\n"
2197 << "; Version: 1.4\n"
2198 << "; Generator: Khronos Glslang Reference Front End; 10\n"
2199 << "; Bound: 139\n"
2200 << "; Schema: 0\n"
2201 << "OpCapability Shader\n"
2202 << "OpCapability RayQueryKHR\n"
2203 << "OpExtension \"SPV_KHR_ray_query\"\n"
2204 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
2205 << "OpMemoryModel Logical GLSL450\n"
2206 << "OpEntryPoint GLCompute %4 \"main\" %60 %86 %114\n"
2207 << "OpExecutionMode %4 LocalSize 1 1 1\n"
2208 << "OpDecorate %60 BuiltIn GlobalInvocationId\n"
2209 << "OpDecorate %86 DescriptorSet 0\n"
2210 << "OpDecorate %86 Binding 1\n"
2211 << "OpDecorate %114 DescriptorSet 0\n"
2212 << "OpDecorate %114 Binding 0\n"
2213 << "%2 = OpTypeVoid\n"
2214 << "%3 = OpTypeFunction %2\n"
2215
2216 // Bare query type
2217 << "%6 = OpTypeRayQueryKHR\n"
2218
2219 // Pointer to query.
2220 << "%7 = OpTypePointer Function %6\n"
2221
2222 // Bare AS type.
2223 << "%8 = OpTypeAccelerationStructureKHR\n"
2224
2225 // Pointer to AS.
2226 << "%9 = OpTypePointer UniformConstant %8\n"
2227
2228 << "%10 = OpTypeInt 32 0\n"
2229 << "%11 = OpTypePointer Function %10\n"
2230 << "%12 = OpTypeFloat 32\n"
2231 << "%13 = OpTypeVector %12 3\n"
2232 << "%14 = OpTypePointer Function %13\n"
2233 << "%15 = OpTypePointer Function %12\n"
2234
2235 // This is the function type for rayQueryInitializeTopWrapper and the old rayQueryInitializeBottomWrapper.
2236 << "%16 = OpTypeFunction %2 %7 %9 %11 %11 %14 %15 %14 %15\n"
2237
2238 // This is the new function type for the modified rayQueryInitializeBottomWrapper that uses a bare AS.
2239 //<< "%16b = OpTypeFunction %2 %6 %8 %11 %11 %14 %15 %14 %15\n"
2240 << "%16b = OpTypeFunction %2 %7 %8 %11 %11 %14 %15 %14 %15\n"
2241
2242 << "%58 = OpTypeVector %10 3\n"
2243 << "%59 = OpTypePointer Input %58\n"
2244 << "%60 = OpVariable %59 Input\n"
2245 << "%61 = OpConstant %10 0\n"
2246 << "%62 = OpTypePointer Input %10\n"
2247 << "%66 = OpConstant %12 0.5\n"
2248 << "%68 = OpConstant %10 1\n"
2249 << "%74 = OpTypeVector %10 4\n"
2250 << "%75 = OpTypePointer Function %74\n"
2251 << "%77 = OpConstantComposite %74 %61 %61 %61 %61\n"
2252 << "%79 = OpConstant %12 0\n"
2253 << "%81 = OpConstant %12 1\n"
2254 << "%83 = OpConstant %12 -1\n"
2255 << "%84 = OpConstantComposite %13 %79 %79 %83\n"
2256 << "%86 = OpVariable %9 UniformConstant\n"
2257 << "%87 = OpConstant %10 255\n"
2258 << "%99 = OpTypeBool\n"
2259 << "%103 = OpConstantFalse %99\n"
2260 << "%104 = OpTypeInt 32 1\n"
2261 << "%105 = OpConstant %104 0\n"
2262 << "%112 = OpTypeImage %10 3D 0 0 0 2 R32ui\n"
2263 << "%113 = OpTypePointer UniformConstant %112\n"
2264 << "%114 = OpVariable %113 UniformConstant\n"
2265 << "%116 = OpTypeVector %10 2\n"
2266 << "%119 = OpTypeVector %104 2\n"
2267 << "%121 = OpTypeVector %104 3\n"
2268 << "%132 = OpConstant %104 1\n"
2269
2270 // This is main().
2271 << "%4 = OpFunction %2 None %3\n"
2272 << "%5 = OpLabel\n"
2273 << "%57 = OpVariable %14 Function\n"
2274 << "%76 = OpVariable %75 Function\n"
2275 << "%78 = OpVariable %15 Function\n"
2276 << "%80 = OpVariable %15 Function\n"
2277 << "%82 = OpVariable %14 Function\n"
2278 << "%85 = OpVariable %7 Function\n"
2279 << "%88 = OpVariable %11 Function\n"
2280 << "%89 = OpVariable %11 Function\n"
2281 << "%90 = OpVariable %14 Function\n"
2282 << "%92 = OpVariable %15 Function\n"
2283 << "%94 = OpVariable %14 Function\n"
2284 << "%96 = OpVariable %15 Function\n"
2285 << "%63 = OpAccessChain %62 %60 %61\n"
2286 << "%64 = OpLoad %10 %63\n"
2287 << "%65 = OpConvertUToF %12 %64\n"
2288 << "%67 = OpFAdd %12 %65 %66\n"
2289 << "%69 = OpAccessChain %62 %60 %68\n"
2290 << "%70 = OpLoad %10 %69\n"
2291 << "%71 = OpConvertUToF %12 %70\n"
2292 << "%72 = OpFAdd %12 %71 %66\n"
2293 << "%73 = OpCompositeConstruct %13 %67 %72 %66\n"
2294 << "OpStore %57 %73\n"
2295 << "OpStore %76 %77\n"
2296 << "OpStore %78 %79\n"
2297 << "OpStore %80 %81\n"
2298 << "OpStore %82 %84\n"
2299 << "OpStore %88 %61\n"
2300 << "OpStore %89 %87\n"
2301 << "%91 = OpLoad %13 %57\n"
2302 << "OpStore %90 %91\n"
2303 << "%93 = OpLoad %12 %78\n"
2304 << "OpStore %92 %93\n"
2305 << "%95 = OpLoad %13 %82\n"
2306 << "OpStore %94 %95\n"
2307 << "%97 = OpLoad %12 %80\n"
2308 << "OpStore %96 %97\n"
2309 << "%98 = OpFunctionCall %2 %35 %85 %86 %88 %89 %90 %92 %94 %96\n"
2310 << "%100 = OpRayQueryProceedKHR %99 %85\n"
2311 << "OpSelectionMerge %102 None\n"
2312 << "OpBranchConditional %100 %101 %102\n"
2313 << "%101 = OpLabel\n"
2314 << "%106 = OpRayQueryGetIntersectionTypeKHR %10 %85 %105\n"
2315 << "%107 = OpIEqual %99 %106 %61\n"
2316 << "OpSelectionMerge %109 None\n"
2317 << "OpBranchConditional %107 %108 %109\n"
2318 << "%108 = OpLabel\n"
2319 << "%110 = OpAccessChain %11 %76 %68\n"
2320 << "OpStore %110 %68\n"
2321 << "%111 = OpAccessChain %11 %76 %61\n"
2322 << "OpStore %111 %68\n"
2323 << "OpBranch %109\n"
2324 << "%109 = OpLabel\n"
2325 << "OpBranch %102\n"
2326 << "%102 = OpLabel\n"
2327 << "%115 = OpLoad %112 %114\n"
2328 << "%117 = OpLoad %58 %60\n"
2329 << "%118 = OpVectorShuffle %116 %117 %117 0 1\n"
2330 << "%120 = OpBitcast %119 %118\n"
2331 << "%122 = OpCompositeExtract %104 %120 0\n"
2332 << "%123 = OpCompositeExtract %104 %120 1\n"
2333 << "%124 = OpCompositeConstruct %121 %122 %123 %105\n"
2334 << "%125 = OpAccessChain %11 %76 %61\n"
2335 << "%126 = OpLoad %10 %125\n"
2336 << "%127 = OpCompositeConstruct %74 %126 %61 %61 %61\n"
2337 << "OpImageWrite %115 %124 %127 ZeroExtend\n"
2338 << "%128 = OpLoad %112 %114\n"
2339 << "%129 = OpLoad %58 %60\n"
2340 << "%130 = OpVectorShuffle %116 %129 %129 0 1\n"
2341 << "%131 = OpBitcast %119 %130\n"
2342 << "%133 = OpCompositeExtract %104 %131 0\n"
2343 << "%134 = OpCompositeExtract %104 %131 1\n"
2344 << "%135 = OpCompositeConstruct %121 %133 %134 %132\n"
2345 << "%136 = OpAccessChain %11 %76 %68\n"
2346 << "%137 = OpLoad %10 %136\n"
2347 << "%138 = OpCompositeConstruct %74 %137 %61 %61 %61\n"
2348 << "OpImageWrite %128 %135 %138 ZeroExtend\n"
2349 << "OpReturn\n"
2350 << "OpFunctionEnd\n"
2351
2352 // This is rayQueryInitializeBottomWrapper, calling OpRayQueryInitializeKHR.
2353 // We have modified the function type so it takes bare arguments.
2354 //%25 = OpFunction %2 None %16
2355 << "%25 = OpFunction %2 None %16b\n"
2356
2357 // These is the modified parameter.
2358 << "%17 = OpFunctionParameter %7\n"
2359 //<< "%17 = OpFunctionParameter %6\n"
2360 //%18 = OpFunctionParameter %9
2361 << "%18 = OpFunctionParameter %8\n"
2362
2363 << "%19 = OpFunctionParameter %11\n"
2364 << "%20 = OpFunctionParameter %11\n"
2365 << "%21 = OpFunctionParameter %14\n"
2366 << "%22 = OpFunctionParameter %15\n"
2367 << "%23 = OpFunctionParameter %14\n"
2368 << "%24 = OpFunctionParameter %15\n"
2369 << "%26 = OpLabel\n"
2370
2371 // We no longer need to load this parameter.
2372 //%37 = OpLoad %8 %18
2373
2374 << "%38 = OpLoad %10 %19\n"
2375 << "%39 = OpLoad %10 %20\n"
2376 << "%40 = OpLoad %13 %21\n"
2377 << "%41 = OpLoad %12 %22\n"
2378 << "%42 = OpLoad %13 %23\n"
2379 << "%43 = OpLoad %12 %24\n"
2380
2381 // We call OpRayQueryInitializeKHR with bare arguments.
2382 // Note: some experimental lines to pass a bare rayQuery as the first argument have been commented out.
2383 //OpRayQueryInitializeKHR %17 %37 %38 %39 %40 %41 %42 %43
2384 << "OpRayQueryInitializeKHR %17 %18 %38 %39 %40 %41 %42 %43\n"
2385
2386 << "OpReturn\n"
2387 << "OpFunctionEnd\n"
2388
2389 // This is rayQueryInitializeTopWrapper, calling rayQueryInitializeBottomWrapper.
2390 << "%35 = OpFunction %2 None %16\n"
2391 << "%27 = OpFunctionParameter %7\n"
2392 << "%28 = OpFunctionParameter %9\n"
2393 << "%29 = OpFunctionParameter %11\n"
2394 << "%30 = OpFunctionParameter %11\n"
2395 << "%31 = OpFunctionParameter %14\n"
2396 << "%32 = OpFunctionParameter %15\n"
2397 << "%33 = OpFunctionParameter %14\n"
2398 << "%34 = OpFunctionParameter %15\n"
2399 << "%36 = OpLabel\n"
2400 << "%44 = OpVariable %11 Function\n"
2401 << "%46 = OpVariable %11 Function\n"
2402 << "%48 = OpVariable %14 Function\n"
2403 << "%50 = OpVariable %15 Function\n"
2404 << "%52 = OpVariable %14 Function\n"
2405 << "%54 = OpVariable %15 Function\n"
2406
2407 // We need to load the second argument.
2408 //<< "%27b = OpLoad %6 %27\n"
2409 << "%28b = OpLoad %8 %28\n"
2410
2411 << "%45 = OpLoad %10 %29\n"
2412 << "OpStore %44 %45\n"
2413 << "%47 = OpLoad %10 %30\n"
2414 << "OpStore %46 %47\n"
2415 << "%49 = OpLoad %13 %31\n"
2416 << "OpStore %48 %49\n"
2417 << "%51 = OpLoad %12 %32\n"
2418 << "OpStore %50 %51\n"
2419 << "%53 = OpLoad %13 %33\n"
2420 << "OpStore %52 %53\n"
2421 << "%55 = OpLoad %12 %34\n"
2422 << "OpStore %54 %55\n"
2423
2424 // We call rayQueryInitializeBottomWrapper with the loaded argument.
2425 //%56 = OpFunctionCall %2 %25 %27 %28 %44 %46 %48 %50 %52 %54
2426 //<< "%56 = OpFunctionCall %2 %25 %27b %28b %44 %46 %48 %50 %52 %54\n"
2427 << "%56 = OpFunctionCall %2 %25 %27 %28b %44 %46 %48 %50 %52 %54\n"
2428
2429 << "OpReturn\n"
2430 << "OpFunctionEnd\n"
2431 ;
2432
2433 programCollection.spirvAsmSources.add("comp_as_triangle") << spvBuildOptions << css.str();
2434 }
2435
RayQueryASBasicTestInstance(Context & context,const TestParams & data)2436 RayQueryASBasicTestInstance::RayQueryASBasicTestInstance (Context& context, const TestParams& data)
2437 : vkt::TestInstance (context)
2438 , m_data (data)
2439 {
2440 }
2441
~RayQueryASBasicTestInstance(void)2442 RayQueryASBasicTestInstance::~RayQueryASBasicTestInstance (void)
2443 {
2444 }
2445
runTest(TestConfiguration * testConfiguration,SceneBuilder * sceneBuilder,const deUint32 workerThreadsCount)2446 de::MovePtr<BufferWithMemory> RayQueryASBasicTestInstance::runTest (TestConfiguration* testConfiguration,
2447 SceneBuilder* sceneBuilder,
2448 const deUint32 workerThreadsCount)
2449 {
2450 testConfiguration->initConfiguration(m_context, m_data);
2451
2452 const DeviceInterface& vkd = m_context.getDeviceInterface();
2453 const VkDevice device = m_context.getDevice();
2454 const VkQueue queue = m_context.getUniversalQueue();
2455 Allocator& allocator = m_context.getDefaultAllocator();
2456 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2457
2458 const bool htCopy = (workerThreadsCount != 0) && (m_data.operationType == OP_COPY);
2459 const bool htSerialize = (workerThreadsCount != 0) && (m_data.operationType == OP_SERIALIZE);
2460
2461
2462 const VkFormat imageFormat = testConfiguration->getResultImageFormat();
2463 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
2464 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2465 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2466 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
2467
2468 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2469 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2470 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
2471 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
2472
2473 const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2474
2475 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
2476 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2477
2478 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures;
2479 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
2480 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructureCopies;
2481 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructureCopy;
2482 std::vector<de::SharedPtr<SerialStorage>> bottomSerialized;
2483 std::vector<de::SharedPtr<SerialStorage>> topSerialized;
2484 std::vector<VkDeviceSize> accelerationCompactedSizes;
2485 std::vector<VkDeviceSize> accelerationSerialSizes;
2486 Move<VkQueryPool> m_queryPoolCompact;
2487 Move<VkQueryPool> m_queryPoolSerial;
2488
2489 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2490 {
2491 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
2492 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2493 **image, imageSubresourceRange);
2494 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
2495
2496 const VkClearValue clearValue = testConfiguration->getClearValue();
2497 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
2498
2499 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
2500 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2501 **image, imageSubresourceRange);
2502 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
2503
2504 // build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures )
2505 bool bottomCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2506 bool bottomSerial = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2507 const bool buildWithoutGeom = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM);
2508 const bool bottomNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM);
2509 const bool topNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP);
2510 const bool inactiveInstances = (m_data.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_INSTANCES);
2511 bottomLevelAccelerationStructures = sceneBuilder->initBottomAccelerationStructures(m_context, m_data);
2512 VkBuildAccelerationStructureFlagsKHR allowCompactionFlag = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
2513 VkBuildAccelerationStructureFlagsKHR emptyCompactionFlag = VkBuildAccelerationStructureFlagsKHR(0);
2514 VkBuildAccelerationStructureFlagsKHR bottomCompactFlags = (bottomCompact ? allowCompactionFlag : emptyCompactionFlag);
2515 VkBuildAccelerationStructureFlagsKHR bottomBuildFlags = m_data.buildFlags | bottomCompactFlags;
2516 std::vector<VkAccelerationStructureKHR> accelerationStructureHandles;
2517 std::vector<VkDeviceSize> bottomBlasCompactSize;
2518 std::vector<VkDeviceSize> bottomBlasSerialSize;
2519
2520 for (auto& blas : bottomLevelAccelerationStructures)
2521 {
2522 blas->setBuildType (m_data.buildType);
2523 blas->setBuildFlags (bottomBuildFlags);
2524 blas->setUseArrayOfPointers (m_data.bottomUsesAOP);
2525 blas->setCreateGeneric (m_data.bottomGeneric);
2526 blas->setBuildWithoutGeometries (buildWithoutGeom);
2527 blas->setBuildWithoutPrimitives (bottomNoPrimitives);
2528 blas->createAndBuild (vkd, device, *cmdBuffer, allocator);
2529 accelerationStructureHandles.push_back (*(blas->getPtr()));
2530 }
2531
2532 if (m_data.operationType == OP_COMPACT)
2533 {
2534 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
2535 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2536 m_queryPoolCompact = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount);
2537 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2538 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize);
2539 }
2540 if (m_data.operationType == OP_SERIALIZE)
2541 {
2542 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
2543 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2544 m_queryPoolSerial = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
2545 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2546 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize);
2547 }
2548
2549 // 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
2550 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial))
2551 {
2552 endCommandBuffer(vkd, *cmdBuffer);
2553
2554 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2555
2556 if (bottomCompact)
2557 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));
2558 if (bottomSerial)
2559 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));
2560
2561 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2562 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2563 }
2564
2565 auto bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructures;
2566 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2567 {
2568 switch (m_data.operationType)
2569 {
2570 case OP_COPY:
2571 {
2572 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2573 {
2574 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2575 asCopy->setDeferredOperation(htCopy, workerThreadsCount);
2576 asCopy->setBuildType(m_data.buildType);
2577 asCopy->setBuildFlags(m_data.buildFlags);
2578 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2579 asCopy->setCreateGeneric(m_data.bottomGeneric);
2580 asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2581 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2582 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), 0u, 0u);
2583 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2584 }
2585 break;
2586 }
2587 case OP_COMPACT:
2588 {
2589 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2590 {
2591 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2592 asCopy->setBuildType(m_data.buildType);
2593 asCopy->setBuildFlags(m_data.buildFlags);
2594 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2595 asCopy->setCreateGeneric(m_data.bottomGeneric);
2596 asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2597 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2598 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), bottomBlasCompactSize[i], 0u);
2599 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2600 }
2601 break;
2602 }
2603 case OP_SERIALIZE:
2604 {
2605 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2606 {
2607 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, bottomBlasSerialSize[i]));
2608
2609 bottomLevelAccelerationStructures[i]->setDeferredOperation(htSerialize, workerThreadsCount);
2610 bottomLevelAccelerationStructures[i]->serialize(vkd, device, *cmdBuffer, storage.get());
2611 bottomSerialized.push_back(storage);
2612
2613 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2614 {
2615 endCommandBuffer(vkd, *cmdBuffer);
2616
2617 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2618
2619 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2620 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2621 }
2622
2623 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2624 asCopy->setBuildType(m_data.buildType);
2625 asCopy->setBuildFlags(m_data.buildFlags);
2626 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2627 asCopy->setCreateGeneric(m_data.bottomGeneric);
2628 asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2629 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2630 asCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2631 asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2632 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2633 }
2634 break;
2635 }
2636 default:
2637 DE_ASSERT(DE_FALSE);
2638 }
2639 bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies;
2640 }
2641
2642 // build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures )
2643 bool topCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION;
2644 bool topSerial = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION;
2645 VkBuildAccelerationStructureFlagsKHR topCompactFlags = (topCompact ? allowCompactionFlag : emptyCompactionFlag);
2646 VkBuildAccelerationStructureFlagsKHR topBuildFlags = m_data.buildFlags | topCompactFlags;
2647 std::vector<VkAccelerationStructureKHR> topLevelStructureHandles;
2648 std::vector<VkDeviceSize> topBlasCompactSize;
2649 std::vector<VkDeviceSize> topBlasSerialSize;
2650
2651 topLevelAccelerationStructure = sceneBuilder->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr);
2652 topLevelAccelerationStructure->setBuildType (m_data.buildType);
2653 topLevelAccelerationStructure->setBuildFlags (topBuildFlags);
2654 topLevelAccelerationStructure->setBuildWithoutPrimitives (topNoPrimitives);
2655 topLevelAccelerationStructure->setUseArrayOfPointers (m_data.topUsesAOP);
2656 topLevelAccelerationStructure->setCreateGeneric (m_data.topGeneric);
2657 topLevelAccelerationStructure->setInactiveInstances (inactiveInstances);
2658 topLevelAccelerationStructure->createAndBuild (vkd, device, *cmdBuffer, allocator);
2659 topLevelStructureHandles.push_back (*(topLevelAccelerationStructure->getPtr()));
2660
2661 if (topCompact)
2662 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize);
2663 if (topSerial)
2664 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize);
2665
2666 // 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
2667 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial))
2668 {
2669 endCommandBuffer(vkd, *cmdBuffer);
2670
2671 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2672
2673 if (topCompact)
2674 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));
2675 if (topSerial)
2676 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));
2677
2678 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2679 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2680 }
2681
2682 const TopLevelAccelerationStructure* topLevelRayTracedPtr = topLevelAccelerationStructure.get();
2683 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION)
2684 {
2685 switch (m_data.operationType)
2686 {
2687 case OP_COPY:
2688 {
2689 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2690 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount);
2691 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2692 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2693 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2694 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2695 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2696 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2697 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), 0u, 0u);
2698 break;
2699 }
2700 case OP_COMPACT:
2701 {
2702 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2703 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2704 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2705 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2706 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2707 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2708 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2709 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], 0u);
2710 break;
2711 }
2712 case OP_SERIALIZE:
2713 {
2714 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, topBlasSerialSize[0]));
2715
2716 topLevelAccelerationStructure->setDeferredOperation(htSerialize, workerThreadsCount);
2717 topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get());
2718 topSerialized.push_back(storage);
2719
2720 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2721 {
2722 endCommandBuffer(vkd, *cmdBuffer);
2723
2724 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2725
2726 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2727 beginCommandBuffer(vkd, *cmdBuffer, 0u);
2728 }
2729
2730 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2731 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2732 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2733 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2734 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2735 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2736 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2737 topLevelAccelerationStructureCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2738 topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2739 break;
2740 }
2741 default:
2742 DE_ASSERT(DE_FALSE);
2743 }
2744 topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get();
2745 }
2746
2747 const VkMemoryBarrier preTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
2748 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &preTraceMemoryBarrier);
2749
2750 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
2751 {
2752 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
2753 DE_NULL, // const void* pNext;
2754 1u, // deUint32 accelerationStructureCount;
2755 topLevelRayTracedPtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
2756 };
2757
2758 testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet, resultImageInfo);
2759
2760 const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
2761 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2762 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
2763
2764 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
2765
2766 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
2767 }
2768 endCommandBuffer(vkd, *cmdBuffer);
2769
2770 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2771
2772 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2773
2774 return resultBuffer;
2775 }
2776
iterateNoWorkers(void)2777 bool RayQueryASBasicTestInstance::iterateNoWorkers (void)
2778 {
2779 de::SharedPtr<TestConfiguration> testConfiguration = createTestConfiguration(m_data.shaderSourcePipeline);
2780 de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2781
2782 const de::MovePtr<BufferWithMemory> buffer = runTest(testConfiguration.get(), sceneBuilder.get(), 0);
2783
2784 return testConfiguration->verifyImage(buffer.get(), m_context, m_data);
2785 }
2786
iterateWithWorkers(void)2787 bool RayQueryASBasicTestInstance::iterateWithWorkers (void)
2788 {
2789 de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2790
2791 de::SharedPtr<TestConfiguration> testConfigurationS = createTestConfiguration(m_data.shaderSourcePipeline);
2792 de::MovePtr<BufferWithMemory> singleThreadBufferCPU = runTest(testConfigurationS.get(), sceneBuilder.get(), 0);
2793 const bool singleThreadValidation = testConfigurationS->verifyImage(singleThreadBufferCPU.get(), m_context, m_data);
2794 testConfigurationS.clear();
2795
2796 de::SharedPtr<TestConfiguration> testConfigurationM = createTestConfiguration(m_data.shaderSourcePipeline);
2797 de::MovePtr<BufferWithMemory> multiThreadBufferCPU = runTest(testConfigurationM.get(), sceneBuilder.get(), m_data.workerThreadsCount);
2798 const bool multiThreadValidation = testConfigurationM->verifyImage(multiThreadBufferCPU.get(), m_context, m_data);
2799 testConfigurationM.clear();
2800
2801 const deUint32 result = singleThreadValidation && multiThreadValidation;
2802
2803 return result;
2804 }
2805
iterate(void)2806 tcu::TestStatus RayQueryASBasicTestInstance::iterate(void)
2807 {
2808 bool result;
2809 if (m_data.workerThreadsCount != 0)
2810 result = iterateWithWorkers();
2811 else
2812 result = iterateNoWorkers();
2813
2814 if (result)
2815 return tcu::TestStatus::pass("Pass");
2816 else
2817 return tcu::TestStatus::fail("Fail");
2818 }
2819
2820 // Tests dynamic indexing of acceleration structures
2821 class RayQueryASDynamicIndexingTestCase : public TestCase
2822 {
2823 public:
2824 RayQueryASDynamicIndexingTestCase (tcu::TestContext& context, const char* name);
2825 ~RayQueryASDynamicIndexingTestCase (void) = default;
2826
2827 void checkSupport (Context& context) const override;
2828 void initPrograms (SourceCollections& programCollection) const override;
2829 TestInstance* createInstance (Context& context) const override;
2830 };
2831
2832 class RayQueryASDynamicIndexingTestInstance : public TestInstance
2833 {
2834 public:
2835 RayQueryASDynamicIndexingTestInstance (Context& context);
2836 ~RayQueryASDynamicIndexingTestInstance (void) = default;
2837 tcu::TestStatus iterate (void) override;
2838 };
2839
RayQueryASDynamicIndexingTestCase(tcu::TestContext & context,const char * name)2840 RayQueryASDynamicIndexingTestCase::RayQueryASDynamicIndexingTestCase(tcu::TestContext& context, const char* name)
2841 : TestCase(context, name, "")
2842 {
2843 }
2844
checkSupport(Context & context) const2845 void RayQueryASDynamicIndexingTestCase::checkSupport(Context& context) const
2846 {
2847 commonASTestsCheckSupport(context);
2848 context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
2849 }
2850
initPrograms(SourceCollections & programCollection) const2851 void RayQueryASDynamicIndexingTestCase::initPrograms(SourceCollections& programCollection) const
2852 {
2853 const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2854
2855 // compute shader is defined in spir-v as it requires possing pointer to TLAS that was read from ssbo;
2856 // original spir-v code was generated using following glsl code but resulting spir-v code was modiifed
2857
2858 // #version 460 core
2859 // #extension GL_EXT_ray_query : require
2860 // #extension GL_EXT_nonuniform_qualifier : enable
2861
2862 // #define ARRAY_SIZE 500
2863 // layout(set = 0, binding = 0) uniform accelerationStructureEXT tlasArray[ARRAY_SIZE];
2864 // layout(set = 0, binding = 1) readonly buffer topLevelASPointers {
2865 // uvec2 ptr[];
2866 // } tlasPointers;
2867 // layout(set = 0, binding = 2) readonly buffer topLevelASIndices {
2868 // uint idx[];
2869 // } tlasIndices;
2870 // layout(set = 0, binding = 3, std430) writeonly buffer Result {
2871 // uint value[];
2872 // } result;
2873
2874 // void main()
2875 // {
2876 // float tmin = 0.0;
2877 // float tmax = 2.0;
2878 // vec3 origin = vec3(0.25f, 0.5f, 1.0);
2879 // vec3 direction = vec3(0.0,0.0,-1.0);
2880 // uint tlasIndex = tlasIndices.idx[nonuniformEXT(gl_GlobalInvocationID.x)];
2881
2882 // rayQueryEXT rq;
2883 // rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2884 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x)], 2);
2885
2886 // if (rayQueryProceedEXT(rq))
2887 // {
2888 // if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
2889 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x)], 3);
2890 // }
2891
2892 // //rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2893 // rayQueryInitializeEXT(rq, *tlasPointers.ptr[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2894 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 2)], 5);
2895
2896 // if (rayQueryProceedEXT(rq))
2897 // {
2898 // if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
2899 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 3)], 7);
2900 // }
2901 // }
2902
2903 const std::string compSource =
2904 "OpCapability Shader\n"
2905 "OpCapability RayQueryKHR\n"
2906 "OpCapability ShaderNonUniform\n"
2907 "OpExtension \"SPV_EXT_descriptor_indexing\"\n"
2908 "OpExtension \"SPV_KHR_ray_query\"\n"
2909 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
2910 "OpMemoryModel Logical GLSL450\n"
2911 "OpEntryPoint GLCompute %4 \"main\" %var_index_ssbo %33 %var_as_arr_uni_ptr %64 %83 %var_as_pointers_ssbo\n"
2912 "OpExecutionMode %4 LocalSize 1 1 1\n"
2913 "OpDecorate %25 ArrayStride 4\n"
2914 "OpMemberDecorate %26 0 NonWritable\n"
2915 "OpMemberDecorate %26 0 Offset 0\n"
2916 "OpDecorate %26 Block\n"
2917 "OpDecorate %var_index_ssbo DescriptorSet 0\n"
2918 "OpDecorate %var_index_ssbo Binding 2\n"
2919 "OpDecorate %33 BuiltIn GlobalInvocationId\n"
2920 "OpDecorate %38 NonUniform\n"
2921 "OpDecorate %40 NonUniform\n"
2922 "OpDecorate %41 NonUniform\n"
2923 "OpDecorate %var_as_arr_uni_ptr DescriptorSet 0\n"
2924 "OpDecorate %var_as_arr_uni_ptr Binding 0\n"
2925 "OpDecorate %51 NonUniform\n"
2926 "OpDecorate %53 NonUniform\n"
2927 "OpDecorate %54 NonUniform\n"
2928 "OpDecorate %61 ArrayStride 4\n"
2929 "OpMemberDecorate %62 0 NonReadable\n"
2930 "OpMemberDecorate %62 0 Offset 0\n"
2931 "OpDecorate %62 Block\n"
2932 "OpDecorate %64 DescriptorSet 0\n"
2933 "OpDecorate %64 Binding 3\n"
2934 "OpDecorate %67 NonUniform\n"
2935 "OpDecorate %83 BuiltIn NumWorkgroups\n"
2936 "OpDecorate %87 NonUniform\n"
2937 "OpDecorate %as_index NonUniform\n"
2938 "OpDecorate %as_device_addres NonUniform\n"
2939 "OpDecorate %105 NonUniform\n"
2940 "OpDecorate %122 NonUniform\n"
2941 "OpDecorate %127 ArrayStride 8\n"
2942 "OpMemberDecorate %128 0 NonWritable\n"
2943 "OpMemberDecorate %128 0 Offset 0\n"
2944 "OpDecorate %128 Block\n"
2945 "OpDecorate %var_as_pointers_ssbo DescriptorSet 0\n"
2946 "OpDecorate %var_as_pointers_ssbo Binding 1\n"
2947 "%2 = OpTypeVoid\n"
2948 "%3 = OpTypeFunction %2\n"
2949 "%6 = OpTypeFloat 32\n"
2950 "%7 = OpTypePointer Function %6\n"
2951 "%9 = OpConstant %6 0\n"
2952 "%11 = OpConstant %6 2\n"
2953 "%12 = OpTypeVector %6 3\n"
2954 "%13 = OpTypePointer Function %12\n"
2955 "%15 = OpConstant %6 0.25\n"
2956 "%16 = OpConstant %6 0.5\n"
2957 "%17 = OpConstant %6 1\n"
2958 "%18 = OpConstantComposite %12 %15 %16 %17\n"
2959 "%20 = OpConstant %6 -1\n"
2960 "%21 = OpConstantComposite %12 %9 %9 %20\n"
2961 "%type_uint32 = OpTypeInt 32 0\n"
2962 "%23 = OpTypePointer Function %type_uint32\n"
2963 "%25 = OpTypeRuntimeArray %type_uint32\n"
2964 "%26 = OpTypeStruct %25\n"
2965 "%27 = OpTypePointer StorageBuffer %26\n"
2966 "%var_index_ssbo = OpVariable %27 StorageBuffer\n"
2967 "%29 = OpTypeInt 32 1\n"
2968 "%c_int32_0 = OpConstant %29 0\n"
2969 "%31 = OpTypeVector %type_uint32 3\n"
2970 "%32 = OpTypePointer Input %31\n"
2971 "%33 = OpVariable %32 Input\n"
2972 "%34 = OpConstant %type_uint32 0\n"
2973 "%35 = OpTypePointer Input %type_uint32\n"
2974 "%type_uint32_ssbo_ptr = OpTypePointer StorageBuffer %type_uint32\n"
2975 "%42 = OpTypeRayQueryKHR\n"
2976 "%43 = OpTypePointer Function %42\n"
2977 "%type_as = OpTypeAccelerationStructureKHR\n"
2978 "%46 = OpConstant %type_uint32 500\n"
2979 "%type_as_arr = OpTypeArray %type_as %46\n"
2980 "%type_as_arr_uni_ptr = OpTypePointer UniformConstant %type_as_arr\n"
2981 "%var_as_arr_uni_ptr = OpVariable %type_as_arr_uni_ptr UniformConstant\n"
2982 "%type_as_uni_ptr = OpTypePointer UniformConstant %type_as\n"
2983 "%55 = OpConstant %type_uint32 16\n"
2984 "%56 = OpConstant %type_uint32 255\n"
2985 "%61 = OpTypeRuntimeArray %type_uint32\n"
2986 "%62 = OpTypeStruct %61\n"
2987 "%63 = OpTypePointer StorageBuffer %62\n"
2988 "%64 = OpVariable %63 StorageBuffer\n"
2989 "%69 = OpConstant %type_uint32 2\n"
2990 "%70 = OpConstant %type_uint32 1\n"
2991 "%72 = OpTypeBool\n"
2992 "%76 = OpConstantFalse %72\n"
2993 "%83 = OpVariable %32 Input\n"
2994 "%89 = OpConstant %type_uint32 3\n"
2995 "%107 = OpConstant %type_uint32 5\n"
2996 "%124 = OpConstant %type_uint32 7\n"
2997
2998 // <changed_section>
2999 "%v2uint = OpTypeVector %type_uint32 2\n"
3000 "%127 = OpTypeRuntimeArray %v2uint\n"
3001 "%128 = OpTypeStruct %127\n"
3002 "%129 = OpTypePointer StorageBuffer %128\n"
3003 "%var_as_pointers_ssbo = OpVariable %129 StorageBuffer\n"
3004 "%type_uint64_ssbo_ptr = OpTypePointer StorageBuffer %v2uint\n"
3005 // </changed_section>
3006
3007 // void main()
3008 "%4 = OpFunction %2 None %3\n"
3009 "%5 = OpLabel\n"
3010 "%8 = OpVariable %7 Function\n"
3011 "%10 = OpVariable %7 Function\n"
3012 "%14 = OpVariable %13 Function\n"
3013 "%19 = OpVariable %13 Function\n"
3014 "%24 = OpVariable %23 Function\n"
3015 "%var_ray_query = OpVariable %43 Function\n"
3016 "OpStore %8 %9\n"
3017 "OpStore %10 %11\n"
3018 "OpStore %14 %18\n"
3019 "OpStore %19 %21\n"
3020 "%36 = OpAccessChain %35 %33 %34\n"
3021 "%37 = OpLoad %type_uint32 %36\n"
3022 "%38 = OpCopyObject %type_uint32 %37\n"
3023 "%40 = OpAccessChain %type_uint32_ssbo_ptr %var_index_ssbo %c_int32_0 %38\n"
3024 "%41 = OpLoad %type_uint32 %40\n"
3025 "OpStore %24 %41\n"
3026
3027 // rayQueryInitializeEXT using AS that was read from array
3028 "%50 = OpLoad %type_uint32 %24\n"
3029 "%51 = OpCopyObject %type_uint32 %50\n"
3030 "%53 = OpAccessChain %type_as_uni_ptr %var_as_arr_uni_ptr %51\n"
3031 "%54 = OpLoad %type_as %53\n"
3032 "%57 = OpLoad %12 %14\n"
3033 "%58 = OpLoad %6 %8\n"
3034 "%59 = OpLoad %12 %19\n"
3035 "%60 = OpLoad %6 %10\n"
3036 "OpRayQueryInitializeKHR %var_ray_query %54 %55 %56 %57 %58 %59 %60\n"
3037
3038 "%65 = OpAccessChain %35 %33 %34\n"
3039 "%66 = OpLoad %type_uint32 %65\n"
3040 "%67 = OpCopyObject %type_uint32 %66\n"
3041 "%68 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %67\n"
3042 "%71 = OpAtomicIAdd %type_uint32 %68 %70 %34 %69\n"
3043
3044 "%73 = OpRayQueryProceedKHR %72 %var_ray_query\n"
3045 "OpSelectionMerge %75 None\n"
3046 "OpBranchConditional %73 %74 %75\n"
3047 "%74 = OpLabel\n"
3048
3049 "%77 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3050 "%78 = OpIEqual %72 %77 %34\n"
3051 "OpSelectionMerge %80 None\n"
3052 "OpBranchConditional %78 %79 %80\n"
3053 "%79 = OpLabel\n"
3054 "%81 = OpAccessChain %35 %33 %34\n"
3055 "%82 = OpLoad %type_uint32 %81\n"
3056 "%84 = OpAccessChain %35 %83 %34\n"
3057 "%85 = OpLoad %type_uint32 %84\n"
3058 "%86 = OpIAdd %type_uint32 %82 %85\n"
3059 "%87 = OpCopyObject %type_uint32 %86\n"
3060 "%88 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %87\n"
3061 "%90 = OpAtomicIAdd %type_uint32 %88 %70 %34 %89\n"
3062 "OpBranch %80\n"
3063 "%80 = OpLabel\n"
3064 "OpBranch %75\n"
3065 "%75 = OpLabel\n"
3066
3067 // rayQueryInitializeEXT using pointer to AS
3068 "%91 = OpLoad %type_uint32 %24\n"
3069 "%as_index = OpCopyObject %type_uint32 %91\n"
3070
3071 // <changed_section>
3072 "%as_device_addres_ptr = OpAccessChain %type_uint64_ssbo_ptr %var_as_pointers_ssbo %c_int32_0 %as_index\n"
3073 "%as_device_addres = OpLoad %v2uint %as_device_addres_ptr\n"
3074 "%as_to_use = OpConvertUToAccelerationStructureKHR %type_as %as_device_addres\n"
3075 // </changed_section>
3076
3077 "%95 = OpLoad %12 %14\n"
3078 "%96 = OpLoad %6 %8\n"
3079 "%97 = OpLoad %12 %19\n"
3080 "%98 = OpLoad %6 %10\n"
3081 "OpRayQueryInitializeKHR %var_ray_query %as_to_use %55 %56 %95 %96 %97 %98\n"
3082
3083 "%99 = OpAccessChain %35 %33 %34\n"
3084 "%100 = OpLoad %type_uint32 %99\n"
3085 "%101 = OpAccessChain %35 %83 %34\n"
3086 "%102 = OpLoad %type_uint32 %101\n"
3087 "%103 = OpIMul %type_uint32 %102 %69\n"
3088 "%104 = OpIAdd %type_uint32 %100 %103\n"
3089 "%105 = OpCopyObject %type_uint32 %104\n"
3090 "%106 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %105\n"
3091 "%108 = OpAtomicIAdd %type_uint32 %106 %70 %34 %107\n"
3092
3093 "%109 = OpRayQueryProceedKHR %72 %var_ray_query\n"
3094 "OpSelectionMerge %111 None\n"
3095 "OpBranchConditional %109 %110 %111\n"
3096 "%110 = OpLabel\n"
3097
3098 "%112 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3099 "%113 = OpIEqual %72 %112 %34\n"
3100 "OpSelectionMerge %115 None\n"
3101 "OpBranchConditional %113 %114 %115\n"
3102 "%114 = OpLabel\n"
3103 "%116 = OpAccessChain %35 %33 %34\n"
3104 "%117 = OpLoad %type_uint32 %116\n"
3105 "%118 = OpAccessChain %35 %83 %34\n"
3106 "%119 = OpLoad %type_uint32 %118\n"
3107 "%120 = OpIMul %type_uint32 %119 %89\n"
3108 "%121 = OpIAdd %type_uint32 %117 %120\n"
3109 "%122 = OpCopyObject %type_uint32 %121\n"
3110 "%123 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %122\n"
3111 "%125 = OpAtomicIAdd %type_uint32 %123 %70 %34 %124\n"
3112 "OpBranch %115\n"
3113 "%115 = OpLabel\n"
3114 "OpBranch %111\n"
3115 "%111 = OpLabel\n"
3116 "OpReturn\n"
3117 "OpFunctionEnd\n";
3118
3119 programCollection.spirvAsmSources.add("comp") << compSource << spvBuildOptions;
3120 }
3121
createInstance(Context & context) const3122 TestInstance* RayQueryASDynamicIndexingTestCase::createInstance(Context& context) const
3123 {
3124 return new RayQueryASDynamicIndexingTestInstance(context);
3125 }
3126
3127
RayQueryASDynamicIndexingTestInstance(Context & context)3128 RayQueryASDynamicIndexingTestInstance::RayQueryASDynamicIndexingTestInstance(Context& context)
3129 : vkt::TestInstance(context)
3130 {
3131 }
3132
iterate(void)3133 tcu::TestStatus RayQueryASDynamicIndexingTestInstance::iterate(void)
3134 {
3135 const DeviceInterface& vkd = m_context.getDeviceInterface();
3136 const VkDevice device = m_context.getDevice();
3137 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3138 const VkQueue queue = m_context.getUniversalQueue();
3139 Allocator& allocator = m_context.getDefaultAllocator();
3140 const deUint32 tlasCount = 500; // changing this will require also changing shaders
3141 const deUint32 activeTlasCount = 32; // number of tlas out of <tlasCount> that will be active
3142
3143 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
3144 .addArrayBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, VK_SHADER_STAGE_COMPUTE_BIT)
3145 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // pointers to all acceleration structures
3146 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with indices of all acceleration structures
3147 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with result values
3148 .build(vkd, device);
3149
3150 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
3151 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount)
3152 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3153 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3154 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3155 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
3156 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
3157
3158 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
3159 Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);
3160 const VkComputePipelineCreateInfo pipelineCreateInfo
3161 {
3162 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
3163 DE_NULL, // const void* pNext
3164 0u, // VkPipelineCreateFlags flags
3165 { // VkPipelineShaderStageCreateInfo stage
3166 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3167 DE_NULL,
3168 (VkPipelineShaderStageCreateFlags)0,
3169 VK_SHADER_STAGE_COMPUTE_BIT,
3170 *shaderModule,
3171 "main",
3172 DE_NULL
3173 },
3174 *pipelineLayout, // VkPipelineLayout layout
3175 DE_NULL, // VkPipeline basePipelineHandle
3176 0, // deInt32 basePipelineIndex
3177 };
3178
3179 Move<VkPipeline> pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
3180
3181 const VkDeviceSize pointerBufferSize = tlasCount * sizeof(VkDeviceAddress);
3182 const VkBufferCreateInfo pointerBufferCreateInfo = makeBufferCreateInfo(pointerBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3183 de::MovePtr<BufferWithMemory> pointerBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, pointerBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress));
3184
3185 const VkDeviceSize indicesBufferSize = activeTlasCount * sizeof(deUint32);
3186 const VkBufferCreateInfo indicesBufferCreateInfo = makeBufferCreateInfo(indicesBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3187 de::MovePtr<BufferWithMemory> indicesBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, indicesBufferCreateInfo, MemoryRequirement::HostVisible));
3188
3189 const VkDeviceSize resultBufferSize = activeTlasCount * sizeof(deUint32) * 4;
3190 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(resultBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
3191 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3192
3193 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
3194 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3195
3196 de::SharedPtr<BottomLevelAccelerationStructure> blas = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
3197 std::vector<de::MovePtr<TopLevelAccelerationStructure>> tlasVect(tlasCount);
3198 std::vector<VkDeviceAddress> tlasPtrVect(tlasCount);
3199 std::vector<VkAccelerationStructureKHR> tlasVkVect;
3200
3201 // randomly scatter AS indices across the range (number of them should be equal to the max subgroup size)
3202 deRandom rnd;
3203 deRandom_init(&rnd, 123);
3204 std::set<deUint32> asIndicesSet;
3205 while (asIndicesSet.size() < activeTlasCount)
3206 asIndicesSet.insert(deRandom_getUint32(&rnd) % tlasCount);
3207
3208 // fill indices buffer
3209 deUint32 helperIndex = 0;
3210 auto& indicesBufferAlloc = indicesBuffer->getAllocation();
3211 deUint32* indicesBufferPtr = reinterpret_cast<deUint32*>(indicesBufferAlloc.getHostPtr());
3212 std::for_each(asIndicesSet.begin(), asIndicesSet.end(),
3213 [&helperIndex, indicesBufferPtr](const deUint32& index)
3214 {
3215 indicesBufferPtr[helperIndex++] = index;
3216 });
3217 vk::flushAlloc(vkd, device, indicesBufferAlloc);
3218
3219 // clear result buffer
3220 auto& resultBufferAlloc = resultBuffer->getAllocation();
3221 void* resultBufferPtr = resultBufferAlloc.getHostPtr();
3222 deMemset(resultBufferPtr, 0, static_cast<size_t>(resultBufferSize));
3223 vk::flushAlloc(vkd, device, resultBufferAlloc);
3224
3225 beginCommandBuffer(vkd, *cmdBuffer, 0u);
3226 {
3227 // build bottom level acceleration structure
3228 blas->setGeometryData(
3229 {
3230 { 0.0, 0.0, 0.0 },
3231 { 1.0, 0.0, 0.0 },
3232 { 0.0, 1.0, 0.0 },
3233 },
3234 true,
3235 0u
3236 );
3237
3238 blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3239
3240 // build top level acceleration structures
3241 for (deUint32 tlasIndex = 0; tlasIndex < tlasCount; ++tlasIndex)
3242 {
3243 auto& tlas = tlasVect[tlasIndex];
3244 tlas = makeTopLevelAccelerationStructure();
3245 tlas->setInstanceCount(1);
3246 tlas->addInstance(blas);
3247 if (!asIndicesSet.count(tlasIndex))
3248 {
3249 // tlas that are not in asIndicesSet should be empty but it is hard to do
3250 // that with current cts utils so we are marking them as inactive instead
3251 tlas->setInactiveInstances(true);
3252 }
3253 tlas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3254
3255 // get acceleration structure device address
3256 const VkAccelerationStructureDeviceAddressInfoKHR addressInfo =
3257 {
3258 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType
3259 DE_NULL, // const void* pNext
3260 *tlas->getPtr() // VkAccelerationStructureKHR accelerationStructure
3261 };
3262 VkDeviceAddress vkda = vkd.getAccelerationStructureDeviceAddressKHR(device, &addressInfo);
3263 tlasPtrVect[tlasIndex] = vkda;
3264 }
3265
3266 // fill pointer buffer
3267 vkd.cmdUpdateBuffer(*cmdBuffer, **pointerBuffer, 0, pointerBufferSize, tlasPtrVect.data());
3268
3269 // wait for data transfers
3270 const VkMemoryBarrier uploadBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
3271 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &uploadBarrier, 1u);
3272
3273 // wait for as build
3274 const VkMemoryBarrier asBuildBarrier = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
3275 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &asBuildBarrier, 1u);
3276
3277 tlasVkVect.reserve(tlasCount);
3278 for (auto& tlas : tlasVect)
3279 tlasVkVect.push_back(*tlas->getPtr());
3280
3281 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
3282 {
3283 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
3284 DE_NULL, // const void* pNext;
3285 tlasCount, // deUint32 accelerationStructureCount;
3286 tlasVkVect.data(), // const VkAccelerationStructureKHR* pAccelerationStructures;
3287 };
3288
3289 const vk::VkDescriptorBufferInfo pointerBufferInfo = makeDescriptorBufferInfo(**pointerBuffer, 0u, VK_WHOLE_SIZE);
3290 const vk::VkDescriptorBufferInfo indicesBufferInfo = makeDescriptorBufferInfo(**indicesBuffer, 0u, VK_WHOLE_SIZE);
3291 const vk::VkDescriptorBufferInfo resultInfo = makeDescriptorBufferInfo(**resultBuffer, 0u, VK_WHOLE_SIZE);
3292
3293 DescriptorSetUpdateBuilder()
3294 .writeArray (*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, &accelerationStructureWriteDescriptorSet)
3295 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &pointerBufferInfo)
3296 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indicesBufferInfo)
3297 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo)
3298 .update(vkd, device);
3299
3300 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
3301
3302 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3303
3304 vkd.cmdDispatch(*cmdBuffer, activeTlasCount, 1, 1);
3305
3306 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
3307 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
3308 }
3309 endCommandBuffer(vkd, *cmdBuffer);
3310
3311 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
3312
3313 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), resultBufferSize);
3314
3315 // verify result buffer
3316 deUint32 failures = 0;
3317 const deUint32* resultPtr = reinterpret_cast<deUint32*>(resultBuffer->getAllocation().getHostPtr());
3318 for (deUint32 index = 0; index < activeTlasCount; ++index)
3319 {
3320 failures += (resultPtr[0 * activeTlasCount + index] != 2) +
3321 (resultPtr[1 * activeTlasCount + index] != 3) +
3322 (resultPtr[2 * activeTlasCount + index] != 5) +
3323 (resultPtr[3 * activeTlasCount + index] != 7);
3324 }
3325
3326 if (failures)
3327 return tcu::TestStatus::fail(de::toString(failures) + " failures, " + de::toString(4 * activeTlasCount - failures) + " are ok");
3328 return tcu::TestStatus::pass("Pass");
3329 }
3330
3331 } // anonymous
3332
3333 /********************/
3334
addBasicBuildingTests(tcu::TestCaseGroup * group)3335 void addBasicBuildingTests(tcu::TestCaseGroup* group)
3336 {
3337 struct ShaderSourceTypeData
3338 {
3339 ShaderSourceType shaderSourceType;
3340 ShaderSourcePipeline shaderSourcePipeline;
3341 const char* name;
3342 } shaderSourceTypes[] =
3343 {
3344 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3345 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3346 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3347 };
3348
3349 struct
3350 {
3351 vk::VkAccelerationStructureBuildTypeKHR buildType;
3352 const char* name;
3353 } buildTypes[] =
3354 {
3355 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3356 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3357 };
3358
3359 struct
3360 {
3361 BottomTestType testType;
3362 bool usesAOP;
3363 const char* name;
3364 } bottomTestTypes[] =
3365 {
3366 { BTT_TRIANGLES, false, "triangles" },
3367 { BTT_TRIANGLES, true, "triangles_aop" },
3368 { BTT_AABBS, false, "aabbs" },
3369 { BTT_AABBS, true, "aabbs_aop" },
3370 };
3371
3372 struct
3373 {
3374 TopTestType testType;
3375 bool usesAOP;
3376 const char* name;
3377 } topTestTypes[] =
3378 {
3379 { TTT_IDENTICAL_INSTANCES, false, "identical_instances" },
3380 { TTT_IDENTICAL_INSTANCES, true, "identical_instances_aop" },
3381 { TTT_DIFFERENT_INSTANCES, false, "different_instances" },
3382 { TTT_DIFFERENT_INSTANCES, true, "different_instances_aop" },
3383 };
3384
3385 struct BuildFlagsData
3386 {
3387 VkBuildAccelerationStructureFlagsKHR flags;
3388 const char* name;
3389 };
3390
3391 BuildFlagsData optimizationTypes[] =
3392 {
3393 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3394 { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, "fasttrace" },
3395 { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, "fastbuild" },
3396 };
3397
3398 BuildFlagsData updateTypes[] =
3399 {
3400 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3401 { VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, "update" },
3402 };
3403
3404 BuildFlagsData compactionTypes[] =
3405 {
3406 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3407 { VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, "compaction" },
3408 };
3409
3410 BuildFlagsData lowMemoryTypes[] =
3411 {
3412 { VkBuildAccelerationStructureFlagsKHR(0u), "0" },
3413 { VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, "lowmemory" },
3414 };
3415
3416 struct
3417 {
3418 bool padVertices;
3419 const char* name;
3420 } paddingType[] =
3421 {
3422 { false, "nopadding" },
3423 { true, "padded" },
3424 };
3425
3426 struct
3427 {
3428 bool topGeneric;
3429 bool bottomGeneric;
3430 const char* suffix;
3431 } createGenericParams[] =
3432 {
3433 { false, false, "" },
3434 { false, true, "_bottomgeneric" },
3435 { true, false, "_topgeneric" },
3436 { true, true, "_bothgeneric" },
3437 };
3438
3439 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3440 {
3441 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
3442
3443 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3444 {
3445 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
3446
3447 for (size_t bottomNdx = 0; bottomNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++bottomNdx)
3448 {
3449 de::MovePtr<tcu::TestCaseGroup> bottomGroup(new tcu::TestCaseGroup(group->getTestContext(), bottomTestTypes[bottomNdx].name, ""));
3450
3451 for (size_t topNdx = 0; topNdx < DE_LENGTH_OF_ARRAY(topTestTypes); ++topNdx)
3452 {
3453 de::MovePtr<tcu::TestCaseGroup> topGroup(new tcu::TestCaseGroup(group->getTestContext(), topTestTypes[topNdx].name, ""));
3454
3455 for (int paddingTypeIdx = 0; paddingTypeIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingTypeIdx)
3456 {
3457 de::MovePtr<tcu::TestCaseGroup> paddingTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingTypeIdx].name, ""));
3458
3459 for (size_t optimizationNdx = 0; optimizationNdx < DE_LENGTH_OF_ARRAY(optimizationTypes); ++optimizationNdx)
3460 {
3461 for (size_t updateNdx = 0; updateNdx < DE_LENGTH_OF_ARRAY(updateTypes); ++updateNdx)
3462 {
3463 for (size_t compactionNdx = 0; compactionNdx < DE_LENGTH_OF_ARRAY(compactionTypes); ++compactionNdx)
3464 {
3465 for (size_t lowMemoryNdx = 0; lowMemoryNdx < DE_LENGTH_OF_ARRAY(lowMemoryTypes); ++lowMemoryNdx)
3466 {
3467 for (int createGenericIdx = 0; createGenericIdx < DE_LENGTH_OF_ARRAY(createGenericParams); ++createGenericIdx)
3468 {
3469 std::string testName =
3470 std::string(optimizationTypes[optimizationNdx].name) + "_" +
3471 std::string(updateTypes[updateNdx].name) + "_" +
3472 std::string(compactionTypes[compactionNdx].name) + "_" +
3473 std::string(lowMemoryTypes[lowMemoryNdx].name) +
3474 std::string(createGenericParams[createGenericIdx].suffix);
3475
3476 TestParams testParams
3477 {
3478 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3479 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3480 buildTypes[buildTypeNdx].buildType,
3481 VK_FORMAT_R32G32B32_SFLOAT,
3482 paddingType[paddingTypeIdx].padVertices,
3483 VK_INDEX_TYPE_NONE_KHR,
3484 bottomTestTypes[bottomNdx].testType,
3485 InstanceCullFlags::NONE,
3486 bottomTestTypes[bottomNdx].usesAOP,
3487 createGenericParams[createGenericIdx].bottomGeneric,
3488 topTestTypes[topNdx].testType,
3489 topTestTypes[topNdx].usesAOP,
3490 createGenericParams[createGenericIdx].topGeneric,
3491 optimizationTypes[optimizationNdx].flags | updateTypes[updateNdx].flags | compactionTypes[compactionNdx].flags | lowMemoryTypes[lowMemoryNdx].flags,
3492 OT_NONE,
3493 OP_NONE,
3494 TEST_WIDTH,
3495 TEST_HEIGHT,
3496 0u,
3497 EmptyAccelerationStructureCase::NOT_EMPTY,
3498 };
3499 paddingTypeGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), testName.c_str(), "", testParams));
3500 }
3501 }
3502 }
3503 }
3504 }
3505 topGroup->addChild(paddingTypeGroup.release());
3506 }
3507 bottomGroup->addChild(topGroup.release());
3508 }
3509 buildGroup->addChild(bottomGroup.release());
3510 }
3511 sourceTypeGroup->addChild(buildGroup.release());
3512 }
3513 group->addChild(sourceTypeGroup.release());
3514 }
3515 }
3516
addVertexIndexFormatsTests(tcu::TestCaseGroup * group)3517 void addVertexIndexFormatsTests(tcu::TestCaseGroup* group)
3518 {
3519 struct ShaderSourceTypeData
3520 {
3521 ShaderSourceType shaderSourceType;
3522 ShaderSourcePipeline shaderSourcePipeline;
3523 const char* name;
3524 } shaderSourceTypes[] =
3525 {
3526 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3527 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3528 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3529 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3530 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3531 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3532 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3533 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3534 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3535 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3536 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3537 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3538 };
3539
3540 struct
3541 {
3542 vk::VkAccelerationStructureBuildTypeKHR buildType;
3543 const char* name;
3544 } buildTypes[] =
3545 {
3546 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3547 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3548 };
3549
3550 const VkFormat vertexFormats[] =
3551 {
3552 // Mandatory formats.
3553 VK_FORMAT_R32G32_SFLOAT,
3554 VK_FORMAT_R32G32B32_SFLOAT,
3555 VK_FORMAT_R16G16_SFLOAT,
3556 VK_FORMAT_R16G16B16A16_SFLOAT,
3557 VK_FORMAT_R16G16_SNORM,
3558 VK_FORMAT_R16G16B16A16_SNORM,
3559
3560 // Additional formats.
3561 VK_FORMAT_R8G8_SNORM,
3562 VK_FORMAT_R8G8B8_SNORM,
3563 VK_FORMAT_R8G8B8A8_SNORM,
3564 VK_FORMAT_R16G16B16_SNORM,
3565 VK_FORMAT_R16G16B16_SFLOAT,
3566 VK_FORMAT_R32G32B32A32_SFLOAT,
3567 VK_FORMAT_R64G64_SFLOAT,
3568 VK_FORMAT_R64G64B64_SFLOAT,
3569 VK_FORMAT_R64G64B64A64_SFLOAT,
3570 };
3571
3572 struct
3573 {
3574 VkIndexType indexType;
3575 const char* name;
3576 } indexFormats[] =
3577 {
3578 { VK_INDEX_TYPE_NONE_KHR , "index_none" },
3579 { VK_INDEX_TYPE_UINT16 , "index_uint16" },
3580 { VK_INDEX_TYPE_UINT32 , "index_uint32" },
3581 };
3582
3583 struct
3584 {
3585 bool padVertices;
3586 const char* name;
3587 } paddingType[] =
3588 {
3589 { false, "nopadding" },
3590 { true, "padded" },
3591 };
3592
3593 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3594 {
3595 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
3596
3597 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3598 {
3599 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
3600
3601 for (size_t vertexFormatNdx = 0; vertexFormatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); ++vertexFormatNdx)
3602 {
3603 const auto format = vertexFormats[vertexFormatNdx];
3604 const auto formatName = getFormatSimpleName(format);
3605
3606 de::MovePtr<tcu::TestCaseGroup> vertexFormatGroup(new tcu::TestCaseGroup(group->getTestContext(), formatName.c_str(), ""));
3607
3608 for (int paddingIdx = 0; paddingIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingIdx)
3609 {
3610 de::MovePtr<tcu::TestCaseGroup> paddingGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingIdx].name, ""));
3611
3612 for (size_t indexFormatNdx = 0; indexFormatNdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatNdx)
3613 {
3614 TestParams testParams
3615 {
3616 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3617 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3618 buildTypes[buildTypeNdx].buildType,
3619 format,
3620 paddingType[paddingIdx].padVertices,
3621 indexFormats[indexFormatNdx].indexType,
3622 BTT_TRIANGLES,
3623 InstanceCullFlags::NONE,
3624 false,
3625 false,
3626 TTT_IDENTICAL_INSTANCES,
3627 false,
3628 false,
3629 VkBuildAccelerationStructureFlagsKHR(0u),
3630 OT_NONE,
3631 OP_NONE,
3632 TEST_WIDTH,
3633 TEST_HEIGHT,
3634 0u,
3635 EmptyAccelerationStructureCase::NOT_EMPTY,
3636 };
3637 paddingGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), indexFormats[indexFormatNdx].name, "", testParams));
3638 }
3639 vertexFormatGroup->addChild(paddingGroup.release());
3640 }
3641 buildGroup->addChild(vertexFormatGroup.release());
3642 }
3643 sourceTypeGroup->addChild(buildGroup.release());
3644 }
3645 group->addChild(sourceTypeGroup.release());
3646 }
3647 }
3648
addOperationTestsImpl(tcu::TestCaseGroup * group,const deUint32 workerThreads)3649 void addOperationTestsImpl (tcu::TestCaseGroup* group, const deUint32 workerThreads)
3650 {
3651 struct ShaderSourceTypeData
3652 {
3653 ShaderSourceType shaderSourceType;
3654 ShaderSourcePipeline shaderSourcePipeline;
3655 const char* name;
3656 } shaderSourceTypes[] =
3657 {
3658 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3659 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3660 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3661 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3662 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3663 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3664 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3665 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3666 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3667 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3668 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3669 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3670 };
3671
3672 struct
3673 {
3674 OperationType operationType;
3675 const char* name;
3676 } operationTypes[] =
3677 {
3678 { OP_COPY, "copy" },
3679 { OP_COMPACT, "compaction" },
3680 { OP_SERIALIZE, "serialization" },
3681 };
3682
3683 struct
3684 {
3685 vk::VkAccelerationStructureBuildTypeKHR buildType;
3686 const char* name;
3687 } buildTypes[] =
3688 {
3689 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3690 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3691 };
3692
3693 struct
3694 {
3695 OperationTarget operationTarget;
3696 const char* name;
3697 } operationTargets[] =
3698 {
3699 { OT_TOP_ACCELERATION, "top_acceleration_structure" },
3700 { OT_BOTTOM_ACCELERATION, "bottom_acceleration_structure" },
3701 };
3702
3703 struct
3704 {
3705 BottomTestType testType;
3706 const char* name;
3707 } bottomTestTypes[] =
3708 {
3709 { BTT_TRIANGLES, "triangles" },
3710 { BTT_AABBS, "aabbs" },
3711 };
3712
3713 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3714 {
3715 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
3716
3717 for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx)
3718 {
3719 if (workerThreads > 0)
3720 if (operationTypes[operationTypeNdx].operationType != OP_COPY && operationTypes[operationTypeNdx].operationType != OP_SERIALIZE)
3721 continue;
3722
3723 de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name, ""));
3724
3725 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3726 {
3727 if (workerThreads > 0 && buildTypes[buildTypeNdx].buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR)
3728 continue;
3729
3730 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
3731
3732 for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets); ++operationTargetNdx)
3733 {
3734 de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name, ""));
3735
3736 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
3737 {
3738 TopTestType topTest = (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ? TTT_DIFFERENT_INSTANCES : TTT_IDENTICAL_INSTANCES;
3739
3740 TestParams testParams
3741 {
3742 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3743 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3744 buildTypes[buildTypeNdx].buildType,
3745 VK_FORMAT_R32G32B32_SFLOAT,
3746 false,
3747 VK_INDEX_TYPE_NONE_KHR,
3748 bottomTestTypes[testTypeNdx].testType,
3749 InstanceCullFlags::NONE,
3750 false,
3751 false,
3752 topTest,
3753 false,
3754 false,
3755 VkBuildAccelerationStructureFlagsKHR(0u),
3756 operationTargets[operationTargetNdx].operationTarget,
3757 operationTypes[operationTypeNdx].operationType,
3758 TEST_WIDTH,
3759 TEST_HEIGHT,
3760 workerThreads,
3761 EmptyAccelerationStructureCase::NOT_EMPTY,
3762 };
3763 operationTargetGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, "", testParams));
3764 }
3765 buildGroup->addChild(operationTargetGroup.release());
3766 }
3767 operationTypeGroup->addChild(buildGroup.release());
3768 }
3769 sourceTypeGroup->addChild(operationTypeGroup.release());
3770 }
3771 group->addChild(sourceTypeGroup.release());
3772 }
3773 }
3774
addOperationTests(tcu::TestCaseGroup * group)3775 void addOperationTests (tcu::TestCaseGroup* group)
3776 {
3777 addOperationTestsImpl(group, 0);
3778 }
3779
addHostThreadingOperationTests(tcu::TestCaseGroup * group)3780 void addHostThreadingOperationTests (tcu::TestCaseGroup* group)
3781 {
3782 const deUint32 threads[] = { 1, 2, 3, 4, 8, std::numeric_limits<deUint32>::max() };
3783
3784 for (size_t threadsNdx = 0; threadsNdx < DE_LENGTH_OF_ARRAY(threads); ++threadsNdx)
3785 {
3786 const std::string groupName = threads[threadsNdx] != std::numeric_limits<deUint32>::max()
3787 ? de::toString(threads[threadsNdx])
3788 : "max";
3789
3790 de::MovePtr<tcu::TestCaseGroup> threadGroup(new tcu::TestCaseGroup(group->getTestContext(), groupName.c_str(), ""));
3791
3792 addOperationTestsImpl(threadGroup.get(), threads[threadsNdx]);
3793
3794 group->addChild(threadGroup.release());
3795 }
3796 }
3797
addFuncArgTests(tcu::TestCaseGroup * group)3798 void addFuncArgTests (tcu::TestCaseGroup* group)
3799 {
3800 const struct
3801 {
3802 vk::VkAccelerationStructureBuildTypeKHR buildType;
3803 const char* name;
3804 } buildTypes[] =
3805 {
3806 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3807 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3808 };
3809
3810 auto& ctx = group->getTestContext();
3811
3812 for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3813 {
3814 TestParams testParams
3815 {
3816 SST_COMPUTE_SHADER,
3817 SSP_COMPUTE_PIPELINE,
3818 buildTypes[buildTypeNdx].buildType,
3819 VK_FORMAT_R32G32B32_SFLOAT,
3820 false,
3821 VK_INDEX_TYPE_NONE_KHR,
3822 BTT_TRIANGLES,
3823 InstanceCullFlags::NONE,
3824 false,
3825 false,
3826 TTT_IDENTICAL_INSTANCES,
3827 false,
3828 false,
3829 VkBuildAccelerationStructureFlagsKHR(0u),
3830 OT_NONE,
3831 OP_NONE,
3832 TEST_WIDTH,
3833 TEST_HEIGHT,
3834 0u,
3835 EmptyAccelerationStructureCase::NOT_EMPTY,
3836 };
3837
3838 group->addChild(new RayQueryASFuncArgTestCase(ctx, buildTypes[buildTypeNdx].name, "", testParams));
3839 }
3840 }
3841
addInstanceTriangleCullingTests(tcu::TestCaseGroup * group)3842 void addInstanceTriangleCullingTests (tcu::TestCaseGroup* group)
3843 {
3844 const struct
3845 {
3846 ShaderSourceType shaderSourceType;
3847 ShaderSourcePipeline shaderSourcePipeline;
3848 std::string name;
3849 } shaderSourceTypes[] =
3850 {
3851 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3852 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3853 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3854 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3855 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3856 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3857 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3858 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3859 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3860 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3861 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3862 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3863 };
3864
3865 const struct
3866 {
3867 InstanceCullFlags cullFlags;
3868 std::string name;
3869 } cullFlags[] =
3870 {
3871 { InstanceCullFlags::NONE, "noflags" },
3872 { InstanceCullFlags::COUNTERCLOCKWISE, "ccw" },
3873 { InstanceCullFlags::CULL_DISABLE, "nocull" },
3874 { InstanceCullFlags::ALL, "ccw_nocull" },
3875 };
3876
3877 const struct
3878 {
3879 TopTestType topType;
3880 std::string name;
3881 } topType[] =
3882 {
3883 { TTT_DIFFERENT_INSTANCES, "transformed" }, // Each instance has its own transformation matrix.
3884 { TTT_IDENTICAL_INSTANCES, "notransform" }, // "Identical" instances, different geometries.
3885 };
3886
3887 const struct
3888 {
3889 vk::VkAccelerationStructureBuildTypeKHR buildType;
3890 std::string name;
3891 } buildTypes[] =
3892 {
3893 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3894 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3895 };
3896
3897 const struct
3898 {
3899 VkIndexType indexType;
3900 std::string name;
3901 } indexFormats[] =
3902 {
3903 { VK_INDEX_TYPE_NONE_KHR , "index_none" },
3904 { VK_INDEX_TYPE_UINT16 , "index_uint16" },
3905 { VK_INDEX_TYPE_UINT32 , "index_uint32" },
3906 };
3907
3908 auto& ctx = group->getTestContext();
3909
3910 for (int shaderSourceIdx = 0; shaderSourceIdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceIdx)
3911 {
3912 de::MovePtr<tcu::TestCaseGroup> shaderSourceGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceIdx].name.c_str(), ""));
3913
3914 for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
3915 {
3916 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str(), ""));
3917
3918 for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
3919 {
3920 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str(), ""));
3921
3922 for (int topTypeIdx = 0; topTypeIdx < DE_LENGTH_OF_ARRAY(topType); ++topTypeIdx)
3923 {
3924 for (int cullFlagsIdx = 0; cullFlagsIdx < DE_LENGTH_OF_ARRAY(cullFlags); ++cullFlagsIdx)
3925 {
3926 const std::string testName = topType[topTypeIdx].name + "_" + cullFlags[cullFlagsIdx].name;
3927
3928 TestParams testParams
3929 {
3930 shaderSourceTypes[shaderSourceIdx].shaderSourceType,
3931 shaderSourceTypes[shaderSourceIdx].shaderSourcePipeline,
3932 buildTypes[buildTypeIdx].buildType,
3933 VK_FORMAT_R32G32B32_SFLOAT,
3934 false,
3935 indexFormats[indexFormatIdx].indexType,
3936 BTT_TRIANGLES,
3937 cullFlags[cullFlagsIdx].cullFlags,
3938 false,
3939 false,
3940 topType[topTypeIdx].topType,
3941 false,
3942 false,
3943 VkBuildAccelerationStructureFlagsKHR(0u),
3944 OT_NONE,
3945 OP_NONE,
3946 TEST_WIDTH,
3947 TEST_HEIGHT,
3948 0u,
3949 EmptyAccelerationStructureCase::NOT_EMPTY,
3950 };
3951 indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, testName.c_str(), "", testParams));
3952 }
3953 }
3954 buildTypeGroup->addChild(indexTypeGroup.release());
3955 }
3956 shaderSourceGroup->addChild(buildTypeGroup.release());
3957 }
3958 group->addChild(shaderSourceGroup.release());
3959 }
3960 }
3961
addDynamicIndexingTests(tcu::TestCaseGroup * group)3962 void addDynamicIndexingTests(tcu::TestCaseGroup* group)
3963 {
3964 auto& ctx = group->getTestContext();
3965 group->addChild(new RayQueryASDynamicIndexingTestCase(ctx, "dynamic_indexing"));
3966 }
3967
addEmptyAccelerationStructureTests(tcu::TestCaseGroup * group)3968 void addEmptyAccelerationStructureTests (tcu::TestCaseGroup* group)
3969 {
3970 const struct
3971 {
3972 ShaderSourceType shaderSourceType;
3973 ShaderSourcePipeline shaderSourcePipeline;
3974 std::string name;
3975 } shaderSourceTypes[] =
3976 {
3977 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
3978 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
3979 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
3980 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
3981 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
3982 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
3983 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
3984 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
3985 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
3986 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
3987 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
3988 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
3989 };
3990
3991 const struct
3992 {
3993 vk::VkAccelerationStructureBuildTypeKHR buildType;
3994 std::string name;
3995 } buildTypes[] =
3996 {
3997 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" },
3998 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" },
3999 };
4000
4001 const struct
4002 {
4003 VkIndexType indexType;
4004 std::string name;
4005 } indexFormats[] =
4006 {
4007 { VK_INDEX_TYPE_NONE_KHR , "index_none" },
4008 { VK_INDEX_TYPE_UINT16 , "index_uint16" },
4009 { VK_INDEX_TYPE_UINT32 , "index_uint32" },
4010 };
4011
4012 const struct
4013 {
4014 EmptyAccelerationStructureCase emptyASCase;
4015 std::string name;
4016 } emptyCases[] =
4017 {
4018 { EmptyAccelerationStructureCase::INACTIVE_TRIANGLES, "inactive_triangles" },
4019 { EmptyAccelerationStructureCase::INACTIVE_INSTANCES, "inactive_instances" },
4020 { EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM, "no_geometries_bottom" },
4021 { EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP, "no_primitives_top" },
4022 { EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM, "no_primitives_bottom" },
4023 };
4024
4025 auto& ctx = group->getTestContext();
4026
4027 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
4028 {
4029 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceNdx].name.c_str(), ""));
4030
4031 for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
4032 {
4033 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str(), ""));
4034
4035 for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
4036 {
4037 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str(), ""));
4038
4039 for (int emptyCaseIdx = 0; emptyCaseIdx < DE_LENGTH_OF_ARRAY(emptyCases); ++emptyCaseIdx)
4040 {
4041 TestParams testParams
4042 {
4043 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
4044 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
4045 buildTypes[buildTypeIdx].buildType,
4046 VK_FORMAT_R32G32B32_SFLOAT,
4047 false,
4048 indexFormats[indexFormatIdx].indexType,
4049 BTT_TRIANGLES,
4050 InstanceCullFlags::NONE,
4051 false,
4052 false,
4053 TTT_IDENTICAL_INSTANCES,
4054 false,
4055 false,
4056 VkBuildAccelerationStructureFlagsKHR(0u),
4057 OT_NONE,
4058 OP_NONE,
4059 TEST_WIDTH,
4060 TEST_HEIGHT,
4061 0u,
4062 emptyCases[emptyCaseIdx].emptyASCase,
4063 };
4064 indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, emptyCases[emptyCaseIdx].name.c_str(), "", testParams));
4065 }
4066 buildTypeGroup->addChild(indexTypeGroup.release());
4067 }
4068 sourceTypeGroup->addChild(buildTypeGroup.release());
4069 }
4070 group->addChild(sourceTypeGroup.release());
4071 }
4072 }
4073
createAccelerationStructuresTests(tcu::TestContext & testCtx)4074 tcu::TestCaseGroup* createAccelerationStructuresTests(tcu::TestContext& testCtx)
4075 {
4076 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "acceleration_structures", "Acceleration structure tests using rayQuery feature"));
4077
4078 addTestGroup(group.get(), "flags", "Test building AS with different build types, build flags and geometries/instances using arrays or arrays of pointers", addBasicBuildingTests);
4079 addTestGroup(group.get(), "format", "Test building AS with different vertex and index formats", addVertexIndexFormatsTests);
4080 addTestGroup(group.get(), "operations", "Test copying, compaction and serialization of AS", addOperationTests);
4081 addTestGroup(group.get(), "host_threading", "Test host threading operations", addHostThreadingOperationTests);
4082 addTestGroup(group.get(), "function_argument", "Test using AS as function argument using both pointers and bare values", addFuncArgTests);
4083 addTestGroup(group.get(), "instance_triangle_culling", "Test building AS with counterclockwise triangles and/or disabling face culling", addInstanceTriangleCullingTests);
4084 addTestGroup(group.get(), "dynamic_indexing", "Exercise dynamic indexing of acceleration structures", addDynamicIndexingTests);
4085 addTestGroup(group.get(), "empty", "Test building empty acceleration structures using different methods", addEmptyAccelerationStructureTests);
4086
4087 return group.release();
4088 }
4089
4090 } // RayQuery
4091
4092 } // vkt
4093