• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 Valve Corporation.
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 VK_EXT_attachment_feedback_loop_layout Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktPipelineAttachmentFeedbackLoopLayoutTests.hpp"
25 #include "vktPipelineImageSamplingInstance.hpp"
26 #include "vktPipelineImageUtil.hpp"
27 #include "vktPipelineVertexUtil.hpp"
28 #include "vktTestCase.hpp"
29 #include "vktPipelineClearUtil.hpp"
30 
31 #include "vkImageUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 #include "vkPrograms.hpp"
39 #include "vkImageWithMemory.hpp"
40 #include "vkBufferWithMemory.hpp"
41 
42 #include "tcuPlatform.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuMaybe.hpp"
47 
48 #include "deStringUtil.hpp"
49 #include "deMemory.h"
50 
51 #include <iomanip>
52 #include <sstream>
53 #include <vector>
54 #include <string>
55 #include <memory>
56 #include <utility>
57 #include <algorithm>
58 
59 namespace vkt
60 {
61 namespace pipeline
62 {
63 
64 using namespace vk;
65 using de::MovePtr;
66 
67 namespace
68 {
69 
70 enum TestMode
71 {
72 	TEST_MODE_READ_ONLY = 0,
73 	TEST_MODE_WRITE_ONLY = 1,
74 	TEST_MODE_READ_WRITE_SAME_PIXEL = 2,		// Sample from and write to the same pixel
75 	TEST_MODE_READ_WRITE_DIFFERENT_AREAS = 3,	// Sample from one half of the image and write the values to the other half
76 };
77 
78 enum ImageAspectTestMode
79 {
80 	IMAGE_ASPECT_TEST_COLOR = 0,
81 	IMAGE_ASPECT_TEST_DEPTH = 1,
82 	IMAGE_ASPECT_TEST_STENCIL = 2,
83 };
84 
85 // Output images are a square of this size
86 const int outputImageSize = 256;
87 
getImageAspectTestMode(const VkFormat format)88 ImageAspectTestMode getImageAspectTestMode (const VkFormat format)
89 {
90 	if (tcu::hasDepthComponent(mapVkFormat(format).order))
91 		return IMAGE_ASPECT_TEST_DEPTH;
92 
93 	if (tcu::hasStencilComponent(mapVkFormat(format).order))
94 		return IMAGE_ASPECT_TEST_STENCIL;
95 
96 	return IMAGE_ASPECT_TEST_COLOR;
97 };
98 
99 class SamplerViewType {
100 public:
SamplerViewType(vk::VkImageViewType type,bool normalized=true)101 	SamplerViewType (vk::VkImageViewType type, bool normalized = true)
102 		: m_viewType(type), m_normalized(normalized)
103 	{
104 		if (!normalized)
105 			DE_ASSERT(type == vk::VK_IMAGE_VIEW_TYPE_2D || type == vk::VK_IMAGE_VIEW_TYPE_1D);
106 	}
107 
operator vk::VkImageViewType() const108 	operator vk::VkImageViewType () const
109 	{
110 		return m_viewType;
111 	}
112 
isNormalized() const113 	bool isNormalized () const
114 	{
115 		return m_normalized;
116 	}
117 
118 private:
119 	vk::VkImageViewType m_viewType;
120 	bool				m_normalized;
121 };
122 
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)123 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
124 									   const DeviceInterface&		vkd,
125 									   const VkPhysicalDevice&		physDevice,
126 									   const VkDevice				device,
127 									   const VkImage&				image,
128 									   const MemoryRequirement		requirement,
129 									   Allocator&					allocator,
130 									   AllocationKind				allocationKind)
131 {
132 	switch (allocationKind)
133 	{
134 		case ALLOCATION_KIND_SUBALLOCATED:
135 		{
136 			const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vkd, device, image);
137 
138 			return allocator.allocate(memoryRequirements, requirement);
139 		}
140 
141 		case ALLOCATION_KIND_DEDICATED:
142 		{
143 			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
144 		}
145 
146 		default:
147 		{
148 			TCU_THROW(InternalError, "Invalid allocation kind");
149 		}
150 	}
151 }
152 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)153 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
154 										const DeviceInterface&		vkd,
155 										const VkPhysicalDevice&		physDevice,
156 										const VkDevice				device,
157 										const VkBuffer&				buffer,
158 										const MemoryRequirement		requirement,
159 										Allocator&					allocator,
160 										AllocationKind				allocationKind)
161 {
162 	switch (allocationKind)
163 	{
164 		case ALLOCATION_KIND_SUBALLOCATED:
165 		{
166 			const VkMemoryRequirements	memoryRequirements	= getBufferMemoryRequirements(vkd, device, buffer);
167 
168 			return allocator.allocate(memoryRequirements, requirement);
169 		}
170 
171 		case ALLOCATION_KIND_DEDICATED:
172 		{
173 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
174 		}
175 
176 		default:
177 		{
178 			TCU_THROW(InternalError, "Invalid allocation kind");
179 		}
180 	}
181 }
182 
getCompatibleImageType(VkImageViewType viewType)183 static VkImageType getCompatibleImageType (VkImageViewType viewType)
184 {
185 	switch (viewType)
186 	{
187 		case VK_IMAGE_VIEW_TYPE_1D:				return VK_IMAGE_TYPE_1D;
188 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:		return VK_IMAGE_TYPE_1D;
189 		case VK_IMAGE_VIEW_TYPE_2D:				return VK_IMAGE_TYPE_2D;
190 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:		return VK_IMAGE_TYPE_2D;
191 		case VK_IMAGE_VIEW_TYPE_3D:				return VK_IMAGE_TYPE_3D;
192 		case VK_IMAGE_VIEW_TYPE_CUBE:			return VK_IMAGE_TYPE_2D;
193 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:		return VK_IMAGE_TYPE_2D;
194 		default:
195 			break;
196 	}
197 
198 	DE_ASSERT(false);
199 	return VK_IMAGE_TYPE_1D;
200 }
201 
202 template<typename TcuFormatType>
createTestTexture(const TcuFormatType format,VkImageViewType viewType,const tcu::IVec3 & size,int layerCount)203 static MovePtr<TestTexture> createTestTexture (const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)
204 {
205 	MovePtr<TestTexture>	texture;
206 	const VkImageType		imageType = getCompatibleImageType(viewType);
207 
208 	switch (imageType)
209 	{
210 		case VK_IMAGE_TYPE_1D:
211 			if (layerCount == 1)
212 				texture = MovePtr<TestTexture>(new TestTexture1D(format, size.x()));
213 			else
214 				texture = MovePtr<TestTexture>(new TestTexture1DArray(format, size.x(), layerCount));
215 
216 			break;
217 
218 		case VK_IMAGE_TYPE_2D:
219 			if (layerCount == 1)
220 			{
221 				texture = MovePtr<TestTexture>(new TestTexture2D(format, size.x(), size.y()));
222 			}
223 			else
224 			{
225 				if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
226 				{
227 					if (layerCount == tcu::CUBEFACE_LAST && viewType == VK_IMAGE_VIEW_TYPE_CUBE)
228 					{
229 						texture = MovePtr<TestTexture>(new TestTextureCube(format, size.x()));
230 					}
231 					else
232 					{
233 						DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
234 
235 						texture = MovePtr<TestTexture>(new TestTextureCubeArray(format, size.x(), layerCount));
236 					}
237 				}
238 				else
239 				{
240 					texture = MovePtr<TestTexture>(new TestTexture2DArray(format, size.x(), size.y(), layerCount));
241 				}
242 			}
243 
244 			break;
245 
246 		case VK_IMAGE_TYPE_3D:
247 			texture = MovePtr<TestTexture>(new TestTexture3D(format, size.x(), size.y(), size.z()));
248 			break;
249 
250 		default:
251 			DE_ASSERT(false);
252 	}
253 
254 	return texture;
255 }
256 
getAspectFlags(tcu::TextureFormat format)257 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
258 {
259 	VkImageAspectFlags	aspectFlag	= 0;
260 	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
261 	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
262 
263 	if (!aspectFlag)
264 		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
265 
266 	return aspectFlag;
267 }
268 
getAspectFlags(VkFormat format)269 VkImageAspectFlags getAspectFlags (VkFormat format)
270 {
271 	if (isCompressedFormat(format))
272 		return VK_IMAGE_ASPECT_COLOR_BIT;
273 	else
274 		return getAspectFlags(mapVkFormat(format));
275 }
276 
getSizeCompatibleTcuTextureFormat(VkFormat format)277 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
278 {
279 	if (isCompressedFormat(format))
280 		return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
281 	else
282 		return mapVkFormat(format);
283 }
284 
285 // Utilities to create test nodes
getFormatCaseName(const VkFormat format)286 std::string getFormatCaseName (const VkFormat format)
287 {
288 	const std::string fullName = getFormatName(format);
289 
290 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
291 
292 	return de::toLower(fullName.substr(10));
293 }
294 
295 class AttachmentFeedbackLoopLayoutImageSamplingInstance : public ImageSamplingInstance
296 {
297 public:
298 								AttachmentFeedbackLoopLayoutImageSamplingInstance	(Context&						context,
299 																					 ImageSamplingInstanceParams	params,
300 																					 bool							useImageAsColorOrDSAttachment_,
301 																					 bool							useDifferentAreasSampleWrite_,
302 																					 bool							interleaveReadWriteComponents_);
303 
304 	virtual						~AttachmentFeedbackLoopLayoutImageSamplingInstance	(void);
305 
306 	virtual tcu::TestStatus		iterate												(void) override;
307 
308 protected:
309 	virtual tcu::TestStatus		verifyImage											(void) override;
310 	virtual void				setup												(void) override;
311 
312 	ImageSamplingInstanceParams		m_params;
313 	const bool						m_useImageAsColorOrDSAttachment;
314 	const bool						m_useDifferentAreasSampleWrite;
315 	const bool						m_interleaveReadWriteComponents;
316 };
317 
318 class AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance : public AttachmentFeedbackLoopLayoutImageSamplingInstance
319 {
320 public:
321 								AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance	(Context&						context,
322 																								 ImageSamplingInstanceParams	params,
323 																								 bool							useImageAsColorOrDSAttachment_,
324 																								 bool							useDifferentAreasSampleWrite_,
325 																								 bool							interleaveReadWriteComponents_);
326 
327 	virtual						~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance	(void);
328 
329 	virtual tcu::TestStatus		iterate												(void) override;
330 
331 protected:
332 	virtual tcu::TestStatus		verifyImage											(void) override;
333 	virtual void				setup												(void) override;
334 
335 	bool										m_separateStencilUsage;
336 
337 	std::vector<SharedImagePtr>					m_dsImages;
338 	std::vector<SharedAllocPtr>					m_dsImageAllocs;
339 	std::vector<SharedImageViewPtr>				m_dsAttachmentViews;
340 };
341 
AttachmentFeedbackLoopLayoutImageSamplingInstance(Context & context,ImageSamplingInstanceParams params,bool useImageAsColorOrDSAttachment_,bool useDifferentAreasSampleWrite_,bool interleaveReadWriteComponents_)342 AttachmentFeedbackLoopLayoutImageSamplingInstance::AttachmentFeedbackLoopLayoutImageSamplingInstance (Context&						context,
343 																									  ImageSamplingInstanceParams	params,
344 																									  bool							useImageAsColorOrDSAttachment_,
345 																									  bool							useDifferentAreasSampleWrite_,
346 																									  bool							interleaveReadWriteComponents_)
347 	: ImageSamplingInstance				(context, params)
348 	, m_params							(params)
349 	, m_useImageAsColorOrDSAttachment	(useImageAsColorOrDSAttachment_)
350 	, m_useDifferentAreasSampleWrite	(useDifferentAreasSampleWrite_)
351 	, m_interleaveReadWriteComponents	(interleaveReadWriteComponents_)
352 {
353 }
354 
setup(void)355 void AttachmentFeedbackLoopLayoutImageSamplingInstance::setup (void)
356 {
357 	const InstanceInterface&				vki						= m_context.getInstanceInterface();
358 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
359 	const VkPhysicalDevice					physDevice				= m_context.getPhysicalDevice();
360 	const VkDevice							vkDevice				= m_context.getDevice();
361 	const VkQueue							queue					= m_context.getUniversalQueue();
362 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
363 	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
364 	const VkComponentMapping				componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
365 	tcu::UVec2								renderSize				= m_useImageAsColorOrDSAttachment ? tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() }) : m_renderSize;
366 
367 	DE_ASSERT(m_samplerParams.pNext == DE_NULL);
368 
369 	// Create texture images, views and samplers
370 	{
371 		VkImageCreateFlags			imageFlags			= 0u;
372 
373 		if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
374 			imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
375 
376 		// Initialize texture data
377 		if (isCompressedFormat(m_imageFormat))
378 			m_texture = createTestTexture(mapVkCompressedFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
379 		else
380 			m_texture = createTestTexture(mapVkFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
381 
382 		VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
383 			VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
384 
385 		if (isDepthStencilFormat(m_imageFormat))
386 			imageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
387 		else
388 			imageUsageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
389 
390 		const VkImageCreateInfo	imageParams =
391 		{
392 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
393 			DE_NULL,														// const void*				pNext;
394 			imageFlags,														// VkImageCreateFlags		flags;
395 			getCompatibleImageType(m_imageViewType),						// VkImageType				imageType;
396 			m_imageFormat,													// VkFormat					format;
397 			{																// VkExtent3D				extent;
398 				(deUint32)m_imageSize.x(),
399 				(deUint32)m_imageSize.y(),
400 				(deUint32)m_imageSize.z()
401 			},
402 			(deUint32)m_texture->getNumLevels(),							// deUint32					mipLevels;
403 			(deUint32)m_layerCount,											// deUint32					arrayLayers;
404 			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
405 			VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
406 			imageUsageFlags,												// VkImageUsageFlags		usage;
407 			VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
408 			1u,																// deUint32					queueFamilyIndexCount;
409 			&queueFamilyIndex,												// const deUint32*			pQueueFamilyIndices;
410 			VK_IMAGE_LAYOUT_UNDEFINED										// VkImageLayout			initialLayout;
411 		};
412 
413 		checkImageSupport(vki, physDevice, imageParams);
414 
415 		m_images.resize(m_imageCount);
416 		m_imageAllocs.resize(m_imageCount);
417 		m_imageViews.resize(m_imageCount);
418 
419 		// Create command pool
420 		m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
421 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
422 
423 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
424 		{
425 			m_images[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &imageParams)));
426 			m_imageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_images[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
427 			VK_CHECK(vk.bindImageMemory(vkDevice, **m_images[imgNdx], (*m_imageAllocs[imgNdx])->getMemory(), (*m_imageAllocs[imgNdx])->getOffset()));
428 
429 			// Upload texture data
430 			uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, **m_images[imgNdx], m_imageLayout);
431 
432 			// Create image view and sampler
433 			const VkImageViewCreateInfo imageViewParams =
434 			{
435 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
436 				DE_NULL,									// const void*				pNext;
437 				0u,											// VkImageViewCreateFlags	flags;
438 				**m_images[imgNdx],							// VkImage					image;
439 				m_imageViewType,							// VkImageViewType			viewType;
440 				m_imageFormat,								// VkFormat					format;
441 				m_componentMapping,							// VkComponentMapping		components;
442 				m_subresourceRange,							// VkImageSubresourceRange	subresourceRange;
443 			};
444 
445 			m_imageViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &imageViewParams)));
446 		}
447 
448 		m_sampler	= createSampler(vk, vkDevice, &m_samplerParams);
449 	}
450 
451 	// Create descriptor set for image and sampler
452 	{
453 		DescriptorPoolBuilder descriptorPoolBuilder;
454 		if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
455 			descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 1u);
456 		descriptorPoolBuilder.addType(m_samplingType, m_imageCount);
457 		m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
458 			m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? m_imageCount + 1u : m_imageCount);
459 
460 		DescriptorSetLayoutBuilder setLayoutBuilder;
461 		if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
462 			setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
463 		setLayoutBuilder.addArrayBinding(m_samplingType, m_imageCount, VK_SHADER_STAGE_FRAGMENT_BIT);
464 		m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
465 
466 		const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
467 		{
468 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
469 			DE_NULL,											// const void*					pNext;
470 			*m_descriptorPool,									// VkDescriptorPool				descriptorPool;
471 			1u,													// deUint32						setLayoutCount;
472 			&m_descriptorSetLayout.get()						// const VkDescriptorSetLayout*	pSetLayouts;
473 		};
474 
475 		m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
476 
477 		const VkSampler sampler = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? DE_NULL : *m_sampler;
478 		std::vector<VkDescriptorImageInfo> descriptorImageInfo(m_imageCount);
479 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
480 		{
481 			descriptorImageInfo[imgNdx].sampler		= sampler;									// VkSampler		sampler;
482 			descriptorImageInfo[imgNdx].imageView	= **m_imageViews[imgNdx];					// VkImageView		imageView;
483 			descriptorImageInfo[imgNdx].imageLayout	= m_imageLayout;							// VkImageLayout	imageLayout;
484 		}
485 
486 		DescriptorSetUpdateBuilder setUpdateBuilder;
487 		if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
488 		{
489 			const VkDescriptorImageInfo descriptorSamplerInfo =
490 			{
491 				*m_sampler,									// VkSampler		sampler;
492 				DE_NULL,									// VkImageView		imageView;
493 				m_imageLayout,								// VkImageLayout	imageLayout;
494 			};
495 			setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_SAMPLER, &descriptorSamplerInfo);
496 		}
497 
498 		const deUint32 binding = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? 1u : 0u;
499 		setUpdateBuilder.writeArray(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(binding), m_samplingType, m_imageCount, descriptorImageInfo.data());
500 		setUpdateBuilder.update(vk, vkDevice);
501 	}
502 
503 	// Create color images and views
504 	{
505 		const VkImageCreateInfo colorImageParams =
506 		{
507 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
508 			DE_NULL,																	// const void*				pNext;
509 			0u,																			// VkImageCreateFlags		flags;
510 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
511 			m_colorFormat,																// VkFormat					format;
512 			{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1u },					// VkExtent3D				extent;
513 			1u,																			// deUint32					mipLevels;
514 			1u,																			// deUint32					arrayLayers;
515 			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
516 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
517 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
518 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
519 			1u,																			// deUint32					queueFamilyIndexCount;
520 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
521 			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
522 		};
523 
524 		checkImageSupport(vki, physDevice, colorImageParams);
525 
526 		m_colorImages.resize(m_imageCount);
527 		m_colorImageAllocs.resize(m_imageCount);
528 		m_colorAttachmentViews.resize(m_imageCount);
529 
530 		if (m_useImageAsColorOrDSAttachment)
531 		{
532 			for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
533 			{
534 				m_colorImages[imgNdx] = m_images[imgNdx];
535 				m_colorImageAllocs[imgNdx] = m_imageAllocs[imgNdx];
536 				m_colorAttachmentViews[imgNdx] = m_imageViews[imgNdx];
537 			}
538 		}
539 		else
540 		{
541 			for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
542 			{
543 				m_colorImages[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &colorImageParams)));
544 				m_colorImageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_colorImages[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
545 				VK_CHECK(vk.bindImageMemory(vkDevice, **m_colorImages[imgNdx], (*m_colorImageAllocs[imgNdx])->getMemory(), (*m_colorImageAllocs[imgNdx])->getOffset()));
546 
547 				const VkImageViewCreateInfo colorAttachmentViewParams =
548 				{
549 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
550 					DE_NULL,											// const void*				pNext;
551 					0u,													// VkImageViewCreateFlags	flags;
552 					**m_colorImages[imgNdx],							// VkImage					image;
553 					VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
554 					m_colorFormat,										// VkFormat					format;
555 					componentMappingRGBA,								// VkComponentMapping		components;
556 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
557 				};
558 
559 				m_colorAttachmentViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &colorAttachmentViewParams)));
560 			}
561 		}
562 	}
563 
564 	// Create render pass
565 	{
566 		std::vector<VkAttachmentDescription>	attachmentDescriptions(m_imageCount);
567 		std::vector<VkAttachmentReference>		attachmentReferences(m_imageCount);
568 
569 		VkAttachmentLoadOp	loadOp		= m_useImageAsColorOrDSAttachment ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
570 		VkImageLayout		imageLayout	= m_useImageAsColorOrDSAttachment ? m_imageLayout : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
571 
572 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
573 		{
574 			attachmentDescriptions[imgNdx].flags			= 0u;																	// VkAttachmentDescriptionFlags		flags;
575 			attachmentDescriptions[imgNdx].format			= m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat;		// VkFormat							format;
576 			attachmentDescriptions[imgNdx].samples			= VK_SAMPLE_COUNT_1_BIT;												// VkSampleCountFlagBits			samples;
577 			attachmentDescriptions[imgNdx].loadOp			= loadOp;																// VkAttachmentLoadOp				loadOp;
578 			attachmentDescriptions[imgNdx].storeOp			= VK_ATTACHMENT_STORE_OP_STORE;											// VkAttachmentStoreOp				storeOp;
579 			attachmentDescriptions[imgNdx].stencilLoadOp	= loadOp;																// VkAttachmentLoadOp				stencilLoadOp;
580 			attachmentDescriptions[imgNdx].stencilStoreOp	= VK_ATTACHMENT_STORE_OP_STORE;											// VkAttachmentStoreOp				stencilStoreOp;
581 			attachmentDescriptions[imgNdx].initialLayout	= imageLayout;															// VkImageLayout					initialLayout;
582 			attachmentDescriptions[imgNdx].finalLayout		= imageLayout;															// VkImageLayout					finalLayout;
583 
584 			attachmentReferences[imgNdx].attachment			= (deUint32)imgNdx;														// deUint32							attachment;
585 			attachmentReferences[imgNdx].layout				= imageLayout;															// VkImageLayout					layout;
586 		}
587 
588 		const VkSubpassDescription subpassDescription =
589 		{
590 			0u,													// VkSubpassDescriptionFlags	flags;
591 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
592 			0u,													// deUint32						inputAttachmentCount;
593 			DE_NULL,											// const VkAttachmentReference*	pInputAttachments;
594 			(deUint32)m_imageCount,								// deUint32						colorAttachmentCount;
595 			&attachmentReferences[0],							// const VkAttachmentReference*	pColorAttachments;
596 			DE_NULL,											// const VkAttachmentReference*	pResolveAttachments;
597 			DE_NULL,											// const VkAttachmentReference*	pDepthStencilAttachment;
598 			0u,													// deUint32						preserveAttachmentCount;
599 			DE_NULL												// const VkAttachmentReference*	pPreserveAttachments;
600 		};
601 
602 		std::vector<VkSubpassDependency> subpassDependencies;
603 
604 		if (m_useImageAsColorOrDSAttachment)
605 		{
606 			const VkSubpassDependency spdVal =
607 			{
608 				0u,																	//	uint32_t				srcSubpass;
609 				0u,																	//	uint32_t				dstSubpass;
610 				VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,								//	VkPipelineStageFlags	srcStageMask;
611 				VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						//	VkPipelineStageFlags	dstStageMask;
612 				VK_ACCESS_SHADER_READ_BIT,											//	VkAccessFlags			srcAccessMask;
613 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,								//	VkAccessFlags			dstAccessMask;
614 				VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT | VK_DEPENDENCY_BY_REGION_BIT,	//	VkDependencyFlags		dependencyFlags;
615 			};
616 
617 			subpassDependencies.push_back(spdVal);
618 		}
619 
620 		const VkRenderPassCreateInfo renderPassParams =
621 		{
622 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
623 			DE_NULL,											// const void*						pNext;
624 			0u,													// VkRenderPassCreateFlags			flags;
625 			(deUint32)attachmentDescriptions.size(),			// deUint32							attachmentCount;
626 			&attachmentDescriptions[0],							// const VkAttachmentDescription*	pAttachments;
627 			1u,													// deUint32							subpassCount;
628 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
629 			static_cast<uint32_t>(subpassDependencies.size()),	// deUint32							dependencyCount;
630 			de::dataOrNull(subpassDependencies),				// const VkSubpassDependency*		pDependencies;
631 		};
632 
633 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
634 	}
635 
636 	// Create framebuffer
637 	{
638 		std::vector<VkImageView> pAttachments(m_imageCount);
639 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
640 			pAttachments[imgNdx] =  m_colorAttachmentViews[imgNdx]->get();
641 
642 		const VkFramebufferCreateInfo framebufferParams =
643 		{
644 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
645 			DE_NULL,											// const void*				pNext;
646 			0u,													// VkFramebufferCreateFlags	flags;
647 			*m_renderPass,										// VkRenderPass				renderPass;
648 			(deUint32)m_imageCount,								// deUint32					attachmentCount;
649 			&pAttachments[0],									// const VkImageView*		pAttachments;
650 			(deUint32)renderSize.x(),							// deUint32					width;
651 			(deUint32)renderSize.y(),							// deUint32					height;
652 			1u													// deUint32					layers;
653 		};
654 
655 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
656 	}
657 
658 	// Create pipeline layouts
659 	{
660 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
661 		{
662 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
663 			DE_NULL,											// const void*					pNext;
664 			VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,	// VkPipelineLayoutCreateFlags	flags;
665 			0u,													// deUint32						setLayoutCount;
666 			DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
667 			0u,													// deUint32						pushConstantRangeCount;
668 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
669 		};
670 
671 		m_preRasterizationStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
672 	}
673 	{
674 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
675 		{
676 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
677 			DE_NULL,											// const void*					pNext;
678 			VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,	// VkPipelineLayoutCreateFlags	flags;
679 			1u,													// deUint32						setLayoutCount;
680 			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*	pSetLayouts;
681 			0u,													// deUint32						pushConstantRangeCount;
682 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
683 		};
684 
685 		m_fragmentStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
686 	}
687 
688 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
689 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
690 
691 	// Create pipeline
692 	{
693 		const VkVertexInputBindingDescription vertexInputBindingDescription =
694 		{
695 			0u,									// deUint32					binding;
696 			sizeof(Vertex4Tex4),				// deUint32					strideInBytes;
697 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	inputRate;
698 		};
699 
700 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
701 		{
702 			{
703 				0u,										// deUint32	location;
704 				0u,										// deUint32	binding;
705 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
706 				0u										// deUint32	offset;
707 			},
708 			{
709 				1u,										// deUint32	location;
710 				0u,										// deUint32	binding;
711 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
712 				DE_OFFSET_OF(Vertex4Tex4, texCoord),	// deUint32	offset;
713 			}
714 		};
715 
716 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
717 		{
718 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
719 			DE_NULL,														// const void*								pNext;
720 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
721 			1u,																// deUint32									vertexBindingDescriptionCount;
722 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
723 			2u,																// deUint32									vertexAttributeDescriptionCount;
724 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
725 		};
726 
727 		const std::vector<VkViewport>	viewports	(1, makeViewport(renderSize));
728 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(renderSize));
729 
730 		std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates(m_imageCount);
731 
732 		VkColorComponentFlags colorComponents = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
733 
734 		if (m_interleaveReadWriteComponents)
735 			colorComponents = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_B_BIT;
736 
737 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
738 		{
739 			colorBlendAttachmentStates[imgNdx].blendEnable			= false;												// VkBool32					blendEnable;
740 			colorBlendAttachmentStates[imgNdx].srcColorBlendFactor	= VK_BLEND_FACTOR_ONE;									// VkBlendFactor			srcColorBlendFactor;
741 			colorBlendAttachmentStates[imgNdx].dstColorBlendFactor	= VK_BLEND_FACTOR_ZERO;									// VkBlendFactor			dstColorBlendFactor;
742 			colorBlendAttachmentStates[imgNdx].colorBlendOp			= VK_BLEND_OP_ADD;										// VkBlendOp				colorBlendOp;
743 			colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor	= VK_BLEND_FACTOR_ONE;									// VkBlendFactor			srcAlphaBlendFactor;
744 			colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor	= VK_BLEND_FACTOR_ZERO;									// VkBlendFactor			dstAlphaBlendFactor;
745 			colorBlendAttachmentStates[imgNdx].alphaBlendOp			= VK_BLEND_OP_ADD;										// VkBlendOp				alphaBlendOp;
746 			colorBlendAttachmentStates[imgNdx].colorWriteMask		= colorComponents;										// VkColorComponentFlags	colorWriteMask;
747 		}
748 
749 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
750 		{
751 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
752 			DE_NULL,													// const void*									pNext;
753 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
754 			false,														// VkBool32										logicOpEnable;
755 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
756 			(deUint32)m_imageCount,										// deUint32										attachmentCount;
757 			&colorBlendAttachmentStates[0],								// const VkPipelineColorBlendAttachmentState*	pAttachments;
758 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
759 		};
760 
761 		m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
762 						  .setDefaultDepthStencilState()
763 						  .setDefaultRasterizationState()
764 						  .setDefaultMultisampleState()
765 						  .setupVertexInputState(&vertexInputStateParams)
766 						  .setupPreRasterizationShaderState(viewports,
767 														scissors,
768 														*m_preRasterizationStatePipelineLayout,
769 														*m_renderPass,
770 														0u,
771 														*m_vertexShaderModule)
772 						  .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule)
773 						  .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
774 						  .buildPipeline();
775 	}
776 
777 	// Create vertex buffer
778 	{
779 		const VkDeviceSize			vertexBufferSize	= (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
780 		const VkBufferCreateInfo	vertexBufferParams	=
781 		{
782 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
783 			DE_NULL,									// const void*			pNext;
784 			0u,											// VkBufferCreateFlags	flags;
785 			vertexBufferSize,							// VkDeviceSize			size;
786 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
787 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
788 			1u,											// deUint32				queueFamilyIndexCount;
789 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
790 		};
791 
792 		DE_ASSERT(vertexBufferSize > 0);
793 
794 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
795 		m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
796 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
797 
798 		// Load vertices into vertex buffer
799 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
800 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
801 	}
802 
803 	// Create command buffer
804 	{
805 		VkFormat clearFormat = m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat;
806 		const std::vector<VkClearValue> attachmentClearValues (m_imageCount, defaultClearValue(clearFormat));
807 
808 		std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
809 
810 		VkAccessFlags dstAccessMask = isDepthStencilFormat(m_imageFormat) ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT : VK_ACCESS_SHADER_READ_BIT;
811 		VkPipelineStageFlags pipelineStageFlags = isDepthStencilFormat(m_imageFormat) ? VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
812 
813 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
814 		{
815 			preAttachmentBarriers[imgNdx].sType								= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;								// VkStructureType			sType;
816 			preAttachmentBarriers[imgNdx].pNext								= DE_NULL;																// const void*				pNext;
817 			preAttachmentBarriers[imgNdx].srcAccessMask						= VK_ACCESS_TRANSFER_WRITE_BIT;											// VkAccessFlags			srcAccessMask;
818 			preAttachmentBarriers[imgNdx].dstAccessMask						= dstAccessMask;														// VkAccessFlags			dstAccessMask;
819 			preAttachmentBarriers[imgNdx].oldLayout							= m_imageLayout;														// VkImageLayout			oldLayout;
820 			preAttachmentBarriers[imgNdx].newLayout							= m_imageLayout;														// VkImageLayout			newLayout;
821 			preAttachmentBarriers[imgNdx].srcQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;												// deUint32					srcQueueFamilyIndex;
822 			preAttachmentBarriers[imgNdx].dstQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;												// deUint32					dstQueueFamilyIndex;
823 			preAttachmentBarriers[imgNdx].image								= **m_images[imgNdx];													// VkImage					image;
824 			preAttachmentBarriers[imgNdx].subresourceRange					= m_subresourceRange;													// VkImageSubresourceRange	subresourceRange;
825 		}
826 
827 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
828 
829 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, pipelineStageFlags, (VkDependencyFlags)0,
830 			0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
831 
832 		if (!m_useImageAsColorOrDSAttachment)
833 		{
834 			// Pipeline barrier for the color attachment, which is a different image than the sampled one.
835 			for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
836 			{
837 				preAttachmentBarriers[imgNdx].sType								= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;								// VkStructureType			sType;
838 				preAttachmentBarriers[imgNdx].pNext								= DE_NULL;																// const void*				pNext;
839 				preAttachmentBarriers[imgNdx].srcAccessMask						= (VkAccessFlagBits)0u;													// VkAccessFlags			srcAccessMask;
840 				preAttachmentBarriers[imgNdx].dstAccessMask						= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;									// VkAccessFlags			dstAccessMask;
841 				preAttachmentBarriers[imgNdx].oldLayout							= VK_IMAGE_LAYOUT_UNDEFINED;											// VkImageLayout			oldLayout;
842 				preAttachmentBarriers[imgNdx].newLayout							= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;								// VkImageLayout			newLayout;
843 				preAttachmentBarriers[imgNdx].srcQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;												// deUint32					srcQueueFamilyIndex;
844 				preAttachmentBarriers[imgNdx].dstQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;												// deUint32					dstQueueFamilyIndex;
845 				preAttachmentBarriers[imgNdx].image								= **m_colorImages[imgNdx];												// VkImage					image;
846 				preAttachmentBarriers[imgNdx].subresourceRange.aspectMask		= getAspectFlags(m_colorFormat);										// VkImageSubresourceRange	subresourceRange;
847 				preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel		= 0u;
848 				preAttachmentBarriers[imgNdx].subresourceRange.levelCount		= 1u;
849 				preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer	= 0u;
850 				preAttachmentBarriers[imgNdx].subresourceRange.layerCount		= 1u;
851 			}
852 
853 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
854 								  0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
855 
856 			beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), (deUint32)attachmentClearValues.size(), &attachmentClearValues[0]);
857 		}
858 		else
859 		{
860 			// Do not clear the color attachments as we are using the sampled texture as color attachment as well.
861 			beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), 0u, DE_NULL);
862 		}
863 
864 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
865 
866 		vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
867 
868 		const VkDeviceSize vertexBufferOffset = 0;
869 		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
870 		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
871 
872 		endRenderPass(vk, *m_cmdBuffer);
873 		endCommandBuffer(vk, *m_cmdBuffer);
874 	}
875 }
876 
AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(Context & context,ImageSamplingInstanceParams params,bool useImageAsColorOrDSAttachment_,bool useDifferentAreasSampleWrite_,bool interleaveReadWriteComponents_)877 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (Context&						context,
878 																															  ImageSamplingInstanceParams	params,
879 																															  bool							useImageAsColorOrDSAttachment_,
880 																															  bool							useDifferentAreasSampleWrite_,
881 																															  bool							interleaveReadWriteComponents_)
882 	: AttachmentFeedbackLoopLayoutImageSamplingInstance		(context, params, useImageAsColorOrDSAttachment_, useDifferentAreasSampleWrite_, interleaveReadWriteComponents_)
883 	, m_separateStencilUsage								(params.separateStencilUsage)
884 {
885 }
886 
~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(void)887 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (void)
888 {
889 }
890 
setup(void)891 void AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::setup (void)
892 {
893 	const InstanceInterface&				vki						= m_context.getInstanceInterface();
894 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
895 	const VkPhysicalDevice					physDevice				= m_context.getPhysicalDevice();
896 	const VkDevice							vkDevice				= m_context.getDevice();
897 	const VkQueue							queue					= m_context.getUniversalQueue();
898 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
899 	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
900 	tcu::UVec2								renderSize				= tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
901 
902 	DE_ASSERT(m_useImageAsColorOrDSAttachment && isDepthStencilFormat(m_imageFormat));
903 	DE_ASSERT(m_samplerParams.pNext == DE_NULL);
904 
905 	// Create texture images, views
906 	{
907 		VkImageCreateFlags			imageFlags			= 0u;
908 
909 		if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
910 			imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
911 
912 		// Initialize texture data
913 		if (isCompressedFormat(m_imageFormat))
914 			m_texture = createTestTexture(mapVkCompressedFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
915 		else
916 			m_texture = createTestTexture(mapVkFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
917 
918 		VkImageUsageFlags imageUsageFlags =
919 			VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
920 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
921 
922 		const VkImageCreateInfo	imageParams =
923 		{
924 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
925 			DE_NULL,														// const void*				pNext;
926 			imageFlags,														// VkImageCreateFlags		flags;
927 			getCompatibleImageType(m_imageViewType),						// VkImageType				imageType;
928 			m_imageFormat,													// VkFormat					format;
929 			{																// VkExtent3D				extent;
930 				(deUint32)m_imageSize.x(),
931 				(deUint32)m_imageSize.y(),
932 				(deUint32)m_imageSize.z()
933 			},
934 			(deUint32)m_texture->getNumLevels(),							// deUint32					mipLevels;
935 			(deUint32)m_layerCount,											// deUint32					arrayLayers;
936 			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
937 			VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
938 			imageUsageFlags,												// VkImageUsageFlags		usage;
939 			VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
940 			1u,																// deUint32					queueFamilyIndexCount;
941 			&queueFamilyIndex,												// const deUint32*			pQueueFamilyIndices;
942 			VK_IMAGE_LAYOUT_UNDEFINED										// VkImageLayout			initialLayout;
943 		};
944 
945 		checkImageSupport(vki, physDevice, imageParams);
946 
947 		m_images.resize(m_imageCount);
948 		m_imageAllocs.resize(m_imageCount);
949 
950 		// Create command pool
951 		m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
952 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
953 
954 		int numImageViews = m_interleaveReadWriteComponents ? m_imageCount + 1 : m_imageCount;
955 		m_imageViews.resize(numImageViews);
956 
957 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
958 		{
959 			m_images[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &imageParams)));
960 			m_imageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_images[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
961 			VK_CHECK(vk.bindImageMemory(vkDevice, **m_images[imgNdx], (*m_imageAllocs[imgNdx])->getMemory(), (*m_imageAllocs[imgNdx])->getOffset()));
962 
963 			// Upload texture data
964 			uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, **m_images[imgNdx], m_imageLayout);
965 
966 		}
967 
968 		for (int imgNdx = 0; imgNdx < numImageViews; ++imgNdx)
969 		{
970 			VkImage image = (m_interleaveReadWriteComponents && imgNdx == m_imageCount) ? **m_images[imgNdx - 1] : **m_images[imgNdx];
971 
972 			// Create image view and sampler
973 			VkImageViewCreateInfo imageViewParams =
974 			{
975 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
976 				DE_NULL,									// const void*				pNext;
977 				0u,											// VkImageViewCreateFlags	flags;
978 				image,										// VkImage					image;
979 				m_imageViewType,							// VkImageViewType			viewType;
980 				m_imageFormat,								// VkFormat					format;
981 				m_componentMapping,							// VkComponentMapping		components;
982 				m_subresourceRange,							// VkImageSubresourceRange	subresourceRange;
983 			};
984 
985 			if (m_interleaveReadWriteComponents && imgNdx == m_imageCount)
986 			{
987 				imageViewParams.subresourceRange.aspectMask = getImageAspectFlags(mapVkFormat(m_imageFormat));
988 			}
989 
990 			m_imageViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &imageViewParams)));
991 		}
992 
993 		m_sampler	= createSampler(vk, vkDevice, &m_samplerParams);
994 	}
995 
996 	// Create descriptor set for image and sampler
997 	{
998 		DescriptorPoolBuilder descriptorPoolBuilder;
999 		if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1000 			descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 1u);
1001 		descriptorPoolBuilder.addType(m_samplingType, m_imageCount);
1002 		m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1003 			m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? m_imageCount + 1u : m_imageCount);
1004 
1005 		DescriptorSetLayoutBuilder setLayoutBuilder;
1006 		if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1007 			setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
1008 		setLayoutBuilder.addArrayBinding(m_samplingType, m_imageCount, VK_SHADER_STAGE_FRAGMENT_BIT);
1009 		m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
1010 
1011 		const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
1012 		{
1013 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
1014 			DE_NULL,											// const void*					pNext;
1015 			*m_descriptorPool,									// VkDescriptorPool				descriptorPool;
1016 			1u,													// deUint32						setLayoutCount;
1017 			&m_descriptorSetLayout.get()						// const VkDescriptorSetLayout*	pSetLayouts;
1018 		};
1019 
1020 		m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
1021 
1022 		const VkSampler sampler = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? DE_NULL : *m_sampler;
1023 		std::vector<VkDescriptorImageInfo> descriptorImageInfo(m_imageCount);
1024 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1025 		{
1026 			descriptorImageInfo[imgNdx].sampler		= sampler;									// VkSampler		sampler;
1027 			descriptorImageInfo[imgNdx].imageView	= **m_imageViews[imgNdx];					// VkImageView		imageView;
1028 			descriptorImageInfo[imgNdx].imageLayout	= m_imageLayout;							// VkImageLayout	imageLayout;
1029 		}
1030 
1031 		DescriptorSetUpdateBuilder setUpdateBuilder;
1032 		if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1033 		{
1034 			const VkDescriptorImageInfo descriptorSamplerInfo =
1035 			{
1036 				*m_sampler,									// VkSampler		sampler;
1037 				DE_NULL,									// VkImageView		imageView;
1038 				m_imageLayout,								// VkImageLayout	imageLayout;
1039 			};
1040 			setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_SAMPLER, &descriptorSamplerInfo);
1041 		}
1042 
1043 		const deUint32 binding = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? 1u : 0u;
1044 		setUpdateBuilder.writeArray(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(binding), m_samplingType, m_imageCount, descriptorImageInfo.data());
1045 		setUpdateBuilder.update(vk, vkDevice);
1046 	}
1047 
1048 	// Create depth-stencil images and views, no color attachment
1049 	{
1050 		m_dsImages.resize(m_imageCount);
1051 		m_dsImageAllocs.resize(m_imageCount);
1052 		m_dsAttachmentViews.resize(m_imageCount);
1053 
1054 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1055 		{
1056 			m_dsImages[imgNdx] = m_images[imgNdx];
1057 			m_dsImageAllocs[imgNdx] = m_imageAllocs[imgNdx];
1058 			m_dsAttachmentViews[imgNdx] = m_interleaveReadWriteComponents ? m_imageViews[imgNdx + 1] : m_imageViews[imgNdx];
1059 		}
1060 	}
1061 
1062 	// Create render pass
1063 	{
1064 		std::vector<VkAttachmentDescription>	attachmentDescriptions(m_imageCount);
1065 		std::vector<VkAttachmentReference>		attachmentReferences(m_imageCount);
1066 
1067 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1068 		{
1069 			attachmentDescriptions[imgNdx].flags			= 0u;																	// VkAttachmentDescriptionFlags		flags;
1070 			attachmentDescriptions[imgNdx].format			= m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat;		// VkFormat							format;
1071 			attachmentDescriptions[imgNdx].samples			= VK_SAMPLE_COUNT_1_BIT;												// VkSampleCountFlagBits			samples;
1072 			attachmentDescriptions[imgNdx].loadOp			= VK_ATTACHMENT_LOAD_OP_LOAD;											// VkAttachmentLoadOp				loadOp;
1073 			attachmentDescriptions[imgNdx].storeOp			= VK_ATTACHMENT_STORE_OP_STORE;											// VkAttachmentStoreOp				storeOp;
1074 			attachmentDescriptions[imgNdx].stencilLoadOp	= VK_ATTACHMENT_LOAD_OP_LOAD;											// VkAttachmentLoadOp				stencilLoadOp;
1075 			attachmentDescriptions[imgNdx].stencilStoreOp	= VK_ATTACHMENT_STORE_OP_STORE;											// VkAttachmentStoreOp				stencilStoreOp;
1076 			attachmentDescriptions[imgNdx].initialLayout	= m_imageLayout;														// VkImageLayout					initialLayout;
1077 			attachmentDescriptions[imgNdx].finalLayout		= m_imageLayout;														// VkImageLayout					finalLayout;
1078 
1079 			attachmentReferences[imgNdx].attachment			= (deUint32)imgNdx;														// deUint32							attachment;
1080 			attachmentReferences[imgNdx].layout				= m_imageLayout;														// VkImageLayout					layout;
1081 		}
1082 
1083 		const VkSubpassDescription subpassDescription =
1084 		{
1085 			0u,																				// VkSubpassDescriptionFlags	flags;
1086 			VK_PIPELINE_BIND_POINT_GRAPHICS,												// VkPipelineBindPoint			pipelineBindPoint;
1087 			0u,																				// deUint32						inputAttachmentCount;
1088 			DE_NULL,																		// const VkAttachmentReference*	pInputAttachments;
1089 			0u,																				// deUint32						colorAttachmentCount;
1090 			DE_NULL,																		// const VkAttachmentReference*	pColorAttachments;
1091 			DE_NULL,																		// const VkAttachmentReference*	pResolveAttachments;
1092 			&attachmentReferences[0],														// const VkAttachmentReference*	pDepthStencilAttachment;
1093 			0u,																				// deUint32						preserveAttachmentCount;
1094 			DE_NULL																			// const VkAttachmentReference*	pPreserveAttachments;
1095 		};
1096 
1097 		std::vector<VkSubpassDependency> subpassDependencies;
1098 
1099 		if (m_useImageAsColorOrDSAttachment)
1100 		{
1101 			const auto srcStageMask		= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
1102 			const auto srcAccessMask	= VK_ACCESS_SHADER_READ_BIT;
1103 			const auto dstStageMask		= (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1104 			const auto dstAccessMask	= (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT);
1105 
1106 			const VkSubpassDependency spdVal =
1107 			{
1108 				0u,																	//	uint32_t				srcSubpass;
1109 				0u,																	//	uint32_t				dstSubpass;
1110 				srcStageMask,														//	VkPipelineStageFlags	srcStageMask;
1111 				dstStageMask,														//	VkPipelineStageFlags	dstStageMask;
1112 				srcAccessMask,														//	VkAccessFlags			srcAccessMask;
1113 				dstAccessMask,														//	VkAccessFlags			dstAccessMask;
1114 				VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT | VK_DEPENDENCY_BY_REGION_BIT,	//	VkDependencyFlags		dependencyFlags;
1115 			};
1116 
1117 			subpassDependencies.push_back(spdVal);
1118 		}
1119 
1120 		const VkRenderPassCreateInfo renderPassParams =
1121 		{
1122 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
1123 			DE_NULL,											// const void*						pNext;
1124 			0u,													// VkRenderPassCreateFlags			flags;
1125 			(deUint32)attachmentDescriptions.size(),			// deUint32							attachmentCount;
1126 			&attachmentDescriptions[0],							// const VkAttachmentDescription*	pAttachments;
1127 			1u,													// deUint32							subpassCount;
1128 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
1129 			static_cast<uint32_t>(subpassDependencies.size()),	// deUint32							dependencyCount;
1130 			de::dataOrNull(subpassDependencies),				// const VkSubpassDependency*		pDependencies;
1131 		};
1132 
1133 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1134 	}
1135 
1136 	// Create framebuffer
1137 	{
1138 		std::vector<VkImageView> pAttachments(m_imageCount);
1139 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1140 		{
1141 			pAttachments[imgNdx] = m_dsAttachmentViews[imgNdx]->get();
1142 		}
1143 
1144 		const VkFramebufferCreateInfo framebufferParams =
1145 		{
1146 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
1147 			DE_NULL,											// const void*				pNext;
1148 			0u,													// VkFramebufferCreateFlags	flags;
1149 			*m_renderPass,										// VkRenderPass				renderPass;
1150 			(deUint32)m_imageCount,								// deUint32					attachmentCount;
1151 			&pAttachments[0],									// const VkImageView*		pAttachments;
1152 			(deUint32)renderSize.x(),							// deUint32					width;
1153 			(deUint32)renderSize.y(),							// deUint32					height;
1154 			1u													// deUint32					layers;
1155 		};
1156 
1157 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1158 	}
1159 
1160 	// Create pipeline layout
1161 	{
1162 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1163 		{
1164 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
1165 			DE_NULL,											// const void*					pNext;
1166 			VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,	// VkPipelineLayoutCreateFlags	flags;
1167 			0u,													// deUint32						setLayoutCount;
1168 			DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
1169 			0u,													// deUint32						pushConstantRangeCount;
1170 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
1171 		};
1172 
1173 		m_preRasterizationStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1174 	}
1175 	{
1176 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1177 		{
1178 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
1179 			DE_NULL,											// const void*					pNext;
1180 			VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,	// VkPipelineLayoutCreateFlags	flags;
1181 			1u,													// deUint32						setLayoutCount;
1182 			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*	pSetLayouts;
1183 			0u,													// deUint32						pushConstantRangeCount;
1184 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
1185 		};
1186 
1187 		m_fragmentStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1188 	}
1189 
1190 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
1191 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
1192 
1193 	// Create pipeline
1194 	{
1195 		const VkVertexInputBindingDescription vertexInputBindingDescription =
1196 		{
1197 			0u,									// deUint32					binding;
1198 			sizeof(Vertex4Tex4),				// deUint32					strideInBytes;
1199 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	inputRate;
1200 		};
1201 
1202 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1203 		{
1204 			{
1205 				0u,										// deUint32	location;
1206 				0u,										// deUint32	binding;
1207 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
1208 				0u										// deUint32	offset;
1209 			},
1210 			{
1211 				1u,										// deUint32	location;
1212 				0u,										// deUint32	binding;
1213 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
1214 				DE_OFFSET_OF(Vertex4Tex4, texCoord),	// deUint32	offset;
1215 			}
1216 		};
1217 
1218 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1219 		{
1220 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
1221 			DE_NULL,														// const void*								pNext;
1222 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
1223 			1u,																// deUint32									vertexBindingDescriptionCount;
1224 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
1225 			2u,																// deUint32									vertexAttributeDescriptionCount;
1226 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
1227 		};
1228 
1229 		const std::vector<VkViewport>	viewports	(1, makeViewport(renderSize));
1230 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(renderSize));
1231 
1232 		std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates(m_imageCount);
1233 
1234 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1235 		{
1236 			colorBlendAttachmentStates[imgNdx].blendEnable			= false;												// VkBool32					blendEnable;
1237 			colorBlendAttachmentStates[imgNdx].srcColorBlendFactor	= VK_BLEND_FACTOR_ONE;									// VkBlendFactor			srcColorBlendFactor;
1238 			colorBlendAttachmentStates[imgNdx].dstColorBlendFactor	= VK_BLEND_FACTOR_ZERO;									// VkBlendFactor			dstColorBlendFactor;
1239 			colorBlendAttachmentStates[imgNdx].colorBlendOp			= VK_BLEND_OP_ADD;										// VkBlendOp				colorBlendOp;
1240 			colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor	= VK_BLEND_FACTOR_ONE;									// VkBlendFactor			srcAlphaBlendFactor;
1241 			colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor	= VK_BLEND_FACTOR_ZERO;									// VkBlendFactor			dstAlphaBlendFactor;
1242 			colorBlendAttachmentStates[imgNdx].alphaBlendOp			= VK_BLEND_OP_ADD;										// VkBlendOp				alphaBlendOp;
1243 			colorBlendAttachmentStates[imgNdx].colorWriteMask		= 0u;													// VkColorComponentFlags	colorWriteMask;
1244 		}
1245 
1246 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1247 		{
1248 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
1249 			DE_NULL,													// const void*									pNext;
1250 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
1251 			false,														// VkBool32										logicOpEnable;
1252 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
1253 			0u,															// deUint32										attachmentCount;
1254 			DE_NULL,													// const VkPipelineColorBlendAttachmentState*	pAttachments;
1255 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
1256 		};
1257 
1258 		VkBool32 depthTestEnable =
1259 			((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !m_interleaveReadWriteComponents) ||
1260 			((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && m_interleaveReadWriteComponents);
1261 
1262 		VkBool32 stencilTestEnable =
1263 			((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !m_interleaveReadWriteComponents) ||
1264 			((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && m_interleaveReadWriteComponents);
1265 
1266 		const auto stencilFrontOpState	= makeStencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_NEVER, 0xFFu, 0xFFu, 0u);
1267 		const auto stencilBackOpState	= makeStencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0xFFu, 0xFFu, 0u);
1268 
1269 		const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1270 		{
1271 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,							// VkStructureType							sType
1272 			DE_NULL,																			// const void*								pNext
1273 			0u,																					// VkPipelineDepthStencilStateCreateFlags	flags
1274 			depthTestEnable,																	// VkBool32									depthTestEnable
1275 			depthTestEnable,																	// VkBool32									depthWriteEnable
1276 			VK_COMPARE_OP_ALWAYS,																// VkCompareOp								depthCompareOp
1277 			DE_FALSE,																			// VkBool32									depthBoundsTestEnable
1278 			stencilTestEnable,																	// VkBool32									stencilTestEnable
1279 			stencilFrontOpState,																// VkStencilOpState							front
1280 			stencilBackOpState,																	// VkStencilOpState							back
1281 			0.0f,																				// float									minDepthBounds
1282 			1.0f,																				// float									maxDepthBounds;
1283 		};
1284 
1285 		m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
1286 						  .setDefaultDepthStencilState()
1287 						  .setDefaultRasterizationState()
1288 						  .setDefaultMultisampleState()
1289 						  .setupVertexInputState(&vertexInputStateParams)
1290 						  .setupPreRasterizationShaderState(viewports,
1291 														scissors,
1292 														*m_preRasterizationStatePipelineLayout,
1293 														*m_renderPass,
1294 														0u,
1295 														*m_vertexShaderModule)
1296 						  .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule, &depthStencilStateCreateInfo)
1297 						  .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
1298 						  .buildPipeline();
1299 
1300 	}
1301 
1302 	// Create vertex buffer
1303 	{
1304 		const VkDeviceSize			vertexBufferSize	= (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
1305 		const VkBufferCreateInfo	vertexBufferParams	=
1306 		{
1307 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1308 			DE_NULL,									// const void*			pNext;
1309 			0u,											// VkBufferCreateFlags	flags;
1310 			vertexBufferSize,							// VkDeviceSize			size;
1311 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
1312 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1313 			1u,											// deUint32				queueFamilyIndexCount;
1314 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
1315 		};
1316 
1317 		DE_ASSERT(vertexBufferSize > 0);
1318 
1319 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
1320 		m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
1321 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1322 
1323 		// Load vertices into vertex buffer
1324 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
1325 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1326 	}
1327 
1328 	// Create command buffer
1329 	{
1330 		std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
1331 
1332 		for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1333 		{
1334 			preAttachmentBarriers[imgNdx].sType								= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;								// VkStructureType			sType;
1335 			preAttachmentBarriers[imgNdx].pNext								= DE_NULL;																// const void*				pNext;
1336 			preAttachmentBarriers[imgNdx].srcAccessMask						= VK_ACCESS_TRANSFER_WRITE_BIT;																	// VkAccessFlags			srcAccessMask;
1337 			preAttachmentBarriers[imgNdx].dstAccessMask						= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;	// VkAccessFlags			dstAccessMask;
1338 			preAttachmentBarriers[imgNdx].oldLayout							= m_imageLayout;														// VkImageLayout			oldLayout;
1339 			preAttachmentBarriers[imgNdx].newLayout							= m_imageLayout;														// VkImageLayout			newLayout;
1340 			preAttachmentBarriers[imgNdx].srcQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;												// deUint32					srcQueueFamilyIndex;
1341 			preAttachmentBarriers[imgNdx].dstQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;												// deUint32					dstQueueFamilyIndex;
1342 			preAttachmentBarriers[imgNdx].image								= **m_dsImages[imgNdx];													// VkImage					image;
1343 			preAttachmentBarriers[imgNdx].subresourceRange.aspectMask		= getAspectFlags(m_imageFormat);										// VkImageSubresourceRange	subresourceRange;
1344 			preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel		= 0u;
1345 			preAttachmentBarriers[imgNdx].subresourceRange.levelCount		= 1u;
1346 			preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer	= 0u;
1347 			preAttachmentBarriers[imgNdx].subresourceRange.layerCount		= 1u;
1348 		}
1349 
1350 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1351 
1352 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1353 			0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
1354 
1355 		// Do not clear the color attachments as we are using the texture as color attachment.
1356 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), 0u, DE_NULL);
1357 
1358 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
1359 
1360 		vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1361 
1362 		const VkDeviceSize vertexBufferOffset = 0;
1363 		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1364 		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
1365 
1366 		endRenderPass(vk, *m_cmdBuffer);
1367 		endCommandBuffer(vk, *m_cmdBuffer);
1368 	}
1369 }
1370 
verifyImage(void)1371 tcu::TestStatus AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::verifyImage(void)
1372 {
1373 	const tcu::TextureFormat	tcuFormat		= getSizeCompatibleTcuTextureFormat(m_imageFormat);
1374 	const bool					isDepth			= (!m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1375 												   (m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT));
1376 	const bool					isStencil		= (!m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) ||
1377 												   (m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT));
1378 	// ImageSamplingInstance::verifyImage() doesn't support stencil sampling.
1379 	if (!m_useImageAsColorOrDSAttachment && !isStencil)
1380 		return ImageSamplingInstance::verifyImage();
1381 
1382 	const tcu::Vec4	fThreshold (0.005f);
1383 	const tcu::UVec4 uThreshold (0u); // Due to unsigned normalized fixed-point integers conversion to floats and viceversa.
1384 	tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
1385 
1386 	de::MovePtr<tcu::TextureLevel> referenceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(tcuFormat,
1387 																							  m_imageSize.x(),
1388 																							  m_imageSize.y(),
1389 																							  m_imageSize.z()));
1390 
1391 	for (int z = 0; z < m_imageSize.z(); z++)
1392 		for (int y = 0; y < m_imageSize.y(); y++)
1393 			for (int x = 0; x < m_imageSize.x(); x++)
1394 			{
1395 				if (isDepth)
1396 				{
1397 					float depth = 0.0f;
1398 					if (m_interleaveReadWriteComponents)
1399 					{
1400 						int stencil = 1 + m_texture->getLevel(0, 0).getPixStencil(x, y, z);
1401 						depth = static_cast<float>(stencil) / 255.0f;
1402 					}
1403 					else
1404 					{
1405 						if (m_useDifferentAreasSampleWrite && x < m_imageSize.x() / 2)
1406 							depth = m_texture->getLevel(0, 0).getPixDepth(x + (m_imageSize.x() / 2), y, z) + 0.1f;
1407 						else
1408 							depth = m_texture->getLevel(0, 0).getPixDepth(x, y, z);
1409 
1410 						if (!m_useDifferentAreasSampleWrite)
1411 							depth += 0.1f;
1412 					}
1413 
1414 					depth = deFloatClamp(depth, 0.0f, 1.0f);
1415 					referenceTextureLevel->getAccess().setPixDepth(depth, x, y, z);
1416 				}
1417 				if (isStencil)
1418 				{
1419 					int stencil = 0;
1420 					if (m_interleaveReadWriteComponents)
1421 					{
1422 						float depth = m_texture->getLevel(0, 0).getPixDepth(x, y, z) + 0.1f;
1423 						stencil = static_cast<int>(depth * 255.0f);
1424 					}
1425 					else
1426 					{
1427 						if (m_useDifferentAreasSampleWrite && x < m_imageSize.x() / 2)
1428 							stencil = 1 + m_texture->getLevel(0, 0).getPixStencil(x + (m_imageSize.x() / 2), y, z);
1429 						else
1430 							stencil = m_texture->getLevel(0, 0).getPixStencil(x, y, z);
1431 
1432 						if (!m_useDifferentAreasSampleWrite)
1433 							stencil += 1;
1434 
1435 						stencil = deClamp32(stencil, 0, 255);
1436 					}
1437 
1438 					referenceTextureLevel->getAccess().setPixStencil(stencil, x, y, z);
1439 				}
1440 			}
1441 
1442 	for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1443 	{
1444 		if (isDepth)
1445 		{
1446 			// Read back result image
1447 			de::MovePtr<tcu::TextureLevel>			resultTexture			(readDepthAttachment(m_context.getDeviceInterface(),
1448 																				m_context.getDevice(),
1449 																				m_context.getUniversalQueue(),
1450 																				m_context.getUniversalQueueFamilyIndex(),
1451 																				m_context.getDefaultAllocator(),
1452 																				**m_dsImages[imgNdx],
1453 																				m_imageFormat,
1454 																				renderSize,
1455 																				VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1456 
1457 			const tcu::ConstPixelBufferAccess		result	= resultTexture->getAccess();
1458 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1459 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1460 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(referenceTextureLevel->getAccess(), mode);
1461 			bool									isIntegerFormat		= isUintFormat(mapTextureFormat(depthResult.getFormat())) || isIntFormat(mapTextureFormat(depthResult.getFormat()));
1462 
1463 			if (!isIntegerFormat)
1464 			{
1465 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1466 					return tcu::TestStatus::fail("Failed depth");
1467 			}
1468 			else
1469 			{
1470 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1471 					return tcu::TestStatus::fail("Failed depth");
1472 			}
1473 		}
1474 
1475 		if (isStencil)
1476 		{
1477 			// Read back result image
1478 			de::MovePtr<tcu::TextureLevel>			resultTexture			(readStencilAttachment(m_context.getDeviceInterface(),
1479 																				m_context.getDevice(),
1480 																				m_context.getUniversalQueue(),
1481 																				m_context.getUniversalQueueFamilyIndex(),
1482 																				m_context.getDefaultAllocator(),
1483 																				**m_dsImages[imgNdx],
1484 																				m_imageFormat,
1485 																				renderSize,
1486 																				VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1487 
1488 			const tcu::ConstPixelBufferAccess		result	= resultTexture->getAccess();
1489 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1490 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1491 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(referenceTextureLevel->getAccess(), mode);
1492 			bool									isIntegerFormat		= isUintFormat(mapTextureFormat(stencilResult.getFormat())) || isIntFormat(mapTextureFormat(stencilResult.getFormat()));
1493 
1494 			if (!isIntegerFormat)
1495 			{
1496 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1497 					return tcu::TestStatus::fail("Failed stencil");
1498 			}
1499 			else
1500 			{
1501 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1502 					return tcu::TestStatus::fail("Failed stencil");
1503 			}
1504 		}
1505 	}
1506 
1507 	return tcu::TestStatus::pass("Pass");
1508 }
1509 
iterate(void)1510 tcu::TestStatus AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::iterate (void)
1511 {
1512 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1513 	const VkDevice				vkDevice	= m_context.getDevice();
1514 	const VkQueue				queue		= m_context.getUniversalQueue();
1515 
1516 	setup();
1517 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1518 
1519 	return verifyImage();
1520 }
1521 
verifyImage(void)1522 tcu::TestStatus AttachmentFeedbackLoopLayoutImageSamplingInstance::verifyImage(void)
1523 {
1524 	if (!m_useImageAsColorOrDSAttachment)
1525 		return ImageSamplingInstance::verifyImage();
1526 
1527 	const tcu::Vec4	fThreshold (0.01f);
1528 	const tcu::UVec4 uThreshold (1u);
1529 	tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
1530 
1531 	const tcu::TextureFormat	tcuFormat		= getSizeCompatibleTcuTextureFormat(m_imageFormat);
1532 	de::MovePtr<tcu::TextureLevel> referenceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(tcuFormat,
1533 																												m_imageSize.x(),
1534 																												m_imageSize.y(),
1535 																												m_imageSize.z()));
1536 
1537 	for (int z = 0; z < m_imageSize.z(); z++)
1538 		for (int y = 0; y < m_imageSize.y(); y++)
1539 			for (int x = 0; x < m_imageSize.x(); x++)
1540 			{
1541 				tcu::Vec4 color = tcu::Vec4(1.0f);
1542 
1543 				if (m_useDifferentAreasSampleWrite && (x < m_imageSize.x() / 2))
1544 					color = m_texture->getLevel(0, 0).getPixel(x + (m_imageSize.x() / 2), y, z) + tcu::Vec4(0.1f);
1545 				else
1546 					color = m_texture->getLevel(0, 0).getPixel(x, y, z);
1547 
1548 				if (!m_useDifferentAreasSampleWrite)
1549 					color += tcu::Vec4(0.1f);
1550 
1551 				if (m_interleaveReadWriteComponents)
1552 				{
1553 					tcu::Vec4 sampledColor = m_texture->getLevel(0, 0).getPixel(x, y, z);
1554 					color.x() = color.y();
1555 					color.y() = sampledColor.y();
1556 					color.z() = color.w();
1557 					color.w() = sampledColor.w();
1558 				}
1559 
1560 				color.x() = deFloatClamp(color.x(), 0.0f, 1.0f);
1561 				color.y() = deFloatClamp(color.y(), 0.0f, 1.0f);
1562 				color.z() = deFloatClamp(color.z(), 0.0f, 1.0f);
1563 				color.w() = deFloatClamp(color.w(), 0.0f, 1.0f);
1564 
1565 				referenceTextureLevel->getAccess().setPixel(color, x, y, z);
1566 			}
1567 
1568 	for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1569 	{
1570 		// Read back result image
1571 		de::MovePtr<tcu::TextureLevel>		resultTexture			(readColorAttachment(m_context.getDeviceInterface(),
1572 																						 m_context.getDevice(),
1573 																						 m_context.getUniversalQueue(),
1574 																						 m_context.getUniversalQueueFamilyIndex(),
1575 																						 m_context.getDefaultAllocator(),
1576 																						 **m_colorImages[imgNdx],
1577 																						 m_colorFormat,
1578 																						 renderSize,
1579 																						 vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1580 		const tcu::ConstPixelBufferAccess	result	= resultTexture->getAccess();
1581 		const bool							isIntegerFormat	= isUintFormat(m_imageFormat) || isIntFormat(m_imageFormat);
1582 
1583 		if (!isIntegerFormat)
1584 		{
1585 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1586 				return tcu::TestStatus::fail("Failed color");
1587 		}
1588 		else
1589 		{
1590 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1591 				return tcu::TestStatus::fail("Failed color");
1592 		}
1593 	}
1594 
1595 	return tcu::TestStatus::pass("Pass");
1596 }
1597 
~AttachmentFeedbackLoopLayoutImageSamplingInstance(void)1598 AttachmentFeedbackLoopLayoutImageSamplingInstance::~AttachmentFeedbackLoopLayoutImageSamplingInstance (void)
1599 {
1600 }
1601 
iterate(void)1602 tcu::TestStatus AttachmentFeedbackLoopLayoutImageSamplingInstance::iterate (void)
1603 {
1604 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1605 	const VkDevice				vkDevice	= m_context.getDevice();
1606 	const VkQueue				queue		= m_context.getUniversalQueue();
1607 
1608 	setup();
1609 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1610 
1611 	return verifyImage();
1612 }
1613 
1614 class AttachmentFeedbackLoopLayoutSamplerTest : public vkt::TestCase {
1615 public:
1616 										AttachmentFeedbackLoopLayoutSamplerTest			(tcu::TestContext&				testContext,
1617 																						 vk::PipelineConstructionType	pipelineConstructionType,
1618 																						 const char*					name,
1619 																						 const char*					description,
1620 																						 SamplerViewType				imageViewType,
1621 																						 VkFormat						imageFormat,
1622 																						 int							imageSize,
1623 																						 VkDescriptorType				imageDescriptorType,
1624 																						 float							samplerLod,
1625 																						 TestMode						testMode,
1626 																						 ImageAspectTestMode			imageAspectTestMode,
1627 																						 bool							interleaveReadWriteComponents);
~AttachmentFeedbackLoopLayoutSamplerTest(void)1628 	virtual								~AttachmentFeedbackLoopLayoutSamplerTest		(void) {}
1629 
1630 	virtual ImageSamplingInstanceParams	getImageSamplingInstanceParams	(SamplerViewType	imageViewType,
1631 																		 VkFormat			imageFormat,
1632 																		 int				imageSize,
1633 																		 VkDescriptorType	imageDescriptorType,
1634 																		 float				samplerLod) const;
1635 
1636 	virtual void						initPrograms					(SourceCollections& sourceCollections) const;
1637 	virtual void						checkSupport					(Context& context) const;
1638 	virtual TestInstance*				createInstance					(Context& context) const;
1639 	virtual tcu::UVec2					getRenderSize					(SamplerViewType viewType) const;
1640 	virtual std::vector<Vertex4Tex4>	createVertices					(void) const;
1641 	virtual VkSamplerCreateInfo			getSamplerCreateInfo			(void) const;
1642 	virtual VkComponentMapping			getComponentMapping				(void) const;
1643 
1644 	static std::string					getGlslSamplerType				(const tcu::TextureFormat& format, SamplerViewType type);
1645 	static tcu::IVec3					getImageSize					(SamplerViewType viewType, int size);
1646 	static int							getArraySize					(SamplerViewType viewType);
1647 
1648 	static std::string					getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount);
1649 	static std::string					getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type);
1650 	static std::string					getGlslSamplerDecl (int imageCount);
1651 	static std::string					getGlslTextureDecl (int imageCount);
1652 
1653 protected:
1654 	vk::PipelineConstructionType		m_pipelineConstructionType;
1655 	SamplerViewType						m_imageViewType;
1656 	VkFormat							m_imageFormat;
1657 	int									m_imageSize;
1658 	VkDescriptorType					m_imageDescriptorType;
1659 	float								m_samplerLod;
1660 	TestMode							m_testMode;
1661 	ImageAspectTestMode					m_imageAspectTestMode;
1662 	bool								m_interleaveReadWriteComponents;
1663 };
1664 
1665 // AttachmentFeedbackLoopLayoutSamplerTest
1666 
AttachmentFeedbackLoopLayoutSamplerTest(tcu::TestContext & testContext,vk::PipelineConstructionType pipelineConstructionType,const char * name,const char * description,SamplerViewType imageViewType,VkFormat imageFormat,int imageSize,VkDescriptorType imageDescriptorType,float samplerLod,TestMode testMode,ImageAspectTestMode imageAspectTestMode,bool interleaveReadWriteComponents=false)1667 AttachmentFeedbackLoopLayoutSamplerTest::AttachmentFeedbackLoopLayoutSamplerTest	(tcu::TestContext&				testContext,
1668 																					 vk::PipelineConstructionType	pipelineConstructionType,
1669 																					 const char*					name,
1670 																					 const char*					description,
1671 																					 SamplerViewType				imageViewType,
1672 																					 VkFormat						imageFormat,
1673 																					 int							imageSize,
1674 																					 VkDescriptorType				imageDescriptorType,
1675 																					 float							samplerLod,
1676 																					 TestMode						testMode,
1677 																					 ImageAspectTestMode			imageAspectTestMode,
1678 																					 bool							interleaveReadWriteComponents = false)
1679 	: vkt::TestCase					(testContext, name, description)
1680 	, m_pipelineConstructionType	(pipelineConstructionType)
1681 	, m_imageViewType				(imageViewType)
1682 	, m_imageFormat					(imageFormat)
1683 	, m_imageSize					(imageSize)
1684 	, m_imageDescriptorType			(imageDescriptorType)
1685 	, m_samplerLod					(samplerLod)
1686 	, m_testMode					(testMode)
1687 	, m_imageAspectTestMode			(imageAspectTestMode)
1688 	, m_interleaveReadWriteComponents	(interleaveReadWriteComponents)
1689 {
1690 }
1691 
getImageSamplingInstanceParams(SamplerViewType imageViewType,VkFormat imageFormat,int imageSize,VkDescriptorType imageDescriptorType,float samplerLod) const1692 ImageSamplingInstanceParams AttachmentFeedbackLoopLayoutSamplerTest::getImageSamplingInstanceParams (SamplerViewType	imageViewType,
1693 																									 VkFormat			imageFormat,
1694 																									 int				imageSize,
1695 																									 VkDescriptorType	imageDescriptorType,
1696 																									 float				samplerLod) const
1697 {
1698 	const tcu::UVec2				renderSize			= getRenderSize(imageViewType);
1699 	const std::vector<Vertex4Tex4>	vertices			= createVertices();
1700 	const VkSamplerCreateInfo		samplerParams		= getSamplerCreateInfo();
1701 	const VkComponentMapping		componentMapping	= getComponentMapping();
1702 
1703 	VkImageAspectFlags				imageAspect			= 0u;
1704 	VkPipelineCreateFlags			pipelineCreateFlags = 0u;
1705 	if (!isCompressedFormat(imageFormat))
1706 	{
1707 		if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR)
1708 		{
1709 			DE_ASSERT(!tcu::hasDepthComponent(mapVkFormat(imageFormat).order) &&
1710 					  !tcu::hasStencilComponent(mapVkFormat(imageFormat).order));
1711 			imageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
1712 			pipelineCreateFlags = VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1713 		}
1714 		if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH)
1715 		{
1716 			DE_ASSERT(tcu::hasDepthComponent(mapVkFormat(imageFormat).order));
1717 			imageAspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
1718 			pipelineCreateFlags = VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1719 		}
1720 	    if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL)
1721 		{
1722 			DE_ASSERT(tcu::hasStencilComponent(mapVkFormat(imageFormat).order));
1723 			imageAspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
1724 			pipelineCreateFlags = VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1725 		}
1726 	}
1727 	else
1728 	{
1729 		imageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
1730 	}
1731 
1732 	const VkImageSubresourceRange	subresourceRange	=
1733 	{
1734 		imageAspect,										// VkImageAspectFlags	aspectMask;
1735 		0u,													// deUint32				baseMipLevel;
1736 		1u,													// deUint32				mipLevels;
1737 		0u,													// deUint32				baseArrayLayer;
1738 		(deUint32)getArraySize(imageViewType)				// deUint32				arraySize;
1739 	};
1740 
1741 	return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat,
1742 									   getImageSize(imageViewType, imageSize),
1743 									   getArraySize(imageViewType),
1744 									   componentMapping, subresourceRange,
1745 									   samplerParams, samplerLod, vertices, false,
1746 									   imageDescriptorType, 1u, ALLOCATION_KIND_SUBALLOCATED,
1747 									   vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT,
1748 									   pipelineCreateFlags);
1749 }
1750 
checkSupport(Context & context) const1751 void AttachmentFeedbackLoopLayoutSamplerTest::checkSupport (Context& context) const
1752 {
1753 	context.requireDeviceFunctionality("VK_EXT_attachment_feedback_loop_layout");
1754 
1755 	checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1756 
1757 	vk::VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT attachmentFeedbackLoopLayoutFeatures =
1758 	{
1759 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT,	// VkStructureType	sType;
1760 		DE_NULL,																				// void*			pNext;
1761 		DE_FALSE,																				// VkBool32		attachmentFeedbackLoopLayout;
1762 	};
1763 
1764 	vk::VkPhysicalDeviceFeatures2 features2;
1765 	deMemset(&features2, 0, sizeof(features2));
1766 	features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1767 	features2.pNext = &attachmentFeedbackLoopLayoutFeatures;
1768 
1769 	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
1770 
1771 	if (attachmentFeedbackLoopLayoutFeatures.attachmentFeedbackLoopLayout == DE_FALSE)
1772 	{
1773 		throw tcu::NotSupportedError("attachmentFeedbackLoopLayout not supported");
1774 	}
1775 
1776 	checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod));
1777 
1778 	ImageSamplingInstanceParams	params = getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod);
1779 
1780 	bool useImageAsColorOrDSAttachment	= m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL;
1781 	if (useImageAsColorOrDSAttachment)
1782 	{
1783 		VkFormatProperties	formatProps;
1784 		const InstanceInterface& instanceInterface = context.getInstanceInterface();
1785 		VkFormatFeatureFlags attachmentFormatFeature = isDepthStencilFormat(params.imageFormat) ?
1786 			VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1787 
1788 		instanceInterface.getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), params.imageFormat, &formatProps);
1789 		bool error =
1790 			(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0u ||
1791 			(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT ) == 0u ||
1792 			(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT ) == 0u ||
1793 			(formatProps.optimalTilingFeatures & attachmentFormatFeature ) == 0u;
1794 
1795 		if (error)
1796 		{
1797 			throw tcu::NotSupportedError("format doesn't support some required features");
1798 		}
1799 
1800 		if ((!m_interleaveReadWriteComponents && m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL) ||
1801 			(m_interleaveReadWriteComponents && m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH))
1802 			context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
1803 	}
1804 }
1805 
getGlslTextureType(const tcu::TextureFormat & format,VkImageViewType type)1806 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type)
1807 {
1808 	std::ostringstream textureType;
1809 
1810 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1811 		textureType << "u";
1812 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1813 		textureType << "i";
1814 
1815 	switch (type)
1816 	{
1817 		case VK_IMAGE_VIEW_TYPE_1D:
1818 			textureType << "texture1D";
1819 			break;
1820 
1821 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1822 			textureType << "texture1DArray";
1823 			break;
1824 
1825 		case VK_IMAGE_VIEW_TYPE_2D:
1826 			textureType << "texture2D";
1827 			break;
1828 
1829 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1830 			textureType << "texture2DArray";
1831 			break;
1832 
1833 		case VK_IMAGE_VIEW_TYPE_3D:
1834 			textureType << "texture3D";
1835 			break;
1836 
1837 		case VK_IMAGE_VIEW_TYPE_CUBE:
1838 			textureType << "textureCube";
1839 			break;
1840 
1841 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1842 			textureType << "textureCubeArray";
1843 			break;
1844 
1845 		default:
1846 			DE_FATAL("Unknown image view type");
1847 	}
1848 
1849 	return textureType.str();
1850 }
1851 
getGlslSamplerDecl(int imageCount)1852 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSamplerDecl (int imageCount)
1853 {
1854 	std::ostringstream samplerArray;
1855 	samplerArray << "texSamplers[" << imageCount << "]";
1856 
1857 	return imageCount > 1 ? samplerArray.str() : "texSampler";
1858 }
1859 
getGlslTextureDecl(int imageCount)1860 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslTextureDecl (int imageCount)
1861 {
1862 	std::ostringstream textureArray;
1863 	textureArray << "texImages[" << imageCount << "]";
1864 
1865 	return imageCount > 1 ? textureArray.str() : "texImage";
1866 }
1867 
getGlslSampler(const tcu::TextureFormat & format,VkImageViewType type,VkDescriptorType samplingType,int imageCount)1868 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)
1869 {
1870 	std::string texSampler	= imageCount > 1 ? "texSamplers[i]" : "texSampler";
1871 	std::string texImage	= imageCount > 1 ? "texImages[i]" : "texImage";
1872 
1873 	switch (samplingType)
1874 	{
1875 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1876 			return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
1877 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1878 		default:
1879 			return texSampler;
1880 	}
1881 }
1882 
initPrograms(SourceCollections & sourceCollections) const1883 void AttachmentFeedbackLoopLayoutSamplerTest::initPrograms (SourceCollections& sourceCollections) const
1884 {
1885 	std::ostringstream				vertexSrc;
1886 	std::ostringstream				fragmentSrc;
1887 	const char*						texCoordSwizzle	= DE_NULL;
1888 	const VkFormat					vkFormat = m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL ? VK_FORMAT_S8_UINT : m_imageFormat;
1889 	const tcu::TextureFormat		format			= (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(vkFormat))
1890 																						  : mapVkFormat(vkFormat);
1891 	tcu::Vec4						lookupScale;
1892 	tcu::Vec4						lookupBias;
1893 
1894 	getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
1895 
1896 	switch (m_imageViewType)
1897 	{
1898 		case VK_IMAGE_VIEW_TYPE_1D:
1899 			texCoordSwizzle = "x";
1900 			break;
1901 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1902 		case VK_IMAGE_VIEW_TYPE_2D:
1903 			texCoordSwizzle = "xy";
1904 			break;
1905 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1906 		case VK_IMAGE_VIEW_TYPE_3D:
1907 		case VK_IMAGE_VIEW_TYPE_CUBE:
1908 			texCoordSwizzle = "xyz";
1909 			break;
1910 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1911 			texCoordSwizzle = "xyzw";
1912 			break;
1913 		default:
1914 			DE_ASSERT(false);
1915 			break;
1916 	}
1917 
1918 	vertexSrc << "#version 440\n"
1919 			  << "layout(location = 0) in vec4 position;\n"
1920 			  << "layout(location = 1) in vec4 texCoords;\n"
1921 			  << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
1922 			  << "out gl_PerVertex {\n"
1923 			  << "	vec4 gl_Position;\n"
1924 			  << "};\n"
1925 			  << "void main (void)\n"
1926 			  << "{\n"
1927 			  << "	gl_Position = position;\n"
1928 			  << "	vtxTexCoords = texCoords;\n"
1929 			  << "}\n";
1930 
1931 	fragmentSrc << "#version 440\n";
1932 
1933 	if ((m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL) ||
1934 		(m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_interleaveReadWriteComponents))
1935 	{
1936 		fragmentSrc << "#extension GL_ARB_shader_stencil_export: require\n";
1937 	}
1938 
1939 	switch (m_imageDescriptorType)
1940 	{
1941 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1942 			fragmentSrc
1943 				<< "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
1944 				<< "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(1u) << ";\n";
1945 			break;
1946 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1947 		default:
1948 			fragmentSrc
1949 				<< "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(1u) << ";\n";
1950 	}
1951 
1952 	if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR || m_testMode == TEST_MODE_READ_ONLY)
1953 		fragmentSrc	<< "layout(location = 0) out highp vec4 fragColor;\n";
1954 
1955 	fragmentSrc	<< "layout(location = 0) in highp vec4 vtxTexCoords;\n"
1956 				<< "void main (void)\n"
1957 				<< "{\n";
1958 
1959 	if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode != TEST_MODE_READ_ONLY)
1960 		fragmentSrc	<< "	uvec4 read_data = ";
1961 	else
1962 		fragmentSrc	<< "	vec4 read_data = ";
1963 
1964 	if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
1965 	{
1966 		fragmentSrc << "vec4(1.0f, 0.0f, 0.0f, 1.0f);\n";
1967 
1968 		fragmentSrc << "	read_data.x = ";
1969 		if (m_samplerLod > 0.0f)
1970 		{
1971 			DE_ASSERT(m_imageViewType.isNormalized());
1972 			fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed <<  m_samplerLod << ").x";
1973 		}
1974 		else
1975 		{
1976 			if (m_imageViewType.isNormalized())
1977 				fragmentSrc << "texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ").x" << std::fixed;
1978 			else
1979 				fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0).x" << std::fixed;
1980 		}
1981 
1982 		fragmentSrc << " + 0.1f;\n";
1983 	}
1984 	else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode == TEST_MODE_READ_ONLY)
1985 	{
1986 		if (m_samplerLod > 0.0f)
1987 		{
1988 			DE_ASSERT(m_imageViewType.isNormalized());
1989 			fragmentSrc << "vec4(textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed <<  m_samplerLod << ").x / 255.0f, 0.0f, 0.0f, 1.0f)";
1990 		}
1991 		else
1992 		{
1993 			if (m_imageViewType.isNormalized())
1994 				fragmentSrc << "vec4(texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ").x / 255.0f, 0.0f, 0.0f, 1.0f)" << std::fixed;
1995 			else
1996 				fragmentSrc << "vec4(textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0).x / 255.0f, 0.0f, 0.0f, 1.0f)" << std::fixed;
1997 		}
1998 
1999 		fragmentSrc << ";\n";
2000 	}
2001 	else
2002 	{
2003 		if (m_samplerLod > 0.0f)
2004 		{
2005 			DE_ASSERT(m_imageViewType.isNormalized());
2006 			fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed <<  m_samplerLod << ")";
2007 		}
2008 		else
2009 		{
2010 			if (m_imageViewType.isNormalized())
2011 				fragmentSrc << "texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
2012 			else
2013 				fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0)" << std::fixed;
2014 		}
2015 
2016 		if (m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2017 		{
2018 			if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL)
2019 				fragmentSrc << " + uvec4(1u, 0u, 0u, 0)";
2020 			else
2021 				fragmentSrc << " + vec4(0.1f)";
2022 		}
2023 
2024 		fragmentSrc << ";\n";
2025 	}
2026 
2027 	if (m_interleaveReadWriteComponents)
2028 	{
2029 		if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR)
2030 		{
2031 			fragmentSrc << "	fragColor = vec4(1.0f);\n"
2032 						<< "	fragColor.x = read_data.y;\n"
2033 						<< "	fragColor.z = read_data.w;\n";
2034 		}
2035 		else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH)
2036 		{
2037 			fragmentSrc << "	gl_FragStencilRefARB = int(clamp(read_data.x * 255.0f, 0.0f, 255.0f));\n";
2038 		}
2039 		else
2040 		{
2041 			fragmentSrc << "	gl_FragDepth = clamp(float(read_data.x) / 255.0f, 0.0f, 1.0f);\n";
2042 		}
2043 	}
2044 	else
2045 	{
2046 		if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2047 		{
2048 			fragmentSrc << "	gl_FragDepth = clamp(read_data.x, 0.0f, 1.0f);\n";
2049 		}
2050 		else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2051 		{
2052 			fragmentSrc << "	gl_FragStencilRefARB = int(clamp(read_data.x, 0u, 255u));\n";
2053 		}
2054 		else
2055 		{
2056 			fragmentSrc << "	fragColor = read_data;\n";
2057 		}
2058 	}
2059 
2060 	fragmentSrc	<< "}\n";
2061 
2062 	sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
2063 	sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
2064 }
2065 
createInstance(Context & context) const2066 TestInstance* AttachmentFeedbackLoopLayoutSamplerTest::createInstance (Context& context) const
2067 {
2068 	const bool useImageAsColorOrDSAttachment	= m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL;
2069 	const bool useDifferentAreasSampleWrite		= m_testMode == TEST_MODE_READ_WRITE_DIFFERENT_AREAS;
2070 
2071 	if (m_imageAspectTestMode != IMAGE_ASPECT_TEST_COLOR && useImageAsColorOrDSAttachment)
2072 		return new AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod), useImageAsColorOrDSAttachment, useDifferentAreasSampleWrite, m_interleaveReadWriteComponents);
2073 	return new AttachmentFeedbackLoopLayoutImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod), useImageAsColorOrDSAttachment, useDifferentAreasSampleWrite, m_interleaveReadWriteComponents);
2074 }
2075 
getRenderSize(SamplerViewType viewType) const2076 tcu::UVec2 AttachmentFeedbackLoopLayoutSamplerTest::getRenderSize (SamplerViewType viewType) const
2077 {
2078 	if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
2079 	{
2080 		return tcu::UVec2(16u, 16u);
2081 	}
2082 	else
2083 	{
2084 		return tcu::UVec2(16u * 3u, 16u * 2u);
2085 	}
2086 }
2087 
createFullscreenQuadArray(vk::VkImageViewType viewType,unsigned arraySize)2088 std::vector<Vertex4Tex4> createFullscreenQuadArray (vk::VkImageViewType viewType, unsigned arraySize)
2089 {
2090 	using tcu::Vec4;
2091 	std::vector<Vertex4Tex4>	verticesArray;
2092 
2093 	const Vertex4Tex4 lowerLeftVertex =
2094 	{
2095 		Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
2096 		Vec4(0.0f, 0.0f, 0.0f, 0.0f)
2097 	};
2098 	const Vertex4Tex4 upperLeftVertex =
2099 	{
2100 		Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
2101 		Vec4(0.0f, 1.0f, 0.0f, 0.0f)
2102 	};
2103 	const Vertex4Tex4 lowerRightVertex =
2104 	{
2105 		Vec4(1.0f, -1.0f, 0.0f, 1.0f),
2106 		Vec4(1.0f, 0.0f, 0.0f, 0.0f)
2107 	};
2108 	const Vertex4Tex4 upperRightVertex =
2109 	{
2110 		Vec4(1.0f, 1.0f, 0.0f, 1.0f),
2111 		Vec4(1.0f, 1.0f, 0.0f, 0.0f)
2112 	};
2113 
2114 	for (unsigned arrayNdx = 0; arrayNdx < arraySize; arrayNdx++)
2115 	{
2116 		Vertex4Tex4 vertices[6] =
2117 		{
2118 			lowerLeftVertex,
2119 			upperLeftVertex,
2120 			lowerRightVertex,
2121 
2122 			upperLeftVertex,
2123 			lowerRightVertex,
2124 			upperRightVertex
2125 		};
2126 
2127 		for (int i = 0; i < 6; i++)
2128 		{
2129 			if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
2130 			{
2131 				vertices[i].position.y() = (float)arrayNdx;
2132 				vertices[i].texCoord.y() = (float)arrayNdx;
2133 			}
2134 			else
2135 			{
2136 				vertices[i].position.z() = (float)arrayNdx;
2137 				vertices[i].texCoord.z() = (float)arrayNdx;
2138 			}
2139 			verticesArray.push_back(vertices[i]);
2140 		}
2141 	}
2142 
2143 	return verticesArray;
2144 }
2145 
createTestQuadAttachmentFeedbackLoopLayout(vk::VkImageViewType viewType)2146 std::vector<Vertex4Tex4> createTestQuadAttachmentFeedbackLoopLayout (vk::VkImageViewType viewType)
2147 {
2148 	std::vector<Vertex4Tex4> vertices;
2149 
2150 	switch (viewType)
2151 	{
2152 		case vk::VK_IMAGE_VIEW_TYPE_1D:
2153 		case vk::VK_IMAGE_VIEW_TYPE_2D:
2154 			vertices = createFullscreenQuad();
2155 			break;
2156 
2157 		case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2158 			vertices = createFullscreenQuadArray(viewType, 6u);
2159 			break;
2160 
2161 		case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2162 		case vk::VK_IMAGE_VIEW_TYPE_3D:
2163 		case vk::VK_IMAGE_VIEW_TYPE_CUBE:
2164 		case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2165 			vertices = createFullscreenQuadArray(viewType, 6u);
2166 			break;
2167 
2168 		default:
2169 			DE_ASSERT(false);
2170 			break;
2171 	}
2172 
2173 	return vertices;
2174 }
2175 
createVertices(void) const2176 std::vector<Vertex4Tex4> AttachmentFeedbackLoopLayoutSamplerTest::createVertices (void) const
2177 {
2178 	std::vector<Vertex4Tex4> vertices = m_testMode != TEST_MODE_READ_WRITE_DIFFERENT_AREAS ?
2179 		createTestQuadMosaic(m_imageViewType) :
2180 		createTestQuadAttachmentFeedbackLoopLayout(m_imageViewType);
2181 	for (unsigned int i = 0; i < vertices.size(); ++i) {
2182 		if (m_testMode == TEST_MODE_READ_WRITE_DIFFERENT_AREAS)
2183 		{
2184 			vertices[i].texCoord.x() = std::max(vertices[i].texCoord.x(), 0.5f);
2185 			vertices[i].position.x() = std::min(vertices[i].position.x(), 0.0f);
2186 		}
2187 		if (!m_imageViewType.isNormalized()) {
2188 			const float imageSize = static_cast<float>(m_imageSize);
2189 			for (int j = 0; j < tcu::Vec4::SIZE; ++j)
2190 				vertices[i].texCoord[j] *= imageSize;
2191 		}
2192 	}
2193 	return vertices;
2194 }
2195 
getSamplerCreateInfo(void) const2196 VkSamplerCreateInfo AttachmentFeedbackLoopLayoutSamplerTest::getSamplerCreateInfo (void) const
2197 {
2198 	const VkSamplerCreateInfo defaultSamplerParams =
2199 	{
2200 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,										// VkStructureType			sType;
2201 		DE_NULL,																	// const void*				pNext;
2202 		0u,																			// VkSamplerCreateFlags		flags;
2203 		VK_FILTER_NEAREST,															// VkFilter					magFilter;
2204 		VK_FILTER_NEAREST,															// VkFilter					minFilter;
2205 		VK_SAMPLER_MIPMAP_MODE_NEAREST,												// VkSamplerMipmapMode		mipmapMode;
2206 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,										// VkSamplerAddressMode		addressModeU;
2207 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,										// VkSamplerAddressMode		addressModeV;
2208 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,										// VkSamplerAddressMode		addressModeW;
2209 		0.0f,																		// float					mipLodBias;
2210 		VK_FALSE,																	// VkBool32					anisotropyEnable;
2211 		1.0f,																		// float					maxAnisotropy;
2212 		false,																		// VkBool32					compareEnable;
2213 		VK_COMPARE_OP_NEVER,														// VkCompareOp				compareOp;
2214 		0.0f,																		// float					minLod;
2215 		(m_imageViewType.isNormalized() ? 0.25f : 0.0f),							// float					maxLod;
2216 		getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat, false),	// VkBorderColor			borderColor;
2217 		!m_imageViewType.isNormalized(),											// VkBool32					unnormalizedCoordinates;
2218 	};
2219 
2220 	return defaultSamplerParams;
2221 }
2222 
getComponentMapping(void) const2223 VkComponentMapping AttachmentFeedbackLoopLayoutSamplerTest::getComponentMapping (void) const
2224 {
2225 	const VkComponentMapping	componentMapping	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2226 	return componentMapping;
2227 }
2228 
getGlslSamplerType(const tcu::TextureFormat & format,SamplerViewType type)2229 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type)
2230 {
2231 	std::ostringstream samplerType;
2232 
2233 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2234 		samplerType << "u";
2235 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2236 		samplerType << "i";
2237 
2238 	switch (type)
2239 	{
2240 		case VK_IMAGE_VIEW_TYPE_1D:
2241 			samplerType << "sampler1D";
2242 			break;
2243 
2244 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2245 			samplerType << "sampler1DArray";
2246 			break;
2247 
2248 		case VK_IMAGE_VIEW_TYPE_2D:
2249 			samplerType << "sampler2D";
2250 			break;
2251 
2252 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2253 			samplerType << "sampler2DArray";
2254 			break;
2255 
2256 		case VK_IMAGE_VIEW_TYPE_3D:
2257 			samplerType << "sampler3D";
2258 			break;
2259 
2260 		case VK_IMAGE_VIEW_TYPE_CUBE:
2261 			samplerType << "samplerCube";
2262 			break;
2263 
2264 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2265 			samplerType << "samplerCubeArray";
2266 			break;
2267 
2268 		default:
2269 			DE_FATAL("Unknown image view type");
2270 			break;
2271 	}
2272 
2273 	return samplerType.str();
2274 }
2275 
getImageSize(SamplerViewType viewType,int size)2276 tcu::IVec3 AttachmentFeedbackLoopLayoutSamplerTest::getImageSize (SamplerViewType viewType, int size)
2277 {
2278 	switch (viewType)
2279 	{
2280 		case VK_IMAGE_VIEW_TYPE_1D:
2281 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2282 			return tcu::IVec3(size, 1, 1);
2283 
2284 		case VK_IMAGE_VIEW_TYPE_3D:
2285 			return tcu::IVec3(size, size, 4);
2286 
2287 		default:
2288 			break;
2289 	}
2290 
2291 	return tcu::IVec3(size, size, 1);
2292 }
2293 
getArraySize(SamplerViewType viewType)2294 int AttachmentFeedbackLoopLayoutSamplerTest::getArraySize (SamplerViewType viewType)
2295 {
2296 	switch (viewType)
2297 	{
2298 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2299 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2300 		case VK_IMAGE_VIEW_TYPE_CUBE:
2301 			return 6;
2302 
2303 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2304 			return 36;
2305 
2306 		default:
2307 			break;
2308 	}
2309 
2310 	return 1;
2311 }
2312 } // anonymous
2313 
createAttachmentFeedbackLoopLayoutSamplerTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)2314 tcu::TestCaseGroup* createAttachmentFeedbackLoopLayoutSamplerTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
2315 {
2316 	// TODO: implement layer rendering with a geometry shader to render to arrays, 3D and cube images.
2317 	const struct
2318 	{
2319 		SamplerViewType		type;
2320 		const char*			name;
2321 		bool				readOnly;
2322 	}
2323 	imageViewTypes[] =
2324 	{
2325 		{ VK_IMAGE_VIEW_TYPE_1D,			"1d", false },
2326 		{ { VK_IMAGE_VIEW_TYPE_1D, false },	"1d_unnormalized", false },
2327 		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		"1d_array", true },
2328 		{ VK_IMAGE_VIEW_TYPE_2D,			"2d", false },
2329 		{ { VK_IMAGE_VIEW_TYPE_2D, false },	"2d_unnormalized", false },
2330 		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		"2d_array", true },
2331 		{ VK_IMAGE_VIEW_TYPE_3D,			"3d", true },
2332 		{ VK_IMAGE_VIEW_TYPE_CUBE,			"cube", true },
2333 		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	"cube_array", true }
2334 	};
2335 
2336 	const VkFormat formats[] =
2337 	{
2338 		VK_FORMAT_R8G8B8A8_UNORM,
2339 		VK_FORMAT_D16_UNORM,
2340 		VK_FORMAT_D32_SFLOAT,
2341 		VK_FORMAT_D16_UNORM_S8_UINT,
2342 		VK_FORMAT_D24_UNORM_S8_UINT,
2343 		VK_FORMAT_D32_SFLOAT_S8_UINT,
2344 		VK_FORMAT_S8_UINT
2345 	};
2346 
2347 	de::MovePtr<tcu::TestCaseGroup> samplingTypeTests		(new tcu::TestCaseGroup(testCtx, "sampler", ""));
2348 
2349 	const struct
2350 	{
2351 		enum TestMode		mode;
2352 		const char*			name;
2353 	}
2354 	testModes[] =
2355 	{
2356 		{ TEST_MODE_READ_ONLY,							"_read" },
2357 		{ TEST_MODE_READ_WRITE_SAME_PIXEL,				"_read_write_same_pixel" },
2358 		{ TEST_MODE_READ_WRITE_DIFFERENT_AREAS,			"_read_write_different_areas" },
2359 	};
2360 
2361 	const char* imageAspectTestModes[] = { "_color", "_depth", "_stencil" };
2362 
2363 	const struct
2364 	{
2365 		VkDescriptorType	type;
2366 		const char*			name;
2367 	}
2368 	imageDescriptorTypes[] =
2369 	{
2370 		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	"combined_image_sampler" },
2371 		{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				"sampled_image" },
2372 	};
2373 
2374 	const struct
2375 	{
2376 		bool				interleaveReadWriteComponents;
2377 		const char*			name;
2378 	}
2379 	interleaveReadWriteComponentsModes[] =
2380 	{
2381 		{ false,							"" },
2382 		{ true,								"_interleave_read_write_components" },
2383 	};
2384 
2385 
2386 	for (int imageDescriptorTypeNdx = 0; imageDescriptorTypeNdx < DE_LENGTH_OF_ARRAY(imageDescriptorTypes); imageDescriptorTypeNdx++)
2387 	{
2388 		VkDescriptorType					imageDescriptorType		= imageDescriptorTypes[imageDescriptorTypeNdx].type;
2389 		de::MovePtr<tcu::TestCaseGroup>	imageDescriptorTypeGroup	(new tcu::TestCaseGroup(testCtx, imageDescriptorTypes[imageDescriptorTypeNdx].name, (std::string("Uses a ") + imageDescriptorTypes[imageDescriptorTypeNdx].name + " sampler").c_str()));
2390 		de::MovePtr<tcu::TestCaseGroup> imageTypeTests		(new tcu::TestCaseGroup(testCtx, "image_type", ""));
2391 
2392 		for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
2393 		{
2394 			const SamplerViewType			viewType		= imageViewTypes[viewTypeNdx].type;
2395 			de::MovePtr<tcu::TestCaseGroup> viewTypeGroup   (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
2396 			de::MovePtr<tcu::TestCaseGroup>	formatTests		(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
2397 
2398 			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2399 			{
2400 				const VkFormat	format			= formats[formatNdx];
2401 				const bool		isCompressed	= isCompressedFormat(format);
2402 				const bool		isDepthStencil	= !isCompressed && tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order);
2403 				ImageAspectTestMode	imageAspectTestMode = getImageAspectTestMode(format);
2404 
2405 				if (isCompressed)
2406 				{
2407 					// Do not use compressed formats with 1D and 1D array textures.
2408 					if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
2409 						break;
2410 				}
2411 
2412 				for (int testModeNdx = 0; testModeNdx < DE_LENGTH_OF_ARRAY(testModes); testModeNdx++)
2413 				{
2414 					if (imageViewTypes[viewTypeNdx].readOnly && testModes[testModeNdx].mode != TEST_MODE_READ_ONLY)
2415 						continue;
2416 
2417 					for (int restrictColorNdx = 0; restrictColorNdx < DE_LENGTH_OF_ARRAY(interleaveReadWriteComponentsModes); restrictColorNdx++)
2418 					{
2419 						// Limit the interleaveReadWriteComponents test to the ones sampling and writing to the same pixel, to avoid having more tests that are not really adding coverage.
2420 						if (interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents &&
2421 							testModes[testModeNdx].mode != TEST_MODE_READ_WRITE_SAME_PIXEL)
2422 							continue;
2423 
2424 						// If the format is depth-only or stencil-only, do not read one component and write it to the other, as it is missing.
2425 						if (interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents &&
2426 							(tcu::hasDepthComponent(mapVkFormat(format).order) || tcu::hasStencilComponent(mapVkFormat(format).order)) && !isDepthStencil)
2427 							continue;
2428 
2429 						std::string name = getFormatCaseName(format) + imageAspectTestModes[imageAspectTestMode] + testModes[testModeNdx].name + interleaveReadWriteComponentsModes[restrictColorNdx].name;
2430 						formatTests->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, name.c_str(), "", viewType, format, outputImageSize, imageDescriptorType, 0.0f, testModes[testModeNdx].mode, imageAspectTestMode, interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents));
2431 
2432 						if (!isCompressed && isDepthStencil)
2433 						{
2434 							// Image is depth-stencil. Add the stencil case as well.
2435 							std::string stencilTestName = getFormatCaseName(format) + imageAspectTestModes[IMAGE_ASPECT_TEST_STENCIL] + testModes[testModeNdx].name + interleaveReadWriteComponentsModes[restrictColorNdx].name;
2436 							formatTests->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, stencilTestName.c_str(), "", viewType, format, outputImageSize, imageDescriptorType, 0.0f, testModes[testModeNdx].mode, IMAGE_ASPECT_TEST_STENCIL, interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents));
2437 						}
2438 					}
2439 				}
2440 			}
2441 
2442 			viewTypeGroup->addChild(formatTests.release());
2443 			imageTypeTests->addChild(viewTypeGroup.release());
2444 		}
2445 		imageDescriptorTypeGroup->addChild(imageTypeTests.release());
2446 		samplingTypeTests->addChild(imageDescriptorTypeGroup.release());
2447 	}
2448 
2449 	return samplingTypeTests.release();
2450 }
2451 
createAttachmentFeedbackLoopLayoutTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)2452 tcu::TestCaseGroup* createAttachmentFeedbackLoopLayoutTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
2453 {
2454 	de::MovePtr<tcu::TestCaseGroup> attachmentFeedbackLoopLayoutTests(new tcu::TestCaseGroup(testCtx, "attachment_feedback_loop_layout", "VK_EXT_attachment_feedback_loop_layout tests"));
2455 	{
2456 		attachmentFeedbackLoopLayoutTests->addChild(createAttachmentFeedbackLoopLayoutSamplerTests(testCtx, pipelineConstructionType));
2457 	}
2458 
2459 	return attachmentFeedbackLoopLayoutTests.release();
2460 }
2461 
2462 } // pipeline
2463 } // vkt
2464