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 traversal control in ray query extension
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRayQueryTraversalControlTests.hpp"
25
26 #include <array>
27
28 #include "vkDefs.hpp"
29
30 #include "vktTestCase.hpp"
31 #include "vktTestGroupUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBufferWithMemory.hpp"
37 #include "vkImageWithMemory.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "deRandom.hpp"
41 #include "tcuTexture.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "tcuTestLog.hpp"
44 #include "tcuImageCompare.hpp"
45
46 #include "vkRayTracingUtil.hpp"
47
48 namespace vkt
49 {
50 namespace RayQuery
51 {
52 namespace
53 {
54 using namespace vk;
55 using namespace vkt;
56
57 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
58 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
59 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
60 | VK_SHADER_STAGE_MISS_BIT_KHR
61 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
62 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
63
64 enum ShaderSourcePipeline
65 {
66 SSP_GRAPHICS_PIPELINE,
67 SSP_COMPUTE_PIPELINE,
68 SSP_RAY_TRACING_PIPELINE
69 };
70
71 enum ShaderSourceType
72 {
73 SST_VERTEX_SHADER,
74 SST_TESSELATION_CONTROL_SHADER,
75 SST_TESSELATION_EVALUATION_SHADER,
76 SST_GEOMETRY_SHADER,
77 SST_FRAGMENT_SHADER,
78 SST_COMPUTE_SHADER,
79 SST_RAY_GENERATION_SHADER,
80 SST_INTERSECTION_SHADER,
81 SST_ANY_HIT_SHADER,
82 SST_CLOSEST_HIT_SHADER,
83 SST_MISS_SHADER,
84 SST_CALLABLE_SHADER,
85 };
86
87 enum ShaderTestType
88 {
89 STT_GENERATE_INTERSECTION = 0,
90 STT_SKIP_INTERSECTION = 1,
91 };
92
93 enum BottomTestType
94 {
95 BTT_TRIANGLES,
96 BTT_AABBS
97 };
98
99 const deUint32 TEST_WIDTH = 8;
100 const deUint32 TEST_HEIGHT = 8;
101
102 struct TestParams;
103
104 class TestConfiguration
105 {
106 public:
107 virtual ~TestConfiguration ();
108 virtual void initConfiguration (Context& context,
109 TestParams& testParams) = 0;
110 virtual void fillCommandBuffer (Context& context,
111 TestParams& testParams,
112 VkCommandBuffer commandBuffer,
113 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
114 const VkDescriptorImageInfo& resultImageInfo) = 0;
115 virtual bool verifyImage (BufferWithMemory* resultBuffer,
116 Context& context,
117 TestParams& testParams) = 0;
118 virtual VkFormat getResultImageFormat () = 0;
119 virtual size_t getResultImageFormatSize () = 0;
120 virtual VkClearValue getClearValue () = 0;
121 };
122
~TestConfiguration()123 TestConfiguration::~TestConfiguration()
124 {
125 }
126
127 struct TestParams
128 {
129 deUint32 width;
130 deUint32 height;
131 ShaderSourceType shaderSourceType;
132 ShaderSourcePipeline shaderSourcePipeline;
133 ShaderTestType shaderTestType;
134 BottomTestType bottomType;
135 };
136
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)137 deUint32 getShaderGroupHandleSize (const InstanceInterface& vki,
138 const VkPhysicalDevice physicalDevice)
139 {
140 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
141
142 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
143 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
144 }
145
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)146 deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
147 const VkPhysicalDevice physicalDevice)
148 {
149 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
150
151 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
152 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
153 }
154
makeImageCreateInfo(deUint32 width,deUint32 height,deUint32 depth,VkFormat format)155 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
156 {
157 const VkImageCreateInfo imageCreateInfo =
158 {
159 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
160 DE_NULL, // const void* pNext;
161 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
162 VK_IMAGE_TYPE_3D, // VkImageType imageType;
163 format, // VkFormat format;
164 makeExtent3D(width, height, depth), // VkExtent3D extent;
165 1u, // deUint32 mipLevels;
166 1u, // deUint32 arrayLayers;
167 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
168 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
169 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
170 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
171 0u, // deUint32 queueFamilyIndexCount;
172 DE_NULL, // const deUint32* pQueueFamilyIndices;
173 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
174 };
175
176 return imageCreateInfo;
177 }
178
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)179 bool registerShaderModule (const DeviceInterface& vkd,
180 const VkDevice device,
181 Context& context,
182 std::vector<de::SharedPtr<Move<VkShaderModule>>>& shaderModules,
183 std::vector<VkPipelineShaderStageCreateInfo>& shaderCreateInfos,
184 VkShaderStageFlagBits stage,
185 const std::string& externalNamePart,
186 const std::string& internalNamePart)
187 {
188 char fullShaderName[40];
189 snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
190 std::string fsn = fullShaderName;
191 if (fsn.empty())
192 return false;
193
194 shaderModules.push_back(makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0)));
195
196 shaderCreateInfos.push_back(
197 {
198 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
199 DE_NULL,
200 (VkPipelineShaderStageCreateFlags)0,
201 stage, // stage
202 shaderModules.back()->get(), // shader
203 "main",
204 DE_NULL, // pSpecializationInfo
205 });
206
207 return true;
208 }
209
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,RayTracingPipeline & rayTracingPipeline,VkShaderStageFlagBits shaderStage,const std::string & externalNamePart,const std::string & internalNamePart,deUint32 groupIndex)210 bool registerShaderModule (const DeviceInterface& vkd,
211 const VkDevice device,
212 Context& context,
213 RayTracingPipeline& rayTracingPipeline,
214 VkShaderStageFlagBits shaderStage,
215 const std::string& externalNamePart,
216 const std::string& internalNamePart,
217 deUint32 groupIndex)
218 {
219 char fullShaderName[40];
220 snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
221 std::string fsn = fullShaderName;
222 if (fsn.empty())
223 return false;
224 Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0);
225 if (*shaderModule == DE_NULL)
226 return false;
227 rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex);
228 return true;
229 }
230
231 class GraphicsConfiguration : public TestConfiguration
232 {
233 public:
234 virtual ~GraphicsConfiguration ();
235 void initConfiguration (Context& context,
236 TestParams& testParams) override;
237 void fillCommandBuffer (Context& context,
238 TestParams& testParams,
239 VkCommandBuffer commandBuffer,
240 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
241 const VkDescriptorImageInfo& resultImageInfo) override;
242 bool verifyImage (BufferWithMemory* resultBuffer,
243 Context& context,
244 TestParams& testParams) override;
245 VkFormat getResultImageFormat () override;
246 size_t getResultImageFormatSize () override;
247 VkClearValue getClearValue () override;
248 protected:
249 Move<VkDescriptorSetLayout> descriptorSetLayout;
250 Move<VkDescriptorPool> descriptorPool;
251 Move<VkDescriptorSet> descriptorSet;
252 Move<VkPipelineLayout> pipelineLayout;
253 Move<VkRenderPass> renderPass;
254 Move<VkFramebuffer> framebuffer;
255 std::vector<de::SharedPtr<Move<VkShaderModule> > > shaderModules;
256 Move<VkPipeline> pipeline;
257 std::vector<tcu::Vec3> vertices;
258 Move<VkBuffer> vertexBuffer;
259 de::MovePtr<Allocation> vertexAlloc;
260 };
261
~GraphicsConfiguration()262 GraphicsConfiguration::~GraphicsConfiguration()
263 {
264 shaderModules.clear();
265 }
266
initConfiguration(Context & context,TestParams & testParams)267 void GraphicsConfiguration::initConfiguration (Context& context,
268 TestParams& testParams)
269 {
270 const DeviceInterface& vkd = context.getDeviceInterface();
271 const VkDevice device = context.getDevice();
272 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
273 Allocator& allocator = context.getDefaultAllocator();
274
275 descriptorSetLayout = DescriptorSetLayoutBuilder()
276 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
277 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
278 .build(vkd, device);
279 descriptorPool = DescriptorPoolBuilder()
280 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
281 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
282 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
283 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
284 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
285
286 std::vector<std::vector<std::string>> rayQueryTestName(2);
287 rayQueryTestName[BTT_TRIANGLES].push_back("rq_gen_triangle");
288 rayQueryTestName[BTT_AABBS].push_back("rq_gen_aabb");
289 rayQueryTestName[BTT_TRIANGLES].push_back("rq_skip_triangle");
290 rayQueryTestName[BTT_AABBS].push_back("rq_skip_aabb");
291
292 const std::map<ShaderSourceType,std::vector<std::string>> shaderNames =
293 {
294 //idx: 0 1 2 3 4
295 //shader: vert, tesc, tese, geom, frag,
296 { SST_VERTEX_SHADER, { "vert_%s", "", "", "", "", } },
297 { SST_TESSELATION_CONTROL_SHADER, { "vert", "tesc_%s", "tese", "", "", } },
298 { SST_TESSELATION_EVALUATION_SHADER, { "vert", "tesc", "tese_%s", "", "", } },
299 { SST_GEOMETRY_SHADER, { "vert", "", "", "geom_%s", "", } },
300 { SST_FRAGMENT_SHADER, { "vert", "", "", "", "frag_%s", } },
301 };
302
303 auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
304 if(shaderNameIt == end(shaderNames))
305 TCU_THROW(InternalError, "Wrong shader source type");
306
307 std::vector<VkPipelineShaderStageCreateInfo> shaderCreateInfos;
308 bool tescX, teseX, fragX;
309 registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_VERTEX_BIT, shaderNameIt->second[0], rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
310 tescX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, shaderNameIt->second[1], rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
311 teseX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, shaderNameIt->second[2], rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
312 registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_GEOMETRY_BIT, shaderNameIt->second[3], rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
313 fragX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_FRAGMENT_BIT, shaderNameIt->second[4], rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
314
315 const vk::VkSubpassDescription subpassDesc =
316 {
317 (vk::VkSubpassDescriptionFlags)0,
318 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
319 0u, // inputCount
320 DE_NULL, // pInputAttachments
321 0u, // colorCount
322 DE_NULL, // pColorAttachments
323 DE_NULL, // pResolveAttachments
324 DE_NULL, // depthStencilAttachment
325 0u, // preserveCount
326 DE_NULL, // pPreserveAttachments
327 };
328 const vk::VkRenderPassCreateInfo renderPassParams =
329 {
330 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
331 DE_NULL, // pNext
332 (vk::VkRenderPassCreateFlags)0,
333 0u, // attachmentCount
334 DE_NULL, // pAttachments
335 1u, // subpassCount
336 &subpassDesc, // pSubpasses
337 0u, // dependencyCount
338 DE_NULL, // pDependencies
339 };
340
341 renderPass = createRenderPass(vkd, device, &renderPassParams);
342
343 const vk::VkFramebufferCreateInfo framebufferParams =
344 {
345 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
346 DE_NULL, // pNext
347 (vk::VkFramebufferCreateFlags)0,
348 *renderPass, // renderPass
349 0u, // attachmentCount
350 DE_NULL, // pAttachments
351 testParams.width, // width
352 testParams.height, // height
353 1u, // layers
354 };
355
356 framebuffer = createFramebuffer(vkd, device, &framebufferParams);
357
358 VkPrimitiveTopology testTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
359 tcu::Vec3 v0(1.0f, 1.0f, 0.0f);
360 tcu::Vec3 v1(float(testParams.width) - 1.0f, 1.0f, 0.0f);
361 tcu::Vec3 v2(1.0f, float(testParams.height) - 1.0f, 0.0f);
362 tcu::Vec3 v3(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0f);
363
364 switch (testParams.shaderSourceType)
365 {
366 case SST_TESSELATION_CONTROL_SHADER:
367 case SST_TESSELATION_EVALUATION_SHADER:
368 testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
369 vertices.push_back(v0);
370 vertices.push_back(v1);
371 vertices.push_back(v2);
372 vertices.push_back(v1);
373 vertices.push_back(v3);
374 vertices.push_back(v2);
375 break;
376 case SST_VERTEX_SHADER:
377 case SST_GEOMETRY_SHADER:
378 vertices.push_back(v0);
379 vertices.push_back(v1);
380 vertices.push_back(v2);
381 vertices.push_back(v3);
382 break;
383 case SST_FRAGMENT_SHADER:
384 vertices.push_back( tcu::Vec3(-1.0f, 1.0f, 0.0f) );
385 vertices.push_back( tcu::Vec3(-1.0f, -1.0f, 0.0f) );
386 vertices.push_back( tcu::Vec3( 1.0f, 1.0f, 0.0f) );
387 vertices.push_back( tcu::Vec3( 1.0f, -1.0f, 0.0f) );
388 break;
389 default:
390 TCU_THROW(InternalError, "Wrong shader source type");
391 }
392
393 const VkVertexInputBindingDescription vertexInputBindingDescription =
394 {
395 0u, // uint32_t binding;
396 sizeof(tcu::Vec3), // uint32_t stride;
397 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
398 };
399
400 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
401 {
402 0u, // uint32_t location;
403 0u, // uint32_t binding;
404 VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
405 0u, // uint32_t offset;
406 };
407
408 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
409 {
410 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
411 DE_NULL, // const void* pNext;
412 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
413 1u, // deUint32 vertexBindingDescriptionCount;
414 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
415 1u, // deUint32 vertexAttributeDescriptionCount;
416 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
417 };
418
419 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
420 {
421 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
422 DE_NULL, // const void* pNext;
423 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
424 testTopology, // VkPrimitiveTopology topology;
425 VK_FALSE // VkBool32 primitiveRestartEnable;
426 };
427
428 const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo =
429 {
430 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
431 DE_NULL, // const void* pNext;
432 VkPipelineTessellationStateCreateFlags(0u), // VkPipelineTessellationStateCreateFlags flags;
433 3u // deUint32 patchControlPoints;
434 };
435
436 VkViewport viewport = makeViewport(testParams.width, testParams.height);
437 VkRect2D scissor = makeRect2D(testParams.width, testParams.height);
438
439 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
440 {
441 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
442 DE_NULL, // const void* pNext
443 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
444 1u, // deUint32 viewportCount
445 &viewport, // const VkViewport* pViewports
446 1u, // deUint32 scissorCount
447 &scissor // const VkRect2D* pScissors
448 };
449
450 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
451 {
452 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
453 DE_NULL, // const void* pNext;
454 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
455 VK_FALSE, // VkBool32 depthClampEnable;
456 fragX ? VK_FALSE : VK_TRUE, // VkBool32 rasterizerDiscardEnable;
457 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
458 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
459 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
460 VK_FALSE, // VkBool32 depthBiasEnable;
461 0.0f, // float depthBiasConstantFactor;
462 0.0f, // float depthBiasClamp;
463 0.0f, // float depthBiasSlopeFactor;
464 1.0f // float lineWidth;
465 };
466
467 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
468 {
469 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
470 DE_NULL, // const void* pNext;
471 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
472 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
473 VK_FALSE, // VkBool32 sampleShadingEnable;
474 0.0f, // float minSampleShading;
475 DE_NULL, // const VkSampleMask* pSampleMask;
476 VK_FALSE, // VkBool32 alphaToCoverageEnable;
477 VK_FALSE // VkBool32 alphaToOneEnable;
478 };
479
480 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
481 {
482 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
483 DE_NULL, // const void* pNext;
484 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
485 DE_FALSE, // VkBool32 logicOpEnable;
486 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp;
487 0, // deUint32 attachmentCount;
488 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments;
489 { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4];
490 };
491
492 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
493 {
494 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
495 DE_NULL, // const void* pNext;
496 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
497 static_cast<deUint32>(shaderCreateInfos.size()), // deUint32 stageCount;
498 shaderCreateInfos.data(), // const VkPipelineShaderStageCreateInfo* pStages;
499 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
500 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
501 (tescX||teseX) ? &tessellationStateCreateInfo : DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
502 fragX ? &viewportStateCreateInfo : DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState;
503 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
504 fragX ? &multisampleStateCreateInfo : DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
505 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
506 fragX ? &colorBlendStateCreateInfo : DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
507 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
508 pipelineLayout.get(), // VkPipelineLayout layout;
509 renderPass.get(), // VkRenderPass renderPass;
510 0u, // deUint32 subpass;
511 DE_NULL, // VkPipeline basePipelineHandle;
512 0 // int basePipelineIndex;
513 };
514
515 pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo);
516
517 const VkBufferCreateInfo vertexBufferParams =
518 {
519 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
520 DE_NULL, // const void* pNext;
521 0u, // VkBufferCreateFlags flags;
522 VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()), // VkDeviceSize size;
523 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
524 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
525 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
526 1u, // deUint32 queueFamilyIndexCount;
527 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
528 };
529
530 vertexBuffer = createBuffer(vkd, device, &vertexBufferParams);
531 vertexAlloc = allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible);
532 VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
533
534 // Upload vertex data
535 deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3));
536 flushAlloc(vkd, device, *vertexAlloc);
537 }
538
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)539 void GraphicsConfiguration::fillCommandBuffer (Context& context,
540 TestParams& testParams,
541 VkCommandBuffer commandBuffer,
542 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
543 const VkDescriptorImageInfo& resultImageInfo)
544 {
545 const DeviceInterface& vkd = context.getDeviceInterface();
546 const VkDevice device = context.getDevice();
547
548 DescriptorSetUpdateBuilder()
549 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
550 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
551 .update(vkd, device);
552
553 const VkRenderPassBeginInfo renderPassBeginInfo =
554 {
555 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
556 DE_NULL, // const void* pNext;
557 *renderPass, // VkRenderPass renderPass;
558 *framebuffer, // VkFramebuffer framebuffer;
559 makeRect2D(testParams.width, testParams.height), // VkRect2D renderArea;
560 0u, // uint32_t clearValueCount;
561 DE_NULL // const VkClearValue* pClearValues;
562 };
563 VkDeviceSize vertexBufferOffset = 0u;
564
565 vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
566 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
567 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
568 vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
569 vkd.cmdDraw(commandBuffer, deUint32(vertices.size()), 1, 0, 0);
570 vkd.cmdEndRenderPass(commandBuffer);
571 }
572
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)573 bool GraphicsConfiguration::verifyImage (BufferWithMemory* resultBuffer,
574 Context& context,
575 TestParams& testParams)
576 {
577 // create result image
578 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
579 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
580
581 // create reference image
582 std::vector<deUint32> reference(testParams.width * testParams.height * 2);
583 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
584
585 tcu::UVec4 rqValue0, rqValue1;
586 switch (testParams.shaderTestType)
587 {
588 case STT_GENERATE_INTERSECTION:
589 switch (testParams.bottomType)
590 {
591 case BTT_TRIANGLES:
592 rqValue0 = tcu::UVec4(1, 0, 0, 0);
593 rqValue1 = tcu::UVec4(1, 0, 0, 0);
594 break;
595 case BTT_AABBS:
596 rqValue0 = tcu::UVec4(2, 0, 0, 0);
597 rqValue1 = tcu::UVec4(1, 0, 0, 0);
598 break;
599 default:
600 TCU_THROW(InternalError, "Wrong bottom test type");
601 }
602 break;
603 case STT_SKIP_INTERSECTION:
604 switch (testParams.bottomType)
605 {
606 case BTT_TRIANGLES:
607 rqValue0 = tcu::UVec4(0, 0, 0, 0);
608 rqValue1 = tcu::UVec4(1, 0, 0, 0);
609 break;
610 case BTT_AABBS:
611 rqValue0 = tcu::UVec4(0, 0, 0, 0);
612 rqValue1 = tcu::UVec4(1, 0, 0, 0);
613 break;
614 default:
615 TCU_THROW(InternalError, "Wrong bottom test type");
616 }
617 break;
618 default:
619 TCU_THROW(InternalError, "Wrong shader test type");
620 }
621
622 std::vector<std::vector<deUint32>> primitives =
623 {
624 {0, 1, 2},
625 {1, 3, 2}
626 };
627
628 tcu::UVec4 clearValue, missValue, hitValue0, hitValue1;
629 hitValue0 = rqValue0;
630 hitValue1 = rqValue1;
631 missValue = tcu::UVec4(0, 0, 0, 0);
632 clearValue = tcu::UVec4(0xFF, 0, 0, 0);
633
634 switch (testParams.shaderSourceType)
635 {
636 case SST_VERTEX_SHADER:
637 tcu::clear(referenceAccess, clearValue);
638 for (deUint32 vertexNdx = 0; vertexNdx < 4; ++vertexNdx)
639 {
640 if (vertexNdx == 0)
641 {
642 referenceAccess.setPixel(hitValue0, vertexNdx, 0, 0);
643 referenceAccess.setPixel(hitValue1, vertexNdx, 0, 1);
644 }
645 else
646 {
647 referenceAccess.setPixel(missValue, vertexNdx, 0, 0);
648 referenceAccess.setPixel(missValue, vertexNdx, 0, 1);
649 }
650 }
651 break;
652 case SST_TESSELATION_EVALUATION_SHADER:
653 case SST_TESSELATION_CONTROL_SHADER:
654 case SST_GEOMETRY_SHADER:
655 tcu::clear(referenceAccess, clearValue);
656 for (deUint32 primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx)
657 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
658 {
659 deUint32 vNdx = primitives[primitiveNdx][vertexNdx];
660 if (vNdx==0)
661 {
662 referenceAccess.setPixel(hitValue0, primitiveNdx, vertexNdx, 0);
663 referenceAccess.setPixel(hitValue1, primitiveNdx, vertexNdx, 1);
664 }
665 else
666 {
667 referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 0);
668 referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 1);
669 }
670 }
671 break;
672 case SST_FRAGMENT_SHADER:
673 tcu::clear(referenceAccess, missValue);
674 for (deUint32 y = 1; y < testParams.height - 1; ++y)
675 for (deUint32 x = 1; x < testParams.width - 1; ++x)
676 {
677 referenceAccess.setPixel(hitValue0, x, y, 0);
678 referenceAccess.setPixel(hitValue1, x, y, 1);
679 }
680 break;
681 default:
682 TCU_THROW(InternalError, "Wrong shader source type");
683 }
684
685 // compare result and reference
686 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
687 }
688
getResultImageFormat()689 VkFormat GraphicsConfiguration::getResultImageFormat ()
690 {
691 return VK_FORMAT_R32_UINT;
692 }
693
getResultImageFormatSize()694 size_t GraphicsConfiguration::getResultImageFormatSize ()
695 {
696 return sizeof(deUint32);
697 }
698
getClearValue()699 VkClearValue GraphicsConfiguration::getClearValue ()
700 {
701 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
702 }
703
704 class ComputeConfiguration : public TestConfiguration
705 {
706 public:
707 virtual ~ComputeConfiguration ();
708 void initConfiguration (Context& context,
709 TestParams& testParams) override;
710 void fillCommandBuffer (Context& context,
711 TestParams& testParams,
712 VkCommandBuffer commandBuffer,
713 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
714 const VkDescriptorImageInfo& resultImageInfo) override;
715 bool verifyImage (BufferWithMemory* resultBuffer,
716 Context& context,
717 TestParams& testParams) override;
718 VkFormat getResultImageFormat () override;
719 size_t getResultImageFormatSize () override;
720 VkClearValue getClearValue () override;
721 protected:
722 Move<VkDescriptorSetLayout> descriptorSetLayout;
723 Move<VkDescriptorPool> descriptorPool;
724 Move<VkDescriptorSet> descriptorSet;
725 Move<VkPipelineLayout> pipelineLayout;
726 Move<VkShaderModule> shaderModule;
727 Move<VkPipeline> pipeline;
728 };
729
~ComputeConfiguration()730 ComputeConfiguration::~ComputeConfiguration()
731 {
732 }
733
initConfiguration(Context & context,TestParams & testParams)734 void ComputeConfiguration::initConfiguration (Context& context,
735 TestParams& testParams)
736 {
737 const DeviceInterface& vkd = context.getDeviceInterface();
738 const VkDevice device = context.getDevice();
739
740 descriptorSetLayout = DescriptorSetLayoutBuilder()
741 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
742 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
743 .build(vkd, device);
744 descriptorPool = DescriptorPoolBuilder()
745 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
746 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
747 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
748 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
749 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
750
751 std::vector<std::vector<std::string>> rayQueryTestName(2);
752 rayQueryTestName[BTT_TRIANGLES].push_back("comp_rq_gen_triangle");
753 rayQueryTestName[BTT_AABBS].push_back("comp_rq_gen_aabb");
754 rayQueryTestName[BTT_TRIANGLES].push_back("comp_rq_skip_triangle");
755 rayQueryTestName[BTT_AABBS].push_back("comp_rq_skip_aabb");
756
757 shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[testParams.bottomType][testParams.shaderTestType]), 0u);
758 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
759 {
760 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
761 DE_NULL, // const void* pNext;
762 0u, // VkPipelineShaderStageCreateFlags flags;
763 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
764 *shaderModule, // VkShaderModule module;
765 "main", // const char* pName;
766 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
767 };
768 const VkComputePipelineCreateInfo pipelineCreateInfo =
769 {
770 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
771 DE_NULL, // const void* pNext;
772 0u, // VkPipelineCreateFlags flags;
773 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage;
774 *pipelineLayout, // VkPipelineLayout layout;
775 DE_NULL, // VkPipeline basePipelineHandle;
776 0, // deInt32 basePipelineIndex;
777 };
778
779 pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
780 }
781
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)782 void ComputeConfiguration::fillCommandBuffer (Context& context,
783 TestParams& testParams,
784 VkCommandBuffer commandBuffer,
785 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
786 const VkDescriptorImageInfo& resultImageInfo)
787 {
788 const DeviceInterface& vkd = context.getDeviceInterface();
789 const VkDevice device = context.getDevice();
790
791 DescriptorSetUpdateBuilder()
792 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
793 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
794 .update(vkd, device);
795
796 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
797
798 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
799
800 vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1);
801 }
802
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)803 bool ComputeConfiguration::verifyImage (BufferWithMemory* resultBuffer,
804 Context& context,
805 TestParams& testParams)
806 {
807 // create result image
808 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
809 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
810
811 // create reference image
812 std::vector<deUint32> reference(testParams.width * testParams.height * 2);
813 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
814
815 tcu::UVec4 rqValue0, rqValue1;
816 switch (testParams.shaderTestType)
817 {
818 case STT_GENERATE_INTERSECTION:
819 switch (testParams.bottomType)
820 {
821 case BTT_TRIANGLES:
822 rqValue0 = tcu::UVec4(1, 0, 0, 0);
823 rqValue1 = tcu::UVec4(1, 0, 0, 0);
824 break;
825 case BTT_AABBS:
826 rqValue0 = tcu::UVec4(2, 0, 0, 0);
827 rqValue1 = tcu::UVec4(1, 0, 0, 0);
828 break;
829 default:
830 TCU_THROW(InternalError, "Wrong bottom test type");
831 }
832 break;
833 case STT_SKIP_INTERSECTION:
834 switch (testParams.bottomType)
835 {
836 case BTT_TRIANGLES:
837 rqValue0 = tcu::UVec4(0, 0, 0, 0);
838 rqValue1 = tcu::UVec4(1, 0, 0, 0);
839 break;
840 case BTT_AABBS:
841 rqValue0 = tcu::UVec4(0, 0, 0, 0);
842 rqValue1 = tcu::UVec4(1, 0, 0, 0);
843 break;
844 default:
845 TCU_THROW(InternalError, "Wrong bottom test type");
846 }
847 break;
848 default:
849 TCU_THROW(InternalError, "Wrong shader test type");
850 }
851
852 tcu::UVec4 missValue0, missValue1, hitValue0, hitValue1;
853 hitValue0 = rqValue0;
854 hitValue1 = rqValue1;
855 missValue0 = tcu::UVec4(0, 0, 0, 0);
856 missValue1 = tcu::UVec4(0, 0, 0, 0);
857
858 tcu::clear(referenceAccess, missValue0);
859 for (deUint32 y = 0; y < testParams.height; ++y)
860 for (deUint32 x = 0; x < testParams.width; ++x)
861 referenceAccess.setPixel(missValue1, x, y, 1);
862
863 for (deUint32 y = 1; y < testParams.height - 1; ++y)
864 for (deUint32 x = 1; x < testParams.width - 1; ++x)
865 {
866 referenceAccess.setPixel(hitValue0, x, y, 0);
867 referenceAccess.setPixel(hitValue1, x, y, 1);
868 }
869
870 // compare result and reference
871 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
872 }
873
getResultImageFormat()874 VkFormat ComputeConfiguration::getResultImageFormat ()
875 {
876 return VK_FORMAT_R32_UINT;
877 }
878
getResultImageFormatSize()879 size_t ComputeConfiguration::getResultImageFormatSize ()
880 {
881 return sizeof(deUint32);
882 }
883
getClearValue()884 VkClearValue ComputeConfiguration::getClearValue ()
885 {
886 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
887 }
888
889 class RayTracingConfiguration : public TestConfiguration
890 {
891 public:
892 virtual ~RayTracingConfiguration ();
893 void initConfiguration (Context& context,
894 TestParams& testParams) override;
895 void fillCommandBuffer (Context& context,
896 TestParams& testParams,
897 VkCommandBuffer commandBuffer,
898 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
899 const VkDescriptorImageInfo& resultImageInfo) override;
900 bool verifyImage (BufferWithMemory* resultBuffer,
901 Context& context,
902 TestParams& testParams) override;
903 VkFormat getResultImageFormat () override;
904 size_t getResultImageFormatSize () override;
905 VkClearValue getClearValue () override;
906 protected:
907 Move<VkDescriptorSetLayout> descriptorSetLayout;
908 Move<VkDescriptorPool> descriptorPool;
909 Move<VkDescriptorSet> descriptorSet;
910 Move<VkPipelineLayout> pipelineLayout;
911
912 de::MovePtr<RayTracingPipeline> rayTracingPipeline;
913 Move<VkPipeline> rtPipeline;
914
915 de::MovePtr<BufferWithMemory> raygenShaderBindingTable;
916 de::MovePtr<BufferWithMemory> hitShaderBindingTable;
917 de::MovePtr<BufferWithMemory> missShaderBindingTable;
918 de::MovePtr<BufferWithMemory> callableShaderBindingTable;
919
920 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelAccelerationStructures;
921 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
922 };
923
~RayTracingConfiguration()924 RayTracingConfiguration::~RayTracingConfiguration()
925 {
926 }
927
initConfiguration(Context & context,TestParams & testParams)928 void RayTracingConfiguration::initConfiguration (Context& context,
929 TestParams& testParams)
930 {
931 const InstanceInterface& vki = context.getInstanceInterface();
932 const DeviceInterface& vkd = context.getDeviceInterface();
933 const VkDevice device = context.getDevice();
934 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
935 Allocator& allocator = context.getDefaultAllocator();
936
937 descriptorSetLayout = DescriptorSetLayoutBuilder()
938 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
939 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
940 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
941 .build(vkd, device);
942 descriptorPool = DescriptorPoolBuilder()
943 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
944 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
945 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
946 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
947 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
948 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
949
950 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
951
952 const std::map<ShaderSourceType,std::vector<std::string>> shaderNames =
953 {
954 //idx: 0 1 2 3 4 5
955 //shader: rgen, isect, ahit, chit, miss, call
956 //group: 0 1 1 1 2 3
957 { SST_RAY_GENERATION_SHADER, { "rgen_%s", "", "", "", "", "" } },
958 { SST_INTERSECTION_SHADER, { "rgen", "isect_%s", "", "chit_isect", "miss", "" } },
959 { SST_ANY_HIT_SHADER, { "rgen", "isect", "ahit_%s", "", "miss", "" } },
960 { SST_CLOSEST_HIT_SHADER, { "rgen", "isect", "", "chit_%s", "miss", "" } },
961 { SST_MISS_SHADER, { "rgen", "isect", "", "chit", "miss_%s", "" } },
962 { SST_CALLABLE_SHADER, { "rgen_call", "", "", "chit", "miss", "call_%s" } },
963 };
964
965 std::vector<std::vector<std::string>> rayQueryTestName(2);
966 rayQueryTestName[BTT_TRIANGLES].push_back("rq_gen_triangle");
967 rayQueryTestName[BTT_AABBS].push_back("rq_gen_aabb");
968 rayQueryTestName[BTT_TRIANGLES].push_back("rq_skip_triangle");
969 rayQueryTestName[BTT_AABBS].push_back("rq_skip_aabb");
970
971 auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
972 if(shaderNameIt == end(shaderNames))
973 TCU_THROW(InternalError, "Wrong shader source type");
974
975 bool rgenX, isectX, ahitX, chitX, missX, callX;
976 rgenX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_RAYGEN_BIT_KHR, shaderNameIt->second[0], rayQueryTestName[testParams.bottomType][testParams.shaderTestType], 0);
977 if (testParams.shaderSourceType == SST_INTERSECTION_SHADER)
978 isectX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_INTERSECTION_BIT_KHR, shaderNameIt->second[1], rayQueryTestName[testParams.bottomType][testParams.shaderTestType], 1);
979 else
980 isectX = false;
981 ahitX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_ANY_HIT_BIT_KHR, shaderNameIt->second[2], rayQueryTestName[testParams.bottomType][testParams.shaderTestType], 1);
982 chitX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, shaderNameIt->second[3], rayQueryTestName[testParams.bottomType][testParams.shaderTestType], 1);
983 missX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_MISS_BIT_KHR, shaderNameIt->second[4], rayQueryTestName[testParams.bottomType][testParams.shaderTestType], 2);
984 callX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CALLABLE_BIT_KHR, shaderNameIt->second[5], rayQueryTestName[testParams.bottomType][testParams.shaderTestType], 3);
985 bool hitX = isectX || ahitX || chitX;
986
987 rtPipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
988
989 deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
990 deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
991
992 if (rgenX) raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
993 if (hitX) hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
994 if (missX) missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
995 if (callX) callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
996 }
997
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)998 void RayTracingConfiguration::fillCommandBuffer (Context& context,
999 TestParams& testParams,
1000 VkCommandBuffer commandBuffer,
1001 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet,
1002 const VkDescriptorImageInfo& resultImageInfo)
1003 {
1004 const InstanceInterface& vki = context.getInstanceInterface();
1005 const DeviceInterface& vkd = context.getDeviceInterface();
1006 const VkDevice device = context.getDevice();
1007 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1008 Allocator& allocator = context.getDefaultAllocator();
1009
1010 {
1011 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1012 bottomLevelAccelerationStructure->setGeometryCount(1);
1013
1014 de::SharedPtr<RaytracedGeometryBase> geometry;
1015 if (testParams.shaderSourceType != SST_INTERSECTION_SHADER)
1016 {
1017 tcu::Vec3 v0(0.0f, 0.5f * float(testParams.height), 0.0f);
1018 tcu::Vec3 v1(0.0f, 0.0f, 0.0f);
1019 tcu::Vec3 v2(float(testParams.width), 0.5f * float(testParams.height), 0.0f);
1020 tcu::Vec3 v3(float(testParams.width), 0.0f, 0.0f);
1021
1022 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1023 geometry->addVertex(v0);
1024 geometry->addVertex(v1);
1025 geometry->addVertex(v2);
1026 geometry->addVertex(v2);
1027 geometry->addVertex(v1);
1028 geometry->addVertex(v3);
1029 }
1030 else // testParams.shaderSourceType == SST_INTERSECTION_SHADER
1031 {
1032 tcu::Vec3 v0(0.0f, 0.0f, -0.1f);
1033 tcu::Vec3 v1(float(testParams.width), 0.5f * float(testParams.height), 0.1f);
1034
1035 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1036 geometry->addVertex(v0);
1037 geometry->addVertex(v1);
1038 }
1039 bottomLevelAccelerationStructure->addGeometry(geometry);
1040 bottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1041
1042 for (auto& blas : bottomLevelAccelerationStructures)
1043 blas->createAndBuild(vkd, device, commandBuffer, allocator);
1044 }
1045
1046 topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1047 topLevelAccelerationStructure->setInstanceCount(1);
1048 topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]);
1049 topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1050
1051 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
1052 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1053 {
1054 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1055 DE_NULL, // const void* pNext;
1056 1u, // deUint32 accelerationStructureCount;
1057 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
1058 };
1059
1060 DescriptorSetUpdateBuilder()
1061 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1062 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1063 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1064 .update(vkd, device);
1065
1066 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1067
1068 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline);
1069
1070 deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1071 VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = raygenShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1072 VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = hitShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1073 VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = missShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1074 VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = callableShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1075
1076 cmdTraceRays(vkd,
1077 commandBuffer,
1078 &raygenShaderBindingTableRegion,
1079 &missShaderBindingTableRegion,
1080 &hitShaderBindingTableRegion,
1081 &callableShaderBindingTableRegion,
1082 testParams.width, testParams.height, 1);
1083 }
1084
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1085 bool RayTracingConfiguration::verifyImage (BufferWithMemory* resultBuffer,
1086 Context& context,
1087 TestParams& testParams)
1088 {
1089 // create result image
1090 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
1091 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
1092
1093 // create reference image
1094 std::vector<deUint32> reference(testParams.width * testParams.height * 2);
1095 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
1096
1097 tcu::UVec4 rqValue0, rqValue1;
1098 switch (testParams.shaderTestType)
1099 {
1100 case STT_GENERATE_INTERSECTION:
1101 switch (testParams.bottomType)
1102 {
1103 case BTT_TRIANGLES:
1104 rqValue0 = tcu::UVec4(1, 0, 0, 0);
1105 rqValue1 = tcu::UVec4(1, 0, 0, 0);
1106 break;
1107 case BTT_AABBS:
1108 rqValue0 = tcu::UVec4(2, 0, 0, 0);
1109 rqValue1 = tcu::UVec4(1, 0, 0, 0);
1110 break;
1111 default:
1112 TCU_THROW(InternalError, "Wrong bottom test type");
1113 }
1114 break;
1115 case STT_SKIP_INTERSECTION:
1116 switch (testParams.bottomType)
1117 {
1118 case BTT_TRIANGLES:
1119 rqValue0 = tcu::UVec4(0, 0, 0, 0);
1120 rqValue1 = tcu::UVec4(1, 0, 0, 0);
1121 break;
1122 case BTT_AABBS:
1123 rqValue0 = tcu::UVec4(0, 0, 0, 0);
1124 rqValue1 = tcu::UVec4(1, 0, 0, 0);
1125 break;
1126 default:
1127 TCU_THROW(InternalError, "Wrong bottom test type");
1128 }
1129 break;
1130 default:
1131 TCU_THROW(InternalError, "Wrong shader test type");
1132 }
1133
1134 std::array<tcu::UVec4,2> missMissValue, missHitValue, hitMissValue, hitHitValue;
1135 switch (testParams.shaderSourceType)
1136 {
1137 case SST_RAY_GENERATION_SHADER:
1138 missMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1139 missHitValue = {{ rqValue0 , rqValue1 }};
1140 hitMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1141 hitHitValue = {{ rqValue0 , rqValue1 }};
1142 break;
1143 case SST_INTERSECTION_SHADER:
1144 missMissValue = {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1145 missHitValue = {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1146 hitMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1147 hitHitValue = {{ rqValue0 , rqValue1 }};
1148 break;
1149 case SST_ANY_HIT_SHADER:
1150 missMissValue = {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1151 missHitValue = {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1152 hitMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1153 hitHitValue = {{ rqValue0 , rqValue1 }};
1154 break;
1155 case SST_CLOSEST_HIT_SHADER:
1156 missMissValue = {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1157 missHitValue = {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1158 hitMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1159 hitHitValue = {{ rqValue0 , rqValue1 }};
1160 break;
1161 case SST_MISS_SHADER:
1162 missMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1163 missHitValue = {{ rqValue0 , rqValue1 }};
1164 hitMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(3, 0, 0, 0) }};
1165 hitHitValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(3, 0, 0, 0) }};
1166 break;
1167 case SST_CALLABLE_SHADER:
1168 missMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1169 missHitValue = {{ rqValue0 , rqValue1 }};
1170 hitMissValue = {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1171 hitHitValue = {{ rqValue0 , rqValue1 }};
1172 break;
1173 default:
1174 TCU_THROW(InternalError, "Wrong shader source type");
1175 }
1176
1177 for (deUint32 y = 0; y < testParams.height / 2; ++y)
1178 for (deUint32 x = 0; x < testParams.width; ++x)
1179 {
1180 referenceAccess.setPixel(hitMissValue[0], x, y, 0);
1181 referenceAccess.setPixel(hitMissValue[1], x, y, 1);
1182 }
1183 for (deUint32 y = testParams.height / 2; y < testParams.height; ++y)
1184 for (deUint32 x = 0; x < testParams.width; ++x)
1185 {
1186 referenceAccess.setPixel(missMissValue[0], x, y, 0);
1187 referenceAccess.setPixel(missMissValue[1], x, y, 1);
1188 }
1189
1190 for (deUint32 y = 1; y < testParams.height / 2; ++y)
1191 for (deUint32 x = 1; x < testParams.width - 1; ++x)
1192 {
1193 referenceAccess.setPixel(hitHitValue[0], x, y, 0);
1194 referenceAccess.setPixel(hitHitValue[1], x, y, 1);
1195 }
1196
1197 for (deUint32 y = testParams.height/2; y < testParams.height - 1; ++y)
1198 for (deUint32 x = 1; x < testParams.width - 1; ++x)
1199 {
1200 referenceAccess.setPixel(missHitValue[0], x, y, 0);
1201 referenceAccess.setPixel(missHitValue[1], x, y, 1);
1202 }
1203
1204 // compare result and reference
1205 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
1206 }
1207
getResultImageFormat()1208 VkFormat RayTracingConfiguration::getResultImageFormat ()
1209 {
1210 return VK_FORMAT_R32_UINT;
1211 }
1212
getResultImageFormatSize()1213 size_t RayTracingConfiguration::getResultImageFormatSize ()
1214 {
1215 return sizeof(deUint32);
1216 }
1217
getClearValue()1218 VkClearValue RayTracingConfiguration::getClearValue ()
1219 {
1220 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1221 }
1222
1223 class RayQueryTraversalControlTestCase : public TestCase
1224 {
1225 public:
1226 RayQueryTraversalControlTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams data);
1227 ~RayQueryTraversalControlTestCase (void);
1228
1229 virtual void checkSupport (Context& context) const;
1230 virtual void initPrograms (SourceCollections& programCollection) const;
1231 virtual TestInstance* createInstance (Context& context) const;
1232 private:
1233 TestParams m_data;
1234 };
1235
1236 class TraversalControlTestInstance : public TestInstance
1237 {
1238 public:
1239 TraversalControlTestInstance (Context& context, const TestParams& data);
1240 ~TraversalControlTestInstance (void);
1241 tcu::TestStatus iterate (void);
1242
1243 private:
1244 TestParams m_data;
1245 };
1246
RayQueryTraversalControlTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams data)1247 RayQueryTraversalControlTestCase::RayQueryTraversalControlTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams data)
1248 : vkt::TestCase (context, name, desc)
1249 , m_data (data)
1250 {
1251 }
1252
~RayQueryTraversalControlTestCase(void)1253 RayQueryTraversalControlTestCase::~RayQueryTraversalControlTestCase (void)
1254 {
1255 }
1256
checkSupport(Context & context) const1257 void RayQueryTraversalControlTestCase::checkSupport (Context& context) const
1258 {
1259 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1260 context.requireDeviceFunctionality("VK_KHR_ray_query");
1261
1262 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures();
1263 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
1264 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1265
1266 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1267 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
1268 TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1269
1270 const VkPhysicalDeviceFeatures2& features2 = context.getDeviceFeatures2();
1271
1272 if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1273 m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1274 features2.features.tessellationShader == DE_FALSE )
1275 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1276
1277 if (m_data.shaderSourceType == SST_GEOMETRY_SHADER &&
1278 features2.features.geometryShader == DE_FALSE )
1279 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1280
1281 switch (m_data.shaderSourceType)
1282 {
1283 case SST_VERTEX_SHADER:
1284 case SST_TESSELATION_CONTROL_SHADER:
1285 case SST_TESSELATION_EVALUATION_SHADER:
1286 case SST_GEOMETRY_SHADER:
1287 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1288 break;
1289 default:
1290 break;
1291 }
1292
1293 if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER ||
1294 m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1295 m_data.shaderSourceType == SST_ANY_HIT_SHADER ||
1296 m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1297 m_data.shaderSourceType == SST_MISS_SHADER ||
1298 m_data.shaderSourceType == SST_CALLABLE_SHADER)
1299 {
1300 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1301
1302 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1303
1304 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1305 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1306 }
1307 }
1308
initPrograms(SourceCollections & programCollection) const1309 void RayQueryTraversalControlTestCase::initPrograms (SourceCollections& programCollection) const
1310 {
1311 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1312
1313 // create parts of programs responsible for test execution
1314 std::vector<std::vector<std::string>> rayQueryTest(2);
1315 std::vector<std::vector<std::string>> rayQueryTestName(2);
1316 {
1317 // STT_GENERATE_INTERSECTION for triangles
1318 std::stringstream css;
1319 css <<
1320 " float tmin = 0.0;\n"
1321 " float tmax = 1.0;\n"
1322 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1323 " rayQueryEXT rq;\n"
1324 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1325 " if(rayQueryProceedEXT(rq))\n"
1326 " {\n"
1327 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1328 " {\n"
1329 " hitValue.y=1;\n"
1330 " rayQueryConfirmIntersectionEXT(rq);\n"
1331 " rayQueryProceedEXT(rq);\n"
1332 " hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1333 " }\n"
1334 " }\n";
1335 rayQueryTest[BTT_TRIANGLES].push_back(css.str());
1336 rayQueryTestName[BTT_TRIANGLES].push_back("rq_gen_triangle");
1337 }
1338 {
1339 // STT_GENERATE_INTERSECTION for AABBs
1340 std::stringstream css;
1341 css <<
1342 " float tmin = 0.0;\n"
1343 " float tmax = 1.0;\n"
1344 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1345 " rayQueryEXT rq;\n"
1346 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1347 " if(rayQueryProceedEXT(rq))\n"
1348 " {\n"
1349 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1350 " {\n"
1351 " hitValue.y=1;\n"
1352 " rayQueryGenerateIntersectionEXT(rq, 0.5);\n"
1353 " rayQueryProceedEXT(rq);\n"
1354 " hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1355 " }\n"
1356 " }\n";
1357 rayQueryTest[BTT_AABBS].push_back(css.str());
1358 rayQueryTestName[BTT_AABBS].push_back("rq_gen_aabb");
1359 }
1360 {
1361 // STT_SKIP_INTERSECTION for triangles
1362 std::stringstream css;
1363 css <<
1364 " float tmin = 0.0;\n"
1365 " float tmax = 1.0;\n"
1366 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1367 " rayQueryEXT rq;\n"
1368 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1369 " if(rayQueryProceedEXT(rq))\n"
1370 " {\n"
1371 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1372 " {\n"
1373 " hitValue.y=1;\n"
1374 " rayQueryProceedEXT(rq);\n"
1375 " hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1376 " }\n"
1377 " }\n";
1378 rayQueryTest[BTT_TRIANGLES].push_back(css.str());
1379 rayQueryTestName[BTT_TRIANGLES].push_back("rq_skip_triangle");
1380 }
1381 {
1382 // STT_SKIP_INTERSECTION for AABBs
1383 std::stringstream css;
1384 css <<
1385 " float tmin = 0.0;\n"
1386 " float tmax = 1.0;\n"
1387 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1388 " rayQueryEXT rq;\n"
1389 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1390 " if(rayQueryProceedEXT(rq))\n"
1391 " {\n"
1392 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1393 " {\n"
1394 " hitValue.y=1;\n"
1395 " rayQueryProceedEXT(rq);\n"
1396 " hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1397 " }\n"
1398 " }\n";
1399 rayQueryTest[BTT_AABBS].push_back(css.str());
1400 rayQueryTestName[BTT_AABBS].push_back("rq_skip_aabb");
1401 }
1402
1403 // create all programs
1404 if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1405 {
1406 {
1407 std::stringstream css;
1408 css <<
1409 "#version 460 core\n"
1410 "layout (location = 0) in vec3 position;\n"
1411 "out gl_PerVertex\n"
1412 "{\n"
1413 " vec4 gl_Position;\n"
1414 "};\n"
1415 "void main()\n"
1416 "{\n"
1417 " gl_Position = vec4(position, 1.0);\n"
1418 "}\n";
1419 programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions;
1420 }
1421
1422 {
1423 std::stringstream css;
1424 css <<
1425 "#version 460 core\n"
1426 "#extension GL_EXT_ray_query : require\n"
1427 "layout (location = 0) in vec3 position;\n"
1428 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1429 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1430 "void main()\n"
1431 "{\n"
1432 " vec3 origin = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n"
1433 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1434 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1435 " imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1436 " imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1437 " gl_Position = vec4(position,1);\n"
1438 "}\n";
1439 std::stringstream cssName;
1440 cssName << "vert_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1441
1442 programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1443 }
1444
1445 {
1446 std::stringstream css;
1447 css <<
1448 "#version 460 core\n"
1449 "#extension GL_EXT_tessellation_shader : require\n"
1450 "in gl_PerVertex {\n"
1451 " vec4 gl_Position;\n"
1452 "} gl_in[];\n"
1453 "layout(vertices = 3) out;\n"
1454 "void main (void)\n"
1455 "{\n"
1456 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1457 " gl_TessLevelInner[0] = 1;\n"
1458 " gl_TessLevelOuter[0] = 1;\n"
1459 " gl_TessLevelOuter[1] = 1;\n"
1460 " gl_TessLevelOuter[2] = 1;\n"
1461 "}\n";
1462 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions;
1463 }
1464
1465 {
1466 std::stringstream css;
1467 css <<
1468 "#version 460 core\n"
1469 "#extension GL_EXT_tessellation_shader : require\n"
1470 "#extension GL_EXT_ray_query : require\n"
1471 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1472 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1473 "in gl_PerVertex {\n"
1474 " vec4 gl_Position;\n"
1475 "} gl_in[];\n"
1476 "layout(vertices = 3) out;\n"
1477 "void main (void)\n"
1478 "{\n"
1479 " vec3 origin = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n"
1480 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1481 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1482 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1483 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1484 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1485 " gl_TessLevelInner[0] = 1;\n"
1486 " gl_TessLevelOuter[0] = 1;\n"
1487 " gl_TessLevelOuter[1] = 1;\n"
1488 " gl_TessLevelOuter[2] = 1;\n"
1489 "}\n";
1490 std::stringstream cssName;
1491 cssName << "tesc_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1492
1493 programCollection.glslSources.add(cssName.str()) << glu::TessellationControlSource(css.str()) << buildOptions;
1494 }
1495
1496 {
1497 std::stringstream css;
1498 css <<
1499 "#version 460 core\n"
1500 "#extension GL_EXT_tessellation_shader : require\n"
1501 "#extension GL_EXT_ray_query : require\n"
1502 "layout(triangles, equal_spacing, ccw) in;\n"
1503 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1504 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1505 "void main (void)\n"
1506 "{\n"
1507 " for (int i = 0; i < 3; ++i)\n"
1508 " {\n"
1509 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1510 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1511 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1512 " imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1513 " imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1514 " }\n"
1515 " gl_Position = gl_in[0].gl_Position;\n"
1516 "}\n";
1517 std::stringstream cssName;
1518 cssName << "tese_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1519
1520 programCollection.glslSources.add(cssName.str()) << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1521 }
1522
1523 {
1524 std::stringstream css;
1525 css <<
1526 "#version 460 core\n"
1527 "#extension GL_EXT_tessellation_shader : require\n"
1528 "layout(triangles, equal_spacing, ccw) in;\n"
1529 "void main (void)\n"
1530 "{\n"
1531 " gl_Position = gl_in[0].gl_Position;\n"
1532 "}\n";
1533
1534 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1535 }
1536
1537 {
1538 std::stringstream css;
1539 css <<
1540 "#version 460 core\n"
1541 "#extension GL_EXT_ray_query : require\n"
1542 "layout(triangles) in;\n"
1543 "layout (triangle_strip, max_vertices = 4) out;\n"
1544 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1545 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1546 "\n"
1547 "in gl_PerVertex {\n"
1548 " vec4 gl_Position;\n"
1549 "} gl_in[];\n"
1550 "out gl_PerVertex {\n"
1551 " vec4 gl_Position;\n"
1552 "};\n"
1553 "void main (void)\n"
1554 "{\n"
1555 " for (int i = 0; i < gl_in.length(); ++i)\n"
1556 " {\n"
1557 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1558 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1559 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1560 " imageStore(result, ivec3(gl_PrimitiveIDIn, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1561 " imageStore(result, ivec3(gl_PrimitiveIDIn, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1562 " gl_Position = gl_in[i].gl_Position;\n"
1563 " EmitVertex();\n"
1564 " }\n"
1565 " EndPrimitive();\n"
1566 "}\n";
1567 std::stringstream cssName;
1568 cssName << "geom_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1569
1570 programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1571 }
1572
1573 {
1574 std::stringstream css;
1575 css <<
1576 "#version 460 core\n"
1577 "#extension GL_EXT_ray_query : require\n"
1578 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1579 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1580 "void main()\n"
1581 "{\n"
1582 " vec3 origin = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n"
1583 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1584 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1585 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1586 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1587 "}\n";
1588 std::stringstream cssName;
1589 cssName << "frag_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1590
1591 programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1592 }
1593 }
1594 else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1595 {
1596 {
1597 std::stringstream css;
1598 css <<
1599 "#version 460 core\n"
1600 "#extension GL_EXT_ray_query : require\n"
1601 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1602 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1603 "void main()\n"
1604 "{\n"
1605 " vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);\n"
1606 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1607 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1608 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1609 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1610 "}\n";
1611 std::stringstream cssName;
1612 cssName << "comp_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1613
1614 programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1615 }
1616 }
1617 else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1618 {
1619 {
1620 std::stringstream css;
1621 css <<
1622 "#version 460 core\n"
1623 "#extension GL_EXT_ray_tracing : require\n"
1624 "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1625 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1626 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1627 "void main()\n"
1628 "{\n"
1629 " float tmin = 0.0;\n"
1630 " float tmax = 1.0;\n"
1631 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1632 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
1633 " hitValue = uvec4(0,0,0,0);\n"
1634 " traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1635 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1636 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1637 "}\n";
1638 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1639 }
1640
1641 {
1642 std::stringstream css;
1643 css <<
1644 "#version 460 core\n"
1645 "#extension GL_EXT_ray_tracing : require\n"
1646 "#extension GL_EXT_ray_query : require\n"
1647 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1648 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1649 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1650 "void main()\n"
1651 "{\n"
1652 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1653 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1654 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1655 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1656 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1657 "}\n";
1658 std::stringstream cssName;
1659 cssName << "rgen_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1660
1661 programCollection.glslSources.add(cssName.str()) << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1662 }
1663
1664 {
1665 std::stringstream css;
1666 css <<
1667 "#version 460 core\n"
1668 "#extension GL_EXT_ray_tracing : require\n"
1669 "struct CallValue\n{\n"
1670 " vec3 origin;\n"
1671 " uvec4 hitValue;\n"
1672 "};\n"
1673 "layout(location = 0) callableDataEXT CallValue param;\n"
1674 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1675 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1676 "void main()\n"
1677 "{\n"
1678 " param.origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1679 " param.hitValue = uvec4(0, 0, 0, 0);\n"
1680 " executeCallableEXT(0, 0);\n"
1681 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
1682 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
1683 "}\n";
1684 programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1685 }
1686
1687 {
1688 std::stringstream css;
1689 css <<
1690 "#version 460 core\n"
1691 "#extension GL_EXT_ray_tracing : require\n"
1692 "hitAttributeEXT uvec4 hitValue;\n"
1693 "void main()\n"
1694 "{\n"
1695 " reportIntersectionEXT(0.5f, 0);\n"
1696 "}\n";
1697
1698 programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1699 }
1700
1701 {
1702 std::stringstream css;
1703 css <<
1704 "#version 460 core\n"
1705 "#extension GL_EXT_ray_tracing : require\n"
1706 "#extension GL_EXT_ray_query : require\n"
1707 "hitAttributeEXT uvec4 hitValue;\n"
1708 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1709 "void main()\n"
1710 "{\n"
1711 " vec3 origin = gl_WorldRayOriginEXT;\n"
1712 " hitValue = uvec4(0,0,0,0);\n" <<
1713 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1714 " reportIntersectionEXT(0.5f, 0);\n"
1715 "}\n";
1716 std::stringstream cssName;
1717 cssName << "isect_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1718
1719 programCollection.glslSources.add(cssName.str()) << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1720 }
1721
1722 {
1723 std::stringstream css;
1724 css <<
1725 "#version 460 core\n"
1726 "#extension GL_EXT_ray_tracing : require\n"
1727 "#extension GL_EXT_ray_query : require\n"
1728 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1729 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1730 "void main()\n"
1731 "{\n"
1732 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
1733 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1734 "}\n";
1735 std::stringstream cssName;
1736 cssName << "ahit_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1737
1738 programCollection.glslSources.add(cssName.str()) << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1739 }
1740
1741 {
1742 std::stringstream css;
1743 css <<
1744 "#version 460 core\n"
1745 "#extension GL_EXT_ray_tracing : require\n"
1746 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1747 "void main()\n"
1748 "{\n"
1749 " hitValue.y = 3;\n"
1750 "}\n";
1751
1752 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1753 }
1754
1755 {
1756 std::stringstream css;
1757 css <<
1758 "#version 460 core\n"
1759 "#extension GL_EXT_ray_tracing : require\n"
1760 "#extension GL_EXT_ray_query : require\n"
1761 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1762 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1763 "void main()\n"
1764 "{\n"
1765 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
1766 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1767 "}\n";
1768 std::stringstream cssName;
1769 cssName << "chit_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1770
1771 programCollection.glslSources.add(cssName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1772 }
1773
1774 {
1775 std::stringstream css;
1776 css <<
1777 "#version 460 core\n"
1778 "#extension GL_EXT_ray_tracing : require\n"
1779 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1780 "hitAttributeEXT uvec4 hitAttrib;\n"
1781 "void main()\n"
1782 "{\n"
1783 " hitValue = hitAttrib;\n"
1784 "}\n";
1785
1786 programCollection.glslSources.add("chit_isect") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1787 }
1788
1789 {
1790 std::stringstream css;
1791 css <<
1792 "#version 460 core\n"
1793 "#extension GL_EXT_ray_tracing : require\n"
1794 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1795 "void main()\n"
1796 "{\n"
1797 " hitValue.x = 4;\n"
1798 "}\n";
1799
1800 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1801 }
1802
1803 {
1804 std::stringstream css;
1805 css <<
1806 "#version 460 core\n"
1807 "#extension GL_EXT_ray_tracing : require\n"
1808 "#extension GL_EXT_ray_query : require\n"
1809 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1810 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1811 "void main()\n"
1812 "{\n"
1813 " vec3 origin = gl_WorldRayOriginEXT;\n" <<
1814 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1815 "}\n";
1816 std::stringstream cssName;
1817 cssName << "miss_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1818
1819 programCollection.glslSources.add(cssName.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1820 }
1821
1822 {
1823 std::stringstream css;
1824 css <<
1825 "#version 460 core\n"
1826 "#extension GL_EXT_ray_tracing : require\n"
1827 "#extension GL_EXT_ray_query : require\n"
1828 "struct CallValue\n{\n"
1829 " vec3 origin;\n"
1830 " uvec4 hitValue;\n"
1831 "};\n"
1832 "layout(location = 0) callableDataInEXT CallValue result;\n"
1833 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1834 "void main()\n"
1835 "{\n"
1836 " vec3 origin = result.origin;\n"
1837 " uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1838 rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1839 " result.hitValue = hitValue;\n"
1840 "}\n";
1841 std::stringstream cssName;
1842 cssName << "call_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1843
1844 programCollection.glslSources.add(cssName.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1845 }
1846 }
1847 }
1848
createInstance(Context & context) const1849 TestInstance* RayQueryTraversalControlTestCase::createInstance (Context& context) const
1850 {
1851 return new TraversalControlTestInstance(context, m_data);
1852 }
1853
TraversalControlTestInstance(Context & context,const TestParams & data)1854 TraversalControlTestInstance::TraversalControlTestInstance (Context& context, const TestParams& data)
1855 : vkt::TestInstance (context)
1856 , m_data (data)
1857 {
1858 }
1859
~TraversalControlTestInstance(void)1860 TraversalControlTestInstance::~TraversalControlTestInstance (void)
1861 {
1862 }
1863
iterate(void)1864 tcu::TestStatus TraversalControlTestInstance::iterate (void)
1865 {
1866 de::SharedPtr<TestConfiguration> testConfiguration;
1867
1868 switch (m_data.shaderSourcePipeline)
1869 {
1870 case SSP_GRAPHICS_PIPELINE:
1871 testConfiguration = de::SharedPtr<TestConfiguration>(new GraphicsConfiguration());
1872 break;
1873 case SSP_COMPUTE_PIPELINE:
1874 testConfiguration = de::SharedPtr<TestConfiguration>(new ComputeConfiguration());
1875 break;
1876 case SSP_RAY_TRACING_PIPELINE:
1877 testConfiguration = de::SharedPtr<TestConfiguration>(new RayTracingConfiguration());
1878 break;
1879 default:
1880 TCU_THROW(InternalError, "Wrong shader source pipeline");
1881 }
1882
1883 testConfiguration->initConfiguration(m_context, m_data);
1884
1885 const DeviceInterface& vkd = m_context.getDeviceInterface();
1886 const VkDevice device = m_context.getDevice();
1887 const VkQueue queue = m_context.getUniversalQueue();
1888 Allocator& allocator = m_context.getDefaultAllocator();
1889 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1890
1891 const VkFormat imageFormat = testConfiguration->getResultImageFormat();
1892 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
1893 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1894 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1895 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
1896
1897 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1898 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1899 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
1900 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
1901
1902 const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1903
1904 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
1905 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1906
1907 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > rayQueryBottomLevelAccelerationStructures;
1908 de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure;
1909
1910 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1911 {
1912 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1913 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1914 **image, imageSubresourceRange);
1915 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1916
1917 const VkClearValue clearValue = testConfiguration->getClearValue();
1918 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1919
1920 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1921 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1922 **image, imageSubresourceRange);
1923 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1924
1925 // build acceleration structures for ray query
1926 {
1927 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1928 bottomLevelAccelerationStructure->setGeometryCount(1);
1929
1930 de::SharedPtr<RaytracedGeometryBase> geometry;
1931 if (m_data.bottomType == BTT_TRIANGLES)
1932 {
1933 tcu::Vec3 v0(1.0f, float(m_data.height) - 1.0f, 0.0f);
1934 tcu::Vec3 v1(1.0f, 1.0f, 0.0f);
1935 tcu::Vec3 v2(float(m_data.width) - 1.0f, float(m_data.height) - 1.0f, 0.0f);
1936 tcu::Vec3 v3(float(m_data.width) - 1.0f, 1.0f, 0.0f);
1937
1938 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1939 geometry->addVertex(v0);
1940 geometry->addVertex(v1);
1941 geometry->addVertex(v2);
1942 geometry->addVertex(v2);
1943 geometry->addVertex(v1);
1944 geometry->addVertex(v3);
1945 }
1946 else // testParams.bottomType != BTT_TRIANGLES
1947 {
1948 tcu::Vec3 v0(1.0f, 1.0f, -0.1f);
1949 tcu::Vec3 v1(float(m_data.width) - 1.0f, float(m_data.height) - 1.0f, 0.1f);
1950
1951 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1952 geometry->addVertex(v0);
1953 geometry->addVertex(v1);
1954 }
1955 bottomLevelAccelerationStructure->addGeometry(geometry);
1956 rayQueryBottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1957 }
1958
1959 for (auto& blas : rayQueryBottomLevelAccelerationStructures)
1960 blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
1961
1962 rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1963 rayQueryTopLevelAccelerationStructure->setInstanceCount(1);
1964 rayQueryTopLevelAccelerationStructure->addInstance(rayQueryBottomLevelAccelerationStructures[0]);
1965 rayQueryTopLevelAccelerationStructure->createAndBuild(vkd, device, *cmdBuffer, allocator);
1966
1967 const TopLevelAccelerationStructure* rayQueryTopLevelAccelerationStructurePtr = rayQueryTopLevelAccelerationStructure.get();
1968 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1969 {
1970 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1971 DE_NULL, // const void* pNext;
1972 1u, // deUint32 accelerationStructureCount;
1973 rayQueryTopLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
1974 };
1975
1976 testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet, resultImageInfo);
1977
1978 const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1979 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1980 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
1981
1982 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
1983
1984 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1985 }
1986 endCommandBuffer(vkd, *cmdBuffer);
1987
1988 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1989
1990 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1991
1992 bool result = testConfiguration->verifyImage(resultBuffer.get(), m_context, m_data);
1993
1994 rayQueryTopLevelAccelerationStructure.clear();
1995 rayQueryBottomLevelAccelerationStructures.clear();
1996 testConfiguration.clear();
1997
1998 if (!result)
1999 return tcu::TestStatus::fail("Fail");
2000 return tcu::TestStatus::pass("Pass");
2001 }
2002
2003 } // anonymous
2004
createTraversalControlTests(tcu::TestContext & testCtx)2005 tcu::TestCaseGroup* createTraversalControlTests(tcu::TestContext& testCtx)
2006 {
2007 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "traversal_control", "Tests verifying traversal control in RT hit shaders"));
2008
2009 struct ShaderSourceTypeData
2010 {
2011 ShaderSourceType shaderSourceType;
2012 ShaderSourcePipeline shaderSourcePipeline;
2013 const char* name;
2014 } shaderSourceTypes[] =
2015 {
2016 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" },
2017 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" },
2018 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" },
2019 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", },
2020 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", },
2021 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", },
2022 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", },
2023 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", },
2024 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", },
2025 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", },
2026 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", },
2027 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", },
2028 };
2029
2030 struct ShaderTestTypeData
2031 {
2032 ShaderTestType shaderTestType;
2033 const char* name;
2034 } shaderTestTypes[] =
2035 {
2036 { STT_GENERATE_INTERSECTION, "generate_intersection" },
2037 { STT_SKIP_INTERSECTION, "skip_intersection" },
2038 };
2039
2040 struct
2041 {
2042 BottomTestType testType;
2043 const char* name;
2044 } bottomTestTypes[] =
2045 {
2046 { BTT_TRIANGLES, "triangles" },
2047 { BTT_AABBS, "aabbs" },
2048 };
2049
2050 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
2051 {
2052 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
2053
2054 for (size_t shaderTestNdx = 0; shaderTestNdx < DE_LENGTH_OF_ARRAY(shaderTestTypes); ++shaderTestNdx)
2055 {
2056 de::MovePtr<tcu::TestCaseGroup> testTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderTestTypes[shaderTestNdx].name, ""));
2057
2058 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
2059 {
2060 TestParams testParams
2061 {
2062 TEST_WIDTH,
2063 TEST_HEIGHT,
2064 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
2065 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
2066 shaderTestTypes[shaderTestNdx].shaderTestType,
2067 bottomTestTypes[testTypeNdx].testType
2068 };
2069 testTypeGroup->addChild(new RayQueryTraversalControlTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, "", testParams));
2070 }
2071 sourceTypeGroup->addChild(testTypeGroup.release());
2072 }
2073 group->addChild(sourceTypeGroup.release());
2074 }
2075
2076 return group.release();
2077 }
2078
2079 } // RayQuery
2080
2081 } // vkt
2082