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 Ray Tracing Callable Shader tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRayTracingCallableShadersTests.hpp"
25
26 #include "vkDefs.hpp"
27
28 #include "vktTestCase.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkBarrierUtil.hpp"
34 #include "vkBufferWithMemory.hpp"
35 #include "vkImageWithMemory.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "deRandom.hpp"
39 #include "tcuSurface.hpp"
40 #include "tcuTexture.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuTestLog.hpp"
43 #include "tcuImageCompare.hpp"
44
45 #include "vkRayTracingUtil.hpp"
46
47 namespace vkt
48 {
49 namespace RayTracing
50 {
51 namespace
52 {
53 using namespace vk;
54 using namespace vkt;
55
56 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
57 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
58 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
59 | VK_SHADER_STAGE_MISS_BIT_KHR
60 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
61 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
62
63 enum CallableShaderTestType
64 {
65 CSTT_RGEN_CALL = 0,
66 CSTT_RGEN_CALL_CALL = 1,
67 CSTT_HIT_CALL = 2,
68 CSTT_RGEN_MULTICALL = 3,
69 CSTT_COUNT
70 };
71
72 const deUint32 TEST_WIDTH = 8;
73 const deUint32 TEST_HEIGHT = 8;
74
75 struct TestParams;
76
77 class TestConfiguration
78 {
79 public:
80 virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (Context& context,
81 TestParams& testParams) = 0;
82 virtual de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (Context& context,
83 TestParams& testParams,
84 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) = 0;
85 virtual void initRayTracingShaders (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
86 Context& context,
87 TestParams& testParams) = 0;
88 virtual void initShaderBindingTables (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
89 Context& context,
90 TestParams& testParams,
91 VkPipeline pipeline,
92 deUint32 shaderGroupHandleSize,
93 deUint32 shaderGroupBaseAlignment,
94 de::MovePtr<BufferWithMemory>& raygenShaderBindingTable,
95 de::MovePtr<BufferWithMemory>& hitShaderBindingTable,
96 de::MovePtr<BufferWithMemory>& missShaderBindingTable,
97 de::MovePtr<BufferWithMemory>& callableShaderBindingTable,
98 VkStridedDeviceAddressRegionKHR& raygenShaderBindingTableRegion,
99 VkStridedDeviceAddressRegionKHR& hitShaderBindingTableRegion,
100 VkStridedDeviceAddressRegionKHR& missShaderBindingTableRegion,
101 VkStridedDeviceAddressRegionKHR& callableShaderBindingTableRegion) = 0;
102 virtual bool verifyImage (BufferWithMemory* resultBuffer,
103 Context& context,
104 TestParams& testParams) = 0;
105 virtual VkFormat getResultImageFormat () = 0;
106 virtual size_t getResultImageFormatSize () = 0;
107 virtual VkClearValue getClearValue () = 0;
108 };
109
110 struct TestParams
111 {
112 deUint32 width;
113 deUint32 height;
114 CallableShaderTestType callableShaderTestType;
115 de::SharedPtr<TestConfiguration> testConfiguration;
116 glu::ShaderType invokingShader;
117 bool multipleInvocations;
118 };
119
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)120 deUint32 getShaderGroupHandleSize (const InstanceInterface& vki,
121 const VkPhysicalDevice physicalDevice)
122 {
123 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
124
125 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
126 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
127 }
128
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)129 deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
130 const VkPhysicalDevice physicalDevice)
131 {
132 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
133
134 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
135 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
136 }
137
makeImageCreateInfo(deUint32 width,deUint32 height,VkFormat format)138 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, VkFormat format)
139 {
140 const VkImageCreateInfo imageCreateInfo =
141 {
142 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
143 DE_NULL, // const void* pNext;
144 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
145 VK_IMAGE_TYPE_2D, // VkImageType imageType;
146 format, // VkFormat format;
147 makeExtent3D(width, height, 1), // VkExtent3D extent;
148 1u, // deUint32 mipLevels;
149 1u, // deUint32 arrayLayers;
150 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
151 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
152 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
153 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
154 0u, // deUint32 queueFamilyIndexCount;
155 DE_NULL, // const deUint32* pQueueFamilyIndices;
156 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
157 };
158
159 return imageCreateInfo;
160 }
161
162 class SingleSquareConfiguration : public TestConfiguration
163 {
164 public:
165 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (Context& context,
166 TestParams& testParams) override;
167 de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (Context& context,
168 TestParams& testParams,
169 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) override;
170 void initRayTracingShaders (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
171 Context& context,
172 TestParams& testParams) override;
173 void initShaderBindingTables (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
174 Context& context,
175 TestParams& testParams,
176 VkPipeline pipeline,
177 deUint32 shaderGroupHandleSize,
178 deUint32 shaderGroupBaseAlignment,
179 de::MovePtr<BufferWithMemory>& raygenShaderBindingTable,
180 de::MovePtr<BufferWithMemory>& hitShaderBindingTable,
181 de::MovePtr<BufferWithMemory>& missShaderBindingTable,
182 de::MovePtr<BufferWithMemory>& callableShaderBindingTable,
183 VkStridedDeviceAddressRegionKHR& raygenShaderBindingTableRegion,
184 VkStridedDeviceAddressRegionKHR& hitShaderBindingTableRegion,
185 VkStridedDeviceAddressRegionKHR& missShaderBindingTableRegion,
186 VkStridedDeviceAddressRegionKHR& callableShaderBindingTableRegion) override;
187 bool verifyImage (BufferWithMemory* resultBuffer,
188 Context& context,
189 TestParams& testParams) override;
190 VkFormat getResultImageFormat () override;
191 size_t getResultImageFormatSize () override;
192 VkClearValue getClearValue () override;
193 };
194
initBottomAccelerationStructures(Context & context,TestParams & testParams)195 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > SingleSquareConfiguration::initBottomAccelerationStructures (Context& context,
196 TestParams& testParams)
197 {
198 DE_UNREF(context);
199
200 tcu::Vec3 v0(1.0, float(testParams.height) - 1.0f, 0.0);
201 tcu::Vec3 v1(1.0, 1.0, 0.0);
202 tcu::Vec3 v2(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0);
203 tcu::Vec3 v3(float(testParams.width) - 1.0f, 1.0, 0.0);
204
205 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > result;
206 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
207 bottomLevelAccelerationStructure->setGeometryCount(1);
208
209 de::SharedPtr<RaytracedGeometryBase> geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
210 geometry->addVertex(v0);
211 geometry->addVertex(v1);
212 geometry->addVertex(v2);
213 geometry->addVertex(v2);
214 geometry->addVertex(v1);
215 geometry->addVertex(v3);
216 bottomLevelAccelerationStructure->addGeometry(geometry);
217
218 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
219
220 return result;
221 }
222
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)223 de::MovePtr<TopLevelAccelerationStructure> SingleSquareConfiguration::initTopAccelerationStructure (Context& context,
224 TestParams& testParams,
225 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
226 {
227 DE_UNREF(context);
228 DE_UNREF(testParams);
229
230 de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure();
231 result->setInstanceCount(1);
232 result->addInstance(bottomLevelAccelerationStructures[0]);
233
234 return result;
235 }
236
initRayTracingShaders(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,Context & context,TestParams & testParams)237 void SingleSquareConfiguration::initRayTracingShaders (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
238 Context& context,
239 TestParams& testParams)
240 {
241 const DeviceInterface& vkd = context.getDeviceInterface();
242 const VkDevice device = context.getDevice();
243
244 switch (testParams.callableShaderTestType)
245 {
246 case CSTT_RGEN_CALL:
247 {
248 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen_call"), 0), 0);
249 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit"), 0), 1);
250 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss"), 0), 2);
251 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_0"), 0), 3);
252 break;
253 }
254 case CSTT_RGEN_CALL_CALL:
255 {
256 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen_call"), 0), 0);
257 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit"), 0), 1);
258 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss"), 0), 2);
259 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_call"), 0), 3);
260 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_0"), 0), 4);
261 break;
262 }
263 case CSTT_HIT_CALL:
264 {
265 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
266 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit_call"), 0), 1);
267 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss_call"), 0), 2);
268 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_0"), 0), 3);
269 break;
270 }
271 case CSTT_RGEN_MULTICALL:
272 {
273 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen_multicall"), 0), 0);
274 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit"), 0), 1);
275 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss"), 0), 2);
276 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_0"), 0), 3);
277 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_1"), 0), 4);
278 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_2"), 0), 5);
279 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_3"), 0), 6);
280 break;
281 }
282 default:
283 TCU_THROW(InternalError, "Wrong shader test type");
284 }
285 }
286
initShaderBindingTables(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,Context & context,TestParams & testParams,VkPipeline pipeline,deUint32 shaderGroupHandleSize,deUint32 shaderGroupBaseAlignment,de::MovePtr<BufferWithMemory> & raygenShaderBindingTable,de::MovePtr<BufferWithMemory> & hitShaderBindingTable,de::MovePtr<BufferWithMemory> & missShaderBindingTable,de::MovePtr<BufferWithMemory> & callableShaderBindingTable,VkStridedDeviceAddressRegionKHR & raygenShaderBindingTableRegion,VkStridedDeviceAddressRegionKHR & hitShaderBindingTableRegion,VkStridedDeviceAddressRegionKHR & missShaderBindingTableRegion,VkStridedDeviceAddressRegionKHR & callableShaderBindingTableRegion)287 void SingleSquareConfiguration::initShaderBindingTables (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
288 Context& context,
289 TestParams& testParams,
290 VkPipeline pipeline,
291 deUint32 shaderGroupHandleSize,
292 deUint32 shaderGroupBaseAlignment,
293 de::MovePtr<BufferWithMemory>& raygenShaderBindingTable,
294 de::MovePtr<BufferWithMemory>& hitShaderBindingTable,
295 de::MovePtr<BufferWithMemory>& missShaderBindingTable,
296 de::MovePtr<BufferWithMemory>& callableShaderBindingTable,
297 VkStridedDeviceAddressRegionKHR& raygenShaderBindingTableRegion,
298 VkStridedDeviceAddressRegionKHR& hitShaderBindingTableRegion,
299 VkStridedDeviceAddressRegionKHR& missShaderBindingTableRegion,
300 VkStridedDeviceAddressRegionKHR& callableShaderBindingTableRegion)
301 {
302 const DeviceInterface& vkd = context.getDeviceInterface();
303 const VkDevice device = context.getDevice();
304 Allocator& allocator = context.getDefaultAllocator();
305
306 switch (testParams.callableShaderTestType)
307 {
308 case CSTT_RGEN_CALL:
309 {
310 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
311 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
312 missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
313 callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
314
315 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
316 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
317 missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
318 callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
319 break;
320 }
321 case CSTT_RGEN_CALL_CALL:
322 {
323 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
324 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
325 missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
326 callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 2);
327
328 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
329 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
330 missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
331 callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, 2*shaderGroupHandleSize);
332 break;
333 }
334 case CSTT_HIT_CALL:
335 {
336 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
337 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
338 missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
339 callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
340
341 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
342 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
343 missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
344 callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
345 break;
346 }
347 case CSTT_RGEN_MULTICALL:
348 {
349 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
350 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
351 missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
352 callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 4);
353
354 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
355 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
356 missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
357 callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, 4*shaderGroupHandleSize);
358 break;
359 }
360 default:
361 TCU_THROW(InternalError, "Wrong shader test type");
362 }
363 }
364
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)365 bool SingleSquareConfiguration::verifyImage (BufferWithMemory* resultBuffer, Context& context, TestParams& testParams)
366 {
367 // create result image
368 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
369 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 1, resultBuffer->getAllocation().getHostPtr());
370
371 // create reference image
372 std::vector<deUint32> reference(testParams.width * testParams.height);
373 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 1, reference.data());
374
375 tcu::UVec4 missValue, hitValue;
376
377 // clear reference image with hit and miss values ( hit works only for tests calling traceRayEXT in rgen shader )
378 switch (testParams.callableShaderTestType)
379 {
380 case CSTT_RGEN_CALL:
381 missValue = tcu::UVec4(1, 0, 0, 0);
382 hitValue = tcu::UVec4(1, 0, 0, 0);
383 break;
384 case CSTT_RGEN_CALL_CALL:
385 missValue = tcu::UVec4(1, 0, 0, 0);
386 hitValue = tcu::UVec4(1, 0, 0, 0);
387 break;
388 case CSTT_HIT_CALL:
389 missValue = tcu::UVec4(1, 0, 0, 0);
390 hitValue = tcu::UVec4(2, 0, 0, 0);
391 break;
392 case CSTT_RGEN_MULTICALL:
393 missValue = tcu::UVec4(16, 0, 0, 0);
394 hitValue = tcu::UVec4(16, 0, 0, 0);
395 break;
396 default:
397 TCU_THROW(InternalError, "Wrong shader test type");
398 }
399
400 tcu::clear(referenceAccess, missValue);
401 for (deUint32 y = 1; y < testParams.width - 1; ++y)
402 for (deUint32 x = 1; x < testParams.height - 1; ++x)
403 referenceAccess.setPixel(hitValue, x, y);
404
405 // compare result and reference
406 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
407 }
408
getResultImageFormat()409 VkFormat SingleSquareConfiguration::getResultImageFormat ()
410 {
411 return VK_FORMAT_R32_UINT;
412 }
413
getResultImageFormatSize()414 size_t SingleSquareConfiguration::getResultImageFormatSize ()
415 {
416 return sizeof(deUint32);
417 }
418
getClearValue()419 VkClearValue SingleSquareConfiguration::getClearValue ()
420 {
421 return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
422 }
423
424 class CallableShaderTestCase : public TestCase
425 {
426 public:
427 CallableShaderTestCase (tcu::TestContext& context, const char* name, const TestParams data);
428 ~CallableShaderTestCase (void);
429
430 virtual void checkSupport (Context& context) const;
431 virtual void initPrograms (SourceCollections& programCollection) const;
432 virtual TestInstance* createInstance (Context& context) const;
433 private:
434 TestParams m_data;
435 };
436
437 class CallableShaderTestInstance : public TestInstance
438 {
439 public:
440 CallableShaderTestInstance (Context& context, const TestParams& data);
441 ~CallableShaderTestInstance (void);
442 tcu::TestStatus iterate (void);
443
444 protected:
445 de::MovePtr<BufferWithMemory> runTest ();
446 private:
447 TestParams m_data;
448 };
449
CallableShaderTestCase(tcu::TestContext & context,const char * name,const TestParams data)450 CallableShaderTestCase::CallableShaderTestCase (tcu::TestContext& context, const char* name, const TestParams data)
451 : vkt::TestCase (context, name)
452 , m_data (data)
453 {
454 }
455
~CallableShaderTestCase(void)456 CallableShaderTestCase::~CallableShaderTestCase (void)
457 {
458 }
459
checkSupport(Context & context) const460 void CallableShaderTestCase::checkSupport (Context& context) const
461 {
462 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
463 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
464
465 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
466 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
467 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
468
469 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
470 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
471 TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
472 }
473
initPrograms(SourceCollections & programCollection) const474 void CallableShaderTestCase::initPrograms (SourceCollections& programCollection) const
475 {
476 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
477 {
478 std::stringstream css;
479 css <<
480 "#version 460 core\n"
481 "#extension GL_EXT_ray_tracing : require\n"
482 "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
483 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
484 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
485 "\n"
486 "void main()\n"
487 "{\n"
488 " float tmin = 0.0;\n"
489 " float tmax = 1.0;\n"
490 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, 0.5f);\n"
491 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
492 " hitValue = uvec4(0,0,0,0);\n"
493 " traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
494 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), hitValue);\n"
495 "}\n";
496 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
497 }
498
499 {
500 std::stringstream css;
501 css <<
502 "#version 460 core\n"
503 "#extension GL_EXT_ray_tracing : require\n"
504 "layout(location = 0) callableDataEXT uvec4 value;\n"
505 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
506 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
507 "\n"
508 "void main()\n"
509 "{\n"
510 " executeCallableEXT(0, 0);\n"
511 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), value);\n"
512 "}\n";
513 programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
514 }
515
516 {
517 std::stringstream css;
518 css <<
519 "#version 460 core\n"
520 "#extension GL_EXT_ray_tracing : require\n"
521 "struct CallValue\n"
522 "{\n"
523 " ivec4 a;\n"
524 " vec4 b;\n"
525 "};\n"
526 "layout(location = 0) callableDataEXT uvec4 value0;\n"
527 "layout(location = 1) callableDataEXT uint value1;\n"
528 "layout(location = 2) callableDataEXT CallValue value2;\n"
529 "layout(location = 4) callableDataEXT vec3 value3;\n"
530 "layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
531 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
532 "\n"
533 "void main()\n"
534 "{\n"
535 " executeCallableEXT(0, 0);\n"
536 " executeCallableEXT(1, 1);\n"
537 " executeCallableEXT(2, 2);\n"
538 " executeCallableEXT(3, 4);\n"
539 " uint resultValue = value0.x + value1 + value2.a.x * uint(floor(value2.b.y)) + uint(floor(value3.z));\n"
540 " imageStore(result, ivec2(gl_LaunchIDEXT.xy), uvec4(resultValue, 0, 0, 0));\n"
541 "}\n";
542 programCollection.glslSources.add("rgen_multicall") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
543 }
544
545 {
546 std::stringstream css;
547 css <<
548 "#version 460 core\n"
549 "#extension GL_EXT_ray_tracing : require\n"
550 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
551 "void main()\n"
552 "{\n"
553 " hitValue = uvec4(1,0,0,1);\n"
554 "}\n";
555
556 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
557 }
558
559 {
560 std::stringstream css;
561 css <<
562 "#version 460 core\n"
563 "#extension GL_EXT_ray_tracing : require\n"
564 "layout(location = 0) callableDataEXT uvec4 value;\n"
565 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
566 "void main()\n"
567 "{\n"
568 " executeCallableEXT(0, 0);\n"
569 " hitValue = value;\n"
570 " hitValue.x = hitValue.x + 1;\n"
571 "}\n";
572
573 programCollection.glslSources.add("chit_call") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
574 }
575
576 {
577 std::stringstream css;
578 css <<
579 "#version 460 core\n"
580 "#extension GL_EXT_ray_tracing : require\n"
581 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
582 "void main()\n"
583 "{\n"
584 " hitValue = uvec4(0,0,0,1);\n"
585 "}\n";
586
587 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
588 }
589
590 {
591 std::stringstream css;
592 css <<
593 "#version 460 core\n"
594 "#extension GL_EXT_ray_tracing : require\n"
595 "layout(location = 0) callableDataEXT uvec4 value;\n"
596 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
597 "void main()\n"
598 "{\n"
599 " executeCallableEXT(0, 0);\n"
600 " hitValue = value;\n"
601 "}\n";
602
603 programCollection.glslSources.add("miss_call") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
604 }
605
606 std::vector<std::string> callableDataDefinition =
607 {
608 "layout(location = 0) callableDataInEXT uvec4 result;\n",
609 "layout(location = 1) callableDataInEXT uint result;\n",
610 "struct CallValue\n{\n ivec4 a;\n vec4 b;\n};\nlayout(location = 2) callableDataInEXT CallValue result;\n",
611 "layout(location = 4) callableDataInEXT vec3 result;\n"
612 };
613
614 std::vector<std::string> callableDataComputation =
615 {
616 " result = uvec4(1,0,0,1);\n",
617 " result = 2;\n",
618 " result.a = ivec4(3,0,0,1);\n result.b = vec4(1.0, 3.2, 0.0, 1);\n",
619 " result = vec3(0.0, 0.0, 4.3);\n",
620 };
621
622 for (deUint32 idx = 0; idx < callableDataDefinition.size(); ++idx)
623 {
624 std::stringstream css;
625 css <<
626 "#version 460 core\n"
627 "#extension GL_EXT_ray_tracing : require\n"
628 << callableDataDefinition[idx] <<
629 "void main()\n"
630 "{\n"
631 << callableDataComputation[idx] <<
632 "}\n";
633 std::stringstream csname;
634 csname << "call_" << idx;
635
636 programCollection.glslSources.add(csname.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
637 }
638
639 {
640 std::stringstream css;
641 css <<
642 "#version 460 core\n"
643 "#extension GL_EXT_ray_tracing : require\n"
644 "layout(location = 0) callableDataInEXT uvec4 result;\n"
645 "layout(location = 1) callableDataEXT uvec4 info;\n"
646 "void main()\n"
647 "{\n"
648 " executeCallableEXT(1, 1);\n"
649 " result = info;\n"
650 "}\n";
651
652 programCollection.glslSources.add("call_call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
653 }
654 }
655
createInstance(Context & context) const656 TestInstance* CallableShaderTestCase::createInstance (Context& context) const
657 {
658 return new CallableShaderTestInstance(context, m_data);
659 }
660
CallableShaderTestInstance(Context & context,const TestParams & data)661 CallableShaderTestInstance::CallableShaderTestInstance (Context& context, const TestParams& data)
662 : vkt::TestInstance (context)
663 , m_data (data)
664 {
665 }
666
~CallableShaderTestInstance(void)667 CallableShaderTestInstance::~CallableShaderTestInstance (void)
668 {
669 }
670
runTest()671 de::MovePtr<BufferWithMemory> CallableShaderTestInstance::runTest ()
672 {
673 const InstanceInterface& vki = m_context.getInstanceInterface();
674 const DeviceInterface& vkd = m_context.getDeviceInterface();
675 const VkDevice device = m_context.getDevice();
676 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
677 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
678 const VkQueue queue = m_context.getUniversalQueue();
679 Allocator& allocator = m_context.getDefaultAllocator();
680 const deUint32 pixelCount = m_data.width * m_data.height * 1;
681
682 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
683 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
684 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
685 .build(vkd, device);
686 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
687 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
688 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
689 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
690 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
691 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
692
693 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
694 m_data.testConfiguration->initRayTracingShaders(rayTracingPipeline, m_context, m_data);
695 Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
696
697 de::MovePtr<BufferWithMemory> raygenShaderBindingTable;
698 de::MovePtr<BufferWithMemory> hitShaderBindingTable;
699 de::MovePtr<BufferWithMemory> missShaderBindingTable;
700 de::MovePtr<BufferWithMemory> callableShaderBindingTable;
701 VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion;
702 VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion;
703 VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion;
704 VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion;
705 m_data.testConfiguration->initShaderBindingTables(rayTracingPipeline, m_context, m_data, *pipeline, getShaderGroupHandleSize(vki, physicalDevice), getShaderGroupBaseAlignment(vki, physicalDevice), raygenShaderBindingTable, hitShaderBindingTable, missShaderBindingTable, callableShaderBindingTable, raygenShaderBindingTableRegion, hitShaderBindingTableRegion, missShaderBindingTableRegion, callableShaderBindingTableRegion);
706
707 const VkFormat imageFormat = m_data.testConfiguration->getResultImageFormat();
708 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, imageFormat);
709 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
710 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
711 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_2D, imageFormat, imageSubresourceRange);
712
713 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(pixelCount*m_data.testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
714 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
715 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 1), resultBufferImageSubresourceLayers);
716 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
717
718 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
719
720 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
721 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
722
723 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelAccelerationStructures;
724 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
725
726 beginCommandBuffer(vkd, *cmdBuffer, 0u);
727 {
728 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
729 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
730 **image, imageSubresourceRange);
731 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
732
733 const VkClearValue clearValue = m_data.testConfiguration->getClearValue();
734 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
735
736 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
737 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
738 **image, imageSubresourceRange);
739 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
740
741 bottomLevelAccelerationStructures = m_data.testConfiguration->initBottomAccelerationStructures(m_context, m_data);
742 for (auto& blas : bottomLevelAccelerationStructures)
743 blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
744 topLevelAccelerationStructure = m_data.testConfiguration->initTopAccelerationStructure(m_context, m_data, bottomLevelAccelerationStructures);
745 topLevelAccelerationStructure->createAndBuild(vkd, device, *cmdBuffer, allocator);
746
747 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
748 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
749 {
750 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
751 DE_NULL, // const void* pNext;
752 1u, // deUint32 accelerationStructureCount;
753 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
754 };
755
756 DescriptorSetUpdateBuilder()
757 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
758 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
759 .update(vkd, device);
760
761 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
762
763 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
764
765 cmdTraceRays(vkd,
766 *cmdBuffer,
767 &raygenShaderBindingTableRegion,
768 &missShaderBindingTableRegion,
769 &hitShaderBindingTableRegion,
770 &callableShaderBindingTableRegion,
771 m_data.width, m_data.height, 1);
772
773 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
774 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
775 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
776
777 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
778
779 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
780 }
781 endCommandBuffer(vkd, *cmdBuffer);
782
783 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
784
785 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
786
787 return resultBuffer;
788 }
789
iterate(void)790 tcu::TestStatus CallableShaderTestInstance::iterate (void)
791 {
792 // run test using arrays of pointers
793 const de::MovePtr<BufferWithMemory> buffer = runTest();
794
795 if (!m_data.testConfiguration->verifyImage(buffer.get(), m_context, m_data))
796 return tcu::TestStatus::fail("Fail");
797 return tcu::TestStatus::pass("Pass");
798 }
799
800 constexpr deUint32 callableDataUintLoc = 0;
801 constexpr deUint32 callableDataFloatLoc = 1;
802 constexpr deUint32 callableDataUintOutLoc = 2;
803
804 struct CallableBuffer0
805 {
806 deUint32 base;
807 deUint32 shift;
808 deUint32 offset;
809 deUint32 multiplier;
810 };
811
812 struct CallableBuffer1
813 {
814 float numerator;
815 float denomenator;
816 deUint32 power;
817 };
818
819 struct Ray
820 {
Rayvkt::RayTracing::__anon8d855eb60111::Ray821 Ray() : o(0.0f), tmin(0.0f), d(0.0f), tmax(0.0f){}
Rayvkt::RayTracing::__anon8d855eb60111::Ray822 Ray(const tcu::Vec3& io, float imin, const tcu::Vec3& id, float imax): o(io), tmin(imin), d(id), tmax(imax){}
823 tcu::Vec3 o;
824 float tmin;
825 tcu::Vec3 d;
826 float tmax;
827 };
828
829 constexpr float MAX_T_VALUE = 1000.0f;
830
AddVertexLayers(std::vector<tcu::Vec3> * pVerts,deUint32 newLayers)831 void AddVertexLayers(std::vector<tcu::Vec3>* pVerts, deUint32 newLayers)
832 {
833 size_t vertsPerLayer = pVerts->size();
834 size_t totalLayers = 1 + newLayers;
835
836 pVerts->reserve(pVerts->size() * totalLayers);
837
838 for (size_t layer = 0; layer < newLayers; ++layer)
839 {
840 for (size_t vert = 0; vert < vertsPerLayer; ++vert)
841 {
842 bool flippedLayer = (layer % 2) == 0;
843 tcu::Vec3 stage = (*pVerts)[flippedLayer ? (vertsPerLayer - vert - 1) : vert];
844 ++stage.z();
845
846 pVerts->push_back(stage);
847 }
848 }
849 }
850
compareFloat(float actual,float expected)851 bool compareFloat(float actual, float expected)
852 {
853 constexpr float eps = 0.01f;
854 bool success = true;
855
856 if (abs(expected - actual) > eps)
857 {
858 success = false;
859 }
860
861 return success;
862 }
863
864 class InvokeCallableShaderTestCase : public TestCase
865 {
866 public:
867 InvokeCallableShaderTestCase (tcu::TestContext& context, const char* name, const TestParams& data);
868 ~InvokeCallableShaderTestCase (void);
869
870 virtual void checkSupport (Context& context) const;
871 virtual void initPrograms (SourceCollections& programCollection) const;
872 virtual TestInstance* createInstance (Context& context) const;
873 private:
874 TestParams params;
875 };
876
877 class InvokeCallableShaderTestInstance : public TestInstance
878 {
879 public:
880 InvokeCallableShaderTestInstance (Context& context, const TestParams& data);
881 ~InvokeCallableShaderTestInstance (void);
882 tcu::TestStatus iterate (void);
883
884 private:
885 TestParams params;
886 };
887
InvokeCallableShaderTestCase(tcu::TestContext & context,const char * name,const TestParams & data)888 InvokeCallableShaderTestCase::InvokeCallableShaderTestCase (tcu::TestContext& context, const char* name, const TestParams& data)
889 : vkt::TestCase (context, name)
890 , params (data)
891 {
892 }
893
~InvokeCallableShaderTestCase(void)894 InvokeCallableShaderTestCase::~InvokeCallableShaderTestCase (void)
895 {
896 }
897
checkSupport(Context & context) const898 void InvokeCallableShaderTestCase::checkSupport (Context& context) const
899 {
900 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
901 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
902
903 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
904 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
905 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
906
907 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
908 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
909 TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
910 }
911
912 //resultData:
913 // x - value0
914 // y - value1
915 // z - value2
916 // w - closestT
verifyResultData(const tcu::Vec4 * resultData,deUint32 index,bool hit,const TestParams & params)917 bool verifyResultData(const tcu::Vec4* resultData, deUint32 index, bool hit, const TestParams& params)
918 {
919 bool success = true;
920
921 float refValue0 = 0.0f;
922 float refValue1 = 0.0f;
923 float refValue2 = 0.0f;
924
925 if (hit)
926 {
927 switch (params.invokingShader)
928 {
929 case glu::SHADERTYPE_RAYGEN :
930 case glu::SHADERTYPE_CLOSEST_HIT:
931 case glu::SHADERTYPE_CALLABLE:
932 refValue0 = 133.0f;
933 break;
934 case glu::SHADERTYPE_MISS:
935 break;
936 default:
937 TCU_THROW(InternalError, "Wrong shader invoking type");
938 break;
939 }
940
941 if (params.multipleInvocations)
942 {
943 switch (params.invokingShader)
944 {
945 case glu::SHADERTYPE_RAYGEN:
946 refValue1 = 17.64f;
947 refValue2 = 35.28f;
948 break;
949 case glu::SHADERTYPE_CLOSEST_HIT:
950 refValue1 = 17.64f;
951 refValue2 = index < 4 ? 35.28f : 8.82f;
952 break;
953 case glu::SHADERTYPE_CALLABLE:
954 refValue1 = 17.64f;
955 refValue2 = index < 6 ? 35.28f : 8.82f;
956 break;
957 case glu::SHADERTYPE_MISS:
958 break;
959 default:
960 TCU_THROW(InternalError, "Wrong shader invoking type");
961 break;
962 }
963 }
964
965 if (resultData->w() != 2.0f)
966 {
967 success = false;
968 }
969 }
970
971 if (!hit)
972 {
973 switch (params.invokingShader)
974 {
975 case glu::SHADERTYPE_RAYGEN:
976 case glu::SHADERTYPE_MISS:
977 case glu::SHADERTYPE_CALLABLE:
978 refValue0 = 133.0f;
979 break;
980 case glu::SHADERTYPE_CLOSEST_HIT:
981 break;
982 default:
983 TCU_THROW(InternalError, "Wrong shader invoking type");
984 break;
985 }
986
987 if (params.multipleInvocations)
988 {
989 switch (params.invokingShader)
990 {
991 case glu::SHADERTYPE_RAYGEN:
992 refValue1 = 17.64f;
993 refValue2 = 8.82f;
994 break;
995 case glu::SHADERTYPE_MISS:
996 refValue1 = 17.64f;
997 refValue2 = index < 10 ? 35.28f : 8.82f;
998 break;
999 case glu::SHADERTYPE_CALLABLE:
1000 refValue1 = 17.64f;
1001 refValue2 = index < 6 ? 35.28f : 8.82f;
1002 break;
1003 case glu::SHADERTYPE_CLOSEST_HIT:
1004 break;
1005 default:
1006 TCU_THROW(InternalError, "Wrong shader invoking type");
1007 break;
1008 }
1009 }
1010
1011 if (resultData->w() != MAX_T_VALUE)
1012 {
1013 success = false;
1014 }
1015 }
1016
1017 if ((!compareFloat(resultData->x(), refValue0)) ||
1018 (!compareFloat(resultData->y(), refValue1)) ||
1019 (!compareFloat(resultData->z(), refValue2)))
1020 {
1021 success = false;
1022 }
1023
1024 return success;
1025 }
1026
getRayGenSource(bool invokeCallable,bool multiInvoke)1027 std::string getRayGenSource(bool invokeCallable, bool multiInvoke)
1028 {
1029 std::ostringstream src;
1030 src <<
1031 "struct Payload { uint lastShader; float closestT; };\n"
1032 "layout(location = 0) rayPayloadEXT Payload payload;\n";
1033
1034 if (invokeCallable)
1035 {
1036 src <<
1037 "#define CALLABLE_DATA_UINT_LOC " << callableDataUintLoc << "\n"
1038 "layout(location = CALLABLE_DATA_UINT_LOC) callableDataEXT uint callableDataUint;\n";
1039
1040 if (multiInvoke)
1041 {
1042 src <<
1043 "#define CALLABLE_DATA_FLOAT_LOC " << callableDataFloatLoc << "\n"
1044 "layout(location = CALLABLE_DATA_FLOAT_LOC) callableDataEXT float callableDataFloat;\n";
1045 }
1046 }
1047
1048 src <<
1049 "void main() {\n"
1050 " uint index = launchIndex();\n"
1051 " Ray ray = rays[index];\n"
1052 " results[index].value0 = 0;\n"
1053 " results[index].value1 = 0;\n"
1054 " results[index].value2 = 0;\n";
1055
1056 if (invokeCallable)
1057 {
1058 src <<
1059 " callableDataUint = " << "0" << ";\n"
1060 " executeCallableEXT(0, CALLABLE_DATA_UINT_LOC);\n"
1061 " results[index].value0 = float(callableDataUint);\n";
1062
1063 if (multiInvoke)
1064 {
1065 src <<
1066 " callableDataFloat = 0.0;\n"
1067 " executeCallableEXT(1, CALLABLE_DATA_FLOAT_LOC);\n"
1068 " results[index].value1 = callableDataFloat;\n";
1069 }
1070 }
1071
1072 src <<
1073 " payload.lastShader = " << glu::SHADERTYPE_RAYGEN << ";\n"
1074 " payload.closestT = " << MAX_T_VALUE << ";\n"
1075 " traceRayEXT(scene, 0x0, 0xff, 0, 0, 0, ray.pos, " << "ray.tmin" << ", ray.dir, ray.tmax, 0);\n";
1076
1077 if (invokeCallable && multiInvoke)
1078 {
1079 src <<
1080 " executeCallableEXT(payload.lastShader == " << glu::SHADERTYPE_CLOSEST_HIT << " ? 1 : 2, CALLABLE_DATA_FLOAT_LOC);\n"
1081 " results[index].value2 = callableDataFloat;\n";
1082 }
1083
1084 src <<
1085 " results[index].closestT = payload.closestT;\n"
1086 "}";
1087
1088 return src.str();
1089 }
1090
getClosestHitSource(bool invokeCallable,bool multiInvoke)1091 std::string getClosestHitSource(bool invokeCallable, bool multiInvoke)
1092 {
1093 std::ostringstream src;
1094 src <<
1095 "struct Payload { uint lastShader; float closestT; };\n"
1096 "layout(location = 0) rayPayloadInEXT Payload payload;\n";
1097
1098 if (invokeCallable)
1099 {
1100 src <<
1101 "#define CALLABLE_DATA_UINT_LOC " << callableDataUintLoc << "\n"
1102 "layout(location = CALLABLE_DATA_UINT_LOC) callableDataEXT uint callableDataUint;\n";
1103
1104 if (multiInvoke)
1105 {
1106 src <<
1107 "#define CALLABLE_DATA_FLOAT_LOC " << callableDataFloatLoc << "\n"
1108 "layout(location = CALLABLE_DATA_FLOAT_LOC) callableDataEXT float callableDataFloat;\n";
1109 }
1110 }
1111
1112 src <<
1113 "void main() {\n"
1114 " payload.lastShader = " << glu::SHADERTYPE_CLOSEST_HIT << ";\n"
1115 " payload.closestT = gl_HitTEXT;\n";
1116
1117 if (invokeCallable)
1118 {
1119 src <<
1120 " uint index = launchIndex();\n"
1121 " callableDataUint = 0;\n"
1122 " executeCallableEXT(0, CALLABLE_DATA_UINT_LOC);\n"
1123 " results[index].value0 = float(callableDataUint);\n";
1124
1125 if (multiInvoke)
1126 {
1127 src <<
1128 " callableDataFloat = 0.0;\n"
1129 " executeCallableEXT(1, CALLABLE_DATA_FLOAT_LOC);\n"
1130 " results[index].value1 = callableDataFloat;\n"
1131 " executeCallableEXT(index < 4 ? 1 : 2, CALLABLE_DATA_FLOAT_LOC);\n"
1132 " results[index].value2 = callableDataFloat;\n";
1133 }
1134 }
1135
1136 src <<
1137 "}";
1138
1139 return src.str();
1140 }
1141
getMissSource(bool invokeCallable,bool multiInvoke)1142 std::string getMissSource(bool invokeCallable, bool multiInvoke)
1143 {
1144 std::ostringstream src;
1145 src <<
1146 "struct Payload { uint lastShader; float closestT; };\n"
1147 "layout(location = 0) rayPayloadInEXT Payload payload;\n";
1148
1149 if (invokeCallable)
1150 {
1151 src <<
1152 "#define CALLABLE_DATA_UINT_LOC " << callableDataUintLoc << "\n"
1153 "layout(location = CALLABLE_DATA_UINT_LOC) callableDataEXT uint callableDataUint;\n";
1154
1155 if (multiInvoke)
1156 {
1157 src <<
1158 "#define CALLABLE_DATA_FLOAT_LOC " << callableDataFloatLoc << "\n"
1159 "layout(location = CALLABLE_DATA_FLOAT_LOC) callableDataEXT float callableDataFloat;\n";
1160 }
1161 }
1162
1163 src <<
1164 "void main() {\n"
1165 " payload.lastShader = " << glu::SHADERTYPE_MISS << ";\n";
1166
1167 if (invokeCallable)
1168 {
1169 src <<
1170 " uint index = launchIndex();\n"
1171 " callableDataUint = 0;\n"
1172 " executeCallableEXT(0, CALLABLE_DATA_UINT_LOC);\n"
1173 " results[index].value0 = float(callableDataUint);\n";
1174
1175 if (multiInvoke)
1176 {
1177 src <<
1178 " callableDataFloat = 0.0;\n"
1179 " executeCallableEXT(1, CALLABLE_DATA_FLOAT_LOC);\n"
1180 " results[index].value1 = callableDataFloat;\n"
1181 " executeCallableEXT(index < 10 ? 1 : 2, CALLABLE_DATA_FLOAT_LOC);\n"
1182 " results[index].value2 = callableDataFloat;\n";
1183 }
1184 }
1185
1186 src <<
1187 "}";
1188
1189 return src.str();
1190 }
1191
getCallableSource(bool invokeCallable,bool multiInvoke)1192 std::string getCallableSource(bool invokeCallable, bool multiInvoke)
1193 {
1194 std::ostringstream src;
1195 src <<
1196 "#define CALLABLE_DATA_UINT_LOC " << callableDataUintLoc << "\n"
1197 "layout(location = CALLABLE_DATA_UINT_LOC) callableDataInEXT uint callableDataUintIn;\n";
1198
1199 if (invokeCallable)
1200 {
1201 src << "#define CALLABLE_DATA_UINT_OUT_LOC " << callableDataUintOutLoc << "\n"
1202 << "layout(location = CALLABLE_DATA_UINT_OUT_LOC) callableDataEXT uint callableDataUint;\n";
1203
1204 if (multiInvoke)
1205 {
1206 src <<
1207 "#define CALLABLE_DATA_FLOAT_LOC " << callableDataFloatLoc << "\n"
1208 "layout(location = CALLABLE_DATA_FLOAT_LOC) callableDataEXT float callableDataFloat;\n";
1209 }
1210 }
1211
1212 src <<
1213 "void main() {\n";
1214
1215 if (invokeCallable)
1216 {
1217 src <<
1218 " uint index = launchIndex();\n"
1219 " callableDataUint = 0;\n"
1220 " executeCallableEXT(1, CALLABLE_DATA_UINT_OUT_LOC);\n"
1221 " callableDataUintIn = callableDataUint;\n";
1222
1223 if (multiInvoke)
1224 {
1225 src <<
1226 " callableDataFloat = 0.0;\n"
1227 " executeCallableEXT(2, CALLABLE_DATA_FLOAT_LOC);\n"
1228 " results[index].value1 = callableDataFloat;\n"
1229 " executeCallableEXT(index < 6 ? 2 : 3, CALLABLE_DATA_FLOAT_LOC);\n"
1230 " results[index].value2 = callableDataFloat;\n";
1231 }
1232 }
1233
1234 src <<
1235 "}";
1236
1237 return src.str();
1238 }
1239
1240 constexpr deUint32 DefaultResultBinding = 0;
1241 constexpr deUint32 DefaultSceneBinding = 1;
1242 constexpr deUint32 DefaultRaysBinding = 2;
1243
1244 enum ShaderSourceFlag
1245 {
1246 DEFINE_RAY = 0x1,
1247 DEFINE_RESULT_BUFFER = 0x2,
1248 DEFINE_SCENE = 0x4,
1249 DEFINE_RAY_BUFFER = 0x8,
1250 DEFINE_SIMPLE_BINDINGS = DEFINE_RESULT_BUFFER | DEFINE_SCENE | DEFINE_RAY_BUFFER
1251 };
1252
generateShaderSource(const char * body,const char * resultType="",deUint32 flags=0,const char * prefix="")1253 static inline std::string generateShaderSource(const char* body, const char* resultType = "", deUint32 flags = 0, const char* prefix = "")
1254 {
1255 std::ostringstream src;
1256 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n";
1257
1258 src << "#extension GL_EXT_ray_tracing : enable\n";
1259
1260 src << prefix << "\n";
1261
1262 if (flags & DEFINE_SIMPLE_BINDINGS)
1263 flags |= DEFINE_RAY_BUFFER;
1264
1265 if (flags & DEFINE_RAY_BUFFER)
1266 flags |= DEFINE_RAY;
1267
1268 if (flags & DEFINE_RAY)
1269 {
1270 src << "struct Ray { vec3 pos; float tmin; vec3 dir; float tmax; };\n";
1271 }
1272
1273 if (flags & DEFINE_RESULT_BUFFER)
1274 src << "layout(std430, set = 0, binding = " << DefaultResultBinding << ") buffer Results { " << resultType << " results[]; };\n";
1275
1276 if (flags & DEFINE_SCENE)
1277 {
1278 src << "layout(set = 0, binding = " << DefaultSceneBinding << ") uniform accelerationStructureEXT scene;\n";
1279 }
1280
1281 if (flags & DEFINE_RAY_BUFFER)
1282 src << "layout(std430, set = 0, binding = " << DefaultRaysBinding << ") buffer Rays { Ray rays[]; };\n";
1283
1284 src << "uint launchIndex() { return gl_LaunchIDEXT.z*gl_LaunchSizeEXT.x*gl_LaunchSizeEXT.y + gl_LaunchIDEXT.y*gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x; }\n";
1285
1286 src << body;
1287
1288 return src.str();
1289 }
1290
addShaderSource(SourceCollections & programCollection,const char * identifier,const char * body,const char * resultType="",deUint32 flags=0,const char * prefix="",deUint32 validatorOptions=0U)1291 template<typename T> inline void addShaderSource(SourceCollections& programCollection, const char* identifier,
1292 const char* body, const char* resultType = "", deUint32 flags = 0,
1293 const char* prefix = "", deUint32 validatorOptions = 0U)
1294 {
1295 std::string text = generateShaderSource(body, resultType, flags, prefix);
1296
1297 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, validatorOptions, true);
1298 programCollection.glslSources.add(identifier) << T(text) << buildOptions;
1299 }
1300
1301
1302
initPrograms(SourceCollections & programCollection) const1303 void InvokeCallableShaderTestCase::initPrograms (SourceCollections& programCollection) const
1304 {
1305 addShaderSource<glu::RaygenSource>(programCollection, "build-raygen",
1306 getRayGenSource(false, false).c_str(), "Result", DEFINE_RAY_BUFFER | DEFINE_SIMPLE_BINDINGS,
1307 "struct Result { float value0; float value1; float value2; float closestT;};");
1308
1309 addShaderSource<glu::RaygenSource>(programCollection, "build-raygen-invoke-callable",
1310 getRayGenSource(true, false).c_str(), "Result", DEFINE_RAY_BUFFER | DEFINE_SIMPLE_BINDINGS,
1311 "struct Result { float value0; float value1; float value2; float closestT;};");
1312
1313 addShaderSource<glu::ClosestHitSource>(programCollection, "build-closesthit",
1314 getClosestHitSource(false, false).c_str(), "", 0, "");
1315
1316 addShaderSource<glu::MissSource>(programCollection, "build-miss",
1317 getMissSource(false, false).c_str(), "", 0, "");
1318
1319 const std::string RAY_PAYLOAD = "rayPayloadEXT";
1320 const std::string TRACE_RAY = "traceRayEXT";
1321 const std::string RAY_PAYLOAD_IN = "rayPayloadInEXT";
1322 const std::string HIT_ATTRIBUTE = "hitAttributeEXT";
1323 const std::string REPORT_INTERSECTION = "reportIntersectionEXT";
1324
1325 const std::string SHADER_RECORD = "shaderRecordEXT";
1326 const std::string CALLABLE_DATA_IN = "callableDataInEXT";
1327 const std::string CALLABLE_DATA = "callableDataEXT";
1328 const std::string EXECUTE_CALLABE = "executeCallableEXT";
1329
1330 std::ostringstream src;
1331 src <<
1332 "#define CALLABLE_DATA_UINT_LOC " << callableDataUintLoc << "\n"
1333 "layout(location = CALLABLE_DATA_UINT_LOC) callableDataInEXT uint callableDataUint;\n"
1334 "layout(" << SHADER_RECORD << ") buffer callableBuffer\n"
1335 "{\n"
1336 " uint base;\n"
1337 " uint shift;\n"
1338 " uint offset;\n"
1339 " uint multiplier;\n"
1340 "};\n"
1341 "void main() {\n"
1342 " callableDataUint += ((base << shift) + offset) * multiplier;\n"
1343 "}";
1344
1345 addShaderSource<glu::CallableSource>(programCollection, "build-callable-0", src.str().c_str(),
1346 "", 0, "");
1347
1348 if (params.multipleInvocations)
1349 {
1350 switch (params.invokingShader)
1351 {
1352 case glu::SHADERTYPE_RAYGEN:
1353 addShaderSource<glu::RaygenSource>(programCollection, "build-raygen-invoke-callable-multi",
1354 getRayGenSource(true, true).c_str(), "Result", DEFINE_RAY_BUFFER | DEFINE_SIMPLE_BINDINGS,
1355 "struct Result { float value0; float value1; float value2; float closestT;};");
1356
1357 break;
1358 case glu::SHADERTYPE_CLOSEST_HIT:
1359 addShaderSource<glu::ClosestHitSource>(programCollection, "build-closesthit-invoke-callable-multi",
1360 getClosestHitSource(true, true).c_str(), "Result", DEFINE_RESULT_BUFFER,
1361 "struct Result { float value0; float value1; float value2; float closestT;};");
1362
1363 break;
1364 case glu::SHADERTYPE_MISS:
1365 addShaderSource<glu::MissSource>(programCollection, "build-miss-invoke-callable-multi",
1366 getMissSource(true, true).c_str(), "Result", DEFINE_RESULT_BUFFER,
1367 "struct Result { float value0; float value1; float value2; float closestT;};");
1368
1369 break;
1370 case glu::SHADERTYPE_CALLABLE:
1371 addShaderSource<glu::CallableSource>(programCollection, "build-callable-invoke-callable-multi",
1372 getCallableSource(true, true).c_str(), "Result", DEFINE_RESULT_BUFFER,
1373 "struct Result { float value0; float value1; float value2; float closestT;};");
1374
1375 break;
1376 default:
1377 TCU_THROW(InternalError, "Wrong shader invoking type");
1378 break;
1379 }
1380
1381 src.str(std::string());
1382 src <<
1383 "#define CALLABLE_DATA_FLOAT_LOC " << callableDataFloatLoc << "\n"
1384 "layout(location = CALLABLE_DATA_FLOAT_LOC) callableDataInEXT float callableDataFloat;\n"
1385 "layout(" << SHADER_RECORD << ") buffer callableBuffer\n"
1386 "{\n"
1387 " float numerator;\n"
1388 " float denomenator;\n"
1389 " uint power;\n"
1390 " uint reserved;\n"
1391 "};\n"
1392 "void main() {\n"
1393 " float base = numerator / denomenator;\n"
1394 " float result = 1;\n"
1395 " for (uint i = 0; i < power; ++i)\n"
1396 " {\n"
1397 " result *= base;\n"
1398 " }\n"
1399 " callableDataFloat += result;\n"
1400 "}";
1401
1402 addShaderSource<glu::CallableSource>(programCollection, "build-callable-1", src.str().c_str(),
1403 "", 0, "");
1404
1405 src.str(std::string());
1406 src <<
1407 "#define CALLABLE_DATA_FLOAT_LOC " << callableDataFloatLoc << "\n"
1408 "layout(location = CALLABLE_DATA_FLOAT_LOC) callableDataInEXT float callableDataFloat;\n"
1409 "void main() {\n"
1410 " callableDataFloat /= 2.0f;\n"
1411 "}";
1412
1413 addShaderSource<glu::CallableSource>(programCollection, "build-callable-2", src.str().c_str(),
1414 "", 0, "");
1415 }
1416 else
1417 {
1418 switch (params.invokingShader)
1419 {
1420 case glu::SHADERTYPE_RAYGEN:
1421 // Always defined since it's needed to invoke callable shaders that invoke other callable shaders
1422
1423 break;
1424 case glu::SHADERTYPE_CLOSEST_HIT:
1425 addShaderSource<glu::ClosestHitSource>(programCollection, "build-closesthit-invoke-callable",
1426 getClosestHitSource(true, false).c_str(), "Result", DEFINE_RESULT_BUFFER,
1427 "struct Result { float value0; float value1; float value2; float closestT;};");
1428
1429 break;
1430 case glu::SHADERTYPE_MISS:
1431 addShaderSource<glu::MissSource>(programCollection, "build-miss-invoke-callable",
1432 getMissSource(true, false).c_str(), "Result", DEFINE_RESULT_BUFFER,
1433 "struct Result { float value0; float value1; float value2; float closestT;};");
1434
1435 break;
1436 case glu::SHADERTYPE_CALLABLE:
1437 addShaderSource<glu::CallableSource>(programCollection, "build-callable-invoke-callable",
1438 getCallableSource(true, false).c_str(), "Result", DEFINE_RESULT_BUFFER,
1439 "struct Result { float value0; float value1; float value2; float closestT;};");
1440
1441 break;
1442 default:
1443 TCU_THROW(InternalError, "Wrong shader invoking type");
1444 break;
1445 }
1446 }
1447 }
1448
createInstance(Context & context) const1449 TestInstance* InvokeCallableShaderTestCase::createInstance (Context& context) const
1450 {
1451 return new InvokeCallableShaderTestInstance(context, params);
1452 }
1453
InvokeCallableShaderTestInstance(Context & context,const TestParams & data)1454 InvokeCallableShaderTestInstance::InvokeCallableShaderTestInstance (Context& context, const TestParams& data)
1455 : vkt::TestInstance (context)
1456 , params (data)
1457 {
1458 }
1459
~InvokeCallableShaderTestInstance(void)1460 InvokeCallableShaderTestInstance::~InvokeCallableShaderTestInstance (void)
1461 {
1462 }
1463
iterate()1464 tcu::TestStatus InvokeCallableShaderTestInstance::iterate()
1465 {
1466 const VkDevice device = m_context.getDevice();
1467 const DeviceInterface& vk = m_context.getDeviceInterface();
1468 const InstanceInterface& vki = m_context.getInstanceInterface();
1469 Allocator& allocator = m_context.getDefaultAllocator();
1470 de::MovePtr<RayTracingProperties> rayTracingProperties = makeRayTracingProperties(vki, m_context.getPhysicalDevice());
1471
1472 vk::Move<VkDescriptorPool> descriptorPool;
1473 vk::Move<VkDescriptorSetLayout> descriptorSetLayout;
1474 std::vector<vk::Move<VkDescriptorSet>> descriptorSet;
1475 vk::Move<VkPipelineLayout> pipelineLayout;
1476
1477 vk::DescriptorPoolBuilder descriptorPoolBuilder;
1478
1479 deUint32 storageBufCount = 0;
1480
1481 const VkDescriptorType accelType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
1482
1483 storageBufCount += 1;
1484
1485 storageBufCount += 1;
1486
1487 descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, storageBufCount);
1488
1489 descriptorPoolBuilder.addType(accelType, 1);
1490
1491 descriptorPool = descriptorPoolBuilder.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1492
1493 vk::DescriptorSetLayoutBuilder setLayoutBuilder;
1494
1495 const deUint32 AllStages = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
1496 VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
1497 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1498
1499 setLayoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, AllStages);
1500 setLayoutBuilder.addSingleBinding(accelType, AllStages);
1501 setLayoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, AllStages);
1502
1503 descriptorSetLayout = setLayoutBuilder.build(vk, device);
1504
1505 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
1506 {
1507 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1508 DE_NULL, // const void* pNext;
1509 *descriptorPool, // VkDescriptorPool descriptorPool;
1510 1u, // deUint32 setLayoutCount;
1511 &descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
1512 };
1513
1514 descriptorSet.push_back(allocateDescriptorSet(vk, device, &descriptorSetAllocateInfo));
1515
1516 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
1517 {
1518 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1519 DE_NULL, // const void* pNext;
1520 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1521 1u, // deUint32 setLayoutCount;
1522 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
1523 0u, // deUint32 pushConstantRangeCount;
1524 nullptr, // const VkPushConstantRange* pPushConstantRanges;
1525 };
1526
1527 pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutInfo);
1528
1529 std::string raygenId = "build-raygen";
1530 std::string missId = "build-miss";
1531 std::string closestHitId = "build-closesthit";
1532 std::vector<std::string> callableIds;
1533
1534 switch (params.invokingShader)
1535 {
1536 case glu::SHADERTYPE_RAYGEN:
1537 {
1538 raygenId.append("-invoke-callable");
1539
1540 if (params.multipleInvocations)
1541 {
1542 raygenId.append("-multi");
1543 }
1544 break;
1545 }
1546 case glu::SHADERTYPE_MISS:
1547 {
1548 missId.append("-invoke-callable");
1549
1550 if (params.multipleInvocations)
1551 {
1552 missId.append("-multi");
1553 }
1554 break;
1555 }
1556 case glu::SHADERTYPE_CLOSEST_HIT:
1557 {
1558 closestHitId.append("-invoke-callable");
1559
1560 if (params.multipleInvocations)
1561 {
1562 closestHitId.append("-multi");
1563 }
1564 break;
1565 }
1566 case glu::SHADERTYPE_CALLABLE:
1567 {
1568 raygenId.append("-invoke-callable");
1569 std::string callableId("build-callable-invoke-callable");
1570
1571 if (params.multipleInvocations)
1572 {
1573 callableId.append("-multi");
1574 }
1575
1576 callableIds.push_back(callableId);
1577 break;
1578 }
1579 default:
1580 {
1581 TCU_THROW(InternalError, "Wrong shader invoking type");
1582 break;
1583 }
1584 }
1585
1586 callableIds.push_back("build-callable-0");
1587 if (params.multipleInvocations)
1588 {
1589 callableIds.push_back("build-callable-1");
1590 callableIds.push_back("build-callable-2");
1591 }
1592
1593 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1594 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(raygenId.c_str()), 0), 0);
1595 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(missId.c_str()), 0), 1);
1596 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(closestHitId.c_str()), 0), 2);
1597 deUint32 callableGroup = 3;
1598 for (auto& callableId : callableIds)
1599 {
1600 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(callableId.c_str()), 0), callableGroup);
1601 ++callableGroup;
1602 }
1603 Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
1604
1605 CallableBuffer0 callableBuffer0 = { 1, 4, 3, 7 };
1606 CallableBuffer1 callableBuffer1 = { 10.5, 2.5, 2 };
1607
1608 size_t MaxBufferSize = std::max(sizeof(callableBuffer0), sizeof(callableBuffer1));
1609 deUint32 shaderGroupHandleSize = rayTracingProperties->getShaderGroupHandleSize();
1610 deUint32 shaderGroupBaseAlignment = rayTracingProperties->getShaderGroupBaseAlignment();
1611 size_t shaderStride = deAlign32(shaderGroupHandleSize + (deUint32)MaxBufferSize, shaderGroupHandleSize);
1612
1613 de::MovePtr<BufferWithMemory> raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
1614 de::MovePtr<BufferWithMemory> missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1615 de::MovePtr<BufferWithMemory> hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
1616 de::MovePtr<BufferWithMemory> callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, (deUint32)callableIds.size(),
1617 0U, 0U, MemoryRequirement::Any, 0U, 0U, (deUint32)MaxBufferSize, nullptr, true);
1618
1619 VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1620 VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1621 VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1622 VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, callableShaderBindingTable->get(), 0), shaderStride, shaderGroupHandleSize);
1623
1624 size_t callableCount = 0;
1625
1626 if (params.invokingShader == glu::SHADERTYPE_CALLABLE)
1627 {
1628 callableCount++;
1629 }
1630
1631 deMemcpy((deUint8*)callableShaderBindingTable->getAllocation().getHostPtr() +
1632 (shaderStride * (callableCount)) + shaderGroupHandleSize,
1633 &callableBuffer0,
1634 sizeof(CallableBuffer0));
1635 callableCount++;
1636
1637 if (params.multipleInvocations)
1638 {
1639 deMemcpy((deUint8*)callableShaderBindingTable->getAllocation().getHostPtr() +
1640 (shaderStride * (callableCount)) + shaderGroupHandleSize,
1641 &callableBuffer1,
1642 sizeof(CallableBuffer1));
1643 callableCount++;
1644 }
1645
1646 flushMappedMemoryRange(vk, device, callableShaderBindingTable->getAllocation().getMemory(), callableShaderBindingTable->getAllocation().getOffset(), VK_WHOLE_SIZE);
1647
1648 // {I}
1649 // (-2,1) (-1,1) (0,1) (1,1) (2,1)
1650 // X------X------X------X------X
1651 // |\ |\ |\ |\ |
1652 // | \ {B}| \ {D}| \ {F}| \ {H}|
1653 // {K}| \ | \ | \ | \ |{L}
1654 // | \ | \ | \ | \ |
1655 // |{A} \ |{C} \ |{E} \ |{G} \ |
1656 // | \| \| \| \|
1657 // X------X------X------X------X
1658 // (-2,-1)(-1,-1) (0,-1) (1,-1) (2,-1)
1659 // {J}
1660 //
1661 // A, B, E, and F are initially opaque
1662 // A and C are forced opaque
1663 // E and G are forced non-opaque
1664
1665 std::vector<Ray> rays = {
1666 Ray{ tcu::Vec3(-1.67f, -0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {A}
1667 Ray{ tcu::Vec3(-1.33f, 0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {B}
1668 Ray{ tcu::Vec3(-0.67f, -0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {C}
1669 Ray{ tcu::Vec3(-0.33f, 0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {D}
1670 Ray{ tcu::Vec3( 0.33f, -0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {E}
1671 Ray{ tcu::Vec3( 0.67f, 0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {F}
1672 Ray{ tcu::Vec3( 1.33f, -0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {G}
1673 Ray{ tcu::Vec3( 1.67f, 0.33f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {H}
1674 Ray{ tcu::Vec3( 0.0f, 1.01f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {I}
1675 Ray{ tcu::Vec3( 0.0f, -1.01f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {J}
1676 Ray{ tcu::Vec3(-2.01f, 0.0f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE }, // {K}
1677 Ray{ tcu::Vec3( 2.01f, 0.0f, 0.0f), 0.0f, tcu::Vec3(0.0f, 0.0f, 1.0f), MAX_T_VALUE } // {L}
1678 };
1679
1680 // B & F
1681 std::vector<tcu::Vec3> blas0VertsOpaque = {
1682 { -2.0f, 1.0f, 2.0f },
1683 { -1.0f, -1.0f, 2.0f },
1684 { -1.0f, 1.0f, 2.0f },
1685 { 0.0f, 1.0f, 2.0f },
1686 { 1.0f, -1.0f, 2.0f },
1687 { 1.0f, 1.0f, 2.0f }
1688 };
1689
1690 // D & H
1691 std::vector<tcu::Vec3> blas0VertsNoOpaque = {
1692 { -1.0f, 1.0f, 2.0f },
1693 { 0.0f, -1.0f, 2.0f },
1694 { 0.0f, 1.0f, 2.0f },
1695 { 1.0f, 1.0f, 2.0f },
1696 { 2.0f, -1.0f, 2.0f },
1697 { 2.0f, 1.0f, 2.0f }
1698 };
1699
1700 // A
1701 std::vector<tcu::Vec3> blas1VertsOpaque = {
1702 { -2.0f, 1.0f, 2.0f },
1703 { -2.0f, -1.0f, 2.0f },
1704 { -1.0f, -1.0f, 2.0f }
1705 };
1706
1707 // C
1708 std::vector<tcu::Vec3> blas1VertsNoOpaque = {
1709 { -1.0f, 1.0f, 2.0f },
1710 { -1.0f, -1.0f, 2.0f },
1711 { 0.0f, -1.0f, 2.0f }
1712 };
1713
1714 // E
1715 std::vector<tcu::Vec3> blas2VertsOpaque = {
1716 { 0.0f, 1.0f, 2.0f },
1717 { 0.0f, -1.0f, 2.0f },
1718 { 1.0f, -1.0f, 2.0f }
1719 };
1720
1721 // G
1722 std::vector<tcu::Vec3> blas2VertsNoOpaque = {
1723 { 1.0f, 1.0f, 2.0f },
1724 { 1.0f, -1.0f, 2.0f },
1725 { 2.0f, -1.0f, 2.0f }
1726 };
1727
1728 AddVertexLayers(&blas0VertsOpaque, 1);
1729 AddVertexLayers(&blas0VertsNoOpaque, 1);
1730 AddVertexLayers(&blas1VertsOpaque, 1);
1731 AddVertexLayers(&blas1VertsNoOpaque, 1);
1732 AddVertexLayers(&blas2VertsOpaque, 1);
1733 AddVertexLayers(&blas2VertsNoOpaque, 1);
1734
1735 std::vector<tcu::Vec3> verts;
1736 verts.reserve(
1737 blas0VertsOpaque.size() + blas0VertsNoOpaque.size() +
1738 blas1VertsOpaque.size() + blas1VertsNoOpaque.size() +
1739 blas2VertsOpaque.size() + blas2VertsNoOpaque.size());
1740 verts.insert(verts.end(), blas0VertsOpaque.begin(), blas0VertsOpaque.end());
1741 verts.insert(verts.end(), blas0VertsNoOpaque.begin(), blas0VertsNoOpaque.end());
1742 verts.insert(verts.end(), blas1VertsOpaque.begin(), blas1VertsOpaque.end());
1743 verts.insert(verts.end(), blas1VertsNoOpaque.begin(), blas1VertsNoOpaque.end());
1744 verts.insert(verts.end(), blas2VertsOpaque.begin(), blas2VertsOpaque.end());
1745 verts.insert(verts.end(), blas2VertsNoOpaque.begin(), blas2VertsNoOpaque.end());
1746
1747 tcu::Surface resultImage(static_cast<int>(rays.size()), 1);
1748
1749 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(rays.size() * sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1750 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
1751 const VkDescriptorBufferInfo resultDescriptorInfo = makeDescriptorBufferInfo(resultBuffer->get(), 0, VK_WHOLE_SIZE);
1752
1753 const VkBufferCreateInfo rayBufferCreateInfo = makeBufferCreateInfo(rays.size() * sizeof(Ray), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1754 de::MovePtr<BufferWithMemory> rayBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, rayBufferCreateInfo, MemoryRequirement::HostVisible));
1755 const VkDescriptorBufferInfo rayDescriptorInfo = makeDescriptorBufferInfo(rayBuffer->get(), 0, VK_WHOLE_SIZE);
1756 memcpy(rayBuffer->getAllocation().getHostPtr(), &rays[0], rays.size() * sizeof(Ray));
1757 flushMappedMemoryRange(vk, device, rayBuffer->getAllocation().getMemory(), rayBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1758
1759 const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, m_context.getUniversalQueueFamilyIndex());
1760 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1761
1762 beginCommandBuffer(vk, *cmdBuffer);
1763
1764 de::SharedPtr<BottomLevelAccelerationStructure> blas0 = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
1765 blas0->setGeometryCount(2);
1766 blas0->addGeometry(blas0VertsOpaque, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
1767 blas0->addGeometry(blas0VertsNoOpaque, true, 0U);
1768 blas0->createAndBuild(vk, device, *cmdBuffer, allocator);
1769
1770 de::SharedPtr<BottomLevelAccelerationStructure> blas1 = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
1771 blas1->setGeometryCount(2);
1772 blas1->addGeometry(blas1VertsOpaque, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
1773 blas1->addGeometry(blas1VertsNoOpaque, true, 0U);
1774 blas1->createAndBuild(vk, device, *cmdBuffer, allocator);
1775
1776 de::SharedPtr<BottomLevelAccelerationStructure> blas2 = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
1777 blas2->setGeometryCount(2);
1778 blas2->addGeometry(blas2VertsOpaque, true, VK_GEOMETRY_OPAQUE_BIT_KHR);
1779 blas2->addGeometry(blas2VertsNoOpaque, true, 0U);
1780 blas2->createAndBuild(vk, device, *cmdBuffer, allocator);
1781
1782 de::MovePtr<TopLevelAccelerationStructure> tlas = makeTopLevelAccelerationStructure();
1783 tlas->setInstanceCount(3);
1784 tlas->addInstance(blas0);
1785 tlas->addInstance(blas1);
1786 tlas->addInstance(blas2);
1787 tlas->createAndBuild(vk, device, *cmdBuffer, allocator);
1788
1789 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1790 {
1791 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1792 DE_NULL, // const void* pNext;
1793 1u, // deUint32 accelerationStructureCount;
1794 tlas->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
1795 };
1796
1797 DescriptorSetUpdateBuilder()
1798 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(DefaultResultBinding), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
1799 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(DefaultSceneBinding), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1800 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(DefaultRaysBinding), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &rayDescriptorInfo)
1801 .update(vk, device);
1802
1803 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
1804 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet[0].get(), 0, DE_NULL);
1805
1806 cmdTraceRays(vk,
1807 *cmdBuffer,
1808 &raygenShaderBindingTableRegion,
1809 &missShaderBindingTableRegion,
1810 &hitShaderBindingTableRegion,
1811 &callableShaderBindingTableRegion,
1812 static_cast<deUint32>(rays.size()), 1, 1);
1813
1814 endCommandBuffer(vk, *cmdBuffer);
1815
1816 submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);
1817
1818 invalidateMappedMemoryRange(vk, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1819
1820 // {I}
1821 // (-2,1) (-1,1) (0,1) (1,1) (2,1)
1822 // X------X------X------X------X
1823 // |\ |\ |\ |\ |
1824 // | \ {B}| \ {D}| \ {F}| \ {H}|
1825 // {K}| \ | \ | \ | \ |{L}
1826 // | \ | \ | \ | \ |
1827 // |{A} \ |{C} \ |{E} \ |{G} \ |
1828 // | \| \| \| \|
1829 // X------X------X------X------X
1830 // (-2,-1)(-1,-1) (0,-1) (1,-1) (2,-1)
1831 // {J}
1832 // A, B, E, and F are opaque
1833 // A and C are forced opaque
1834 // E and G are forced non-opaque
1835
1836 std::vector<bool> hits = { true, true, true, true, true, true, true, true, false, false, false, false };
1837 std::vector<bool> opaques = { true, true, true, false, false, true, false, false, true, true, true, true };
1838
1839
1840 union
1841 {
1842 bool mismatch[32];
1843 deUint32 mismatchAll;
1844 };
1845 mismatchAll = 0;
1846
1847 tcu::Vec4* resultData = (tcu::Vec4*)resultBuffer->getAllocation().getHostPtr();
1848
1849 for (int index = 0; index < resultImage.getWidth(); ++index)
1850 {
1851 if (verifyResultData(&resultData[index], index, hits[index], params))
1852 {
1853 resultImage.setPixel(index, 0, tcu::RGBA(255, 0, 0, 255));
1854 }
1855 else
1856 {
1857 mismatch[index] = true;
1858 resultImage.setPixel(index, 0, tcu::RGBA(0, 0, 0, 255));
1859 }
1860 }
1861
1862 // Write Image
1863 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1864 << tcu::TestLog::Image("Result", "Result", resultImage)
1865 << tcu::TestLog::EndImageSet;
1866
1867 if (mismatchAll != 0)
1868 TCU_FAIL("Result data did not match expected output");
1869
1870 return tcu::TestStatus::pass("pass");
1871 }
1872
1873 } // anonymous
1874
createCallableShadersTests(tcu::TestContext & testCtx)1875 tcu::TestCaseGroup* createCallableShadersTests (tcu::TestContext& testCtx)
1876 {
1877 // Tests veryfying callable shaders
1878 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "callable_shader"));
1879
1880 struct CallableShaderTestTypeData
1881 {
1882 CallableShaderTestType shaderTestType;
1883 const char* name;
1884 } callableShaderTestTypes[] =
1885 {
1886 { CSTT_RGEN_CALL, "rgen_call" },
1887 { CSTT_RGEN_CALL_CALL, "rgen_call_call" },
1888 { CSTT_HIT_CALL, "hit_call" },
1889 { CSTT_RGEN_MULTICALL, "rgen_multicall" },
1890 };
1891
1892 for (size_t shaderTestNdx = 0; shaderTestNdx < DE_LENGTH_OF_ARRAY(callableShaderTestTypes); ++shaderTestNdx)
1893 {
1894 TestParams testParams
1895 {
1896 TEST_WIDTH,
1897 TEST_HEIGHT,
1898 callableShaderTestTypes[shaderTestNdx].shaderTestType,
1899 de::SharedPtr<TestConfiguration>(new SingleSquareConfiguration()),
1900 glu::SHADERTYPE_LAST,
1901 false
1902 };
1903 group->addChild(new CallableShaderTestCase(group->getTestContext(), callableShaderTestTypes[shaderTestNdx].name, testParams));
1904 }
1905
1906 bool multipleInvocations[] = { false , true };
1907 std::string multipleInvocationsText[] = { "_single_invocation", "_multiple_invocations" };
1908 // Callable shaders cannot be called from any-hit shader per GLSL_NV_ray_tracing spec. Assuming same will hold for KHR version.
1909 glu::ShaderType invokingShaders[] = { glu::SHADERTYPE_RAYGEN, glu::SHADERTYPE_CALLABLE, glu::SHADERTYPE_CLOSEST_HIT, glu::SHADERTYPE_MISS };
1910 std::string invokingShadersText[] = { "_invoked_via_raygen" , "_invoked_via_callable" , "_invoked_via_closest_hit" , "_invoked_via_miss" };
1911
1912 for (int j = 0; j < 4; ++j)
1913 {
1914 TestParams params;
1915
1916 std::string name("callable_shader");
1917
1918 params.invokingShader = invokingShaders[j];
1919 name.append(invokingShadersText[j]);
1920
1921 for (int k = 0; k < 2; ++k)
1922 {
1923 std::string nameFull(name);
1924
1925 params.multipleInvocations = multipleInvocations[k];
1926 nameFull.append(multipleInvocationsText[k]);
1927
1928 group->addChild(new InvokeCallableShaderTestCase(group->getTestContext(), nameFull.c_str(), params));
1929 }
1930 }
1931
1932 return group.release();
1933 }
1934
1935 } // RayTracing
1936
1937 } // vkt
1938