• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google 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 Tests for render passses with multisample attachments
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRenderPassMultisampleTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29 
30 #include "vkDefs.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42 
43 #include "tcuFloat.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuMaybe.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorUtil.hpp"
51 
52 #include "deUniquePtr.hpp"
53 #include "deSharedPtr.hpp"
54 
55 using namespace vk;
56 
57 using tcu::BVec4;
58 using tcu::IVec2;
59 using tcu::IVec4;
60 using tcu::UVec2;
61 using tcu::UVec4;
62 using tcu::Vec2;
63 using tcu::Vec4;
64 
65 using tcu::Maybe;
66 using tcu::just;
67 
68 using tcu::ConstPixelBufferAccess;
69 using tcu::PixelBufferAccess;
70 
71 using tcu::TestLog;
72 
73 using std::pair;
74 using std::string;
75 using std::vector;
76 
77 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
78 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
79 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
80 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
81 
82 namespace vkt
83 {
84 namespace
85 {
86 using namespace renderpass;
87 
88 enum
89 {
90 	MAX_COLOR_ATTACHMENT_COUNT = 4u
91 };
92 
93 enum TestSeparateUsage
94 {
95 	TEST_DEPTH	 = (1 << 0),
96 	TEST_STENCIL = (1 << 1)
97 };
98 
99 template<typename T>
safeSharedPtr(T * ptr)100 de::SharedPtr<T> safeSharedPtr (T* ptr)
101 {
102 	try
103 	{
104 		return de::SharedPtr<T>(ptr);
105 	}
106 	catch (...)
107 	{
108 		delete ptr;
109 		throw;
110 	}
111 }
112 
getImageAspectFlags(VkFormat vkFormat)113 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
114 {
115 	const tcu::TextureFormat	format		(mapVkFormat(vkFormat));
116 	const bool					hasDepth	(tcu::hasDepthComponent(format.order));
117 	const bool					hasStencil	(tcu::hasStencilComponent(format.order));
118 
119 	if (hasDepth || hasStencil)
120 	{
121 		return (hasDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0u)
122 				| (hasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0u);
123 	}
124 	else
125 		return VK_IMAGE_ASPECT_COLOR_BIT;
126 }
127 
bindBufferMemory(const DeviceInterface & vk,VkDevice device,VkBuffer buffer,VkDeviceMemory mem,VkDeviceSize memOffset)128 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
129 {
130 	VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
131 }
132 
bindImageMemory(const DeviceInterface & vk,VkDevice device,VkImage image,VkDeviceMemory mem,VkDeviceSize memOffset)133 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
134 {
135 	VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
136 }
137 
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)138 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&	vk,
139 											VkDevice				device,
140 											Allocator&				allocator,
141 											VkBuffer				buffer)
142 {
143 	de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
144 	bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
145 	return allocation;
146 }
147 
createImageMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image)148 de::MovePtr<Allocation> createImageMemory (const DeviceInterface&	vk,
149 										   VkDevice					device,
150 										   Allocator&				allocator,
151 										   VkImage					image)
152 {
153 	de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
154 	bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
155 	return allocation;
156 }
157 
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags flags,VkImageType imageType,VkFormat format,VkExtent3D extent,deUint32 mipLevels,deUint32 arrayLayers,VkSampleCountFlagBits samples,VkImageTiling tiling,VkImageUsageFlags usage,VkSharingMode sharingMode,deUint32 queueFamilyCount,const deUint32 * pQueueFamilyIndices,VkImageLayout initialLayout,TestSeparateUsage separateStencilUsage)158 Move<VkImage> createImage (const DeviceInterface&	vk,
159 						   VkDevice					device,
160 						   VkImageCreateFlags		flags,
161 						   VkImageType				imageType,
162 						   VkFormat					format,
163 						   VkExtent3D				extent,
164 						   deUint32					mipLevels,
165 						   deUint32					arrayLayers,
166 						   VkSampleCountFlagBits	samples,
167 						   VkImageTiling			tiling,
168 						   VkImageUsageFlags		usage,
169 						   VkSharingMode			sharingMode,
170 						   deUint32					queueFamilyCount,
171 						   const deUint32*			pQueueFamilyIndices,
172 						   VkImageLayout			initialLayout,
173 						   TestSeparateUsage		separateStencilUsage)
174 {
175 	VkImageUsageFlags depthUsage	= (separateStencilUsage == TEST_DEPTH)	 ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
176 	VkImageUsageFlags stencilUsage	= (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
177 
178 	const VkImageStencilUsageCreateInfo stencilUsageInfo =
179 	{
180 		VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
181 		DE_NULL,
182 		stencilUsage
183 	};
184 
185 	const VkImageCreateInfo pCreateInfo =
186 	{
187 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
188 		separateStencilUsage ? &stencilUsageInfo : DE_NULL,
189 		flags,
190 		imageType,
191 		format,
192 		extent,
193 		mipLevels,
194 		arrayLayers,
195 		samples,
196 		tiling,
197 		separateStencilUsage ? depthUsage : usage,
198 		sharingMode,
199 		queueFamilyCount,
200 		pQueueFamilyIndices,
201 		initialLayout
202 	};
203 
204 	return createImage(vk, device, &pCreateInfo);
205 }
206 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)207 Move<VkImageView> createImageView (const DeviceInterface&	vk,
208 								   VkDevice					device,
209 								   VkImageViewCreateFlags	flags,
210 								   VkImage					image,
211 								   VkImageViewType			viewType,
212 								   VkFormat					format,
213 								   VkComponentMapping		components,
214 								   VkImageSubresourceRange	subresourceRange)
215 {
216 	const VkImageViewCreateInfo pCreateInfo =
217 	{
218 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
219 		DE_NULL,
220 		flags,
221 		image,
222 		viewType,
223 		format,
224 		components,
225 		subresourceRange,
226 	};
227 	return createImageView(vk, device, &pCreateInfo);
228 }
229 
createImage(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat,VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,deUint32 width,deUint32 height,TestSeparateUsage separateStencilUsage=(TestSeparateUsage)0u)230 Move<VkImage> createImage (const InstanceInterface&	vki,
231 						   VkPhysicalDevice			physicalDevice,
232 						   const DeviceInterface&	vkd,
233 						   VkDevice					device,
234 						   VkFormat					vkFormat,
235 						   VkSampleCountFlagBits	sampleCountBit,
236 						   VkImageUsageFlags		usage,
237 						   deUint32					width,
238 						   deUint32					height,
239 						   TestSeparateUsage		separateStencilUsage = (TestSeparateUsage)0u)
240 {
241 	try
242 	{
243 		const tcu::TextureFormat		format					(mapVkFormat(vkFormat));
244 		const VkImageType				imageType				(VK_IMAGE_TYPE_2D);
245 		const VkImageTiling				imageTiling				(VK_IMAGE_TILING_OPTIMAL);
246 		const VkFormatProperties		formatProperties		(getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
247 		const VkImageFormatProperties	imageFormatProperties	(getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
248 		const VkImageUsageFlags			depthUsage				= (separateStencilUsage == TEST_DEPTH)	 ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
249 		const VkImageUsageFlags			stencilUsage			= (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
250 		const VkExtent3D				imageExtent				=
251 		{
252 			width,
253 			height,
254 			1u
255 		};
256 
257 		if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
258 			&& (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
259 			TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
260 
261 		if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
262 			&& (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
263 			TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
264 
265 		if (imageFormatProperties.maxExtent.width < imageExtent.width
266 			|| imageFormatProperties.maxExtent.height < imageExtent.height
267 			|| ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
268 		{
269 			TCU_THROW(NotSupportedError, "Image type not supported");
270 		}
271 
272 		if (separateStencilUsage)
273 		{
274 			const VkImageStencilUsageCreateInfo	stencilUsageInfo =
275 			{
276 				VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,				//	VkStructureType			sType
277 				DE_NULL,														//	const void*				pNext
278 				stencilUsage													//	VkImageUsageFlags		stencilUsage
279 			};
280 
281 			const VkPhysicalDeviceImageFormatInfo2 formatInfo2 =
282 			{
283 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,			//	VkStructureType			sType
284 				&stencilUsageInfo,												//	const void*				pNext
285 				vkFormat,														//	VkFormat				format
286 				imageType,														//	VkImageType				type
287 				imageTiling,													//	VkImageTiling			tiling
288 				depthUsage,														//	VkImageUsageFlags		usage
289 				(VkImageCreateFlags)0u											//	VkImageCreateFlags		flags
290 			};
291 
292 			VkImageFormatProperties2				extProperties =
293 			{
294 				VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
295 				DE_NULL,
296 			{
297 				{
298 					0,	// width
299 					0,	// height
300 					0,	// depth
301 				},
302 				0u,		// maxMipLevels
303 				0u,		// maxArrayLayers
304 				0,		// sampleCounts
305 				0u,		// maxResourceSize
306 			},
307 			};
308 
309 			if ((vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &formatInfo2, &extProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
310 				|| extProperties.imageFormatProperties.maxExtent.width < imageExtent.width
311 				|| extProperties.imageFormatProperties.maxExtent.height < imageExtent.height
312 				|| ((extProperties.imageFormatProperties.sampleCounts & sampleCountBit) == 0))
313 			{
314 				TCU_THROW(NotSupportedError, "Image format not supported");
315 			}
316 
317 		}
318 
319 		return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED, separateStencilUsage);
320 	}
321 	catch (const vk::Error& error)
322 	{
323 		if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
324 			TCU_THROW(NotSupportedError, "Image format not supported");
325 
326 		throw;
327 	}
328 }
329 
createImageAttachmentView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)330 Move<VkImageView> createImageAttachmentView (const DeviceInterface&	vkd,
331 											 VkDevice				device,
332 											 VkImage				image,
333 											 VkFormat				format,
334 											 VkImageAspectFlags		aspect)
335 {
336 	const VkImageSubresourceRange	range =
337 	{
338 		aspect,
339 		0u,
340 		1u,
341 		0u,
342 		1u
343 	};
344 
345 	return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
346 }
347 
createSrcPrimaryInputImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect,TestSeparateUsage testSeparateUsage)348 Move<VkImageView> createSrcPrimaryInputImageView (const DeviceInterface&	vkd,
349 												  VkDevice					device,
350 												  VkImage					image,
351 												  VkFormat					format,
352 												  VkImageAspectFlags		aspect,
353 												  TestSeparateUsage			testSeparateUsage)
354 {
355 	VkImageAspectFlags primaryDepthStencilAspect = (testSeparateUsage == TEST_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
356 
357 	const VkImageSubresourceRange	range =
358 	{
359 		aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
360 			? primaryDepthStencilAspect
361 			: aspect,
362 		0u,
363 		1u,
364 		0u,
365 		1u
366 	};
367 
368 	return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
369 }
370 
createSrcSecondaryInputImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect,TestSeparateUsage separateStencilUsage)371 Move<VkImageView> createSrcSecondaryInputImageView (const DeviceInterface&	vkd,
372 													VkDevice				device,
373 													VkImage					image,
374 													VkFormat				format,
375 													VkImageAspectFlags		aspect,
376 													TestSeparateUsage		separateStencilUsage)
377 {
378 	if ((aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) && !separateStencilUsage)
379 	{
380 		const VkImageSubresourceRange	range =
381 		{
382 			VK_IMAGE_ASPECT_STENCIL_BIT,
383 			0u,
384 			1u,
385 			0u,
386 			1u
387 		};
388 
389 		return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
390 	}
391 	else
392 		return Move<VkImageView>();
393 }
394 
getPixelSize(VkFormat vkFormat)395 VkDeviceSize getPixelSize (VkFormat vkFormat)
396 {
397 	const tcu::TextureFormat	format	(mapVkFormat(vkFormat));
398 
399 	return format.getPixelSize();
400 }
401 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)402 Move<VkBuffer> createBuffer (const DeviceInterface&		vkd,
403 							 VkDevice					device,
404 							 VkFormat					format,
405 							 deUint32					width,
406 							 deUint32					height)
407 {
408 	const VkBufferUsageFlags	bufferUsage			(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
409 	const VkDeviceSize			pixelSize			(getPixelSize(format));
410 	const VkBufferCreateInfo	createInfo			=
411 	{
412 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
413 		DE_NULL,
414 		0u,
415 
416 		width * height * pixelSize,
417 		bufferUsage,
418 
419 		VK_SHARING_MODE_EXCLUSIVE,
420 		0u,
421 		DE_NULL
422 	};
423 	return createBuffer(vkd, device, &createInfo);
424 }
425 
sampleCountBitFromomSampleCount(deUint32 count)426 VkSampleCountFlagBits sampleCountBitFromomSampleCount (deUint32 count)
427 {
428 	switch (count)
429 	{
430 		case 1:  return VK_SAMPLE_COUNT_1_BIT;
431 		case 2:  return VK_SAMPLE_COUNT_2_BIT;
432 		case 4:  return VK_SAMPLE_COUNT_4_BIT;
433 		case 8:  return VK_SAMPLE_COUNT_8_BIT;
434 		case 16: return VK_SAMPLE_COUNT_16_BIT;
435 		case 32: return VK_SAMPLE_COUNT_32_BIT;
436 		case 64: return VK_SAMPLE_COUNT_64_BIT;
437 
438 		default:
439 			DE_FATAL("Invalid sample count");
440 			return (VkSampleCountFlagBits)(0x1u << count);
441 	}
442 }
443 
createMultisampleImages(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height)444 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface&	vki,
445 												VkPhysicalDevice			physicalDevice,
446 												const DeviceInterface&		vkd,
447 												VkDevice					device,
448 												VkFormat					format,
449 												deUint32					sampleCount,
450 												deUint32					width,
451 												deUint32					height)
452 {
453 	std::vector<VkImageSp> images (sampleCount);
454 
455 	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
456 		images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromomSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));
457 
458 	return images;
459 }
460 
createSingleSampleImages(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height)461 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface&	vki,
462 												 VkPhysicalDevice			physicalDevice,
463 												 const DeviceInterface&		vkd,
464 												 VkDevice					device,
465 												 VkFormat					format,
466 												 deUint32					sampleCount,
467 												 deUint32					width,
468 												 deUint32					height)
469 {
470 	std::vector<VkImageSp> images (sampleCount);
471 
472 	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
473 		images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height)));
474 
475 	return images;
476 }
477 
createImageMemory(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const std::vector<VkImageSp> images)478 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface&		vkd,
479 														   VkDevice						device,
480 														   Allocator&					allocator,
481 														   const std::vector<VkImageSp>	images)
482 {
483 	std::vector<de::SharedPtr<Allocation> > memory (images.size());
484 
485 	for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
486 		memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
487 
488 	return memory;
489 }
490 
createImageAttachmentViews(const DeviceInterface & vkd,VkDevice device,const std::vector<VkImageSp> & images,VkFormat format,VkImageAspectFlagBits aspect)491 std::vector<VkImageViewSp> createImageAttachmentViews (const DeviceInterface&			vkd,
492 													   VkDevice							device,
493 													   const std::vector<VkImageSp>&	images,
494 													   VkFormat							format,
495 													   VkImageAspectFlagBits			aspect)
496 {
497 	std::vector<VkImageViewSp> views (images.size());
498 
499 	for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
500 		views[imageNdx] = safeSharedPtr(new vk::Unique<VkImageView>(createImageAttachmentView(vkd, device, **images[imageNdx], format, aspect)));
501 
502 	return views;
503 }
504 
createBuffers(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height)505 std::vector<VkBufferSp> createBuffers (const DeviceInterface&	vkd,
506 									   VkDevice					device,
507 									   VkFormat					format,
508 									   deUint32					sampleCount,
509 									   deUint32					width,
510 									   deUint32					height)
511 {
512 	std::vector<VkBufferSp> buffers (sampleCount);
513 
514 	for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
515 		buffers[bufferNdx] = safeSharedPtr(new vk::Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));
516 
517 	return buffers;
518 }
519 
createBufferMemory(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const std::vector<VkBufferSp> buffers)520 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface&			vkd,
521 															VkDevice						device,
522 															Allocator&						allocator,
523 															const std::vector<VkBufferSp>	buffers)
524 {
525 	std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
526 
527 	for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
528 		memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
529 
530 	return memory;
531 }
532 
533 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,deUint32 sampleCount,RenderingType renderingType,TestSeparateUsage separateStencilUsage)534 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vkd,
535 									 VkDevice				device,
536 									 VkFormat				srcFormat,
537 									 VkFormat				dstFormat,
538 									 deUint32				sampleCount,
539 									 RenderingType			renderingType,
540 									 TestSeparateUsage		separateStencilUsage)
541 {
542 	const VkSampleCountFlagBits		samples						(sampleCountBitFromomSampleCount(sampleCount));
543 	const deUint32					splitSubpassCount			(deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT));
544 	const tcu::TextureFormat		format						(mapVkFormat(srcFormat));
545 	const bool						isDepthStencilFormat		(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
546 	const VkImageAspectFlags		inputAspect					(separateStencilUsage == TEST_DEPTH ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT
547 																: separateStencilUsage == TEST_STENCIL ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT
548 																									   : getImageAspectFlags(srcFormat));
549 	vector<SubpassDesc>				subpasses;
550 	vector<vector<AttachmentRef> >	dstAttachmentRefs			(splitSubpassCount);
551 	vector<vector<AttachmentRef> >	dstResolveAttachmentRefs	(splitSubpassCount);
552 	vector<AttachmentDesc>			attachments;
553 	vector<SubpassDep>				dependencies;
554 	const AttachmentRef				srcAttachmentRef				//  VkAttachmentReference										||  VkAttachmentReference2KHR
555 	(
556 																	//																||  VkStructureType						sType;
557 		DE_NULL,													//																||  const void*							pNext;
558 		0u,															//  deUint32						attachment;					||  deUint32							attachment;
559 		isDepthStencilFormat										//  VkImageLayout					layout;						||  VkImageLayout						layout;
560 			? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
561 			: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
562 		0u															//																||  VkImageAspectFlags					aspectMask;
563 	);
564 	const AttachmentRef				srcAttachmentInputRef			//  VkAttachmentReference										||  VkAttachmentReference2KHR
565 	(
566 																	//																||  VkStructureType						sType;
567 		DE_NULL,													//																||  const void*							pNext;
568 		0u,															//  deUint32						attachment;					||  deUint32							attachment;
569 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,					//  VkImageLayout					layout;						||  VkImageLayout						layout;
570 		(renderingType == RENDERING_TYPE_RENDERPASS2)				//																||  VkImageAspectFlags					aspectMask;
571 			? inputAspect
572 			: 0u
573 	);
574 
575 	{
576 		const AttachmentDesc srcAttachment							//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
577 		(
578 																	//																||  VkStructureType						sType;
579 			DE_NULL,												//																||  const void*							pNext;
580 			0u,														//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
581 			srcFormat,												//  VkFormat						format;						||  VkFormat							format;
582 			samples,												//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
583 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
584 			VK_ATTACHMENT_STORE_OP_DONT_CARE,						//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
585 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
586 			VK_ATTACHMENT_STORE_OP_DONT_CARE,						//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
587 			VK_IMAGE_LAYOUT_UNDEFINED,								//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
588 			VK_IMAGE_LAYOUT_GENERAL									//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
589 		);
590 
591 		attachments.push_back(srcAttachment);
592 	}
593 
594 	for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
595 	{
596 		for (deUint32 sampleNdx = 0; sampleNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount  - splitSubpassIndex * MAX_COLOR_ATTACHMENT_COUNT); sampleNdx++)
597 		{
598 			// Multisample color attachment
599 			{
600 				const AttachmentDesc dstAttachment					//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
601 				(
602 																	//																||  VkStructureType						sType;
603 					DE_NULL,										//																||  const void*							pNext;
604 					0u,												//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
605 					dstFormat,										//  VkFormat						format;						||  VkFormat							format;
606 					samples,										//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
607 					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
608 					VK_ATTACHMENT_STORE_OP_DONT_CARE,				//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
609 					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
610 					VK_ATTACHMENT_STORE_OP_DONT_CARE,				//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
611 					VK_IMAGE_LAYOUT_UNDEFINED,						//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
612 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
613 				);
614 				const AttachmentRef dstAttachmentRef				//  VkAttachmentReference										||  VkAttachmentReference2KHR
615 				(
616 																	//																||  VkStructureType						sType;
617 					DE_NULL,										//																||  const void*							pNext;
618 					(deUint32)attachments.size(),					//  deUint32						attachment;					||  deUint32							attachment;
619 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//  VkImageLayout					layout;						||  VkImageLayout						layout;
620 					0u												//																||  VkImageAspectFlags					aspectMask;
621 				);
622 
623 				attachments.push_back(dstAttachment);
624 				dstAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
625 			}
626 			// Resolve attachment
627 			{
628 				const AttachmentDesc dstAttachment					//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
629 				(
630 																	//																||  VkStructureType						sType;
631 					DE_NULL,										//																||  const void*							pNext;
632 					0u,												//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
633 					dstFormat,										//  VkFormat						format;						||  VkFormat							format;
634 					VK_SAMPLE_COUNT_1_BIT,							//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
635 					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
636 					VK_ATTACHMENT_STORE_OP_STORE,					//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
637 					VK_ATTACHMENT_LOAD_OP_DONT_CARE,				//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
638 					VK_ATTACHMENT_STORE_OP_STORE,					//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
639 					VK_IMAGE_LAYOUT_UNDEFINED,						//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
640 					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL			//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
641 				);
642 				const AttachmentRef dstAttachmentRef				//  VkAttachmentReference										||  VkAttachmentReference2KHR
643 				(
644 																	//																||  VkStructureType						sType;
645 					DE_NULL,										//																||  const void*							pNext;
646 					(deUint32)attachments.size(),					//  deUint32						attachment;					||  deUint32							attachment;
647 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//  VkImageLayout					layout;						||  VkImageLayout						layout;
648 					0u												//																||  VkImageAspectFlags					aspectMask;
649 				);
650 
651 				attachments.push_back(dstAttachment);
652 				dstResolveAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
653 			}
654 		}
655 	}
656 
657 	{
658 		{
659 			const SubpassDesc	subpass								//  VkSubpassDescription										||  VkSubpassDescription2KHR
660 			(
661 																	//																||  VkStructureType						sType;
662 				DE_NULL,											//																||  const void*							pNext;
663 				(VkSubpassDescriptionFlags)0,						//  VkSubpassDescriptionFlags		flags;						||  VkSubpassDescriptionFlags			flags;
664 				VK_PIPELINE_BIND_POINT_GRAPHICS,					//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
665 				0u,													//																||  deUint32							viewMask;
666 				0u,													//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
667 				DE_NULL,											//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
668 				isDepthStencilFormat ? 0u : 1u,						//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
669 				isDepthStencilFormat ? DE_NULL : &srcAttachmentRef,	//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
670 				DE_NULL,											//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
671 				isDepthStencilFormat ? &srcAttachmentRef : DE_NULL,	//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
672 				0u,													//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
673 				DE_NULL												//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
674 			);
675 
676 			subpasses.push_back(subpass);
677 		}
678 
679 		for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
680 		{
681 			{
682 				const SubpassDesc	subpass									//  VkSubpassDescription										||  VkSubpassDescription2KHR
683 				(
684 																			//																||  VkStructureType						sType;
685 					DE_NULL,												//																||  const void*							pNext;
686 					(VkSubpassDescriptionFlags)0,							//  VkSubpassDescriptionFlags		flags;						||  VkSubpassDescriptionFlags			flags;
687 					VK_PIPELINE_BIND_POINT_GRAPHICS,						//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
688 					0u,														//																||  deUint32							viewMask;
689 					1u,														//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
690 					&srcAttachmentInputRef,									//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
691 					(deUint32)dstAttachmentRefs[splitSubpassIndex].size(),	//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
692 					&dstAttachmentRefs[splitSubpassIndex][0],				//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
693 					&dstResolveAttachmentRefs[splitSubpassIndex][0],		//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
694 					DE_NULL,												//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
695 					0u,														//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
696 					DE_NULL													//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
697 				);
698 				subpasses.push_back(subpass);
699 			}
700 			{
701 				const SubpassDep	dependency																//  VkSubpassDependency							||  VkSubpassDependency2KHR
702 				(
703 																											//												||	VkStructureType			sType;
704 					DE_NULL,																				//												||	const void*				pNext;
705 					0u,																						//  deUint32				srcSubpass;			||	deUint32				srcSubpass;
706 					splitSubpassIndex + 1,																	//  deUint32				dstSubpass;			||	deUint32				dstSubpass;
707 					VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,											//  VkPipelineStageFlags	srcStageMask;		||	VkPipelineStageFlags	srcStageMask;
708 					VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,													//  VkPipelineStageFlags	dstStageMask;		||	VkPipelineStageFlags	dstStageMask;
709 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	//  VkAccessFlags			srcAccessMask;		||	VkAccessFlags			srcAccessMask;
710 					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,													//  VkAccessFlags			dstAccessMask;		||	VkAccessFlags			dstAccessMask;
711 					VK_DEPENDENCY_BY_REGION_BIT,															//  VkDependencyFlags		dependencyFlags;	||	VkDependencyFlags		dependencyFlags;
712 					0u																						//												||	deInt32					viewOffset;
713 				);
714 
715 				dependencies.push_back(dependency);
716 			}
717 		}
718 		// the last subpass must synchronize with all prior subpasses
719 		for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < (splitSubpassCount - 1); splitSubpassIndex++)
720 		{
721 				const SubpassDep	dependency																//  VkSubpassDependency							||  VkSubpassDependency2KHR
722 				(
723 																											//												||	VkStructureType			sType;
724 					DE_NULL,																				//												||	const void*				pNext;
725 					splitSubpassIndex + 1,																	//  deUint32				srcSubpass;			||	deUint32				srcSubpass;
726 					splitSubpassCount,																		//  deUint32				dstSubpass;			||	deUint32				dstSubpass;
727 					VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
728 					| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,											//  VkPipelineStageFlags	srcStageMask;		||	VkPipelineStageFlags	srcStageMask;
729 					VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,													//  VkPipelineStageFlags	dstStageMask;		||	VkPipelineStageFlags	dstStageMask;
730 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	//  VkAccessFlags			srcAccessMask;		||	VkAccessFlags			srcAccessMask;
731 					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,													//  VkAccessFlags			dstAccessMask;		||	VkAccessFlags			dstAccessMask;
732 					VK_DEPENDENCY_BY_REGION_BIT,															//  VkDependencyFlags		dependencyFlags;	||	VkDependencyFlags		dependencyFlags;
733 					0u																						//												||	deInt32					viewOffset;
734 				);
735 				dependencies.push_back(dependency);
736 		}
737 		const RenderPassCreateInfo	renderPassCreator						//  VkRenderPassCreateInfo										||  VkRenderPassCreateInfo2KHR
738 		(
739 																			//  VkStructureType					sType;						||  VkStructureType						sType;
740 			DE_NULL,														//  const void*						pNext;						||  const void*							pNext;
741 			(VkRenderPassCreateFlags)0u,									//  VkRenderPassCreateFlags			flags;						||  VkRenderPassCreateFlags				flags;
742 			(deUint32)attachments.size(),									//  deUint32						attachmentCount;			||  deUint32							attachmentCount;
743 			&attachments[0],												//  const VkAttachmentDescription*	pAttachments;				||  const VkAttachmentDescription2KHR*	pAttachments;
744 			(deUint32)subpasses.size(),										//  deUint32						subpassCount;				||  deUint32							subpassCount;
745 			&subpasses[0],													//  const VkSubpassDescription*		pSubpasses;					||  const VkSubpassDescription2KHR*		pSubpasses;
746 			(deUint32)dependencies.size(),									//  deUint32						dependencyCount;			||  deUint32							dependencyCount;
747 			&dependencies[0],												//  const VkSubpassDependency*		pDependencies;				||  const VkSubpassDependency2KHR*		pDependencies;
748 			0u,																//																||  deUint32							correlatedViewMaskCount;
749 			DE_NULL															//																||  const deUint32*						pCorrelatedViewMasks;
750 		);
751 
752 		return renderPassCreator.createRenderPass(vkd, device);
753 	}
754 }
755 
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,deUint32 sampleCount,const RenderingType renderingType,const TestSeparateUsage separateStencilUsage)756 Move<VkRenderPass> createRenderPass (const DeviceInterface&		vkd,
757 									 VkDevice					device,
758 									 VkFormat					srcFormat,
759 									 VkFormat					dstFormat,
760 									 deUint32					sampleCount,
761 									 const RenderingType		renderingType,
762 									 const TestSeparateUsage	separateStencilUsage)
763 {
764 	switch (renderingType)
765 	{
766 		case RENDERING_TYPE_RENDERPASS_LEGACY:
767 			return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
768 		case RENDERING_TYPE_RENDERPASS2:
769 			return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
770 		default:
771 			TCU_THROW(InternalError, "Impossible");
772 	}
773 }
774 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView srcImageView,const std::vector<VkImageViewSp> & dstMultisampleImageViews,const std::vector<VkImageViewSp> & dstSinglesampleImageViews,deUint32 width,deUint32 height)775 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&				vkd,
776 									   VkDevice								device,
777 									   VkRenderPass							renderPass,
778 									   VkImageView							srcImageView,
779 									   const std::vector<VkImageViewSp>&	dstMultisampleImageViews,
780 									   const std::vector<VkImageViewSp>&	dstSinglesampleImageViews,
781 									   deUint32								width,
782 									   deUint32								height)
783 {
784 	std::vector<VkImageView> attachments;
785 
786 	attachments.reserve(dstMultisampleImageViews.size() + dstSinglesampleImageViews.size() + 1u);
787 
788 	attachments.push_back(srcImageView);
789 
790 	DE_ASSERT(dstMultisampleImageViews.size() == dstSinglesampleImageViews.size());
791 
792 	for (size_t ndx = 0; ndx < dstMultisampleImageViews.size(); ndx++)
793 	{
794 		attachments.push_back(**dstMultisampleImageViews[ndx]);
795 		attachments.push_back(**dstSinglesampleImageViews[ndx]);
796 	}
797 
798 	const VkFramebufferCreateInfo createInfo =
799 	{
800 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
801 		DE_NULL,
802 		0u,
803 
804 		renderPass,
805 		(deUint32)attachments.size(),
806 		&attachments[0],
807 
808 		width,
809 		height,
810 		1u
811 	};
812 
813 	return createFramebuffer(vkd, device, &createInfo);
814 }
815 
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)816 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface&	vkd,
817 												   VkDevice					device)
818 {
819 	const VkPushConstantRange			pushConstant			=
820 	{
821 		VK_SHADER_STAGE_FRAGMENT_BIT,
822 		0u,
823 		4u
824 	};
825 	const VkPipelineLayoutCreateInfo	createInfo	=
826 	{
827 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
828 		DE_NULL,
829 		(vk::VkPipelineLayoutCreateFlags)0,
830 
831 		0u,
832 		DE_NULL,
833 
834 		1u,
835 		&pushConstant
836 	};
837 
838 	return createPipelineLayout(vkd, device, &createInfo);
839 }
840 
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::BinaryCollection & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)841 Move<VkPipeline> createRenderPipeline (const DeviceInterface&		vkd,
842 									   VkDevice						device,
843 									   VkFormat						srcFormat,
844 									   VkRenderPass					renderPass,
845 									   VkPipelineLayout				pipelineLayout,
846 									   const vk::BinaryCollection&	binaryCollection,
847 									   deUint32						width,
848 									   deUint32						height,
849 									   deUint32						sampleCount)
850 {
851 	const tcu::TextureFormat		format						(mapVkFormat(srcFormat));
852 	const bool						isDepthStencilFormat		(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
853 
854 	const Unique<VkShaderModule>	vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
855 	const Unique<VkShaderModule>	fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
856 	// Disable blending
857 	const VkPipelineColorBlendAttachmentState attachmentBlendState =
858 	{
859 		VK_FALSE,
860 		VK_BLEND_FACTOR_SRC_ALPHA,
861 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
862 		VK_BLEND_OP_ADD,
863 		VK_BLEND_FACTOR_ONE,
864 		VK_BLEND_FACTOR_ONE,
865 		VK_BLEND_OP_ADD,
866 		VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
867 	};
868 	const VkPipelineVertexInputStateCreateInfo vertexInputState =
869 	{
870 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
871 		DE_NULL,
872 		(VkPipelineVertexInputStateCreateFlags)0u,
873 
874 		0u,
875 		DE_NULL,
876 
877 		0u,
878 		DE_NULL
879 	};
880 	const std::vector<VkViewport>	viewports	(1, makeViewport(tcu::UVec2(width, height)));
881 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(tcu::UVec2(width, height)));
882 
883 	const VkPipelineMultisampleStateCreateInfo multisampleState =
884 	{
885 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
886 		DE_NULL,
887 		(VkPipelineMultisampleStateCreateFlags)0u,
888 
889 		sampleCountBitFromomSampleCount(sampleCount),
890 		VK_FALSE,
891 		0.0f,
892 		DE_NULL,
893 		VK_FALSE,
894 		VK_FALSE,
895 	};
896 	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
897 	{
898 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
899 		DE_NULL,
900 		(VkPipelineDepthStencilStateCreateFlags)0u,
901 
902 		VK_TRUE,
903 		VK_TRUE,
904 		VK_COMPARE_OP_ALWAYS,
905 		VK_FALSE,
906 		VK_TRUE,
907 		{
908 			VK_STENCIL_OP_KEEP,
909 			VK_STENCIL_OP_INCREMENT_AND_WRAP,
910 			VK_STENCIL_OP_KEEP,
911 			VK_COMPARE_OP_ALWAYS,
912 			~0u,
913 			~0u,
914 			0xFFu / (sampleCount + 1)
915 		},
916 		{
917 			VK_STENCIL_OP_KEEP,
918 			VK_STENCIL_OP_INCREMENT_AND_WRAP,
919 			VK_STENCIL_OP_KEEP,
920 			VK_COMPARE_OP_ALWAYS,
921 			~0u,
922 			~0u,
923 			0xFFu / (sampleCount + 1)
924 		},
925 
926 		0.0f,
927 		1.0f
928 	};
929 	const VkPipelineColorBlendStateCreateInfo blendState =
930 	{
931 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
932 		DE_NULL,
933 		(VkPipelineColorBlendStateCreateFlags)0u,
934 
935 		VK_FALSE,
936 		VK_LOGIC_OP_COPY,
937 		(isDepthStencilFormat ? 0u : 1u),
938 		(isDepthStencilFormat ? DE_NULL : &attachmentBlendState),
939 		{ 0.0f, 0.0f, 0.0f, 0.0f }
940 	};
941 
942 	return makeGraphicsPipeline(vkd,									// const DeviceInterface&                        vk
943 								device,									// const VkDevice                                device
944 								pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
945 								*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
946 								DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
947 								DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
948 								DE_NULL,								// const VkShaderModule                          geometryShaderModule
949 								*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
950 								renderPass,								// const VkRenderPass                            renderPass
951 								viewports,								// const std::vector<VkViewport>&                viewports
952 								scissors,								// const std::vector<VkRect2D>&                  scissors
953 								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
954 								0u,										// const deUint32                                subpass
955 								0u,										// const deUint32                                patchControlPoints
956 								&vertexInputState,						// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
957 								DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
958 								&multisampleState,						// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
959 								&depthStencilState,						// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
960 								&blendState);							// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
961 }
962 
createSplitDescriptorSetLayout(const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat)963 Move<VkDescriptorSetLayout> createSplitDescriptorSetLayout (const DeviceInterface&	vkd,
964 															VkDevice				device,
965 															VkFormat				vkFormat)
966 {
967 	const tcu::TextureFormat				format		(mapVkFormat(vkFormat));
968 	const bool								hasDepth	(tcu::hasDepthComponent(format.order));
969 	const bool								hasStencil	(tcu::hasStencilComponent(format.order));
970 	const VkDescriptorSetLayoutBinding		bindings[]	=
971 	{
972 		{
973 			0u,
974 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
975 			1u,
976 			VK_SHADER_STAGE_FRAGMENT_BIT,
977 			DE_NULL
978 		},
979 		{
980 			1u,
981 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
982 			1u,
983 			VK_SHADER_STAGE_FRAGMENT_BIT,
984 			DE_NULL
985 		}
986 	};
987 	const VkDescriptorSetLayoutCreateInfo	createInfo	=
988 	{
989 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
990 		DE_NULL,
991 		0u,
992 
993 		hasDepth && hasStencil ? 2u : 1u,
994 		bindings
995 	};
996 
997 	return createDescriptorSetLayout(vkd, device, &createInfo);
998 }
999 
createSplitPipelineLayout(const DeviceInterface & vkd,VkDevice device,VkDescriptorSetLayout descriptorSetLayout)1000 Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface&	vkd,
1001 												  VkDevice					device,
1002 												  VkDescriptorSetLayout		descriptorSetLayout)
1003 {
1004 	const VkPushConstantRange			pushConstant			=
1005 	{
1006 		VK_SHADER_STAGE_FRAGMENT_BIT,
1007 		0u,
1008 		4u
1009 	};
1010 	const VkPipelineLayoutCreateInfo	createInfo	=
1011 	{
1012 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1013 		DE_NULL,
1014 		(vk::VkPipelineLayoutCreateFlags)0,
1015 
1016 		1u,
1017 		&descriptorSetLayout,
1018 
1019 		1u,
1020 		&pushConstant
1021 	};
1022 
1023 	return createPipelineLayout(vkd, device, &createInfo);
1024 }
1025 
createSplitPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,deUint32 subpassIndex,VkPipelineLayout pipelineLayout,const vk::BinaryCollection & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)1026 Move<VkPipeline> createSplitPipeline (const DeviceInterface&		vkd,
1027 									  VkDevice						device,
1028 									  VkRenderPass					renderPass,
1029 									  deUint32						subpassIndex,
1030 									  VkPipelineLayout				pipelineLayout,
1031 									  const vk::BinaryCollection&	binaryCollection,
1032 									  deUint32						width,
1033 									  deUint32						height,
1034 									  deUint32						sampleCount)
1035 {
1036 	const Unique<VkShaderModule>	vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
1037 	const Unique<VkShaderModule>	fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 0u));
1038 	// Disable blending
1039 	const VkPipelineColorBlendAttachmentState attachmentBlendState =
1040 	{
1041 		VK_FALSE,
1042 		VK_BLEND_FACTOR_SRC_ALPHA,
1043 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1044 		VK_BLEND_OP_ADD,
1045 		VK_BLEND_FACTOR_ONE,
1046 		VK_BLEND_FACTOR_ONE,
1047 		VK_BLEND_OP_ADD,
1048 		VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1049 	};
1050 	const std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates (de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount), attachmentBlendState);
1051 	const VkPipelineVertexInputStateCreateInfo vertexInputState =
1052 	{
1053 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1054 		DE_NULL,
1055 		(VkPipelineVertexInputStateCreateFlags)0u,
1056 
1057 		0u,
1058 		DE_NULL,
1059 
1060 		0u,
1061 		DE_NULL
1062 	};
1063 	const std::vector<VkViewport>	viewports	(1, makeViewport(tcu::UVec2(width, height)));
1064 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(tcu::UVec2(width, height)));
1065 
1066 	const VkPipelineMultisampleStateCreateInfo multisampleState =
1067 	{
1068 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1069 		DE_NULL,
1070 		(VkPipelineMultisampleStateCreateFlags)0u,
1071 
1072 		sampleCountBitFromomSampleCount(sampleCount),
1073 		VK_FALSE,
1074 		0.0f,
1075 		DE_NULL,
1076 		VK_FALSE,
1077 		VK_FALSE,
1078 	};
1079 	const VkPipelineColorBlendStateCreateInfo blendState =
1080 	{
1081 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1082 		DE_NULL,
1083 		(VkPipelineColorBlendStateCreateFlags)0u,
1084 
1085 		VK_FALSE,
1086 		VK_LOGIC_OP_COPY,
1087 
1088 		(deUint32)attachmentBlendStates.size(),
1089 		&attachmentBlendStates[0],
1090 
1091 		{ 0.0f, 0.0f, 0.0f, 0.0f }
1092 	};
1093 
1094 	return makeGraphicsPipeline(vkd,									// const DeviceInterface&                        vk
1095 								device,									// const VkDevice                                device
1096 								pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
1097 								*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
1098 								DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
1099 								DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
1100 								DE_NULL,								// const VkShaderModule                          geometryShaderModule
1101 								*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
1102 								renderPass,								// const VkRenderPass                            renderPass
1103 								viewports,								// const std::vector<VkViewport>&                viewports
1104 								scissors,								// const std::vector<VkRect2D>&                  scissors
1105 								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
1106 								subpassIndex,							// const deUint32                                subpass
1107 								0u,										// const deUint32                                patchControlPoints
1108 								&vertexInputState,						// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
1109 								DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1110 								&multisampleState,						// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
1111 								DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
1112 								&blendState);							// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
1113 }
1114 
createSplitPipelines(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::BinaryCollection & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)1115 vector<VkPipelineSp> createSplitPipelines (const DeviceInterface&		vkd,
1116 										 VkDevice						device,
1117 										 VkRenderPass					renderPass,
1118 										 VkPipelineLayout				pipelineLayout,
1119 										 const vk::BinaryCollection&	binaryCollection,
1120 										 deUint32						width,
1121 										 deUint32						height,
1122 										 deUint32						sampleCount)
1123 {
1124 	std::vector<VkPipelineSp> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipelineSp)0u);
1125 
1126 	for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
1127 		pipelines[ndx] = safeSharedPtr(new Unique<VkPipeline>(createSplitPipeline(vkd, device, renderPass, (deUint32)(ndx + 1), pipelineLayout, binaryCollection, width, height, sampleCount)));
1128 
1129 	return pipelines;
1130 }
1131 
createSplitDescriptorPool(const DeviceInterface & vkd,VkDevice device)1132 Move<VkDescriptorPool> createSplitDescriptorPool (const DeviceInterface&	vkd,
1133 												  VkDevice					device)
1134 {
1135 	const VkDescriptorPoolSize			size		=
1136 	{
1137 		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
1138 	};
1139 	const VkDescriptorPoolCreateInfo	createInfo	=
1140 	{
1141 		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1142 		DE_NULL,
1143 		VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1144 
1145 
1146 		2u,
1147 		1u,
1148 		&size
1149 	};
1150 
1151 	return createDescriptorPool(vkd, device, &createInfo);
1152 }
1153 
createSplitDescriptorSet(const DeviceInterface & vkd,VkDevice device,VkDescriptorPool pool,VkDescriptorSetLayout layout,VkImageView primaryImageView,VkImageView secondaryImageView)1154 Move<VkDescriptorSet> createSplitDescriptorSet (const DeviceInterface&	vkd,
1155 												VkDevice				device,
1156 												VkDescriptorPool		pool,
1157 												VkDescriptorSetLayout	layout,
1158 												VkImageView				primaryImageView,
1159 												VkImageView				secondaryImageView)
1160 {
1161 	const VkDescriptorSetAllocateInfo	allocateInfo	=
1162 	{
1163 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1164 		DE_NULL,
1165 
1166 		pool,
1167 		1u,
1168 		&layout
1169 	};
1170 	Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));
1171 
1172 	{
1173 		const VkDescriptorImageInfo	imageInfos[]	=
1174 		{
1175 			{
1176 				(VkSampler)0u,
1177 				primaryImageView,
1178 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1179 			},
1180 			{
1181 				(VkSampler)0u,
1182 				secondaryImageView,
1183 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1184 			}
1185 		};
1186 		const VkWriteDescriptorSet	writes[]	=
1187 		{
1188 			{
1189 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1190 				DE_NULL,
1191 
1192 				*set,
1193 				0u,
1194 				0u,
1195 				1u,
1196 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1197 				&imageInfos[0],
1198 				DE_NULL,
1199 				DE_NULL
1200 			},
1201 			{
1202 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1203 				DE_NULL,
1204 
1205 				*set,
1206 				1u,
1207 				0u,
1208 				1u,
1209 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1210 				&imageInfos[1],
1211 				DE_NULL,
1212 				DE_NULL
1213 			}
1214 		};
1215 		const deUint32	count	= secondaryImageView != (VkImageView)0
1216 								? 2u
1217 								: 1u;
1218 
1219 		vkd.updateDescriptorSets(device, count, writes, 0u, DE_NULL);
1220 	}
1221 	return set;
1222 }
1223 
1224 struct TestConfig
1225 {
TestConfigvkt::__anon5531f2100111::TestConfig1226 				TestConfig		(VkFormat			format_,
1227 								 deUint32			sampleCount_,
1228 								 RenderingType		renderingType_,
1229 								 TestSeparateUsage	separateStencilUsage_ = (TestSeparateUsage)0u)
1230 		: format			(format_)
1231 		, sampleCount		(sampleCount_)
1232 		, renderingType		(renderingType_)
1233 		, separateStencilUsage(separateStencilUsage_)
1234 	{
1235 	}
1236 
1237 	VkFormat			format;
1238 	deUint32			sampleCount;
1239 	RenderingType		renderingType;
1240 	TestSeparateUsage	separateStencilUsage;
1241 };
1242 
getSrcImageUsage(VkFormat vkFormat)1243 VkImageUsageFlags getSrcImageUsage (VkFormat vkFormat)
1244 {
1245 	const tcu::TextureFormat	format		(mapVkFormat(vkFormat));
1246 	const bool					hasDepth	(tcu::hasDepthComponent(format.order));
1247 	const bool					hasStencil	(tcu::hasStencilComponent(format.order));
1248 
1249 	if (hasDepth || hasStencil)
1250 		return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1251 	else
1252 		return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1253 }
1254 
getDstFormat(VkFormat vkFormat,TestSeparateUsage separateStencilUsage)1255 VkFormat getDstFormat (VkFormat vkFormat, TestSeparateUsage separateStencilUsage)
1256 {
1257 	const tcu::TextureFormat	format		(mapVkFormat(vkFormat));
1258 	const bool					hasDepth	(tcu::hasDepthComponent(format.order));
1259 	const bool					hasStencil	(tcu::hasStencilComponent(format.order));
1260 
1261 	if (hasDepth && hasStencil && !separateStencilUsage)
1262 		return VK_FORMAT_R32G32_SFLOAT;
1263 	else if (hasDepth || hasStencil)
1264 		return VK_FORMAT_R32_SFLOAT;
1265 	else
1266 		return vkFormat;
1267 }
1268 
isExtensionSupported(Context & context,RenderingType renderingType,TestSeparateUsage separateStencilUsage,VkFormat format)1269 bool isExtensionSupported(Context& context, RenderingType renderingType, TestSeparateUsage separateStencilUsage, VkFormat format)
1270 {
1271 	if (renderingType == RENDERING_TYPE_RENDERPASS2)
1272 		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
1273 
1274 	if (separateStencilUsage)
1275 	{
1276 		context.requireDeviceFunctionality	("VK_EXT_separate_stencil_usage");
1277 		context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1278 	}
1279 
1280 #ifndef CTS_USES_VULKANSC
1281 	if (format == VK_FORMAT_A8_UNORM_KHR)
1282 		context.requireDeviceFunctionality("VK_KHR_maintenance5");
1283 #else
1284 	DE_UNREF(format);
1285 #endif // CTS_USES_VULKANSC
1286 
1287 	return true;
1288 }
1289 
1290 
1291 class MultisampleRenderPassTestInstance : public TestInstance
1292 {
1293 public:
1294 					MultisampleRenderPassTestInstance	(Context& context, TestConfig config);
1295 					~MultisampleRenderPassTestInstance	(void);
1296 
1297 	tcu::TestStatus	iterate								(void);
1298 
1299 	template<typename RenderpassSubpass>
1300 	tcu::TestStatus	iterateInternal						(void);
1301 
1302 private:
1303 	const bool										m_extensionSupported;
1304 	const RenderingType								m_renderingType;
1305 	const TestSeparateUsage							m_separateStencilUsage;
1306 
1307 	const VkFormat									m_srcFormat;
1308 	const VkFormat									m_dstFormat;
1309 	const deUint32									m_sampleCount;
1310 	const deUint32									m_width;
1311 	const deUint32									m_height;
1312 
1313 	const VkImageAspectFlags						m_srcImageAspect;
1314 	const VkImageUsageFlags							m_srcImageUsage;
1315 	const Unique<VkImage>							m_srcImage;
1316 	const de::UniquePtr<Allocation>					m_srcImageMemory;
1317 	const Unique<VkImageView>						m_srcImageView;
1318 	const Unique<VkImageView>						m_srcPrimaryInputImageView;
1319 	const Unique<VkImageView>						m_srcSecondaryInputImageView;
1320 
1321 	const std::vector<VkImageSp>					m_dstMultisampleImages;
1322 	const std::vector<de::SharedPtr<Allocation> >	m_dstMultisampleImageMemory;
1323 	const std::vector<VkImageViewSp>				m_dstMultisampleImageViews;
1324 
1325 	const std::vector<VkImageSp>					m_dstSinglesampleImages;
1326 	const std::vector<de::SharedPtr<Allocation> >	m_dstSinglesampleImageMemory;
1327 	const std::vector<VkImageViewSp>				m_dstSinglesampleImageViews;
1328 
1329 	const std::vector<VkBufferSp>					m_dstBuffers;
1330 	const std::vector<de::SharedPtr<Allocation> >	m_dstBufferMemory;
1331 
1332 	const Unique<VkRenderPass>						m_renderPass;
1333 	const Unique<VkFramebuffer>						m_framebuffer;
1334 
1335 	const Unique<VkPipelineLayout>					m_renderPipelineLayout;
1336 	const Unique<VkPipeline>						m_renderPipeline;
1337 
1338 	const Unique<VkDescriptorSetLayout>				m_splitDescriptorSetLayout;
1339 	const Unique<VkPipelineLayout>					m_splitPipelineLayout;
1340 	const std::vector<VkPipelineSp>					m_splitPipelines;
1341 	const Unique<VkDescriptorPool>					m_splitDescriptorPool;
1342 	const Unique<VkDescriptorSet>					m_splitDescriptorSet;
1343 
1344 	const Unique<VkCommandPool>						m_commandPool;
1345 	tcu::ResultCollector							m_resultCollector;
1346 };
1347 
MultisampleRenderPassTestInstance(Context & context,TestConfig config)1348 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1349 	: TestInstance					(context)
1350 	, m_extensionSupported			(isExtensionSupported(context, config.renderingType, config.separateStencilUsage, config.format))
1351 	, m_renderingType				(config.renderingType)
1352 	, m_separateStencilUsage		(config.separateStencilUsage)
1353 	, m_srcFormat					(config.format)
1354 	, m_dstFormat					(getDstFormat(config.format, config.separateStencilUsage))
1355 	, m_sampleCount					(config.sampleCount)
1356 	, m_width						(32u)
1357 	, m_height						(32u)
1358 
1359 	, m_srcImageAspect				(getImageAspectFlags(m_srcFormat))
1360 	, m_srcImageUsage				(getSrcImageUsage(m_srcFormat))
1361 	, m_srcImage					(createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height, m_separateStencilUsage))
1362 	, m_srcImageMemory				(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1363 	, m_srcImageView				(createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1364 	, m_srcPrimaryInputImageView	(createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1365 	, m_srcSecondaryInputImageView	(createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1366 
1367 	, m_dstMultisampleImages		(createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1368 	, m_dstMultisampleImageMemory	(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1369 	, m_dstMultisampleImageViews	(createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1370 
1371 	, m_dstSinglesampleImages		(createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1372 	, m_dstSinglesampleImageMemory	(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1373 	, m_dstSinglesampleImageViews	(createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1374 
1375 	, m_dstBuffers					(createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1376 	, m_dstBufferMemory				(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1377 
1378 	, m_renderPass					(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount, config.renderingType, m_separateStencilUsage))
1379 	, m_framebuffer					(createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1380 
1381 	, m_renderPipelineLayout		(createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1382 	, m_renderPipeline				(createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1383 
1384 	, m_splitDescriptorSetLayout	(createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1385 	, m_splitPipelineLayout			(createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1386 	, m_splitPipelines				(createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1387 	, m_splitDescriptorPool			(createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1388 	, m_splitDescriptorSet			(createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1389 	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1390 {
1391 }
1392 
~MultisampleRenderPassTestInstance(void)1393 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1394 {
1395 }
1396 
iterate(void)1397 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1398 {
1399 	switch (m_renderingType)
1400 	{
1401 		case RENDERING_TYPE_RENDERPASS_LEGACY:
1402 			return iterateInternal<RenderpassSubpass1>();
1403 		case RENDERING_TYPE_RENDERPASS2:
1404 			return iterateInternal<RenderpassSubpass2>();
1405 		default:
1406 			TCU_THROW(InternalError, "Impossible");
1407 	}
1408 }
1409 
1410 template<typename RenderpassSubpass>
iterateInternal(void)1411 tcu::TestStatus MultisampleRenderPassTestInstance::iterateInternal (void)
1412 {
1413 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
1414 	const VkDevice										device				(m_context.getDevice());
1415 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1416 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1417 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
1418 
1419 	beginCommandBuffer(vkd, *commandBuffer);
1420 
1421 	{
1422 		const VkRenderPassBeginInfo beginInfo =
1423 		{
1424 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1425 			DE_NULL,
1426 
1427 			*m_renderPass,
1428 			*m_framebuffer,
1429 
1430 			{
1431 				{ 0u, 0u },
1432 				{ m_width, m_height }
1433 			},
1434 
1435 			0u,
1436 			DE_NULL
1437 		};
1438 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1439 
1440 		// Stencil needs to be cleared if it exists.
1441 		if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
1442 		{
1443 			const VkClearAttachment clearAttachment =
1444 			{
1445 				VK_IMAGE_ASPECT_STENCIL_BIT,						// VkImageAspectFlags	aspectMask;
1446 				0,													// deUint32				colorAttachment;
1447 				makeClearValueDepthStencil(0, 0)					// VkClearValue			clearValue;
1448 			};
1449 
1450 			const VkClearRect clearRect =
1451 			{
1452 				{
1453 					{ 0u, 0u },
1454 					{ m_width, m_height }
1455 				},
1456 				0,													// deUint32	baseArrayLayer;
1457 				1													// deUint32	layerCount;
1458 			};
1459 
1460 			vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
1461 		}
1462 	}
1463 
1464 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1465 
1466 	for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1467 	{
1468 		vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1469 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1470 	}
1471 
1472 	for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1473 	{
1474 		RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1475 
1476 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
1477 		vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u,  &*m_splitDescriptorSet, 0u, DE_NULL);
1478 		vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1479 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1480 	}
1481 
1482 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1483 
1484 	for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1485 		copyImageToBuffer(vkd, *commandBuffer, **m_dstSinglesampleImages[dstNdx], **m_dstBuffers[dstNdx], tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1486 
1487 	endCommandBuffer(vkd, *commandBuffer);
1488 
1489 	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1490 
1491 	{
1492 		const tcu::TextureFormat		format			(mapVkFormat(m_dstFormat));
1493 		const tcu::TextureFormat		srcFormat		(mapVkFormat(m_srcFormat));
1494 		const bool						verifyDepth		(m_separateStencilUsage ? (m_separateStencilUsage == TEST_DEPTH)   : tcu::hasDepthComponent(srcFormat.order));
1495 		const bool						verifyStencil	(m_separateStencilUsage ? (m_separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(srcFormat.order));
1496 
1497 		for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1498 		{
1499 			Allocation *dstBufMem = m_dstBufferMemory[sampleNdx].get();
1500 			invalidateAlloc(vkd, device, *dstBufMem);
1501 
1502 			const std::string					name		("Sample" + de::toString(sampleNdx));
1503 			const void* const					ptr			(dstBufMem->getHostPtr());
1504 			const tcu::ConstPixelBufferAccess	access		(format, m_width, m_height, 1, ptr);
1505 			tcu::TextureLevel					reference	(format, m_width, m_height);
1506 
1507 			if (verifyDepth || verifyStencil)
1508 			{
1509 				if (verifyDepth)
1510 				{
1511 					for (deUint32 y = 0; y < m_height; y++)
1512 					for (deUint32 x = 0; x < m_width; x++)
1513 					{
1514 						const deUint32	x1				= x ^ sampleNdx;
1515 						const deUint32	y1				= y ^ sampleNdx;
1516 						const float		range			= 1.0f;
1517 						float			depth			= 0.0f;
1518 						deUint32		divider			= 2;
1519 
1520 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1521 						for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1522 						{
1523 							depth += (range / (float)divider)
1524 									* (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1525 							divider *= 2;
1526 						}
1527 
1528 						reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1529 					}
1530 				}
1531 				if (verifyStencil)
1532 				{
1533 					for (deUint32 y = 0; y < m_height; y++)
1534 					for (deUint32 x = 0; x < m_width; x++)
1535 					{
1536 						const deUint32	stencil	= sampleNdx + 1u;
1537 
1538 						if (verifyDepth)
1539 						{
1540 							const Vec4 src (reference.getAccess().getPixel(x, y));
1541 
1542 							reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1543 						}
1544 						else
1545 							reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1546 					}
1547 				}
1548 				{
1549 					const Vec4 threshold (verifyDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1550 
1551 					if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1552 						m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1553 				}
1554 			}
1555 			else
1556 			{
1557 				const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
1558 
1559 				switch (channelClass)
1560 				{
1561 					case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1562 					{
1563 						const UVec4		bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1564 						const UVec4		minValue		(0);
1565 						const UVec4		range			(UVec4(1u) << tcu::min(bits, UVec4(31)));
1566 						const int		componentCount	(tcu::getNumUsedChannels(format.order));
1567 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1568 
1569 						for (deUint32 y = 0; y < m_height; y++)
1570 						for (deUint32 x = 0; x < m_width; x++)
1571 						{
1572 							const deUint32	x1				= x ^ sampleNdx;
1573 							const deUint32	y1				= y ^ sampleNdx;
1574 							UVec4			color			(minValue);
1575 							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1576 							deUint32		nextSrcBit		= 0;
1577 							deUint32		divider			= 2;
1578 
1579 							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1580 							while (nextSrcBit < de::min(bitSize, 10u))
1581 							{
1582 								for (int compNdx = 0; compNdx < componentCount; compNdx++)
1583 								{
1584 									if (dstBitsUsed[compNdx] > bits[compNdx])
1585 										continue;
1586 
1587 									color[compNdx] += (range[compNdx] / divider)
1588 													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1589 
1590 									nextSrcBit++;
1591 									dstBitsUsed[compNdx]++;
1592 								}
1593 
1594 								divider *= 2;
1595 							}
1596 
1597 							reference.getAccess().setPixel(color, x, y);
1598 						}
1599 
1600 						if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1601 							m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1602 
1603 						break;
1604 					}
1605 
1606 					case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1607 					{
1608 						const UVec4		bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1609 						const IVec4		minValue		(0);
1610 						const IVec4		range			((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1611 						const int		componentCount	(tcu::getNumUsedChannels(format.order));
1612 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1613 
1614 						for (deUint32 y = 0; y < m_height; y++)
1615 						for (deUint32 x = 0; x < m_width; x++)
1616 						{
1617 							const deUint32	x1				= x ^ sampleNdx;
1618 							const deUint32	y1				= y ^ sampleNdx;
1619 							IVec4			color			(minValue);
1620 							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1621 							deUint32		nextSrcBit		= 0;
1622 							deUint32		divider			= 2;
1623 
1624 							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1625 							while (nextSrcBit < de::min(bitSize, 10u))
1626 							{
1627 								for (int compNdx = 0; compNdx < componentCount; compNdx++)
1628 								{
1629 									if (dstBitsUsed[compNdx] > bits[compNdx])
1630 										continue;
1631 
1632 									color[compNdx] += (range[compNdx] / divider)
1633 													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1634 
1635 									nextSrcBit++;
1636 									dstBitsUsed[compNdx]++;
1637 								}
1638 
1639 								divider *= 2;
1640 							}
1641 
1642 							reference.getAccess().setPixel(color, x, y);
1643 						}
1644 
1645 						if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1646 							m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1647 
1648 						break;
1649 					}
1650 
1651 					case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1652 					case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1653 					case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1654 					{
1655 						const tcu::TextureFormatInfo	info			(tcu::getTextureFormatInfo(format));
1656 						const UVec4						bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1657 						const Vec4						minLimit		(-65536.0);
1658 						const Vec4						maxLimit		(65536.0);
1659 						const Vec4						minValue		(tcu::max(info.valueMin, minLimit));
1660 						const Vec4						range			(tcu::min(info.valueMax, maxLimit) - minValue);
1661 						const bool						isAlphaOnly		= isAlphaOnlyFormat(m_dstFormat);
1662 						const int						componentCount	(isAlphaOnly ? 4 : tcu::getNumUsedChannels(format.order));
1663 						const deUint32					bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1664 
1665 						for (deUint32 y = 0; y < m_height; y++)
1666 						for (deUint32 x = 0; x < m_width; x++)
1667 						{
1668 							const deUint32	x1				= x ^ sampleNdx;
1669 							const deUint32	y1				= y ^ sampleNdx;
1670 							Vec4			color			(minValue);
1671 							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1672 							deUint32		nextSrcBit		= 0;
1673 							deUint32		divider			= 2;
1674 
1675 							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1676 							while (nextSrcBit < de::min(bitSize, 10u))
1677 							{
1678 								for (int compNdx = 0; compNdx < componentCount; compNdx++)
1679 								{
1680 									if (dstBitsUsed[compNdx] > bits[compNdx])
1681 										continue;
1682 
1683 									color[compNdx] += (range[compNdx] / (float)divider)
1684 													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1685 
1686 									nextSrcBit++;
1687 									dstBitsUsed[compNdx]++;
1688 								}
1689 
1690 								divider *= 2;
1691 							}
1692 
1693 							if (tcu::isSRGB(format))
1694 								reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1695 							else
1696 								reference.getAccess().setPixel(color, x, y);
1697 						}
1698 
1699 						if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1700 						{
1701 							// Convert target format ulps to float ulps and allow 64ulp differences
1702 							const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1703 
1704 							if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1705 								m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1706 						}
1707 						else
1708 						{
1709 							// Allow error of 4 times the minimum presentable difference
1710 							const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1711 
1712 							if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1713 								m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1714 						}
1715 
1716 						break;
1717 					}
1718 
1719 					default:
1720 						DE_FATAL("Unknown channel class");
1721 				}
1722 			}
1723 		}
1724 	}
1725 
1726 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1727 }
1728 
1729 struct Programs
1730 {
initvkt::__anon5531f2100111::Programs1731 	void init (vk::SourceCollections& dst, TestConfig config) const
1732 	{
1733 		const tcu::TextureFormat		format			(mapVkFormat(config.format));
1734 		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
1735 		const bool						testDepth		(config.separateStencilUsage ? (config.separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(format.order));
1736 		const bool						testStencil		(config.separateStencilUsage ? (config.separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(format.order));
1737 
1738 		dst.glslSources.add("quad-vert") << glu::VertexSource(
1739 			"#version 450\n"
1740 			"out gl_PerVertex {\n"
1741 			"\tvec4 gl_Position;\n"
1742 			"};\n"
1743 			"highp float;\n"
1744 			"void main (void) {\n"
1745 			"\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1746 			"\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1747 			"}\n");
1748 
1749 		if (testDepth)
1750 		{
1751 			const Vec4			minValue		(0.0f);
1752 			const Vec4			range			(1.0f);
1753 			std::ostringstream	fragmentShader;
1754 
1755 			fragmentShader <<
1756 				"#version 450\n"
1757 				"layout(push_constant) uniform PushConstant {\n"
1758 				"\thighp uint sampleIndex;\n"
1759 				"} pushConstants;\n"
1760 				"void main (void)\n"
1761 				"{\n"
1762 				"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1763 				"\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1764 				"\thighp float depth;\n"
1765 				"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1766 				"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1767 
1768 			fragmentShader << "\tdepth = "  << minValue[0] << ";\n";
1769 
1770 			{
1771 				deUint32 divider = 2;
1772 
1773 				// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1774 				for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1775 				{
1776 					fragmentShader <<
1777 							"\tdepth += " << (range[0] / (float)divider)
1778 							<< " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1779 
1780 					divider *= 2;
1781 				}
1782 			}
1783 
1784 			fragmentShader <<
1785 				"\tgl_FragDepth = depth;\n"
1786 				"}\n";
1787 
1788 			dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1789 		}
1790 		else if (testStencil)
1791 		{
1792 			dst.glslSources.add("quad-frag") << glu::FragmentSource(
1793 				"#version 450\n"
1794 				"layout(push_constant) uniform PushConstant {\n"
1795 				"\thighp uint sampleIndex;\n"
1796 				"} pushConstants;\n"
1797 				"void main (void)\n"
1798 				"{\n"
1799 				"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1800 				"\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1801 				"}\n");
1802 		}
1803 		else
1804 		{
1805 			switch (channelClass)
1806 			{
1807 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1808 				{
1809 					const UVec4	bits		(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1810 					const UVec4 minValue	(0);
1811 					const UVec4 range		(UVec4(1u) << tcu::min(bits, UVec4(31)));
1812 					std::ostringstream		fragmentShader;
1813 
1814 					fragmentShader <<
1815 						"#version 450\n"
1816 						"layout(location = 0) out highp uvec4 o_color;\n"
1817 						"layout(push_constant) uniform PushConstant {\n"
1818 						"\thighp uint sampleIndex;\n"
1819 						"} pushConstants;\n"
1820 						"void main (void)\n"
1821 						"{\n"
1822 						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1823 						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1824 						"\thighp uint color[4];\n"
1825 						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1826 						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1827 
1828 					for (int ndx = 0; ndx < 4; ndx++)
1829 						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1830 
1831 					{
1832 						const int		componentCount	= tcu::getNumUsedChannels(format.order);
1833 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1834 						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1835 						deUint32		nextSrcBit		= 0;
1836 						deUint32		divider			= 2;
1837 
1838 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1839 						while (nextSrcBit < de::min(bitSize, 10u))
1840 						{
1841 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
1842 							{
1843 								if (dstBitsUsed[compNdx] > bits[compNdx])
1844 									continue;
1845 
1846 								fragmentShader <<
1847 										"\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1848 										<< " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1849 
1850 								nextSrcBit++;
1851 								dstBitsUsed[compNdx]++;
1852 							}
1853 
1854 							divider *= 2;
1855 						}
1856 					}
1857 
1858 					fragmentShader <<
1859 						"\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1860 						"}\n";
1861 
1862 					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1863 					break;
1864 				}
1865 
1866 				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1867 				{
1868 					const UVec4	bits		(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1869 					const IVec4 minValue	(0);
1870 					const IVec4 range		((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1871 					const IVec4 maxV		((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
1872 					const IVec4 clampMax	(maxV - 1);
1873 					const IVec4 clampMin	(-maxV);
1874 					std::ostringstream		fragmentShader;
1875 
1876 					fragmentShader <<
1877 						"#version 450\n"
1878 						"layout(location = 0) out highp ivec4 o_color;\n"
1879 						"layout(push_constant) uniform PushConstant {\n"
1880 						"\thighp uint sampleIndex;\n"
1881 						"} pushConstants;\n"
1882 						"void main (void)\n"
1883 						"{\n"
1884 						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1885 						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1886 						"\thighp int color[4];\n"
1887 						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1888 						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1889 
1890 					for (int ndx = 0; ndx < 4; ndx++)
1891 						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1892 
1893 					{
1894 						const int		componentCount	= tcu::getNumUsedChannels(format.order);
1895 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1896 						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1897 						deUint32		nextSrcBit		= 0;
1898 						deUint32		divider			= 2;
1899 
1900 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1901 						while (nextSrcBit < de::min(bitSize, 10u))
1902 						{
1903 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
1904 							{
1905 								if (dstBitsUsed[compNdx] > bits[compNdx])
1906 									continue;
1907 
1908 								fragmentShader <<
1909 										"\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1910 										<< " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1911 
1912 								nextSrcBit++;
1913 								dstBitsUsed[compNdx]++;
1914 							}
1915 
1916 							divider *= 2;
1917 						}
1918 					}
1919 
1920 					// The spec doesn't define whether signed-integers are clamped on output,
1921 					// so we'll clamp them explicitly to have well-defined outputs.
1922 					fragmentShader <<
1923 						"\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
1924 						"ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
1925 						"}\n";
1926 
1927 					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1928 					break;
1929 				}
1930 
1931 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1932 				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1933 				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1934 				{
1935 					const tcu::TextureFormatInfo	info			(tcu::getTextureFormatInfo(format));
1936 					const UVec4						bits			(tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
1937 					const Vec4						minLimit		(-65536.0);
1938 					const Vec4						maxLimit		(65536.0);
1939 					const Vec4						minValue		(tcu::max(info.valueMin, minLimit));
1940 					const Vec4						range			(tcu::min(info.valueMax, maxLimit) - minValue);
1941 					std::ostringstream				fragmentShader;
1942 
1943 					fragmentShader <<
1944 						"#version 450\n"
1945 						"layout(location = 0) out highp vec4 o_color;\n"
1946 						"layout(push_constant) uniform PushConstant {\n"
1947 						"\thighp uint sampleIndex;\n"
1948 						"} pushConstants;\n"
1949 						"void main (void)\n"
1950 						"{\n"
1951 						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1952 						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1953 						"\thighp float color[4];\n"
1954 						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1955 						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1956 
1957 					for (int ndx = 0; ndx < 4; ndx++)
1958 						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1959 
1960 					{
1961 						const bool		isAlphaOnly		= isAlphaOnlyFormat(config.format);
1962 						const int		componentCount	= (isAlphaOnly ? 4 : tcu::getNumUsedChannels(format.order));
1963 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1964 						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1965 						deUint32		nextSrcBit		= 0;
1966 						deUint32		divider			= 2;
1967 
1968 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1969 						while (nextSrcBit < de::min(bitSize, 10u))
1970 						{
1971 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
1972 							{
1973 								if (dstBitsUsed[compNdx] > bits[compNdx])
1974 									continue;
1975 
1976 								fragmentShader <<
1977 										"\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
1978 										<< " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1979 
1980 								nextSrcBit++;
1981 								dstBitsUsed[compNdx]++;
1982 							}
1983 
1984 							divider *= 2;
1985 						}
1986 					}
1987 
1988 					fragmentShader <<
1989 						"\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
1990 						"}\n";
1991 
1992 					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1993 					break;
1994 				}
1995 
1996 				default:
1997 					DE_FATAL("Unknown channel class");
1998 			}
1999 		}
2000 
2001 		if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2002 		{
2003 			std::ostringstream splitShader;
2004 
2005 			splitShader <<
2006 				"#version 450\n";
2007 
2008 			if (testDepth && testStencil)
2009 			{
2010 				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2011 							<< "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2012 			}
2013 			else if (testDepth)
2014 				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2015 			else if (testStencil)
2016 				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2017 
2018 			splitShader <<
2019 				"layout(push_constant) uniform PushConstant {\n"
2020 				"\thighp uint splitSubpassIndex;\n"
2021 				"} pushConstants;\n";
2022 
2023 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2024 			{
2025 				if (testDepth && testStencil)
2026 					splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2027 				else
2028 					splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2029 			}
2030 
2031 			splitShader <<
2032 				"void main (void)\n"
2033 				"{\n";
2034 
2035 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2036 			{
2037 				if (testDepth)
2038 					splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2039 
2040 				if (testStencil)
2041 					splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2042 
2043 				if (testDepth && testStencil)
2044 					splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2045 				else if (testDepth)
2046 					splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2047 				else if (testStencil)
2048 					splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2049 			}
2050 
2051 			splitShader <<
2052 				"}\n";
2053 
2054 			dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2055 		}
2056 		else
2057 		{
2058 			std::string subpassType;
2059 			std::string outputType;
2060 
2061 			switch (channelClass)
2062 			{
2063 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2064 					subpassType	= "usubpassInputMS";
2065 					outputType	= "uvec4";
2066 					break;
2067 
2068 				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2069 					subpassType	= "isubpassInputMS";
2070 					outputType	= "ivec4";
2071 					break;
2072 
2073 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2074 				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2075 				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2076 					subpassType	= "subpassInputMS";
2077 					outputType	= "vec4";
2078 					break;
2079 
2080 				default:
2081 					DE_FATAL("Unknown channel class");
2082 			}
2083 
2084 			std::ostringstream splitShader;
2085 			splitShader <<
2086 				"#version 450\n"
2087 				"layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2088 				"layout(push_constant) uniform PushConstant {\n"
2089 				"\thighp uint splitSubpassIndex;\n"
2090 				"} pushConstants;\n";
2091 
2092 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2093 				splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2094 
2095 			splitShader <<
2096 				"void main (void)\n"
2097 				"{\n";
2098 
2099 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2100 				splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2101 
2102 			splitShader <<
2103 				"}\n";
2104 
2105 			dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2106 		}
2107 	}
2108 };
2109 
formatToName(VkFormat format)2110 std::string formatToName (VkFormat format)
2111 {
2112 	const std::string	formatStr	= de::toString(format);
2113 	const std::string	prefix		= "VK_FORMAT_";
2114 
2115 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2116 
2117 	return de::toLower(formatStr.substr(prefix.length()));
2118 }
2119 
initTests(tcu::TestCaseGroup * group,RenderingType renderingType)2120 void initTests (tcu::TestCaseGroup* group, RenderingType renderingType)
2121 {
2122 	static const VkFormat	formats[]	=
2123 	{
2124 		VK_FORMAT_R5G6B5_UNORM_PACK16,
2125 		VK_FORMAT_R8_UNORM,
2126 		VK_FORMAT_R8_SNORM,
2127 		VK_FORMAT_R8_UINT,
2128 		VK_FORMAT_R8_SINT,
2129 		VK_FORMAT_R8G8_UNORM,
2130 		VK_FORMAT_R8G8_SNORM,
2131 		VK_FORMAT_R8G8_UINT,
2132 		VK_FORMAT_R8G8_SINT,
2133 #ifndef CTS_USES_VULKANSC
2134 		VK_FORMAT_A8_UNORM_KHR,
2135 #endif // CTS_USES_VULKANSC
2136 		VK_FORMAT_R8G8B8A8_UNORM,
2137 		VK_FORMAT_R8G8B8A8_SNORM,
2138 		VK_FORMAT_R8G8B8A8_UINT,
2139 		VK_FORMAT_R8G8B8A8_SINT,
2140 		VK_FORMAT_R8G8B8A8_SRGB,
2141 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2142 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2143 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
2144 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
2145 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2146 		VK_FORMAT_B8G8R8A8_UNORM,
2147 		VK_FORMAT_B8G8R8A8_SRGB,
2148 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2149 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2150 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
2151 		VK_FORMAT_R16_UNORM,
2152 		VK_FORMAT_R16_SNORM,
2153 		VK_FORMAT_R16_UINT,
2154 		VK_FORMAT_R16_SINT,
2155 		VK_FORMAT_R16_SFLOAT,
2156 		VK_FORMAT_R16G16_UNORM,
2157 		VK_FORMAT_R16G16_SNORM,
2158 		VK_FORMAT_R16G16_UINT,
2159 		VK_FORMAT_R16G16_SINT,
2160 		VK_FORMAT_R16G16_SFLOAT,
2161 		VK_FORMAT_R16G16B16A16_UNORM,
2162 		VK_FORMAT_R16G16B16A16_SNORM,
2163 		VK_FORMAT_R16G16B16A16_UINT,
2164 		VK_FORMAT_R16G16B16A16_SINT,
2165 		VK_FORMAT_R16G16B16A16_SFLOAT,
2166 		VK_FORMAT_R32_UINT,
2167 		VK_FORMAT_R32_SINT,
2168 		VK_FORMAT_R32_SFLOAT,
2169 		VK_FORMAT_R32G32_UINT,
2170 		VK_FORMAT_R32G32_SINT,
2171 		VK_FORMAT_R32G32_SFLOAT,
2172 		VK_FORMAT_R32G32B32A32_UINT,
2173 		VK_FORMAT_R32G32B32A32_SINT,
2174 		VK_FORMAT_R32G32B32A32_SFLOAT,
2175 		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2176 
2177 		VK_FORMAT_D16_UNORM,
2178 		VK_FORMAT_X8_D24_UNORM_PACK32,
2179 		VK_FORMAT_D32_SFLOAT,
2180 		VK_FORMAT_S8_UINT,
2181 		VK_FORMAT_D16_UNORM_S8_UINT,
2182 		VK_FORMAT_D24_UNORM_S8_UINT,
2183 		VK_FORMAT_D32_SFLOAT_S8_UINT
2184 	};
2185 	const deUint32			sampleCounts[] =
2186 	{
2187 		2u, 4u, 8u, 16u, 32u
2188 	};
2189 	tcu::TestContext&				testCtx		(group->getTestContext());
2190 	de::MovePtr<tcu::TestCaseGroup>	extGroup	(new tcu::TestCaseGroup(testCtx, "separate_stencil_usage"));
2191 
2192 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2193 	{
2194 		const VkFormat					format			(formats[formatNdx]);
2195 		const std::string				formatName		(formatToName(format));
2196 		de::MovePtr<tcu::TestCaseGroup>	formatGroup		(new tcu::TestCaseGroup(testCtx, formatName.c_str()));
2197 		de::MovePtr<tcu::TestCaseGroup>	extFormatGroup	(new tcu::TestCaseGroup(testCtx, formatName.c_str()));
2198 
2199 		for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2200 		{
2201 			const deUint32		sampleCount	(sampleCounts[sampleCountNdx]);
2202 			const TestConfig	testConfig	(format, sampleCount, renderingType);
2203 			const std::string	testName	("samples_" + de::toString(sampleCount));
2204 
2205 			formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testConfig));
2206 
2207 			// create tests for VK_EXT_separate_stencil_usage
2208 			if (tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order))
2209 			{
2210 				de::MovePtr<tcu::TestCaseGroup>	sampleGroup	(new tcu::TestCaseGroup(testCtx, testName.c_str()));
2211 				{
2212 					const TestConfig	separateUsageDepthTestConfig	(format, sampleCount, renderingType, TEST_DEPTH);
2213 					sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_depth", separateUsageDepthTestConfig));
2214 
2215 					const TestConfig	separateUsageStencilTestConfig	(format, sampleCount, renderingType, TEST_STENCIL);
2216 					sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_stencil", separateUsageStencilTestConfig));
2217 				}
2218 
2219 				extFormatGroup->addChild(sampleGroup.release());
2220 			}
2221 		}
2222 
2223 		group->addChild(formatGroup.release());
2224 		extGroup->addChild(extFormatGroup.release());
2225 	}
2226 
2227 	group->addChild(extGroup.release());
2228 }
2229 
2230 } // anonymous
2231 
createRenderPassMultisampleTests(tcu::TestContext & testCtx)2232 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2233 {
2234 	return createTestGroup(testCtx, "multisample", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
2235 }
2236 
createRenderPass2MultisampleTests(tcu::TestContext & testCtx)2237 tcu::TestCaseGroup* createRenderPass2MultisampleTests (tcu::TestContext& testCtx)
2238 {
2239 	return createTestGroup(testCtx, "multisample", initTests, RENDERING_TYPE_RENDERPASS2);
2240 }
2241 
2242 } // vkt
2243