• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Acceleration Structure Null Handle Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayTracingNullASTests.hpp"
25 
26 #include "vkDefs.hpp"
27 
28 #include "vktTestCase.hpp"
29 #include "vktCustomInstancesDevices.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 
38 #include "vkRayTracingUtil.hpp"
39 
40 #include "tcuCommandLine.hpp"
41 
42 #include "deClock.h"
43 
44 namespace vkt
45 {
46 namespace RayTracing
47 {
48 namespace
49 {
50 using namespace vk;
51 using namespace std;
52 
53 static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
54 												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
55 												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
56 												| VK_SHADER_STAGE_MISS_BIT_KHR
57 												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
58 												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
59 
60 struct CaseDef
61 {
62 	deUint32	width;
63 	deUint32	height;
64 };
65 
66 enum ShaderGroups
67 {
68 	FIRST_GROUP		= 0,
69 	RAYGEN_GROUP	= FIRST_GROUP,
70 	MISS_GROUP,
71 	HIT_GROUP,
72 	GROUP_COUNT
73 };
74 
getShaderGroupSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)75 deUint32 getShaderGroupSize (const InstanceInterface&	vki,
76 							 const VkPhysicalDevice		physicalDevice)
77 {
78 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
79 
80 	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
81 	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
82 }
83 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)84 deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
85 									  const VkPhysicalDevice	physicalDevice)
86 {
87 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
88 
89 	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
90 	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
91 }
92 
makePipeline(const DeviceInterface & vkd,const VkDevice device,vk::BinaryCollection & collection,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,VkPipelineLayout pipelineLayout,const deUint32 raygenGroup,const deUint32 missGroup,const deUint32 hitGroup)93 Move<VkPipeline> makePipeline (const DeviceInterface&			vkd,
94 							   const VkDevice					device,
95 							   vk::BinaryCollection&			collection,
96 							   de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
97 							   VkPipelineLayout					pipelineLayout,
98 							   const deUint32					raygenGroup,
99 							   const deUint32					missGroup,
100 							   const deUint32					hitGroup)
101 {
102 	Move<VkShaderModule>	raygenShader		= createShaderModule(vkd, device, collection.get("rgen"), 0);
103 	Move<VkShaderModule>	hitShader			= createShaderModule(vkd, device, collection.get("ahit"), 0);
104 	Move<VkShaderModule>	missShader			= createShaderModule(vkd, device, collection.get("miss"), 0);
105 	Move<VkShaderModule>	intersectionShader	= createShaderModule(vkd, device, collection.get("sect"), 0);
106 
107 	rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		raygenShader,		raygenGroup);
108 	rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR,		hitShader,			hitGroup);
109 	rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,			missShader,			missGroup);
110 	rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	intersectionShader,	hitGroup);
111 
112 	Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout);
113 
114 	return pipeline;
115 }
116 
makeImageCreateInfo(deUint32 width,deUint32 height,VkFormat format)117 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, VkFormat format)
118 {
119 	const VkImageUsageFlags	usage			= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
120 	const VkImageCreateInfo	imageCreateInfo	=
121 	{
122 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
123 		DE_NULL,								// const void*				pNext;
124 		(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
125 		VK_IMAGE_TYPE_2D,						// VkImageType				imageType;
126 		format,									// VkFormat					format;
127 		makeExtent3D(width, height, 1u),		// VkExtent3D				extent;
128 		1u,										// deUint32					mipLevels;
129 		1u,										// deUint32					arrayLayers;
130 		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
131 		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
132 		usage,									// VkImageUsageFlags		usage;
133 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
134 		0u,										// deUint32					queueFamilyIndexCount;
135 		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
136 		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
137 	};
138 
139 	return imageCreateInfo;
140 }
141 
142 struct TestDeviceFeatures
143 {
144 	VkPhysicalDeviceRobustness2FeaturesEXT				robustness2Features;
145 	VkPhysicalDeviceRayTracingPipelineFeaturesKHR		rayTracingPipelineFeatures;
146 	VkPhysicalDeviceAccelerationStructureFeaturesKHR	accelerationStructureFeatures;
147 	VkPhysicalDeviceBufferDeviceAddressFeaturesKHR		deviceAddressFeatures;
148 	VkPhysicalDeviceFeatures2							deviceFeatures;
149 
linkStructuresvkt::RayTracing::__anond6bd652a0111::TestDeviceFeatures150 	void linkStructures ()
151 	{
152 		robustness2Features.pNext			= nullptr;
153 		rayTracingPipelineFeatures.pNext	= &robustness2Features;
154 		accelerationStructureFeatures.pNext	= &rayTracingPipelineFeatures;
155 		deviceAddressFeatures.pNext			= &accelerationStructureFeatures;
156 		deviceFeatures.pNext				= &deviceAddressFeatures;
157 	}
158 
TestDeviceFeaturesvkt::RayTracing::__anond6bd652a0111::TestDeviceFeatures159 	TestDeviceFeatures (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
160 	{
161 		robustness2Features.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
162 		rayTracingPipelineFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
163 		accelerationStructureFeatures.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
164 		deviceAddressFeatures.sType			= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
165 		deviceFeatures.sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
166 
167 		linkStructures();
168 		vki.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);
169 	}
170 };
171 
172 struct DeviceHelper
173 {
174 	Move<VkDevice>					device;
175 	de::MovePtr<DeviceDriver>		vkd;
176 	deUint32						queueFamilyIndex;
177 	VkQueue							queue;
178 	de::MovePtr<SimpleAllocator>	allocator;
179 
DeviceHelpervkt::RayTracing::__anond6bd652a0111::DeviceHelper180 	DeviceHelper (Context& context)
181 	{
182 		const auto&	vkp				= context.getPlatformInterface();
183 		const auto&	vki				= context.getInstanceInterface();
184 		const auto	instance		= context.getInstance();
185 		const auto	physicalDevice	= context.getPhysicalDevice();
186 		const auto	queuePriority	= 1.0f;
187 
188 		// Queue index first.
189 		queueFamilyIndex = context.getUniversalQueueFamilyIndex();
190 
191 		// Get device features (these have already been checked in the test case).
192 		TestDeviceFeatures features(vki, physicalDevice);
193 		features.linkStructures();
194 
195 		// Make sure uneeded robustness features are disabled.
196 		features.deviceFeatures.features.robustBufferAccess	= VK_FALSE;
197 		features.robustness2Features.robustBufferAccess2	= VK_FALSE;
198 		features.robustness2Features.robustImageAccess2		= VK_FALSE;
199 
200 		const VkDeviceQueueCreateInfo queueInfo =
201 		{
202 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//	VkStructureType				sType;
203 			nullptr,									//	const void*					pNext;
204 			0u,											//	VkDeviceQueueCreateFlags	flags;
205 			queueFamilyIndex,							//	deUint32					queueFamilyIndex;
206 			1u,											//	deUint32					queueCount;
207 			&queuePriority,								//	const float*				pQueuePriorities;
208 		};
209 
210 		// Required extensions.
211 		std::vector<const char*> requiredExtensions;
212 		requiredExtensions.push_back("VK_KHR_ray_tracing_pipeline");
213 		requiredExtensions.push_back("VK_KHR_acceleration_structure");
214 		requiredExtensions.push_back("VK_KHR_buffer_device_address");
215 		requiredExtensions.push_back("VK_KHR_deferred_host_operations");
216 		requiredExtensions.push_back("VK_EXT_descriptor_indexing");
217 		requiredExtensions.push_back("VK_KHR_spirv_1_4");
218 		requiredExtensions.push_back("VK_KHR_shader_float_controls");
219 		requiredExtensions.push_back("VK_EXT_robustness2");
220 
221 		const VkDeviceCreateInfo createInfo =
222 		{
223 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,				//	VkStructureType					sType;
224 			features.deviceFeatures.pNext,						//	const void*						pNext;
225 			0u,													//	VkDeviceCreateFlags				flags;
226 			1u,													//	deUint32						queueCreateInfoCount;
227 			&queueInfo,											//	const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
228 			0u,													//	deUint32						enabledLayerCount;
229 			nullptr,											//	const char* const*				ppEnabledLayerNames;
230 			static_cast<deUint32>(requiredExtensions.size()),	//	deUint32						enabledExtensionCount;
231 			requiredExtensions.data(),							//	const char* const*				ppEnabledExtensionNames;
232 			&features.deviceFeatures.features,					//	const VkPhysicalDeviceFeatures*	pEnabledFeatures;
233 		};
234 
235 		// Create custom device and related objects.
236 		device		= createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &createInfo);
237 		vkd			= de::MovePtr<DeviceDriver>(new DeviceDriver(vkp, instance, device.get()));
238 		queue		= getDeviceQueue(*vkd, *device, queueFamilyIndex, 0u);
239 		allocator	= de::MovePtr<SimpleAllocator>(new SimpleAllocator(*vkd, device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
240 	}
241 };
242 
243 class RayTracingBuildTestInstance : public TestInstance
244 {
245 public:
246 									RayTracingBuildTestInstance			(Context& context, const CaseDef& data);
247 									~RayTracingBuildTestInstance		(void);
248 	tcu::TestStatus					iterate								(void);
249 
250 protected:
251 	deUint32						validateBuffer						(de::MovePtr<BufferWithMemory> buffer);
252 	de::MovePtr<BufferWithMemory>	runTest								(DeviceHelper& deviceHelper);
253 
254 private:
255 	CaseDef							m_data;
256 };
257 
RayTracingBuildTestInstance(Context & context,const CaseDef & data)258 RayTracingBuildTestInstance::RayTracingBuildTestInstance (Context& context, const CaseDef& data)
259 	: vkt::TestInstance		(context)
260 	, m_data				(data)
261 {
262 }
263 
~RayTracingBuildTestInstance(void)264 RayTracingBuildTestInstance::~RayTracingBuildTestInstance (void)
265 {
266 }
267 
268 class RayTracingTestCase : public TestCase
269 {
270 	public:
271 							RayTracingTestCase	(tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
272 							~RayTracingTestCase	(void);
273 
274 	virtual	void			initPrograms		(SourceCollections& programCollection) const;
275 	virtual TestInstance*	createInstance		(Context& context) const;
276 	virtual void			checkSupport		(Context& context) const;
277 
278 private:
279 	CaseDef					m_data;
280 };
281 
RayTracingTestCase(tcu::TestContext & context,const char * name,const char * desc,const CaseDef data)282 RayTracingTestCase::RayTracingTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
283 	: vkt::TestCase	(context, name, desc)
284 	, m_data		(data)
285 {
286 }
287 
~RayTracingTestCase(void)288 RayTracingTestCase::~RayTracingTestCase	(void)
289 {
290 }
291 
checkSupport(Context & context) const292 void RayTracingTestCase::checkSupport(Context& context) const
293 {
294 	const auto&	vki					= context.getInstanceInterface();
295 	const auto	physicalDevice		= context.getPhysicalDevice();
296 
297 	if (!context.isDeviceFunctionalitySupported("VK_KHR_ray_tracing_pipeline"))
298 	TCU_THROW(NotSupportedError, "VK_KHR_ray_tracing_pipeline not supported");
299 
300 	// VK_KHR_acceleration_structure is required by VK_KHR_ray_tracing_pipeline.
301 	if (!context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
302 		TCU_FAIL("VK_KHR_acceleration_structure not supported but VK_KHR_ray_tracing_pipeline supported");
303 
304 	// VK_KHR_deferred_host_operations is required by VK_KHR_ray_tracing_pipeline.
305 	if (!context.isDeviceFunctionalitySupported("VK_KHR_deferred_host_operations"))
306 		TCU_FAIL("VK_KHR_deferred_host_operations not supported but VK_KHR_ray_tracing_pipeline supported");
307 
308 	// VK_KHR_buffer_device_address is required by VK_KHR_acceleration_structure.
309 	if (!context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
310 		TCU_FAIL("VK_KHR_buffer_device_address not supported but VK_KHR_acceleration_structure supported");
311 
312 	if (!context.isDeviceFunctionalitySupported("VK_EXT_robustness2"))
313 		TCU_THROW(NotSupportedError, "VK_EXT_robustness2 not supported");
314 
315 	// Required extensions supported: check features.
316 	TestDeviceFeatures testFeatures(vki, physicalDevice);
317 
318 	if (!testFeatures.rayTracingPipelineFeatures.rayTracingPipeline)
319 		TCU_THROW(NotSupportedError, "Ray tracing pipelines not supported");
320 
321 	if (!testFeatures.robustness2Features.nullDescriptor)
322 		TCU_THROW(NotSupportedError, "Null descriptors not supported");
323 }
324 
initPrograms(SourceCollections & programCollection) const325 void RayTracingTestCase::initPrograms (SourceCollections& programCollection) const
326 {
327 	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
328 
329 	programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
330 
331 	{
332 		std::stringstream css;
333 		css <<
334 			"#version 460 core\n"
335 			"#extension GL_EXT_nonuniform_qualifier : enable\n"
336 			"#extension GL_EXT_ray_tracing : require\n"
337 			"layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
338 			"hitAttributeEXT vec3 hitAttribute;\n"
339 			"void main()\n"
340 			"{\n"
341 			"  reportIntersectionEXT(1.0f, 0);\n"
342 			"  uvec4 color = uvec4(1,0,0,1);\n"
343 			"  imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
344 			"}\n";
345 
346 		programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
347 	}
348 
349 	{
350 		std::stringstream css;
351 		css <<
352 			"#version 460 core\n"
353 			"#extension GL_EXT_nonuniform_qualifier : enable\n"
354 			"#extension GL_EXT_ray_tracing : require\n"
355 			"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
356 			"hitAttributeEXT vec3 attribs;\n"
357 			"layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
358 			"void main()\n"
359 			"{\n"
360 			"  uvec4 color = uvec4(2,0,0,1);\n"
361 			"  imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
362 			"}\n";
363 
364 		programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
365 	}
366 
367 	{
368 		std::stringstream css;
369 		css <<
370 			"#version 460 core\n"
371 			"#extension GL_EXT_nonuniform_qualifier : enable\n"
372 			"#extension GL_EXT_ray_tracing : require\n"
373 			"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
374 			"hitAttributeEXT vec3 attribs;\n"
375 			"layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
376 			"void main()\n"
377 			"{\n"
378 			"  uvec4 color = uvec4(3,0,0,1);\n"
379 			"  imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
380 			"}\n";
381 
382 		programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
383 	}
384 
385 	{
386 		std::stringstream css;
387 		css <<
388 			"#version 460 core\n"
389 			"#extension GL_EXT_nonuniform_qualifier : enable\n"
390 			"#extension GL_EXT_ray_tracing : require\n"
391 			"layout(location = 0) rayPayloadInEXT dummyPayload { vec4 dummy; };\n"
392 			"layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
393 			"void main()\n"
394 			"{\n"
395 			"  uvec4 color = uvec4(4,0,0,1);\n"
396 			"  imageStore(result, ivec2(gl_LaunchIDEXT.xy), color);\n"
397 			"}\n";
398 
399 		programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
400 	}
401 }
402 
createInstance(Context & context) const403 TestInstance* RayTracingTestCase::createInstance (Context& context) const
404 {
405 	return new RayTracingBuildTestInstance(context, m_data);
406 }
407 
runTest(DeviceHelper & deviceHelper)408 de::MovePtr<BufferWithMemory> RayTracingBuildTestInstance::runTest (DeviceHelper& deviceHelper)
409 {
410 	const InstanceInterface&			vki									= m_context.getInstanceInterface();
411 	const VkPhysicalDevice				physicalDevice						= m_context.getPhysicalDevice();
412 	const DeviceDriver&					vkd									= *deviceHelper.vkd;
413 	const VkDevice						device								= *deviceHelper.device;
414 	const deUint32						queueFamilyIndex					= deviceHelper.queueFamilyIndex;
415 	const VkQueue						queue								= deviceHelper.queue;
416 	SimpleAllocator&					allocator							= *deviceHelper.allocator;
417 	const VkFormat						format								= VK_FORMAT_R32_UINT;
418 	const deUint32						pixelCount							= m_data.width * m_data.height;
419 	const deUint32						shaderGroupHandleSize				= getShaderGroupSize(vki, physicalDevice);
420 	const deUint32						shaderGroupBaseAlignment			= getShaderGroupBaseAlignment(vki, physicalDevice);
421 
422 	const Move<VkDescriptorSetLayout>	descriptorSetLayout					= DescriptorSetLayoutBuilder()
423 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
424 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
425 																					.build(vkd, device);
426 	const Move<VkDescriptorPool>		descriptorPool						= DescriptorPoolBuilder()
427 																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
428 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
429 																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
430 	const Move<VkDescriptorSet>			descriptorSet						= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
431 	const Move<VkPipelineLayout>		pipelineLayout						= makePipelineLayout(vkd, device, descriptorSetLayout.get());
432 	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
433 	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
434 
435 	de::MovePtr<RayTracingPipeline>		rayTracingPipeline					= de::newMovePtr<RayTracingPipeline>();
436 	const Move<VkPipeline>				pipeline							= makePipeline(vkd, device, m_context.getBinaryCollection(), rayTracingPipeline, *pipelineLayout, RAYGEN_GROUP, MISS_GROUP, HIT_GROUP);
437 	const de::MovePtr<BufferWithMemory>	raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, RAYGEN_GROUP, 1u);
438 	const de::MovePtr<BufferWithMemory>	missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, MISS_GROUP, 1u);
439 	const de::MovePtr<BufferWithMemory>	hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, HIT_GROUP, 1u);
440 
441 	const VkStridedDeviceAddressRegionKHR	raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
442 	const VkStridedDeviceAddressRegionKHR	missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
443 	const VkStridedDeviceAddressRegionKHR	hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
444 	const VkStridedDeviceAddressRegionKHR	callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
445 
446 	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.width, m_data.height, format);
447 	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
448 	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
449 	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_2D, format, imageSubresourceRange);
450 
451 	const VkBufferCreateInfo			bufferCreateInfo					= makeBufferCreateInfo(pixelCount*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
452 	const VkImageSubresourceLayers		bufferImageSubresourceLayers		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
453 	const VkBufferImageCopy				bufferImageRegion					= makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 1u), bufferImageSubresourceLayers);
454 	de::MovePtr<BufferWithMemory>		buffer								= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
455 
456 	const VkDescriptorImageInfo			descriptorImageInfo					= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
457 
458 	const VkImageMemoryBarrier			preImageBarrier						= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
459 																				VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
460 																				**image, imageSubresourceRange);
461 	const VkImageMemoryBarrier			postImageBarrier					= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
462 																				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
463 																				**image, imageSubresourceRange);
464 	const VkMemoryBarrier				postTraceMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
465 	const VkMemoryBarrier				postCopyMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
466 	const VkClearValue					clearValue							= makeClearValueColorU32(5u, 5u, 5u, 255u);
467 	const VkAccelerationStructureKHR	topLevelAccelerationStructure		= DE_NULL;
468 
469 	beginCommandBuffer(vkd, *cmdBuffer, 0u);
470 	{
471 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
472 		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
473 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, &postImageBarrier);
474 
475 		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
476 		{
477 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
478 			DE_NULL,															//  const void*							pNext;
479 			1u,																	//  deUint32							accelerationStructureCount;
480 			&topLevelAccelerationStructure,										//  const VkAccelerationStructureKHR*	pAccelerationStructures;
481 		};
482 
483 		DescriptorSetUpdateBuilder()
484 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
485 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
486 			.update(vkd, device);
487 
488 		vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
489 
490 		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
491 
492 		cmdTraceRays(vkd,
493 			*cmdBuffer,
494 			&raygenShaderBindingTableRegion,
495 			&missShaderBindingTableRegion,
496 			&hitShaderBindingTableRegion,
497 			&callableShaderBindingTableRegion,
498 			m_data.width, m_data.height, 1);
499 
500 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
501 
502 		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **buffer, 1u, &bufferImageRegion);
503 
504 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
505 	}
506 	endCommandBuffer(vkd, *cmdBuffer);
507 
508 	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
509 
510 	invalidateMappedMemoryRange(vkd, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), pixelCount * sizeof(deUint32));
511 
512 	return buffer;
513 }
514 
validateBuffer(de::MovePtr<BufferWithMemory> buffer)515 deUint32 RayTracingBuildTestInstance::validateBuffer (de::MovePtr<BufferWithMemory>	buffer)
516 {
517 	const deUint32*	bufferPtr		= (deUint32*)buffer->getAllocation().getHostPtr();
518 	const deUint32	expectedValue	= 4;
519 	deUint32		failures		= 0;
520 	deUint32		pos				= 0;
521 
522 	for (deUint32 y = 0; y < m_data.height; ++y)
523 	for (deUint32 x = 0; x < m_data.width; ++x)
524 	{
525 		if (bufferPtr[pos] != expectedValue)
526 			failures++;
527 
528 		++pos;
529 	}
530 
531 	return failures;
532 }
533 
iterate(void)534 tcu::TestStatus RayTracingBuildTestInstance::iterate (void)
535 {
536 	DeviceHelper					deviceHelper	(m_context);
537 	de::MovePtr<BufferWithMemory>	buffer			= runTest(deviceHelper);
538 	const deUint32					failures		= validateBuffer(buffer);
539 
540 	if (failures == 0)
541 		return tcu::TestStatus::pass("Pass");
542 	else
543 		return tcu::TestStatus::fail("failures=" + de::toString(failures));
544 }
545 
546 }	// anonymous
547 
createNullAccelerationStructureTests(tcu::TestContext & testCtx)548 tcu::TestCaseGroup*	createNullAccelerationStructureTests (tcu::TestContext& testCtx)
549 {
550 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "null_as", "Null Acceleration Structure is accepted as 'always miss' case"));
551 
552 	const CaseDef	caseDef					=
553 	{
554 		8,		//  deUint32	width;
555 		8,		//  deUint32	height;
556 	};
557 	group->addChild(new RayTracingTestCase(testCtx, "test", "", caseDef));
558 
559 	return group.release();
560 }
561 
562 }	// RayTracing
563 }	// vkt
564