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