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