• 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::__anon72fea9d60111::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)1269 bool isExtensionSupported(Context& context, RenderingType renderingType, TestSeparateUsage separateStencilUsage)
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 	return true;
1281 }
1282 
1283 
1284 class MultisampleRenderPassTestInstance : public TestInstance
1285 {
1286 public:
1287 					MultisampleRenderPassTestInstance	(Context& context, TestConfig config);
1288 					~MultisampleRenderPassTestInstance	(void);
1289 
1290 	tcu::TestStatus	iterate								(void);
1291 
1292 	template<typename RenderpassSubpass>
1293 	tcu::TestStatus	iterateInternal						(void);
1294 
1295 private:
1296 	const bool										m_extensionSupported;
1297 	const RenderingType								m_renderingType;
1298 	const TestSeparateUsage							m_separateStencilUsage;
1299 
1300 	const VkFormat									m_srcFormat;
1301 	const VkFormat									m_dstFormat;
1302 	const deUint32									m_sampleCount;
1303 	const deUint32									m_width;
1304 	const deUint32									m_height;
1305 
1306 	const VkImageAspectFlags						m_srcImageAspect;
1307 	const VkImageUsageFlags							m_srcImageUsage;
1308 	const Unique<VkImage>							m_srcImage;
1309 	const de::UniquePtr<Allocation>					m_srcImageMemory;
1310 	const Unique<VkImageView>						m_srcImageView;
1311 	const Unique<VkImageView>						m_srcPrimaryInputImageView;
1312 	const Unique<VkImageView>						m_srcSecondaryInputImageView;
1313 
1314 	const std::vector<VkImageSp>					m_dstMultisampleImages;
1315 	const std::vector<de::SharedPtr<Allocation> >	m_dstMultisampleImageMemory;
1316 	const std::vector<VkImageViewSp>				m_dstMultisampleImageViews;
1317 
1318 	const std::vector<VkImageSp>					m_dstSinglesampleImages;
1319 	const std::vector<de::SharedPtr<Allocation> >	m_dstSinglesampleImageMemory;
1320 	const std::vector<VkImageViewSp>				m_dstSinglesampleImageViews;
1321 
1322 	const std::vector<VkBufferSp>					m_dstBuffers;
1323 	const std::vector<de::SharedPtr<Allocation> >	m_dstBufferMemory;
1324 
1325 	const Unique<VkRenderPass>						m_renderPass;
1326 	const Unique<VkFramebuffer>						m_framebuffer;
1327 
1328 	const Unique<VkPipelineLayout>					m_renderPipelineLayout;
1329 	const Unique<VkPipeline>						m_renderPipeline;
1330 
1331 	const Unique<VkDescriptorSetLayout>				m_splitDescriptorSetLayout;
1332 	const Unique<VkPipelineLayout>					m_splitPipelineLayout;
1333 	const std::vector<VkPipelineSp>					m_splitPipelines;
1334 	const Unique<VkDescriptorPool>					m_splitDescriptorPool;
1335 	const Unique<VkDescriptorSet>					m_splitDescriptorSet;
1336 
1337 	const Unique<VkCommandPool>						m_commandPool;
1338 	tcu::ResultCollector							m_resultCollector;
1339 };
1340 
MultisampleRenderPassTestInstance(Context & context,TestConfig config)1341 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1342 	: TestInstance					(context)
1343 	, m_extensionSupported			(isExtensionSupported(context, config.renderingType, config.separateStencilUsage))
1344 	, m_renderingType				(config.renderingType)
1345 	, m_separateStencilUsage		(config.separateStencilUsage)
1346 	, m_srcFormat					(config.format)
1347 	, m_dstFormat					(getDstFormat(config.format, config.separateStencilUsage))
1348 	, m_sampleCount					(config.sampleCount)
1349 	, m_width						(32u)
1350 	, m_height						(32u)
1351 
1352 	, m_srcImageAspect				(getImageAspectFlags(m_srcFormat))
1353 	, m_srcImageUsage				(getSrcImageUsage(m_srcFormat))
1354 	, m_srcImage					(createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height, m_separateStencilUsage))
1355 	, m_srcImageMemory				(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1356 	, m_srcImageView				(createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1357 	, m_srcPrimaryInputImageView	(createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1358 	, m_srcSecondaryInputImageView	(createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1359 
1360 	, m_dstMultisampleImages		(createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1361 	, m_dstMultisampleImageMemory	(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1362 	, m_dstMultisampleImageViews	(createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1363 
1364 	, m_dstSinglesampleImages		(createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1365 	, m_dstSinglesampleImageMemory	(createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1366 	, m_dstSinglesampleImageViews	(createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1367 
1368 	, m_dstBuffers					(createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1369 	, m_dstBufferMemory				(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1370 
1371 	, m_renderPass					(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount, config.renderingType, m_separateStencilUsage))
1372 	, m_framebuffer					(createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1373 
1374 	, m_renderPipelineLayout		(createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1375 	, m_renderPipeline				(createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1376 
1377 	, m_splitDescriptorSetLayout	(createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1378 	, m_splitPipelineLayout			(createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1379 	, m_splitPipelines				(createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1380 	, m_splitDescriptorPool			(createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1381 	, m_splitDescriptorSet			(createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1382 	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1383 {
1384 }
1385 
~MultisampleRenderPassTestInstance(void)1386 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1387 {
1388 }
1389 
iterate(void)1390 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1391 {
1392 	switch (m_renderingType)
1393 	{
1394 		case RENDERING_TYPE_RENDERPASS_LEGACY:
1395 			return iterateInternal<RenderpassSubpass1>();
1396 		case RENDERING_TYPE_RENDERPASS2:
1397 			return iterateInternal<RenderpassSubpass2>();
1398 		default:
1399 			TCU_THROW(InternalError, "Impossible");
1400 	}
1401 }
1402 
1403 template<typename RenderpassSubpass>
iterateInternal(void)1404 tcu::TestStatus MultisampleRenderPassTestInstance::iterateInternal (void)
1405 {
1406 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
1407 	const VkDevice										device				(m_context.getDevice());
1408 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1409 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1410 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
1411 
1412 	beginCommandBuffer(vkd, *commandBuffer);
1413 
1414 	{
1415 		const VkRenderPassBeginInfo beginInfo =
1416 		{
1417 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1418 			DE_NULL,
1419 
1420 			*m_renderPass,
1421 			*m_framebuffer,
1422 
1423 			{
1424 				{ 0u, 0u },
1425 				{ m_width, m_height }
1426 			},
1427 
1428 			0u,
1429 			DE_NULL
1430 		};
1431 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1432 
1433 		// Stencil needs to be cleared if it exists.
1434 		if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
1435 		{
1436 			const VkClearAttachment clearAttachment =
1437 			{
1438 				VK_IMAGE_ASPECT_STENCIL_BIT,						// VkImageAspectFlags	aspectMask;
1439 				0,													// deUint32				colorAttachment;
1440 				makeClearValueDepthStencil(0, 0)					// VkClearValue			clearValue;
1441 			};
1442 
1443 			const VkClearRect clearRect =
1444 			{
1445 				{
1446 					{ 0u, 0u },
1447 					{ m_width, m_height }
1448 				},
1449 				0,													// deUint32	baseArrayLayer;
1450 				1													// deUint32	layerCount;
1451 			};
1452 
1453 			vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
1454 		}
1455 	}
1456 
1457 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1458 
1459 	for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1460 	{
1461 		vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1462 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1463 	}
1464 
1465 	for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1466 	{
1467 		RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1468 
1469 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
1470 		vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u,  &*m_splitDescriptorSet, 0u, DE_NULL);
1471 		vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1472 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1473 	}
1474 
1475 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1476 
1477 	for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1478 		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);
1479 
1480 	endCommandBuffer(vkd, *commandBuffer);
1481 
1482 	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1483 
1484 	{
1485 		const tcu::TextureFormat		format			(mapVkFormat(m_dstFormat));
1486 		const tcu::TextureFormat		srcFormat		(mapVkFormat(m_srcFormat));
1487 		const bool						verifyDepth		(m_separateStencilUsage ? (m_separateStencilUsage == TEST_DEPTH)   : tcu::hasDepthComponent(srcFormat.order));
1488 		const bool						verifyStencil	(m_separateStencilUsage ? (m_separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(srcFormat.order));
1489 
1490 		for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1491 		{
1492 			Allocation *dstBufMem = m_dstBufferMemory[sampleNdx].get();
1493 			invalidateAlloc(vkd, device, *dstBufMem);
1494 
1495 			const std::string					name		("Sample" + de::toString(sampleNdx));
1496 			const void* const					ptr			(dstBufMem->getHostPtr());
1497 			const tcu::ConstPixelBufferAccess	access		(format, m_width, m_height, 1, ptr);
1498 			tcu::TextureLevel					reference	(format, m_width, m_height);
1499 
1500 			if (verifyDepth || verifyStencil)
1501 			{
1502 				if (verifyDepth)
1503 				{
1504 					for (deUint32 y = 0; y < m_height; y++)
1505 					for (deUint32 x = 0; x < m_width; x++)
1506 					{
1507 						const deUint32	x1				= x ^ sampleNdx;
1508 						const deUint32	y1				= y ^ sampleNdx;
1509 						const float		range			= 1.0f;
1510 						float			depth			= 0.0f;
1511 						deUint32		divider			= 2;
1512 
1513 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1514 						for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1515 						{
1516 							depth += (range / (float)divider)
1517 									* (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1518 							divider *= 2;
1519 						}
1520 
1521 						reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1522 					}
1523 				}
1524 				if (verifyStencil)
1525 				{
1526 					for (deUint32 y = 0; y < m_height; y++)
1527 					for (deUint32 x = 0; x < m_width; x++)
1528 					{
1529 						const deUint32	stencil	= sampleNdx + 1u;
1530 
1531 						if (verifyDepth)
1532 						{
1533 							const Vec4 src (reference.getAccess().getPixel(x, y));
1534 
1535 							reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1536 						}
1537 						else
1538 							reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1539 					}
1540 				}
1541 				{
1542 					const Vec4 threshold (verifyDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1543 
1544 					if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1545 						m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1546 				}
1547 			}
1548 			else
1549 			{
1550 				const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
1551 
1552 				switch (channelClass)
1553 				{
1554 					case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1555 					{
1556 						const UVec4		bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1557 						const UVec4		minValue		(0);
1558 						const UVec4		range			(UVec4(1u) << tcu::min(bits, UVec4(31)));
1559 						const int		componentCount	(tcu::getNumUsedChannels(format.order));
1560 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1561 
1562 						for (deUint32 y = 0; y < m_height; y++)
1563 						for (deUint32 x = 0; x < m_width; x++)
1564 						{
1565 							const deUint32	x1				= x ^ sampleNdx;
1566 							const deUint32	y1				= y ^ sampleNdx;
1567 							UVec4			color			(minValue);
1568 							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1569 							deUint32		nextSrcBit		= 0;
1570 							deUint32		divider			= 2;
1571 
1572 							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1573 							while (nextSrcBit < de::min(bitSize, 10u))
1574 							{
1575 								for (int compNdx = 0; compNdx < componentCount; compNdx++)
1576 								{
1577 									if (dstBitsUsed[compNdx] > bits[compNdx])
1578 										continue;
1579 
1580 									color[compNdx] += (range[compNdx] / divider)
1581 													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1582 
1583 									nextSrcBit++;
1584 									dstBitsUsed[compNdx]++;
1585 								}
1586 
1587 								divider *= 2;
1588 							}
1589 
1590 							reference.getAccess().setPixel(color, x, y);
1591 						}
1592 
1593 						if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1594 							m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1595 
1596 						break;
1597 					}
1598 
1599 					case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1600 					{
1601 						const UVec4		bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1602 						const IVec4		minValue		(0);
1603 						const IVec4		range			((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1604 						const int		componentCount	(tcu::getNumUsedChannels(format.order));
1605 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1606 
1607 						for (deUint32 y = 0; y < m_height; y++)
1608 						for (deUint32 x = 0; x < m_width; x++)
1609 						{
1610 							const deUint32	x1				= x ^ sampleNdx;
1611 							const deUint32	y1				= y ^ sampleNdx;
1612 							IVec4			color			(minValue);
1613 							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1614 							deUint32		nextSrcBit		= 0;
1615 							deUint32		divider			= 2;
1616 
1617 							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1618 							while (nextSrcBit < de::min(bitSize, 10u))
1619 							{
1620 								for (int compNdx = 0; compNdx < componentCount; compNdx++)
1621 								{
1622 									if (dstBitsUsed[compNdx] > bits[compNdx])
1623 										continue;
1624 
1625 									color[compNdx] += (range[compNdx] / divider)
1626 													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1627 
1628 									nextSrcBit++;
1629 									dstBitsUsed[compNdx]++;
1630 								}
1631 
1632 								divider *= 2;
1633 							}
1634 
1635 							reference.getAccess().setPixel(color, x, y);
1636 						}
1637 
1638 						if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1639 							m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1640 
1641 						break;
1642 					}
1643 
1644 					case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1645 					case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1646 					case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1647 					{
1648 						const tcu::TextureFormatInfo	info			(tcu::getTextureFormatInfo(format));
1649 						const UVec4						bits			(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1650 						const Vec4						minLimit		(-65536.0);
1651 						const Vec4						maxLimit		(65536.0);
1652 						const Vec4						minValue		(tcu::max(info.valueMin, minLimit));
1653 						const Vec4						range			(tcu::min(info.valueMax, maxLimit) - minValue);
1654 						const int						componentCount	(tcu::getNumUsedChannels(format.order));
1655 						const deUint32					bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1656 
1657 						for (deUint32 y = 0; y < m_height; y++)
1658 						for (deUint32 x = 0; x < m_width; x++)
1659 						{
1660 							const deUint32	x1				= x ^ sampleNdx;
1661 							const deUint32	y1				= y ^ sampleNdx;
1662 							Vec4			color			(minValue);
1663 							deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1664 							deUint32		nextSrcBit		= 0;
1665 							deUint32		divider			= 2;
1666 
1667 							// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1668 							while (nextSrcBit < de::min(bitSize, 10u))
1669 							{
1670 								for (int compNdx = 0; compNdx < componentCount; compNdx++)
1671 								{
1672 									if (dstBitsUsed[compNdx] > bits[compNdx])
1673 										continue;
1674 
1675 									color[compNdx] += (range[compNdx] / (float)divider)
1676 													* (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1677 
1678 									nextSrcBit++;
1679 									dstBitsUsed[compNdx]++;
1680 								}
1681 
1682 								divider *= 2;
1683 							}
1684 
1685 							if (tcu::isSRGB(format))
1686 								reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1687 							else
1688 								reference.getAccess().setPixel(color, x, y);
1689 						}
1690 
1691 						if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1692 						{
1693 							// Convert target format ulps to float ulps and allow 64ulp differences
1694 							const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1695 
1696 							if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1697 								m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1698 						}
1699 						else
1700 						{
1701 							// Allow error of 4 times the minimum presentable difference
1702 							const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1703 
1704 							if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), 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 
1708 						break;
1709 					}
1710 
1711 					default:
1712 						DE_FATAL("Unknown channel class");
1713 				}
1714 			}
1715 		}
1716 	}
1717 
1718 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1719 }
1720 
1721 struct Programs
1722 {
initvkt::__anon72fea9d60111::Programs1723 	void init (vk::SourceCollections& dst, TestConfig config) const
1724 	{
1725 		const tcu::TextureFormat		format			(mapVkFormat(config.format));
1726 		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(format.type));
1727 		const bool						testDepth		(config.separateStencilUsage ? (config.separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(format.order));
1728 		const bool						testStencil		(config.separateStencilUsage ? (config.separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(format.order));
1729 
1730 		dst.glslSources.add("quad-vert") << glu::VertexSource(
1731 			"#version 450\n"
1732 			"out gl_PerVertex {\n"
1733 			"\tvec4 gl_Position;\n"
1734 			"};\n"
1735 			"highp float;\n"
1736 			"void main (void) {\n"
1737 			"\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1738 			"\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1739 			"}\n");
1740 
1741 		if (testDepth)
1742 		{
1743 			const Vec4			minValue		(0.0f);
1744 			const Vec4			range			(1.0f);
1745 			std::ostringstream	fragmentShader;
1746 
1747 			fragmentShader <<
1748 				"#version 450\n"
1749 				"layout(push_constant) uniform PushConstant {\n"
1750 				"\thighp uint sampleIndex;\n"
1751 				"} pushConstants;\n"
1752 				"void main (void)\n"
1753 				"{\n"
1754 				"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1755 				"\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1756 				"\thighp float depth;\n"
1757 				"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1758 				"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1759 
1760 			fragmentShader << "\tdepth = "  << minValue[0] << ";\n";
1761 
1762 			{
1763 				deUint32 divider = 2;
1764 
1765 				// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1766 				for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1767 				{
1768 					fragmentShader <<
1769 							"\tdepth += " << (range[0] / (float)divider)
1770 							<< " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1771 
1772 					divider *= 2;
1773 				}
1774 			}
1775 
1776 			fragmentShader <<
1777 				"\tgl_FragDepth = depth;\n"
1778 				"}\n";
1779 
1780 			dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1781 		}
1782 		else if (testStencil)
1783 		{
1784 			dst.glslSources.add("quad-frag") << glu::FragmentSource(
1785 				"#version 450\n"
1786 				"layout(push_constant) uniform PushConstant {\n"
1787 				"\thighp uint sampleIndex;\n"
1788 				"} pushConstants;\n"
1789 				"void main (void)\n"
1790 				"{\n"
1791 				"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1792 				"\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1793 				"}\n");
1794 		}
1795 		else
1796 		{
1797 			switch (channelClass)
1798 			{
1799 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1800 				{
1801 					const UVec4	bits		(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1802 					const UVec4 minValue	(0);
1803 					const UVec4 range		(UVec4(1u) << tcu::min(bits, UVec4(31)));
1804 					std::ostringstream		fragmentShader;
1805 
1806 					fragmentShader <<
1807 						"#version 450\n"
1808 						"layout(location = 0) out highp uvec4 o_color;\n"
1809 						"layout(push_constant) uniform PushConstant {\n"
1810 						"\thighp uint sampleIndex;\n"
1811 						"} pushConstants;\n"
1812 						"void main (void)\n"
1813 						"{\n"
1814 						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1815 						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1816 						"\thighp uint color[4];\n"
1817 						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1818 						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1819 
1820 					for (int ndx = 0; ndx < 4; ndx++)
1821 						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1822 
1823 					{
1824 						const int		componentCount	= tcu::getNumUsedChannels(format.order);
1825 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1826 						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1827 						deUint32		nextSrcBit		= 0;
1828 						deUint32		divider			= 2;
1829 
1830 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1831 						while (nextSrcBit < de::min(bitSize, 10u))
1832 						{
1833 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
1834 							{
1835 								if (dstBitsUsed[compNdx] > bits[compNdx])
1836 									continue;
1837 
1838 								fragmentShader <<
1839 										"\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1840 										<< " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1841 
1842 								nextSrcBit++;
1843 								dstBitsUsed[compNdx]++;
1844 							}
1845 
1846 							divider *= 2;
1847 						}
1848 					}
1849 
1850 					fragmentShader <<
1851 						"\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1852 						"}\n";
1853 
1854 					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1855 					break;
1856 				}
1857 
1858 				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1859 				{
1860 					const UVec4	bits		(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1861 					const IVec4 minValue	(0);
1862 					const IVec4 range		((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1863 					const IVec4 maxV		((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
1864 					const IVec4 clampMax	(maxV - 1);
1865 					const IVec4 clampMin	(-maxV);
1866 					std::ostringstream		fragmentShader;
1867 
1868 					fragmentShader <<
1869 						"#version 450\n"
1870 						"layout(location = 0) out highp ivec4 o_color;\n"
1871 						"layout(push_constant) uniform PushConstant {\n"
1872 						"\thighp uint sampleIndex;\n"
1873 						"} pushConstants;\n"
1874 						"void main (void)\n"
1875 						"{\n"
1876 						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1877 						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1878 						"\thighp int color[4];\n"
1879 						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1880 						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1881 
1882 					for (int ndx = 0; ndx < 4; ndx++)
1883 						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1884 
1885 					{
1886 						const int		componentCount	= tcu::getNumUsedChannels(format.order);
1887 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1888 						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1889 						deUint32		nextSrcBit		= 0;
1890 						deUint32		divider			= 2;
1891 
1892 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1893 						while (nextSrcBit < de::min(bitSize, 10u))
1894 						{
1895 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
1896 							{
1897 								if (dstBitsUsed[compNdx] > bits[compNdx])
1898 									continue;
1899 
1900 								fragmentShader <<
1901 										"\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1902 										<< " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1903 
1904 								nextSrcBit++;
1905 								dstBitsUsed[compNdx]++;
1906 							}
1907 
1908 							divider *= 2;
1909 						}
1910 					}
1911 
1912 					// The spec doesn't define whether signed-integers are clamped on output,
1913 					// so we'll clamp them explicitly to have well-defined outputs.
1914 					fragmentShader <<
1915 						"\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
1916 						"ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
1917 						"}\n";
1918 
1919 					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1920 					break;
1921 				}
1922 
1923 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1924 				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1925 				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1926 				{
1927 					const tcu::TextureFormatInfo	info			(tcu::getTextureFormatInfo(format));
1928 					const UVec4						bits			(tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
1929 					const Vec4						minLimit		(-65536.0);
1930 					const Vec4						maxLimit		(65536.0);
1931 					const Vec4						minValue		(tcu::max(info.valueMin, minLimit));
1932 					const Vec4						range			(tcu::min(info.valueMax, maxLimit) - minValue);
1933 					std::ostringstream				fragmentShader;
1934 
1935 					fragmentShader <<
1936 						"#version 450\n"
1937 						"layout(location = 0) out highp vec4 o_color;\n"
1938 						"layout(push_constant) uniform PushConstant {\n"
1939 						"\thighp uint sampleIndex;\n"
1940 						"} pushConstants;\n"
1941 						"void main (void)\n"
1942 						"{\n"
1943 						"\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1944 						"\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1945 						"\thighp float color[4];\n"
1946 						"\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1947 						"\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1948 
1949 					for (int ndx = 0; ndx < 4; ndx++)
1950 						fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1951 
1952 					{
1953 						const int		componentCount	= tcu::getNumUsedChannels(format.order);
1954 						const deUint32	bitSize			(bits[0] + bits[1] + bits[2] + bits[3]);
1955 						deUint32		dstBitsUsed[4]	= { 0u, 0u, 0u, 0u };
1956 						deUint32		nextSrcBit		= 0;
1957 						deUint32		divider			= 2;
1958 
1959 						// \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1960 						while (nextSrcBit < de::min(bitSize, 10u))
1961 						{
1962 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
1963 							{
1964 								if (dstBitsUsed[compNdx] > bits[compNdx])
1965 									continue;
1966 
1967 								fragmentShader <<
1968 										"\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
1969 										<< " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1970 
1971 								nextSrcBit++;
1972 								dstBitsUsed[compNdx]++;
1973 							}
1974 
1975 							divider *= 2;
1976 						}
1977 					}
1978 
1979 					fragmentShader <<
1980 						"\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
1981 						"}\n";
1982 
1983 					dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1984 					break;
1985 				}
1986 
1987 				default:
1988 					DE_FATAL("Unknown channel class");
1989 			}
1990 		}
1991 
1992 		if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
1993 		{
1994 			std::ostringstream splitShader;
1995 
1996 			splitShader <<
1997 				"#version 450\n";
1998 
1999 			if (testDepth && testStencil)
2000 			{
2001 				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2002 							<< "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2003 			}
2004 			else if (testDepth)
2005 				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2006 			else if (testStencil)
2007 				splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2008 
2009 			splitShader <<
2010 				"layout(push_constant) uniform PushConstant {\n"
2011 				"\thighp uint splitSubpassIndex;\n"
2012 				"} pushConstants;\n";
2013 
2014 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2015 			{
2016 				if (testDepth && testStencil)
2017 					splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2018 				else
2019 					splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2020 			}
2021 
2022 			splitShader <<
2023 				"void main (void)\n"
2024 				"{\n";
2025 
2026 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2027 			{
2028 				if (testDepth)
2029 					splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2030 
2031 				if (testStencil)
2032 					splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2033 
2034 				if (testDepth && testStencil)
2035 					splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2036 				else if (testDepth)
2037 					splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2038 				else if (testStencil)
2039 					splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2040 			}
2041 
2042 			splitShader <<
2043 				"}\n";
2044 
2045 			dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2046 		}
2047 		else
2048 		{
2049 			std::string subpassType;
2050 			std::string outputType;
2051 
2052 			switch (channelClass)
2053 			{
2054 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2055 					subpassType	= "usubpassInputMS";
2056 					outputType	= "uvec4";
2057 					break;
2058 
2059 				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2060 					subpassType	= "isubpassInputMS";
2061 					outputType	= "ivec4";
2062 					break;
2063 
2064 				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2065 				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2066 				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2067 					subpassType	= "subpassInputMS";
2068 					outputType	= "vec4";
2069 					break;
2070 
2071 				default:
2072 					DE_FATAL("Unknown channel class");
2073 			}
2074 
2075 			std::ostringstream splitShader;
2076 			splitShader <<
2077 				"#version 450\n"
2078 				"layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2079 				"layout(push_constant) uniform PushConstant {\n"
2080 				"\thighp uint splitSubpassIndex;\n"
2081 				"} pushConstants;\n";
2082 
2083 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2084 				splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2085 
2086 			splitShader <<
2087 				"void main (void)\n"
2088 				"{\n";
2089 
2090 			for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2091 				splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2092 
2093 			splitShader <<
2094 				"}\n";
2095 
2096 			dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2097 		}
2098 	}
2099 };
2100 
formatToName(VkFormat format)2101 std::string formatToName (VkFormat format)
2102 {
2103 	const std::string	formatStr	= de::toString(format);
2104 	const std::string	prefix		= "VK_FORMAT_";
2105 
2106 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2107 
2108 	return de::toLower(formatStr.substr(prefix.length()));
2109 }
2110 
initTests(tcu::TestCaseGroup * group,RenderingType renderingType)2111 void initTests (tcu::TestCaseGroup* group, RenderingType renderingType)
2112 {
2113 	static const VkFormat	formats[]	=
2114 	{
2115 		VK_FORMAT_R5G6B5_UNORM_PACK16,
2116 		VK_FORMAT_R8_UNORM,
2117 		VK_FORMAT_R8_SNORM,
2118 		VK_FORMAT_R8_UINT,
2119 		VK_FORMAT_R8_SINT,
2120 		VK_FORMAT_R8G8_UNORM,
2121 		VK_FORMAT_R8G8_SNORM,
2122 		VK_FORMAT_R8G8_UINT,
2123 		VK_FORMAT_R8G8_SINT,
2124 		VK_FORMAT_R8G8B8A8_UNORM,
2125 		VK_FORMAT_R8G8B8A8_SNORM,
2126 		VK_FORMAT_R8G8B8A8_UINT,
2127 		VK_FORMAT_R8G8B8A8_SINT,
2128 		VK_FORMAT_R8G8B8A8_SRGB,
2129 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2130 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2131 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
2132 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
2133 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2134 		VK_FORMAT_B8G8R8A8_UNORM,
2135 		VK_FORMAT_B8G8R8A8_SRGB,
2136 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2137 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2138 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
2139 		VK_FORMAT_R16_UNORM,
2140 		VK_FORMAT_R16_SNORM,
2141 		VK_FORMAT_R16_UINT,
2142 		VK_FORMAT_R16_SINT,
2143 		VK_FORMAT_R16_SFLOAT,
2144 		VK_FORMAT_R16G16_UNORM,
2145 		VK_FORMAT_R16G16_SNORM,
2146 		VK_FORMAT_R16G16_UINT,
2147 		VK_FORMAT_R16G16_SINT,
2148 		VK_FORMAT_R16G16_SFLOAT,
2149 		VK_FORMAT_R16G16B16A16_UNORM,
2150 		VK_FORMAT_R16G16B16A16_SNORM,
2151 		VK_FORMAT_R16G16B16A16_UINT,
2152 		VK_FORMAT_R16G16B16A16_SINT,
2153 		VK_FORMAT_R16G16B16A16_SFLOAT,
2154 		VK_FORMAT_R32_UINT,
2155 		VK_FORMAT_R32_SINT,
2156 		VK_FORMAT_R32_SFLOAT,
2157 		VK_FORMAT_R32G32_UINT,
2158 		VK_FORMAT_R32G32_SINT,
2159 		VK_FORMAT_R32G32_SFLOAT,
2160 		VK_FORMAT_R32G32B32A32_UINT,
2161 		VK_FORMAT_R32G32B32A32_SINT,
2162 		VK_FORMAT_R32G32B32A32_SFLOAT,
2163 		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2164 
2165 		VK_FORMAT_D16_UNORM,
2166 		VK_FORMAT_X8_D24_UNORM_PACK32,
2167 		VK_FORMAT_D32_SFLOAT,
2168 		VK_FORMAT_S8_UINT,
2169 		VK_FORMAT_D16_UNORM_S8_UINT,
2170 		VK_FORMAT_D24_UNORM_S8_UINT,
2171 		VK_FORMAT_D32_SFLOAT_S8_UINT
2172 	};
2173 	const deUint32			sampleCounts[] =
2174 	{
2175 		2u, 4u, 8u, 16u, 32u
2176 	};
2177 	tcu::TestContext&				testCtx		(group->getTestContext());
2178 	de::MovePtr<tcu::TestCaseGroup>	extGroup	(new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "test VK_EXT_separate_stencil_usage"));
2179 
2180 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2181 	{
2182 		const VkFormat					format			(formats[formatNdx]);
2183 		const std::string				formatName		(formatToName(format));
2184 		de::MovePtr<tcu::TestCaseGroup>	formatGroup		(new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2185 		de::MovePtr<tcu::TestCaseGroup>	extFormatGroup	(new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2186 
2187 		for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2188 		{
2189 			const deUint32		sampleCount	(sampleCounts[sampleCountNdx]);
2190 			const TestConfig	testConfig	(format, sampleCount, renderingType);
2191 			const std::string	testName	("samples_" + de::toString(sampleCount));
2192 
2193 			formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
2194 
2195 			// create tests for VK_EXT_separate_stencil_usage
2196 			if (tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order))
2197 			{
2198 				de::MovePtr<tcu::TestCaseGroup>	sampleGroup	(new tcu::TestCaseGroup(testCtx, testName.c_str(), testName.c_str()));
2199 				{
2200 					const TestConfig	separateUsageDepthTestConfig	(format, sampleCount, renderingType, TEST_DEPTH);
2201 					sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_depth", "depth with input attachment bit", separateUsageDepthTestConfig));
2202 
2203 					const TestConfig	separateUsageStencilTestConfig	(format, sampleCount, renderingType, TEST_STENCIL);
2204 					sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_stencil", "stencil with input attachment bit", separateUsageStencilTestConfig));
2205 				}
2206 
2207 				extFormatGroup->addChild(sampleGroup.release());
2208 			}
2209 		}
2210 
2211 		group->addChild(formatGroup.release());
2212 		extGroup->addChild(extFormatGroup.release());
2213 	}
2214 
2215 	group->addChild(extGroup.release());
2216 }
2217 
2218 } // anonymous
2219 
createRenderPassMultisampleTests(tcu::TestContext & testCtx)2220 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2221 {
2222 	return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
2223 }
2224 
createRenderPass2MultisampleTests(tcu::TestContext & testCtx)2225 tcu::TestCaseGroup* createRenderPass2MultisampleTests (tcu::TestContext& testCtx)
2226 {
2227 	return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS2);
2228 }
2229 
2230 } // vkt
2231