• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Vulkan Image Clearing Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiImageClearingTests.hpp"
26 
27 #include "deRandom.hpp"
28 #include "deMath.h"
29 #include "deSTLUtil.hpp"
30 #include "deStringUtil.hpp"
31 #include "deUniquePtr.hpp"
32 #include "deArrayUtil.hpp"
33 #include "deInt32.h"
34 #include "vkImageUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vktTestCase.hpp"
37 #include "vktTestCaseUtil.hpp"
38 #include "vktTestGroupUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "tcuTexture.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuVectorType.hpp"
46 #include "tcuTexture.hpp"
47 #include "tcuFloat.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuVectorUtil.hpp"
50 #include <sstream>
51 #include <numeric>
52 
53 namespace vkt
54 {
55 
56 namespace api
57 {
58 
59 using namespace vk;
60 using namespace tcu;
61 
62 namespace
63 {
64 
65 enum AllocationKind
66 {
67 	ALLOCATION_KIND_SUBALLOCATED = 0,
68 	ALLOCATION_KIND_DEDICATED,
69 
70 	ALLOCATION_KIND_LAST,
71 };
72 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)73 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
74 										const DeviceInterface&		vkd,
75 										const VkPhysicalDevice&		physDevice,
76 										const VkDevice				device,
77 										const VkBuffer&				buffer,
78 										const MemoryRequirement		requirement,
79 										Allocator&					allocator,
80 										AllocationKind				allocationKind)
81 {
82 	switch (allocationKind)
83 	{
84 		case ALLOCATION_KIND_SUBALLOCATED:
85 		{
86 			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
87 
88 			return allocator.allocate(memoryRequirements, requirement);
89 		}
90 
91 		case ALLOCATION_KIND_DEDICATED:
92 		{
93 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
94 		}
95 
96 		default:
97 		{
98 			TCU_THROW(InternalError, "Invalid allocation kind");
99 		}
100 	}
101 }
102 
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)103 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
104 									   const DeviceInterface&		vkd,
105 									   const VkPhysicalDevice&		physDevice,
106 									   const VkDevice				device,
107 									   const VkImage&				image,
108 									   const MemoryRequirement		requirement,
109 									   Allocator&					allocator,
110 									   AllocationKind				allocationKind)
111 {
112 	switch (allocationKind)
113 	{
114 		case ALLOCATION_KIND_SUBALLOCATED:
115 		{
116 			const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
117 
118 			return allocator.allocate(memoryRequirements, requirement);
119 		}
120 
121 		case ALLOCATION_KIND_DEDICATED:
122 		{
123 			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
124 		}
125 
126 		default:
127 		{
128 			TCU_THROW(InternalError, "Invalid allocation kind");
129 		}
130 	}
131 }
132 
getMipLevelExtent(VkExtent3D baseExtent,const deUint32 mipLevel)133 VkExtent3D getMipLevelExtent (VkExtent3D baseExtent, const deUint32 mipLevel)
134 {
135 	baseExtent.width	= std::max(baseExtent.width  >> mipLevel, 1u);
136 	baseExtent.height	= std::max(baseExtent.height >> mipLevel, 1u);
137 	baseExtent.depth	= std::max(baseExtent.depth  >> mipLevel, 1u);
138 	return baseExtent;
139 }
140 
getNumMipLevels(const VkExtent3D & baseExtent,const deUint32 maxMipLevels)141 deUint32 getNumMipLevels (const VkExtent3D& baseExtent, const deUint32 maxMipLevels)
142 {
143 	const deUint32 widestEdge = std::max(std::max(baseExtent.width, baseExtent.height), baseExtent.depth);
144 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, maxMipLevels);
145 }
146 
greatestCommonDivisor(const deUint32 a,const deUint32 b)147 deUint32 greatestCommonDivisor (const deUint32 a, const deUint32 b)
148 {
149 	/* Find GCD */
150 	deUint32 temp;
151 	deUint32 x=a;
152 	deUint32 y=b;
153 
154 	while (x%y != 0)
155 	{
156 		temp = y;
157 		y = x%y;
158 		x = temp;
159 	}
160 	return y;
161 }
162 
lowestCommonMultiple(const deUint32 a,const deUint32 b)163 deUint32 lowestCommonMultiple (const deUint32 a, const deUint32 b)
164 {
165 	return (a*b)/greatestCommonDivisor(a,b);
166 }
167 
getImageMipLevelSizes(const deUint32 pixelSize,const VkExtent3D & baseExtent,const deUint32 numMipLevels,const deUint32 perLevelAlignment=1u)168 std::vector<deUint32> getImageMipLevelSizes (const deUint32 pixelSize, const VkExtent3D& baseExtent, const deUint32 numMipLevels, const deUint32 perLevelAlignment = 1u)
169 {
170 	std::vector<deUint32> results(numMipLevels);
171 
172 	for (deUint32 mipLevel = 0; mipLevel < numMipLevels; ++mipLevel)
173 	{
174 		const VkExtent3D extent = getMipLevelExtent(baseExtent, mipLevel);
175 		results[mipLevel] = static_cast<deUint32>(extent.width * extent.height * extent.depth * pixelSize);
176 		results[mipLevel] = ((results[mipLevel] + perLevelAlignment-1) / perLevelAlignment) * perLevelAlignment;
177 	}
178 
179 	return results;
180 }
181 
182 struct LayerRange
183 {
184 	deUint32 baseArrayLayer;
185 	deUint32 layerCount;
186 };
187 
isInClearRange(const UVec4 & clearCoords,const deUint32 x,const deUint32 y,deUint32 arrayLayer=0,tcu::Maybe<LayerRange> imageViewLayerRange=tcu::Maybe<LayerRange> (),tcu::Maybe<LayerRange> attachmentClearLayerRange=tcu::Maybe<LayerRange> ())188 inline bool isInClearRange (const UVec4& clearCoords, const deUint32 x, const deUint32 y, deUint32 arrayLayer = 0, tcu::Maybe<LayerRange> imageViewLayerRange = tcu::Maybe<LayerRange>(), tcu::Maybe<LayerRange> attachmentClearLayerRange = tcu::Maybe<LayerRange>())
189 {
190 	if (attachmentClearLayerRange)
191 	{
192 		// Only layers in range passed to clear command are cleared
193 
194 		const deUint32	clearBaseLayer	= (imageViewLayerRange ? imageViewLayerRange->baseArrayLayer : 0) + attachmentClearLayerRange->baseArrayLayer;
195 		const deUint32	clearLayerCount	= (attachmentClearLayerRange->layerCount == VK_REMAINING_ARRAY_LAYERS) ? imageViewLayerRange->layerCount : clearBaseLayer + attachmentClearLayerRange->layerCount;
196 
197 		if ((arrayLayer < clearBaseLayer) || (arrayLayer >= (clearLayerCount)))
198 		{
199 			return false;
200 		}
201 	}
202 
203 	if (clearCoords == UVec4())
204 	{
205 		return true;
206 	}
207 
208 	//! Check if a point lies in a cross-like area.
209 	return !((x <  clearCoords[0] && y <  clearCoords[1]) ||
210 			 (x <  clearCoords[0] && y >= clearCoords[3]) ||
211 			 (x >= clearCoords[2] && y <  clearCoords[1]) ||
212 			 (x >= clearCoords[2] && y >= clearCoords[3]));
213 }
214 
isInInitialClearRange(bool isAttachmentformat,deUint32 mipLevel,deUint32 arrayLayer,LayerRange imageViewLayerRange)215 inline bool isInInitialClearRange (bool isAttachmentformat, deUint32 mipLevel, deUint32 arrayLayer, LayerRange imageViewLayerRange)
216 {
217 	if (!isAttachmentformat)
218 	{
219 		// initial clear is done using renderpass load op - does not apply for non-renderable formats
220 		return false;
221 	}
222 
223 	if (mipLevel > 0)
224 	{
225 		// intial clear is done using FB bound to level 0 only
226 		return false;
227 	}
228 
229 	// Only layers in range bound to framebuffer are cleared to initial color
230 	if ((arrayLayer < imageViewLayerRange.baseArrayLayer) || (arrayLayer >= (imageViewLayerRange.baseArrayLayer + imageViewLayerRange.layerCount)))
231 	{
232 		return false;
233 	}
234 
235 	return true;
236 }
237 
238 // This method is copied from the vktRenderPassTests.cpp. It should be moved to a common place.
calcFloatDiff(float a,float b)239 int calcFloatDiff (float a, float b)
240 {
241 	const int			asign	= Float32(a).sign();
242 	const int			bsign	= Float32(a).sign();
243 
244 	const deUint32		avalue	= (Float32(a).bits() & ((0x1u << 31u) - 1u));
245 	const deUint32		bvalue	= (Float32(b).bits() & ((0x1u << 31u) - 1u));
246 
247 	if (asign != bsign)
248 		return avalue + bvalue + 1u;
249 	else if (avalue < bvalue)
250 		return bvalue - avalue;
251 	else
252 		return avalue - bvalue;
253 }
254 
255 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter.
comparePixelToDepthClearValue(const ConstPixelBufferAccess & access,int x,int y,float ref,std::string & stringResult)256 bool comparePixelToDepthClearValue (const ConstPixelBufferAccess&	access,
257 									int								x,
258 									int								y,
259 									float							ref,
260 									std::string&					stringResult)
261 {
262 	const TextureFormat			format			= getEffectiveDepthStencilTextureFormat(access.getFormat(), Sampler::MODE_DEPTH);
263 	const TextureChannelClass	channelClass	= getTextureChannelClass(format.type);
264 
265 	switch (channelClass)
266 	{
267 		case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
268 		case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
269 		{
270 			const int	bitDepth	= getTextureFormatBitDepth(format).x();
271 			const float	depth		= access.getPixDepth(x, y);
272 			const float	threshold	= 2.0f / (float)((1 << bitDepth) - 1);
273 			const bool	result		= deFloatAbs(depth - ref) <= threshold;
274 
275 			if (!result)
276 			{
277 				std::stringstream s;
278 				s << "Ref:" << ref << " Threshold:" << threshold << " Depth:" << depth;
279 				stringResult	= s.str();
280 			}
281 
282 			return result;
283 		}
284 
285 		case TEXTURECHANNELCLASS_FLOATING_POINT:
286 		{
287 			const float	depth			= access.getPixDepth(x, y);
288 			const int	mantissaBits	= getTextureFormatMantissaBitDepth(format).x();
289 			const int	threshold		= 10 * 1 << (23 - mantissaBits);
290 
291 			DE_ASSERT(mantissaBits <= 23);
292 
293 			const bool	result			= calcFloatDiff(depth, ref) <= threshold;
294 
295 			if (!result)
296 			{
297 				float				floatThreshold	= Float32((deUint32)threshold).asFloat();
298 				std::stringstream	s;
299 
300 				s << "Ref:" << ref << " Threshold:" << floatThreshold << " Depth:" << depth;
301 				stringResult	= s.str();
302 			}
303 
304 			return result;
305 		}
306 
307 		default:
308 			DE_FATAL("Invalid channel class");
309 			return false;
310 	}
311 }
312 
313 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter.
comparePixelToStencilClearValue(const ConstPixelBufferAccess & access,int x,int y,deUint32 ref,std::string & stringResult)314 bool comparePixelToStencilClearValue (const ConstPixelBufferAccess&	access,
315 									  int							x,
316 									  int							y,
317 									  deUint32						ref,
318 									  std::string&					stringResult)
319 {
320 	const deUint32	stencil	= access.getPixStencil(x, y);
321 	const bool		result	= stencil == ref;
322 
323 	if (!result)
324 	{
325 		std::stringstream s;
326 		s << "Ref:" << ref << " Threshold:0" << " Stencil:" << stencil;
327 		stringResult	= s.str();
328 	}
329 
330 	return result;
331 }
332 
333 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter.
comparePixelToColorClearValue(const ConstPixelBufferAccess & access,int x,int y,int z,const VkClearColorValue & ref,std::string & stringResult)334 bool comparePixelToColorClearValue (const ConstPixelBufferAccess&	access,
335 									int								x,
336 									int								y,
337 									int								z,
338 									const VkClearColorValue&		ref,
339 									std::string&					stringResult)
340 {
341 	const TextureFormat				format			= access.getFormat();
342 	const TextureChannelClass		channelClass	= getTextureChannelClass(format.type);
343 	const BVec4						channelMask		= getTextureFormatChannelMask(format);
344 
345 	switch (channelClass)
346 	{
347 		case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
348 		case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
349 		{
350 			const IVec4	bitDepth	(getTextureFormatBitDepth(format));
351 			const Vec4	resColor	(access.getPixel(x, y, z));
352 			Vec4		refColor	(ref.float32[0],
353 									 ref.float32[1],
354 									 ref.float32[2],
355 									 ref.float32[3]);
356 			const int	modifier	= (channelClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) ? 0 : 1;
357 			const Vec4	threshold	(bitDepth[0] > 0 ? 1.0f / ((float)(1 << (bitDepth[0] - modifier)) - 1.0f) : 1.0f,
358 									 bitDepth[1] > 0 ? 1.0f / ((float)(1 << (bitDepth[1] - modifier)) - 1.0f) : 1.0f,
359 									 bitDepth[2] > 0 ? 1.0f / ((float)(1 << (bitDepth[2] - modifier)) - 1.0f) : 1.0f,
360 									 bitDepth[3] > 0 ? 1.0f / ((float)(1 << (bitDepth[3] - modifier)) - 1.0f) : 1.0f);
361 
362 			if (isSRGB(access.getFormat()))
363 				refColor	= linearToSRGB(refColor);
364 
365 			const bool	result		= !(anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold), channelMask), channelMask));
366 
367 			if (!result)
368 			{
369 				std::stringstream s;
370 				s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold << " Color:" << resColor;
371 				stringResult	= s.str();
372 			}
373 
374 			return result;
375 		}
376 
377 		case TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
378 		{
379 			const UVec4	resColor	(access.getPixelUint(x, y, z));
380 			const UVec4	refColor	(ref.uint32[0],
381 									 ref.uint32[1],
382 									 ref.uint32[2],
383 									 ref.uint32[3]);
384 			const UVec4	threshold	(1);
385 
386 			const bool	result		= !(anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold), channelMask), channelMask));
387 
388 			if (!result)
389 			{
390 				std::stringstream s;
391 				s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold << " Color:" << resColor;
392 				stringResult	= s.str();
393 			}
394 
395 			return result;
396 		}
397 
398 		case TEXTURECHANNELCLASS_SIGNED_INTEGER:
399 		{
400 			const IVec4	resColor	(access.getPixelInt(x, y, z));
401 			const IVec4	refColor	(ref.int32[0],
402 									 ref.int32[1],
403 									 ref.int32[2],
404 									 ref.int32[3]);
405 			const IVec4	threshold	(1);
406 
407 			const bool	result		= !(anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold), channelMask), channelMask));
408 
409 			if (!result)
410 			{
411 				std::stringstream s;
412 				s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold << " Color:" << resColor;
413 				stringResult	= s.str();
414 			}
415 
416 			return result;
417 		}
418 
419 		case TEXTURECHANNELCLASS_FLOATING_POINT:
420 		{
421 			const Vec4	resColor		(access.getPixel(x, y, z));
422 			const Vec4	refColor		(ref.float32[0],
423 										 ref.float32[1],
424 										 ref.float32[2],
425 										 ref.float32[3]);
426 			const IVec4	mantissaBits	(getTextureFormatMantissaBitDepth(format));
427 			const IVec4	threshold		(10 * IVec4(1) << (23 - mantissaBits));
428 
429 			DE_ASSERT(allEqual(greaterThanEqual(threshold, IVec4(0)), BVec4(true)));
430 
431 			for (int ndx = 0; ndx < 4; ndx++)
432 			{
433 				const bool result	= !(calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold[ndx] && channelMask[ndx]);
434 
435 				if (!result)
436 				{
437 					float				floatThreshold	= Float32((deUint32)(threshold)[0]).asFloat();
438 					Vec4				thresholdVec4	(floatThreshold,
439 														 floatThreshold,
440 														 floatThreshold,
441 														 floatThreshold);
442 					std::stringstream	s;
443 					s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << thresholdVec4 << " Color:" << resColor;
444 					stringResult	= s.str();
445 
446 					return false;
447 				}
448 			}
449 
450 			return true;
451 		}
452 
453 		default:
454 			DE_FATAL("Invalid channel class");
455 			return false;
456 	}
457 }
458 
459 struct TestParams
460 {
461 	bool			useSingleMipLevel;	//!< only mip level 0, otherwise up to maxMipLevels
462 	VkImageType		imageType;
463 	VkFormat		imageFormat;
464 	VkExtent3D		imageExtent;
465 	deUint32        imageLayerCount;
466 	LayerRange      imageViewLayerRange;
467 	VkClearValue	initValue;
468 	VkClearValue	clearValue[2];		//!< the second value is used with more than one mip map
469 	LayerRange		clearLayerRange;
470 	AllocationKind	allocationKind;
471 };
472 
473 class ImageClearingTestInstance : public vkt::TestInstance
474 {
475 public:
476 										ImageClearingTestInstance		(Context&			context,
477 																		 const TestParams&	testParams);
478 
479 	Move<VkCommandPool>					createCommandPool				(VkCommandPoolCreateFlags commandPoolCreateFlags) const;
480 	Move<VkCommandBuffer>				allocatePrimaryCommandBuffer	(VkCommandPool commandPool) const;
481 	Move<VkImage>						createImage						(VkImageType imageType, VkFormat format, VkExtent3D extent, deUint32 arrayLayerCount, VkImageUsageFlags usage) const;
482 	Move<VkImageView>					createImageView					(VkImage image, VkImageViewType viewType, VkFormat format, VkImageAspectFlags aspectMask, LayerRange layerRange) const;
483 	Move<VkRenderPass>					createRenderPass				(VkFormat format) const;
484 	Move<VkFramebuffer>					createFrameBuffer				(VkImageView imageView, VkRenderPass renderPass, deUint32 imageWidth, deUint32 imageHeight, deUint32 imageLayersCount) const;
485 
486 	void								beginCommandBuffer				(VkCommandBufferUsageFlags usageFlags) const;
487 	void								endCommandBuffer				(void) const;
488 	void								submitCommandBuffer				(void) const;
489 	void								beginRenderPass					(VkSubpassContents content, VkClearValue clearValue) const;
490 
491 	void								pipelineImageBarrier			(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
492 	de::MovePtr<TextureLevelPyramid>	readImage						(VkImageAspectFlags aspectMask, deUint32 baseLayer) const;
493 	tcu::TestStatus						verifyResultImage				(const std::string& successMessage, const UVec4& clearCoords = UVec4()) const;
494 
495 protected:
496 	enum ViewType
497 	{
498 		VIEW_TYPE_SINGLE,
499 		VIEW_TYPE_ARRAY
500 	};
501 	VkImageViewType						getCorrespondingImageViewType	(VkImageType imageType, ViewType viewType) const;
502 	VkImageUsageFlags					getImageUsageFlags				(VkFormat format) const;
503 	VkImageAspectFlags					getImageAspectFlags				(VkFormat format) const;
504 	bool								getIsAttachmentFormat			(VkFormat format) const;
505 	bool								getIsStencilFormat				(VkFormat format) const;
506 	bool								getIsDepthFormat				(VkFormat format) const;
507 	VkImageFormatProperties				getImageFormatProperties		(void) const;
508 	de::MovePtr<Allocation>				allocateAndBindImageMemory		(VkImage image) const;
509 
510 	const TestParams&					m_params;
511 	const VkDevice						m_device;
512 	const InstanceInterface&			m_vki;
513 	const DeviceInterface&				m_vkd;
514 	const VkQueue						m_queue;
515 	const deUint32						m_queueFamilyIndex;
516 	Allocator&							m_allocator;
517 
518 	const bool							m_isAttachmentFormat;
519 	const VkImageUsageFlags				m_imageUsageFlags;
520 	const VkImageAspectFlags			m_imageAspectFlags;
521 	const VkImageFormatProperties		m_imageFormatProperties;
522 	const deUint32						m_imageMipLevels;
523 	const deUint32						m_thresholdMipLevel;
524 
525 	Unique<VkCommandPool>				m_commandPool;
526 	Unique<VkCommandBuffer>				m_commandBuffer;
527 
528 	Unique<VkImage>						m_image;
529 	de::MovePtr<Allocation>				m_imageMemory;
530 	Unique<VkImageView>					m_imageView;
531 	Unique<VkRenderPass>				m_renderPass;
532 	Unique<VkFramebuffer>				m_frameBuffer;
533 };
534 
ImageClearingTestInstance(Context & context,const TestParams & params)535 ImageClearingTestInstance::ImageClearingTestInstance (Context& context, const TestParams& params)
536 	: TestInstance				(context)
537 	, m_params					(params)
538 	, m_device					(context.getDevice())
539 	, m_vki						(context.getInstanceInterface())
540 	, m_vkd						(context.getDeviceInterface())
541 	, m_queue					(context.getUniversalQueue())
542 	, m_queueFamilyIndex		(context.getUniversalQueueFamilyIndex())
543 	, m_allocator				(context.getDefaultAllocator())
544 	, m_isAttachmentFormat		(getIsAttachmentFormat(params.imageFormat))
545 	, m_imageUsageFlags			(getImageUsageFlags(params.imageFormat))
546 	, m_imageAspectFlags		(getImageAspectFlags(params.imageFormat))
547 	, m_imageFormatProperties	(getImageFormatProperties())
548 	, m_imageMipLevels			(params.useSingleMipLevel ? 1u : getNumMipLevels(params.imageExtent, m_imageFormatProperties.maxMipLevels))
549 	, m_thresholdMipLevel		(std::max(m_imageMipLevels / 2u, 1u))
550 	, m_commandPool				(createCommandPool(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT))
551 	, m_commandBuffer			(allocatePrimaryCommandBuffer(*m_commandPool))
552 
553 	, m_image					(createImage(params.imageType,
554 											 params.imageFormat,
555 											 params.imageExtent,
556 											 params.imageLayerCount,
557 											 m_imageUsageFlags))
558 
559 	, m_imageMemory				(allocateAndBindImageMemory(*m_image))
560 	, m_imageView				(m_isAttachmentFormat ? createImageView(*m_image,
561 												 getCorrespondingImageViewType(params.imageType, params.imageLayerCount > 1u ? VIEW_TYPE_ARRAY : VIEW_TYPE_SINGLE),
562 												 params.imageFormat,
563 												 m_imageAspectFlags,
564 												 params.imageViewLayerRange) : vk::Move<VkImageView>())
565 
566 	, m_renderPass				(m_isAttachmentFormat ? createRenderPass(params.imageFormat) : vk::Move<vk::VkRenderPass>())
567 	, m_frameBuffer				(m_isAttachmentFormat ? createFrameBuffer(*m_imageView, *m_renderPass, params.imageExtent.width, params.imageExtent.height, params.imageViewLayerRange.layerCount) : vk::Move<vk::VkFramebuffer>())
568 {
569 	if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
570 	{
571 		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
572 			TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
573 	}
574 }
575 
getCorrespondingImageViewType(VkImageType imageType,ViewType viewType) const576 VkImageViewType ImageClearingTestInstance::getCorrespondingImageViewType (VkImageType imageType, ViewType viewType) const
577 {
578 	switch (imageType)
579 	{
580 	case VK_IMAGE_TYPE_1D:
581 		return (viewType == VIEW_TYPE_ARRAY) ?  VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D;
582 	case VK_IMAGE_TYPE_2D:
583 		return (viewType == VIEW_TYPE_ARRAY) ?  VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
584 	case VK_IMAGE_TYPE_3D:
585 		if (viewType != VIEW_TYPE_SINGLE)
586 		{
587 			DE_FATAL("Cannot have 3D image array");
588 		}
589 		return VK_IMAGE_VIEW_TYPE_3D;
590 	default:
591 		DE_FATAL("Unknown image type!");
592 	}
593 
594 	return VK_IMAGE_VIEW_TYPE_2D;
595 }
596 
getImageUsageFlags(VkFormat format) const597 VkImageUsageFlags ImageClearingTestInstance::getImageUsageFlags (VkFormat format) const
598 {
599 	VkImageUsageFlags	commonFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
600 
601 	if (m_isAttachmentFormat)
602 	{
603 		if (isDepthStencilFormat(format))
604 			return commonFlags | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
605 
606 		return commonFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
607 	}
608 	return commonFlags;
609 }
610 
getImageAspectFlags(VkFormat format) const611 VkImageAspectFlags ImageClearingTestInstance::getImageAspectFlags (VkFormat format) const
612 {
613 	VkImageAspectFlags	imageAspectFlags	= 0;
614 
615 	if (getIsDepthFormat(format))
616 		imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
617 
618 	if (getIsStencilFormat(format))
619 		imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
620 
621 	if (imageAspectFlags == 0)
622 		imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
623 
624 	return imageAspectFlags;
625 }
626 
getIsAttachmentFormat(VkFormat format) const627 bool ImageClearingTestInstance::getIsAttachmentFormat (VkFormat format) const
628 {
629 	const VkFormatProperties props	= vk::getPhysicalDeviceFormatProperties(m_vki, m_context.getPhysicalDevice(), format);
630 
631 	return (props.optimalTilingFeatures & (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) != 0;
632 }
633 
getIsStencilFormat(VkFormat format) const634 bool ImageClearingTestInstance::getIsStencilFormat (VkFormat format) const
635 {
636 	const TextureFormat tcuFormat	= mapVkFormat(format);
637 
638 	if (tcuFormat.order == TextureFormat::S || tcuFormat.order == TextureFormat::DS)
639 		return true;
640 
641 	return false;
642 }
643 
getIsDepthFormat(VkFormat format) const644 bool ImageClearingTestInstance::getIsDepthFormat (VkFormat format) const
645 {
646 	const TextureFormat	tcuFormat	= mapVkFormat(format);
647 
648 	if (tcuFormat.order == TextureFormat::D || tcuFormat.order == TextureFormat::DS)
649 		return true;
650 
651 	return false;
652 }
653 
getImageFormatProperties(void) const654 VkImageFormatProperties ImageClearingTestInstance::getImageFormatProperties (void) const
655 {
656 	VkImageFormatProperties properties;
657 	const VkResult result = m_vki.getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), m_params.imageFormat, m_params.imageType,
658 																		 VK_IMAGE_TILING_OPTIMAL, m_imageUsageFlags, (VkImageCreateFlags)0, &properties);
659 
660 	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
661 		TCU_THROW(NotSupportedError, "Format not supported");
662 	else
663 		return properties;
664 }
665 
allocateAndBindImageMemory(VkImage image) const666 de::MovePtr<Allocation> ImageClearingTestInstance::allocateAndBindImageMemory (VkImage image) const
667 {
668 	de::MovePtr<Allocation>	imageMemory	(allocateImage(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, image, MemoryRequirement::Any, m_allocator, m_params.allocationKind));
669 	VK_CHECK(m_vkd.bindImageMemory(m_device, image, imageMemory->getMemory(), imageMemory->getOffset()));
670 	return imageMemory;
671 }
672 
createCommandPool(VkCommandPoolCreateFlags commandPoolCreateFlags) const673 Move<VkCommandPool> ImageClearingTestInstance::createCommandPool (VkCommandPoolCreateFlags commandPoolCreateFlags) const
674 {
675 	return vk::createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex);
676 }
677 
allocatePrimaryCommandBuffer(VkCommandPool commandPool) const678 Move<VkCommandBuffer> ImageClearingTestInstance::allocatePrimaryCommandBuffer (VkCommandPool commandPool) const
679 {
680 	return vk::allocateCommandBuffer(m_vkd, m_device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
681 }
682 
createImage(VkImageType imageType,VkFormat format,VkExtent3D extent,deUint32 arrayLayerCount,VkImageUsageFlags usage) const683 Move<VkImage> ImageClearingTestInstance::createImage (VkImageType imageType, VkFormat format, VkExtent3D extent, deUint32 arrayLayerCount, VkImageUsageFlags usage) const
684 {
685 	const VkImageCreateInfo					imageCreateInfo			=
686 	{
687 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
688 		DE_NULL,									// const void*				pNext;
689 		0u,											// VkImageCreateFlags		flags;
690 		imageType,									// VkImageType				imageType;
691 		format,										// VkFormat					format;
692 		extent,										// VkExtent3D				extent;
693 		m_imageMipLevels,							// deUint32					mipLevels;
694 		arrayLayerCount,							// deUint32					arrayLayers;
695 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
696 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
697 		usage,										// VkImageUsageFlags		usage;
698 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
699 		1u,											// deUint32					queueFamilyIndexCount;
700 		&m_queueFamilyIndex,						// const deUint32*			pQueueFamilyIndices;
701 		VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
702 	};
703 
704 	return vk::createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
705 }
706 
createImageView(VkImage image,VkImageViewType viewType,VkFormat format,VkImageAspectFlags aspectMask,LayerRange layerRange) const707 Move<VkImageView> ImageClearingTestInstance::createImageView (VkImage image, VkImageViewType viewType, VkFormat format, VkImageAspectFlags aspectMask, LayerRange layerRange) const
708 {
709 	const VkImageViewCreateInfo				imageViewCreateInfo		=
710 	{
711 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
712 		DE_NULL,									// const void*					pNext;
713 		0u,											// VkImageViewCreateFlags		flags;
714 		image,										// VkImage						image;
715 		viewType,									// VkImageViewType				viewType;
716 		format,										// VkFormat						format;
717 		{
718 			VK_COMPONENT_SWIZZLE_IDENTITY,				// VkComponentSwizzle			r;
719 			VK_COMPONENT_SWIZZLE_IDENTITY,				// VkComponentSwizzle			g;
720 			VK_COMPONENT_SWIZZLE_IDENTITY,				// VkComponentSwizzle			b;
721 			VK_COMPONENT_SWIZZLE_IDENTITY,				// VkComponentSwizzle			a;
722 		},											// VkComponentMapping			components;
723 		{
724 			aspectMask,									// VkImageAspectFlags			aspectMask;
725 			0u,											// deUint32						baseMipLevel;
726 			1u,											// deUint32						mipLevels;
727 			layerRange.baseArrayLayer,					// deUint32						baseArrayLayer;
728 			layerRange.layerCount,						// deUint32						arraySize;
729 		},												// VkImageSubresourceRange		subresourceRange;
730 	};
731 
732 	return vk::createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL);
733 }
734 
createRenderPass(VkFormat format) const735 Move<VkRenderPass> ImageClearingTestInstance::createRenderPass (VkFormat format) const
736 {
737 	VkImageLayout							imageLayout;
738 
739 	if (isDepthStencilFormat(format))
740 		imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
741 	else
742 		imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
743 
744 	const VkAttachmentDescription			attachmentDesc			=
745 	{
746 		0u,													// VkAttachmentDescriptionFlags		flags;
747 		format,												// VkFormat							format;
748 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
749 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
750 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
751 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
752 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				stencilStoreOp;
753 		imageLayout,										// VkImageLayout					initialLayout;
754 		imageLayout,										// VkImageLayout					finalLayout;
755 	};
756 
757 	const VkAttachmentDescription			attachments[1]			=
758 	{
759 		attachmentDesc
760 	};
761 
762 	const VkAttachmentReference				attachmentRef			=
763 	{
764 		0u,													// deUint32							attachment;
765 		imageLayout,										// VkImageLayout					layout;
766 	};
767 
768 	const VkAttachmentReference*			pColorAttachments		= DE_NULL;
769 	const VkAttachmentReference*			pDepthStencilAttachment	= DE_NULL;
770 	deUint32								colorAttachmentCount	= 1;
771 
772 	if (isDepthStencilFormat(format))
773 	{
774 		colorAttachmentCount	= 0;
775 		pDepthStencilAttachment	= &attachmentRef;
776 	}
777 	else
778 	{
779 		colorAttachmentCount	= 1;
780 		pColorAttachments		= &attachmentRef;
781 	}
782 
783 	const VkSubpassDescription				subpassDesc[1]			=
784 	{
785 		{
786 			0u,												// VkSubpassDescriptionFlags		flags;
787 			VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint				pipelineBindPoint;
788 			0u,												// deUint32							inputAttachmentCount;
789 			DE_NULL,										// const VkAttachmentReference*		pInputAttachments;
790 			colorAttachmentCount,							// deUint32							colorAttachmentCount;
791 			pColorAttachments,								// const VkAttachmentReference*		pColorAttachments;
792 			DE_NULL,										// const VkAttachmentReference*		pResolveAttachments;
793 			pDepthStencilAttachment,						// const VkAttachmentReference*		pDepthStencilAttachment;
794 			0u,												// deUint32							preserveAttachmentCount;
795 			DE_NULL,										// const VkAttachmentReference*		pPreserveAttachments;
796 		}
797 	};
798 
799 	const VkRenderPassCreateInfo			renderPassCreateInfo	=
800 	{
801 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
802 		DE_NULL,											// const void*						pNext;
803 		0u,													// VkRenderPassCreateFlags			flags;
804 		1u,													// deUint32							attachmentCount;
805 		attachments,										// const VkAttachmentDescription*	pAttachments;
806 		1u,													// deUint32							subpassCount;
807 		subpassDesc,										// const VkSubpassDescription*		pSubpasses;
808 		0u,													// deUint32							dependencyCount;
809 		DE_NULL,											// const VkSubpassDependency*		pDependencies;
810 	};
811 
812 	return vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo, DE_NULL);
813 }
814 
createFrameBuffer(VkImageView imageView,VkRenderPass renderPass,deUint32 imageWidth,deUint32 imageHeight,deUint32 imageLayersCount) const815 Move<VkFramebuffer> ImageClearingTestInstance::createFrameBuffer (VkImageView imageView, VkRenderPass renderPass, deUint32 imageWidth, deUint32 imageHeight, deUint32 imageLayersCount) const
816 {
817 	const VkImageView						attachmentViews[1]		=
818 	{
819 		imageView
820 	};
821 
822 	const VkFramebufferCreateInfo			framebufferCreateInfo	=
823 	{
824 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
825 		DE_NULL,									// const void*				pNext;
826 		0u,											// VkFramebufferCreateFlags	flags;
827 		renderPass,									// VkRenderPass				renderPass;
828 		1,											// deUint32					attachmentCount;
829 		attachmentViews,							// const VkImageView*		pAttachments;
830 		imageWidth,									// deUint32					width;
831 		imageHeight,								// deUint32					height;
832 		imageLayersCount,							// deUint32					layers;
833 	};
834 
835 	return createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL);
836 }
837 
beginCommandBuffer(VkCommandBufferUsageFlags usageFlags) const838 void ImageClearingTestInstance::beginCommandBuffer (VkCommandBufferUsageFlags usageFlags) const
839 {
840 	const VkCommandBufferBeginInfo			commandBufferBeginInfo	=
841 	{
842 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType                          sType;
843 		DE_NULL,												// const void*                              pNext;
844 		usageFlags,												// VkCommandBufferUsageFlags                flags;
845 		DE_NULL													// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
846 	};
847 
848 	VK_CHECK(m_vkd.beginCommandBuffer(*m_commandBuffer, &commandBufferBeginInfo));
849 }
850 
endCommandBuffer(void) const851 void ImageClearingTestInstance::endCommandBuffer (void) const
852 {
853 	VK_CHECK(m_vkd.endCommandBuffer(*m_commandBuffer));
854 }
855 
submitCommandBuffer(void) const856 void ImageClearingTestInstance::submitCommandBuffer (void) const
857 {
858 	const Unique<VkFence>					fence					(createFence(m_vkd, m_device));
859 
860 	const VkSubmitInfo						submitInfo				=
861 	{
862 		VK_STRUCTURE_TYPE_SUBMIT_INFO,							// VkStructureType                sType;
863 		DE_NULL,												// const void*                    pNext;
864 		0u,														// deUint32                       waitSemaphoreCount;
865 		DE_NULL,												// const VkSemaphore*             pWaitSemaphores;
866 		DE_NULL,												// const VkPipelineStageFlags*    pWaitDstStageMask;
867 		1u,														// deUint32                       commandBufferCount;
868 		&(*m_commandBuffer),									// const VkCommandBuffer*         pCommandBuffers;
869 		0u,														// deUint32                       signalSemaphoreCount;
870 		DE_NULL													// const VkSemaphore*             pSignalSemaphores;
871 	};
872 
873 	VK_CHECK(m_vkd.queueSubmit(m_queue, 1, &submitInfo, *fence));
874 
875 	VK_CHECK(m_vkd.waitForFences(m_device, 1, &fence.get(), VK_TRUE, ~0ull));
876 }
877 
pipelineImageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout) const878 void ImageClearingTestInstance::pipelineImageBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
879 {
880 	const VkImageMemoryBarrier		imageBarrier	=
881 	{
882 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
883 		DE_NULL,									// const void*				pNext;
884 		srcAccessMask,								// VkAccessFlags			srcAccessMask;
885 		dstAccessMask,								// VkAccessFlags			dstAccessMask;
886 		oldLayout,									// VkImageLayout			oldLayout;
887 		newLayout,									// VkImageLayout			newLayout;
888 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
889 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
890 		*m_image,									// VkImage					image;
891 		{
892 			m_imageAspectFlags,							// VkImageAspectFlags	aspectMask;
893 			0u,											// deUint32				baseMipLevel;
894 			VK_REMAINING_MIP_LEVELS,					// deUint32				levelCount;
895 			0u,											// deUint32				baseArrayLayer;
896 			VK_REMAINING_ARRAY_LAYERS,					// deUint32				layerCount;
897 		},											// VkImageSubresourceRange	subresourceRange;
898 	};
899 
900 	m_vkd.cmdPipelineBarrier(*m_commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
901 }
902 
readImage(VkImageAspectFlags aspectMask,deUint32 arrayLayer) const903 de::MovePtr<TextureLevelPyramid> ImageClearingTestInstance::readImage (VkImageAspectFlags aspectMask, deUint32 arrayLayer) const
904 {
905 	const TextureFormat					tcuFormat		= aspectMask == VK_IMAGE_ASPECT_COLOR_BIT ? mapVkFormat(m_params.imageFormat) :
906 														  aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ? getDepthCopyFormat(m_params.imageFormat) :
907 														  aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT ? getStencilCopyFormat(m_params.imageFormat) :
908 														  TextureFormat();
909 	const deUint32						pixelSize		= getPixelSize(tcuFormat);
910 	deUint32							alignment		= 4;	// subsequent mip levels aligned to 4 bytes
911 
912 	if (!getIsDepthFormat(m_params.imageFormat) && !getIsStencilFormat(m_params.imageFormat))
913 		alignment = lowestCommonMultiple(pixelSize, alignment); // alignment must be multiple of pixel size, if not D/S.
914 
915 	const std::vector<deUint32>			mipLevelSizes	= getImageMipLevelSizes(pixelSize, m_params.imageExtent, m_imageMipLevels, alignment);
916 	const VkDeviceSize					imageTotalSize	= std::accumulate(mipLevelSizes.begin(), mipLevelSizes.end(), 0u);
917 
918 	de::MovePtr<TextureLevelPyramid>	result			(new TextureLevelPyramid(tcuFormat, m_imageMipLevels));
919 	Move<VkBuffer>						buffer;
920 	de::MovePtr<Allocation>				bufferAlloc;
921 
922 	// Create destination buffer
923 	{
924 		const VkBufferCreateInfo	bufferParams	=
925 		{
926 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
927 			DE_NULL,									// const void*			pNext;
928 			0u,											// VkBufferCreateFlags	flags;
929 			imageTotalSize,								// VkDeviceSize			size;
930 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
931 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
932 			0u,											// deUint32				queueFamilyIndexCount;
933 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
934 		};
935 
936 		buffer		= createBuffer(m_vkd, m_device, &bufferParams);
937 		bufferAlloc	= allocateBuffer(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, *buffer, MemoryRequirement::HostVisible, m_allocator, m_params.allocationKind);
938 		VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
939 	}
940 
941 	// Barriers for copying image to buffer
942 
943 	const VkBufferMemoryBarrier		bufferBarrier	=
944 	{
945 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
946 		DE_NULL,									// const void*		pNext;
947 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
948 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
949 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
950 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
951 		*buffer,									// VkBuffer			buffer;
952 		0u,											// VkDeviceSize		offset;
953 		imageTotalSize,								// VkDeviceSize		size;
954 	};
955 
956 	// Copy image to buffer
957 	std::vector<VkBufferImageCopy> copyRegions;
958 	{
959 		deUint32 offset = 0u;
960 		for (deUint32 mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel)
961 		{
962 			const VkExtent3D		extent	= getMipLevelExtent(m_params.imageExtent, mipLevel);
963 			const VkBufferImageCopy	region	=
964 			{
965 				offset,										// VkDeviceSize				bufferOffset;
966 				0u,											// deUint32					bufferRowLength;
967 				0u,											// deUint32					bufferImageHeight;
968 				{ aspectMask, mipLevel, arrayLayer, 1u },	// VkImageSubresourceLayers	imageSubresource;
969 				{ 0, 0, 0 },								// VkOffset3D				imageOffset;
970 				extent										// VkExtent3D				imageExtent;
971 			};
972 			copyRegions.push_back(region);
973 			offset += mipLevelSizes[mipLevel];
974 		}
975 	}
976 
977 	beginCommandBuffer(0);
978 
979 	pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
980 						 VK_PIPELINE_STAGE_TRANSFER_BIT,
981 						 VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
982 						 VK_ACCESS_TRANSFER_READ_BIT,
983 						 VK_IMAGE_LAYOUT_GENERAL,
984 						 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
985 
986 	m_vkd.cmdCopyImageToBuffer(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, static_cast<deUint32>(copyRegions.size()), &copyRegions[0]);
987 	m_vkd.cmdPipelineBarrier(*m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
988 
989 	pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
990 						 VK_PIPELINE_STAGE_TRANSFER_BIT,
991 						 VK_ACCESS_TRANSFER_READ_BIT,
992 						 VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
993 						 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
994 						 VK_IMAGE_LAYOUT_GENERAL);
995 
996 	endCommandBuffer();
997 	submitCommandBuffer();
998 
999 	invalidateMappedMemoryRange(m_vkd, m_device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), imageTotalSize);
1000 
1001 	{
1002 		deUint32 offset = 0u;
1003 		for (deUint32 mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel)
1004 		{
1005 			const VkExtent3D	extent		= getMipLevelExtent(m_params.imageExtent, mipLevel);
1006 			const void*			pLevelData	= static_cast<const void*>(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + offset);
1007 
1008 			result->allocLevel(mipLevel, extent.width, extent.height, extent.depth);
1009 			copy(result->getLevel(mipLevel), ConstPixelBufferAccess(result->getFormat(), result->getLevel(mipLevel).getSize(), pLevelData));
1010 
1011 			offset += mipLevelSizes[mipLevel];
1012 		}
1013 	}
1014 
1015 	return result;
1016 }
1017 
verifyResultImage(const std::string & successMessage,const UVec4 & clearCoords) const1018 tcu::TestStatus ImageClearingTestInstance::verifyResultImage (const std::string& successMessage, const UVec4& clearCoords) const
1019 {
1020 	DE_ASSERT((clearCoords == UVec4()) || m_params.imageExtent.depth == 1u);
1021 
1022 	if (getIsDepthFormat(m_params.imageFormat))
1023 	{
1024 		DE_ASSERT(m_imageMipLevels == 1u);
1025 
1026 		for (deUint32 arrayLayer = 0; arrayLayer < m_params.imageLayerCount; ++arrayLayer)
1027 		{
1028 			de::MovePtr<TextureLevelPyramid>	image			= readImage(VK_IMAGE_ASPECT_DEPTH_BIT, arrayLayer);
1029 			std::string							message;
1030 			float								depthValue;
1031 
1032 			for (deUint32 y = 0; y < m_params.imageExtent.height; ++y)
1033 			for (deUint32 x = 0; x < m_params.imageExtent.width; ++x)
1034 			{
1035 				if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange, m_params.clearLayerRange))
1036 					depthValue = m_params.clearValue[0].depthStencil.depth;
1037 				else
1038 				if (isInInitialClearRange(m_isAttachmentFormat, 0u /* mipLevel */, arrayLayer, m_params.imageViewLayerRange))
1039 				{
1040 					depthValue = m_params.initValue.depthStencil.depth;
1041 				}
1042 				else
1043 					continue;
1044 
1045 				if (!comparePixelToDepthClearValue(image->getLevel(0), x, y, depthValue, message))
1046 					return TestStatus::fail("Depth value mismatch! " + message);
1047 			}
1048 		}
1049 	}
1050 
1051 	if (getIsStencilFormat(m_params.imageFormat))
1052 	{
1053 		DE_ASSERT(m_imageMipLevels == 1u);
1054 
1055 		for (deUint32 arrayLayer = 0; arrayLayer < m_params.imageLayerCount; ++arrayLayer)
1056 		{
1057 			de::MovePtr<TextureLevelPyramid>	image			= readImage(VK_IMAGE_ASPECT_STENCIL_BIT, arrayLayer);
1058 			std::string							message;
1059 			deUint32							stencilValue;
1060 
1061 			for (deUint32 y = 0; y < m_params.imageExtent.height; ++y)
1062 			for (deUint32 x = 0; x < m_params.imageExtent.width; ++x)
1063 			{
1064 				if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange, m_params.clearLayerRange))
1065 					stencilValue = m_params.clearValue[0].depthStencil.stencil;
1066 				else
1067 				if (isInInitialClearRange(m_isAttachmentFormat, 0u /* mipLevel */, arrayLayer, m_params.imageViewLayerRange))
1068 				{
1069 					stencilValue = m_params.initValue.depthStencil.stencil;
1070 				}
1071 				else
1072 					continue;
1073 
1074 				if (!comparePixelToStencilClearValue(image->getLevel(0), x, y, stencilValue, message))
1075 					return TestStatus::fail("Stencil value mismatch! " + message);
1076 			}
1077 		}
1078 	}
1079 
1080 	if (!isDepthStencilFormat(m_params.imageFormat))
1081 	{
1082 		for (deUint32 arrayLayer = 0; arrayLayer < m_params.imageLayerCount; ++arrayLayer)
1083 		{
1084 			de::MovePtr<TextureLevelPyramid>	image			= readImage(VK_IMAGE_ASPECT_COLOR_BIT, arrayLayer);
1085 			std::string							message;
1086 			const VkClearColorValue*			pColorValue;
1087 
1088 			for (deUint32 mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel)
1089 			{
1090 				const int			clearColorNdx	= (mipLevel < m_thresholdMipLevel ? 0 : 1);
1091 				const VkExtent3D	extent			= getMipLevelExtent(m_params.imageExtent, mipLevel);
1092 
1093 				for (deUint32 z = 0; z < extent.depth;  ++z)
1094 				for (deUint32 y = 0; y < extent.height; ++y)
1095 				for (deUint32 x = 0; x < extent.width;  ++x)
1096 				{
1097 					if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange, m_params.clearLayerRange))
1098 						pColorValue = &m_params.clearValue[clearColorNdx].color;
1099 					else
1100 					{
1101 						if (isInInitialClearRange(m_isAttachmentFormat, mipLevel, arrayLayer, m_params.imageViewLayerRange))
1102 						{
1103 							pColorValue = &m_params.initValue.color;
1104 						}
1105 						else
1106 							continue;
1107 					}
1108 					if (!comparePixelToColorClearValue(image->getLevel(mipLevel), x, y, z, *pColorValue, message))
1109 						return TestStatus::fail("Color value mismatch! " + message);
1110 				}
1111 			}
1112 		}
1113 	}
1114 
1115 	return TestStatus::pass(successMessage);
1116 }
1117 
beginRenderPass(VkSubpassContents content,VkClearValue clearValue) const1118 void ImageClearingTestInstance::beginRenderPass (VkSubpassContents content, VkClearValue clearValue) const
1119 {
1120 	const VkRenderPassBeginInfo renderPassBeginInfo =
1121 	{
1122 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
1123 		DE_NULL,												// const void*			pNext;
1124 		*m_renderPass,											// VkRenderPass			renderPass;
1125 		*m_frameBuffer,											// VkFramebuffer		framebuffer;
1126 		{
1127 			{ 0, 0 },												// VkOffset2D			offset;
1128 			{
1129 				m_params.imageExtent.width,								// deUint32				width;
1130 				m_params.imageExtent.height								// deUint32				height;
1131 			}														// VkExtent2D			extent;
1132 		},														// VkRect2D				renderArea;
1133 		1u,														// deUint32				clearValueCount;
1134 		&clearValue												// const VkClearValue*	pClearValues;
1135 	};
1136 
1137 	m_vkd.cmdBeginRenderPass(*m_commandBuffer, &renderPassBeginInfo, content);
1138 }
1139 
1140 class ClearColorImageTestInstance : public ImageClearingTestInstance
1141 {
1142 public:
ClearColorImageTestInstance(Context & context,const TestParams & testParams)1143 				ClearColorImageTestInstance	(Context& context, const TestParams& testParams) : ImageClearingTestInstance (context, testParams) {}
1144 	TestStatus	iterate						(void);
1145 };
1146 
iterate(void)1147 TestStatus ClearColorImageTestInstance::iterate (void)
1148 {
1149 	std::vector<VkImageSubresourceRange> subresourceRanges;
1150 
1151 	if (m_imageMipLevels == 1)
1152 		subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, 1u, m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount));
1153 	else
1154 	{
1155 		subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags,	0u,						m_thresholdMipLevel,		m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount));
1156 		subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags,	m_thresholdMipLevel,	VK_REMAINING_MIP_LEVELS,	m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount));
1157 	}
1158 
1159 	beginCommandBuffer(0);
1160 
1161 	pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
1162 						 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,			// VkPipelineStageFlags		dstStageMask
1163 						 0,												// VkAccessFlags			srcAccessMask
1164 						 (m_isAttachmentFormat
1165 							? VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
1166 							: VK_ACCESS_TRANSFER_WRITE_BIT),			// VkAccessFlags			dstAccessMask
1167 						 VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
1168 						 (m_isAttachmentFormat
1169 							? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1170 							: VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL));	// VkImageLayout			newLayout;
1171 
1172 	if (m_isAttachmentFormat)
1173 	{
1174 		beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue);
1175 		m_vkd.cmdEndRenderPass(*m_commandBuffer);
1176 
1177 		pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,		// VkPipelineStageFlags		srcStageMask
1178 			VK_PIPELINE_STAGE_TRANSFER_BIT,								// VkPipelineStageFlags		dstStageMask
1179 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags			srcAccessMask
1180 			VK_ACCESS_TRANSFER_WRITE_BIT,								// VkAccessFlags			dstAccessMask
1181 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout			oldLayout;
1182 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);						// VkImageLayout			newLayout;
1183 	}
1184 
1185 	// Different clear color per range
1186 	for (std::size_t i = 0u; i < subresourceRanges.size(); ++i)
1187 		m_vkd.cmdClearColorImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_params.clearValue[i].color, 1, &subresourceRanges[i]);
1188 
1189 	pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,				// VkPipelineStageFlags		srcStageMask
1190 						 VK_PIPELINE_STAGE_TRANSFER_BIT,				// VkPipelineStageFlags		dstStageMask
1191 						 VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask
1192 						 VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags			dstAccessMask
1193 						 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
1194 						 VK_IMAGE_LAYOUT_GENERAL);						// VkImageLayout			newLayout;
1195 
1196 	endCommandBuffer();
1197 	submitCommandBuffer();
1198 
1199 	return verifyResultImage("cmdClearColorImage passed");
1200 }
1201 
1202 class ClearDepthStencilImageTestInstance : public ImageClearingTestInstance
1203 {
1204 public:
ClearDepthStencilImageTestInstance(Context & context,const TestParams & testParams)1205 				ClearDepthStencilImageTestInstance	(Context& context, const TestParams& testParams) : ImageClearingTestInstance (context, testParams) {}
1206 	TestStatus	iterate								(void);
1207 };
1208 
iterate(void)1209 TestStatus ClearDepthStencilImageTestInstance::iterate (void)
1210 {
1211 	const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(m_imageAspectFlags, 0u, 1u, m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount);
1212 
1213 	beginCommandBuffer(0);
1214 
1215 	pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,					// VkPipelineStageFlags		srcStageMask
1216 						 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,				// VkPipelineStageFlags		dstStageMask
1217 						 0,													// VkAccessFlags			srcAccessMask
1218 						 (m_isAttachmentFormat
1219 							?	VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
1220 							:	VK_ACCESS_TRANSFER_WRITE_BIT),				// VkAccessFlags			dstAccessMask
1221 						 VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
1222 						 (m_isAttachmentFormat
1223 							?	VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
1224 							:	VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL));		// VkImageLayout			newLayout;
1225 
1226 	if (m_isAttachmentFormat)
1227 	{
1228 		beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue);
1229 		m_vkd.cmdEndRenderPass(*m_commandBuffer);
1230 
1231 		pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,					// VkPipelineStageFlags		srcStageMask
1232 							 VK_PIPELINE_STAGE_TRANSFER_BIT,						// VkPipelineStageFlags		dstStageMask
1233 							 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
1234 							 VK_ACCESS_TRANSFER_WRITE_BIT,							// VkAccessFlags			dstAccessMask
1235 							 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,		// VkImageLayout			oldLayout;
1236 							 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);					// VkImageLayout			newLayout;
1237 	}
1238 
1239 	m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_params.clearValue[0].depthStencil, 1, &subresourceRange);
1240 
1241 	pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,					// VkPipelineStageFlags		srcStageMask
1242 						 VK_PIPELINE_STAGE_TRANSFER_BIT,					// VkPipelineStageFlags		dstStageMask
1243 						 VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask
1244 						 VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			dstAccessMask
1245 						 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout;
1246 						 VK_IMAGE_LAYOUT_GENERAL);							// VkImageLayout			newLayout;
1247 
1248 	endCommandBuffer();
1249 	submitCommandBuffer();
1250 
1251 	return verifyResultImage("cmdClearDepthStencilImage passed");
1252 }
1253 
1254 class ClearAttachmentTestInstance : public ImageClearingTestInstance
1255 {
1256 public:
1257 	enum ClearType
1258 	{
1259 		FULL_CLEAR,
1260 		PARTIAL_CLEAR,
1261 	};
1262 
ClearAttachmentTestInstance(Context & context,const TestParams & testParams,const ClearType clearType=FULL_CLEAR)1263 	ClearAttachmentTestInstance (Context& context, const TestParams& testParams, const ClearType clearType = FULL_CLEAR)
1264 		: ImageClearingTestInstance	(context, testParams)
1265 		, m_clearType				(clearType)
1266 	{
1267 		if (!m_isAttachmentFormat)
1268 			TCU_THROW(NotSupportedError, "Format not renderable");
1269 	}
1270 
iterate(void)1271 	TestStatus iterate (void)
1272 	{
1273 		const VkClearAttachment clearAttachment =
1274 		{
1275 			m_imageAspectFlags,					// VkImageAspectFlags	aspectMask;
1276 			0u,									// deUint32				colorAttachment;
1277 			m_params.clearValue[0]				// VkClearValue			clearValue;
1278 		};
1279 
1280 		UVec4						clearCoords;
1281 		std::vector<VkClearRect>	clearRects;
1282 
1283 		if (m_clearType == FULL_CLEAR)
1284 		{
1285 			const VkClearRect rect =
1286 			{
1287 				{
1288 					{ 0, 0 },																	// VkOffset2D    offset;
1289 					{ m_params.imageExtent.width, m_params.imageExtent.height }					// VkExtent2D    extent;
1290 				},																			// VkRect2D	rect;
1291 				m_params.clearLayerRange.baseArrayLayer,								// deUint32	baseArrayLayer;
1292 				m_params.clearLayerRange.layerCount,									// deUint32	layerCount;
1293 			};
1294 
1295 			clearRects.push_back(rect);
1296 		}
1297 		else
1298 		{
1299 			const deUint32	clearX		= m_params.imageExtent.width  / 4u;
1300 			const deUint32	clearY		= m_params.imageExtent.height / 4u;
1301 			const deUint32	clearWidth	= m_params.imageExtent.width  / 2u;
1302 			const deUint32	clearHeight	= m_params.imageExtent.height / 2u;
1303 
1304 			clearCoords	= UVec4(clearX,					clearY,
1305 								clearX + clearWidth,	clearY + clearHeight);
1306 
1307 			const VkClearRect rects[2] =
1308 			{
1309 				{
1310 					{
1311 						{ 0,							static_cast<deInt32>(clearY)	},		// VkOffset2D    offset;
1312 						{ m_params.imageExtent.width,	clearHeight						}		// VkExtent2D    extent;
1313 					},																		// VkRect2D	rect;
1314 					m_params.clearLayerRange.baseArrayLayer,								// deUint32	baseArrayLayer;
1315 					m_params.clearLayerRange.layerCount										// deUint32	layerCount;
1316 				},
1317 				{
1318 					{
1319 						{ static_cast<deInt32>(clearX),	0							},			// VkOffset2D    offset;
1320 						{ clearWidth,					m_params.imageExtent.height	}			// VkExtent2D    extent;
1321 					},																		// VkRect2D	rect;
1322 					m_params.clearLayerRange.baseArrayLayer,								// deUint32	baseArrayLayer;
1323 					m_params.clearLayerRange.layerCount										// deUint32	layerCount;
1324 				}
1325 			};
1326 
1327 			clearRects.push_back(rects[0]);
1328 			clearRects.push_back(rects[1]);
1329 		}
1330 
1331 		const bool			isDepthStencil		= isDepthStencilFormat(m_params.imageFormat);
1332 		const VkAccessFlags	accessMask			= (isDepthStencil ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT     : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1333 		const VkImageLayout	attachmentLayout	= (isDepthStencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
1334 
1335 		beginCommandBuffer(0);
1336 
1337 		pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
1338 							 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,			// VkPipelineStageFlags		dstStageMask
1339 							 0,												// VkAccessFlags			srcAccessMask
1340 							 accessMask,									// VkAccessFlags			dstAccessMask
1341 							 VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
1342 							 attachmentLayout);								// VkImageLayout			newLayout;
1343 
1344 		beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue);
1345 		m_vkd.cmdClearAttachments(*m_commandBuffer, 1, &clearAttachment, static_cast<deUint32>(clearRects.size()), &clearRects[0]);
1346 		m_vkd.cmdEndRenderPass(*m_commandBuffer);
1347 
1348 		pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,			// VkPipelineStageFlags		srcStageMask
1349 							 VK_PIPELINE_STAGE_TRANSFER_BIT,				// VkPipelineStageFlags		dstStageMask
1350 							 accessMask,									// VkAccessFlags			srcAccessMask
1351 							 VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags			dstAccessMask
1352 							 attachmentLayout,								// VkImageLayout			oldLayout;
1353 							 VK_IMAGE_LAYOUT_GENERAL);						// VkImageLayout			newLayout;
1354 
1355 		endCommandBuffer();
1356 		submitCommandBuffer();
1357 
1358 		return verifyResultImage("cmdClearAttachments passed", clearCoords);
1359 	}
1360 
1361 private:
1362 	const ClearType	m_clearType;
1363 };
1364 
1365 class PartialClearAttachmentTestInstance : public ClearAttachmentTestInstance
1366 {
1367 public:
PartialClearAttachmentTestInstance(Context & context,const TestParams & testParams)1368 	PartialClearAttachmentTestInstance (Context& context, const TestParams& testParams) : ClearAttachmentTestInstance (context, testParams, PARTIAL_CLEAR) {}
1369 };
1370 
makeClearColorValue(VkFormat format,float r,float g,float b,float a)1371 VkClearValue makeClearColorValue (VkFormat format, float r, float g, float b, float a)
1372 {
1373 	const	TextureFormat tcuFormat	= mapVkFormat(format);
1374 	VkClearValue clearValue;
1375 
1376 	if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_FLOATING_POINT
1377 		|| getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
1378 		|| getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
1379 	{
1380 		clearValue.color.float32[0] = r;
1381 		clearValue.color.float32[1] = g;
1382 		clearValue.color.float32[2] = b;
1383 		clearValue.color.float32[3] = a;
1384 	}
1385 	else if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1386 	{
1387 		UVec4 maxValues = getFormatMaxUintValue(tcuFormat);
1388 
1389 		clearValue.color.uint32[0] = (deUint32)((float)maxValues[0] * r);
1390 		clearValue.color.uint32[1] = (deUint32)((float)maxValues[1] * g);
1391 		clearValue.color.uint32[2] = (deUint32)((float)maxValues[2] * b);
1392 		clearValue.color.uint32[3] = (deUint32)((float)maxValues[3] * a);
1393 	}
1394 	else if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_SIGNED_INTEGER)
1395 	{
1396 		IVec4 maxValues = getFormatMaxIntValue(tcuFormat);
1397 
1398 		clearValue.color.int32[0] = (deUint32)((float)maxValues[0] * r);
1399 		clearValue.color.int32[1] = (deUint32)((float)maxValues[1] * g);
1400 		clearValue.color.int32[2] = (deUint32)((float)maxValues[2] * b);
1401 		clearValue.color.int32[3] = (deUint32)((float)maxValues[3] * a);
1402 	}
1403 	else
1404 		DE_FATAL("Unknown channel class");
1405 
1406 	return clearValue;
1407 }
1408 
getFormatCaseName(VkFormat format)1409 std::string getFormatCaseName (VkFormat format)
1410 {
1411 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
1412 }
1413 
getImageTypeCaseName(VkImageType type)1414 const char* getImageTypeCaseName (VkImageType type)
1415 {
1416 	const char* s_names[] =
1417 	{
1418 		"1d",
1419 		"2d",
1420 		"3d"
1421 	};
1422 	return de::getSizedArrayElement<VK_IMAGE_TYPE_LAST>(s_names, type);
1423 }
1424 
createImageClearingTestsCommon(TestContext & testCtx,tcu::TestCaseGroup * imageClearingTests,AllocationKind allocationKind)1425 TestCaseGroup* createImageClearingTestsCommon (TestContext& testCtx, tcu::TestCaseGroup* imageClearingTests, AllocationKind allocationKind)
1426 {
1427 	de::MovePtr<TestCaseGroup>	colorImageClearTests					(new TestCaseGroup(testCtx, "clear_color_image", "Color Image Clear Tests"));
1428 	de::MovePtr<TestCaseGroup>	depthStencilImageClearTests				(new TestCaseGroup(testCtx, "clear_depth_stencil_image", "Color Depth/Stencil Image Tests"));
1429 	de::MovePtr<TestCaseGroup>	colorAttachmentClearTests				(new TestCaseGroup(testCtx, "clear_color_attachment", "Color Color Attachment Tests"));
1430 	de::MovePtr<TestCaseGroup>	depthStencilAttachmentClearTests		(new TestCaseGroup(testCtx, "clear_depth_stencil_attachment", "Color Depth/Stencil Attachment Tests"));
1431 	de::MovePtr<TestCaseGroup>	partialColorAttachmentClearTests		(new TestCaseGroup(testCtx, "partial_clear_color_attachment", "Clear Partial Color Attachment Tests"));
1432 	de::MovePtr<TestCaseGroup>	partialDepthStencilAttachmentClearTests	(new TestCaseGroup(testCtx, "partial_clear_depth_stencil_attachment", "Clear Partial Depth/Stencil Attachment Tests"));
1433 
1434 	// Some formats are commented out due to the tcu::TextureFormat does not support them yet.
1435 	const VkFormat		colorImageFormatsToTest[]	=
1436 	{
1437 		VK_FORMAT_R4G4_UNORM_PACK8,
1438 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1439 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1440 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1441 		VK_FORMAT_B5G6R5_UNORM_PACK16,
1442 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1443 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1444 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1445 		VK_FORMAT_R8_UNORM,
1446 		VK_FORMAT_R8_SNORM,
1447 		VK_FORMAT_R8_USCALED,
1448 		VK_FORMAT_R8_SSCALED,
1449 		VK_FORMAT_R8_UINT,
1450 		VK_FORMAT_R8_SINT,
1451 		VK_FORMAT_R8_SRGB,
1452 		VK_FORMAT_R8G8_UNORM,
1453 		VK_FORMAT_R8G8_SNORM,
1454 		VK_FORMAT_R8G8_USCALED,
1455 		VK_FORMAT_R8G8_SSCALED,
1456 		VK_FORMAT_R8G8_UINT,
1457 		VK_FORMAT_R8G8_SINT,
1458 		VK_FORMAT_R8G8_SRGB,
1459 		VK_FORMAT_R8G8B8_UNORM,
1460 		VK_FORMAT_R8G8B8_SNORM,
1461 		VK_FORMAT_R8G8B8_USCALED,
1462 		VK_FORMAT_R8G8B8_SSCALED,
1463 		VK_FORMAT_R8G8B8_UINT,
1464 		VK_FORMAT_R8G8B8_SINT,
1465 		VK_FORMAT_R8G8B8_SRGB,
1466 		VK_FORMAT_B8G8R8_UNORM,
1467 		VK_FORMAT_B8G8R8_SNORM,
1468 		VK_FORMAT_B8G8R8_USCALED,
1469 		VK_FORMAT_B8G8R8_SSCALED,
1470 		VK_FORMAT_B8G8R8_UINT,
1471 		VK_FORMAT_B8G8R8_SINT,
1472 		VK_FORMAT_B8G8R8_SRGB,
1473 		VK_FORMAT_R8G8B8A8_UNORM,
1474 		VK_FORMAT_R8G8B8A8_SNORM,
1475 		VK_FORMAT_R8G8B8A8_USCALED,
1476 		VK_FORMAT_R8G8B8A8_SSCALED,
1477 		VK_FORMAT_R8G8B8A8_UINT,
1478 		VK_FORMAT_R8G8B8A8_SINT,
1479 		VK_FORMAT_R8G8B8A8_SRGB,
1480 		VK_FORMAT_B8G8R8A8_UNORM,
1481 		VK_FORMAT_B8G8R8A8_SNORM,
1482 		VK_FORMAT_B8G8R8A8_USCALED,
1483 		VK_FORMAT_B8G8R8A8_SSCALED,
1484 		VK_FORMAT_B8G8R8A8_UINT,
1485 		VK_FORMAT_B8G8R8A8_SINT,
1486 		VK_FORMAT_B8G8R8A8_SRGB,
1487 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1488 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1489 		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1490 		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1491 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1492 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1493 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1494 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1495 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1496 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1497 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1498 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
1499 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
1500 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1501 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1502 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1503 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1504 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1505 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
1506 		VK_FORMAT_R16_UNORM,
1507 		VK_FORMAT_R16_SNORM,
1508 		VK_FORMAT_R16_USCALED,
1509 		VK_FORMAT_R16_SSCALED,
1510 		VK_FORMAT_R16_UINT,
1511 		VK_FORMAT_R16_SINT,
1512 		VK_FORMAT_R16_SFLOAT,
1513 		VK_FORMAT_R16G16_UNORM,
1514 		VK_FORMAT_R16G16_SNORM,
1515 		VK_FORMAT_R16G16_USCALED,
1516 		VK_FORMAT_R16G16_SSCALED,
1517 		VK_FORMAT_R16G16_UINT,
1518 		VK_FORMAT_R16G16_SINT,
1519 		VK_FORMAT_R16G16_SFLOAT,
1520 		VK_FORMAT_R16G16B16_UNORM,
1521 		VK_FORMAT_R16G16B16_SNORM,
1522 		VK_FORMAT_R16G16B16_USCALED,
1523 		VK_FORMAT_R16G16B16_SSCALED,
1524 		VK_FORMAT_R16G16B16_UINT,
1525 		VK_FORMAT_R16G16B16_SINT,
1526 		VK_FORMAT_R16G16B16_SFLOAT,
1527 		VK_FORMAT_R16G16B16A16_UNORM,
1528 		VK_FORMAT_R16G16B16A16_SNORM,
1529 		VK_FORMAT_R16G16B16A16_USCALED,
1530 		VK_FORMAT_R16G16B16A16_SSCALED,
1531 		VK_FORMAT_R16G16B16A16_UINT,
1532 		VK_FORMAT_R16G16B16A16_SINT,
1533 		VK_FORMAT_R16G16B16A16_SFLOAT,
1534 		VK_FORMAT_R32_UINT,
1535 		VK_FORMAT_R32_SINT,
1536 		VK_FORMAT_R32_SFLOAT,
1537 		VK_FORMAT_R32G32_UINT,
1538 		VK_FORMAT_R32G32_SINT,
1539 		VK_FORMAT_R32G32_SFLOAT,
1540 		VK_FORMAT_R32G32B32_UINT,
1541 		VK_FORMAT_R32G32B32_SINT,
1542 		VK_FORMAT_R32G32B32_SFLOAT,
1543 		VK_FORMAT_R32G32B32A32_UINT,
1544 		VK_FORMAT_R32G32B32A32_SINT,
1545 		VK_FORMAT_R32G32B32A32_SFLOAT,
1546 //		VK_FORMAT_R64_UINT,
1547 //		VK_FORMAT_R64_SINT,
1548 //		VK_FORMAT_R64_SFLOAT,
1549 //		VK_FORMAT_R64G64_UINT,
1550 //		VK_FORMAT_R64G64_SINT,
1551 //		VK_FORMAT_R64G64_SFLOAT,
1552 //		VK_FORMAT_R64G64B64_UINT,
1553 //		VK_FORMAT_R64G64B64_SINT,
1554 //		VK_FORMAT_R64G64B64_SFLOAT,
1555 //		VK_FORMAT_R64G64B64A64_UINT,
1556 //		VK_FORMAT_R64G64B64A64_SINT,
1557 //		VK_FORMAT_R64G64B64A64_SFLOAT,
1558 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1559 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1560 //		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
1561 //		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
1562 //		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
1563 //		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1564 //		VK_FORMAT_BC2_UNORM_BLOCK,
1565 //		VK_FORMAT_BC2_SRGB_BLOCK,
1566 //		VK_FORMAT_BC3_UNORM_BLOCK,
1567 //		VK_FORMAT_BC3_SRGB_BLOCK,
1568 //		VK_FORMAT_BC4_UNORM_BLOCK,
1569 //		VK_FORMAT_BC4_SNORM_BLOCK,
1570 //		VK_FORMAT_BC5_UNORM_BLOCK,
1571 //		VK_FORMAT_BC5_SNORM_BLOCK,
1572 //		VK_FORMAT_BC6H_UFLOAT_BLOCK,
1573 //		VK_FORMAT_BC6H_SFLOAT_BLOCK,
1574 //		VK_FORMAT_BC7_UNORM_BLOCK,
1575 //		VK_FORMAT_BC7_SRGB_BLOCK,
1576 //		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1577 //		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1578 //		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1579 //		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1580 //		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1581 //		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1582 //		VK_FORMAT_EAC_R11_UNORM_BLOCK,
1583 //		VK_FORMAT_EAC_R11_SNORM_BLOCK,
1584 //		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1585 //		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1586 //		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1587 //		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
1588 //		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
1589 //		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1590 //		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
1591 //		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
1592 //		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1593 //		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
1594 //		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
1595 //		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1596 //		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
1597 //		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
1598 //		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1599 //		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
1600 //		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
1601 //		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1602 //		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
1603 //		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
1604 //		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1605 //		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
1606 //		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
1607 //		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1608 //		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
1609 //		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
1610 //		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1611 //		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
1612 //		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
1613 //		VK_FORMAT_ASTC_12x12_SRGB_BLOCK
1614 	};
1615 	const size_t	numOfColorImageFormatsToTest			= DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
1616 
1617 	const VkFormat	depthStencilImageFormatsToTest[]		=
1618 	{
1619 		VK_FORMAT_D16_UNORM,
1620 		VK_FORMAT_X8_D24_UNORM_PACK32,
1621 		VK_FORMAT_D32_SFLOAT,
1622 		VK_FORMAT_S8_UINT,
1623 		VK_FORMAT_D16_UNORM_S8_UINT,
1624 		VK_FORMAT_D24_UNORM_S8_UINT,
1625 		VK_FORMAT_D32_SFLOAT_S8_UINT
1626 	};
1627 	const size_t	numOfDepthStencilImageFormatsToTest		= DE_LENGTH_OF_ARRAY(depthStencilImageFormatsToTest);
1628 
1629 	struct ImageLayerParams
1630 	{
1631 		deUint32		imageLayerCount;
1632 		LayerRange		imageViewRange;
1633 		LayerRange		clearLayerRange;
1634 		const char*		testName;
1635 	};
1636 	const ImageLayerParams imageLayerParamsToTest[] =
1637 	{
1638 		{
1639 			1u,									// imageLayerCount
1640 			{0u, 1u},							// imageViewRange
1641 			{0u, 1u},							// clearLayerRange
1642 			"single_layer"						// testName
1643 		},
1644 		{
1645 			16u,								// imageLayerCount
1646 			{3u, 12u},							// imageViewRange
1647 			{2u, 5u},							// clearLayerRange
1648 			"multiple_layers"					// testName
1649 		},
1650 		{
1651 			16u,								// imageLayerCount
1652 			{ 3u, 12u },						// imageViewRange
1653 			{ 8u, VK_REMAINING_ARRAY_LAYERS },	// clearLayerRange
1654 			"remaining_array_layers"			// testName
1655 		}
1656 	};
1657 
1658 	// Include test cases with VK_REMAINING_ARRAY_LAYERS when using vkCmdClearColorImage
1659 	const size_t	numOfImageLayerParamsToTest				= DE_LENGTH_OF_ARRAY(imageLayerParamsToTest);
1660 
1661 	// Exclude test cases with VK_REMAINING_ARRAY_LAYERS when using vkCmdClearAttachments
1662 	const size_t	numOfAttachmentLayerParamsToTest		= numOfImageLayerParamsToTest - 1;
1663 
1664 	// Clear color image
1665 	{
1666 		const VkImageType			imageTypesToTest[]		=
1667 		{
1668 			VK_IMAGE_TYPE_1D,
1669 			VK_IMAGE_TYPE_2D,
1670 			VK_IMAGE_TYPE_3D
1671 		};
1672 		const size_t				numOfImageTypesToTest	= DE_LENGTH_OF_ARRAY(imageTypesToTest);
1673 
1674 		const VkExtent3D			imageDimensionsByType[]	=
1675 		{
1676 			{ 256, 1, 1},
1677 			{ 256, 256, 1},
1678 			{ 256, 256, 16}
1679 		};
1680 
1681 		for (size_t	imageTypeIndex = 0; imageTypeIndex < numOfImageTypesToTest; ++imageTypeIndex)
1682 		{
1683 			de::MovePtr<TestCaseGroup> imageTypeGroup(new TestCaseGroup(testCtx, getImageTypeCaseName(imageTypesToTest[imageTypeIndex]), ""));
1684 
1685 			for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest; ++imageLayerParamsIndex)
1686 			{
1687 				// 3D ARRAY images are not supported
1688 				if (imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount > 1u && imageTypesToTest[imageTypeIndex] == VK_IMAGE_TYPE_3D)
1689 					continue;
1690 
1691 				de::MovePtr<TestCaseGroup> imageLayersGroup(new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName, ""));
1692 
1693 				for (size_t imageFormatIndex = 0; imageFormatIndex < numOfColorImageFormatsToTest; ++imageFormatIndex)
1694 				{
1695 					const VkFormat		format			= colorImageFormatsToTest[imageFormatIndex];
1696 					const std::string	testCaseName	= getFormatCaseName(format);
1697 					const TestParams	testParams		=
1698 					{
1699 						false,																// bool				useSingleMipLevel;
1700 						imageTypesToTest[imageTypeIndex],									// VkImageType		imageType;
1701 						format,																// VkFormat			imageFormat;
1702 						imageDimensionsByType[imageTypeIndex],								// VkExtent3D		imageExtent;
1703 						imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount,		// deUint32         imageLayerCount;
1704 						{
1705 							0u,
1706 							imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount
1707 						},																	// LayerRange		imageViewLayerRange;
1708 						makeClearColorValue(format, 0.2f, 0.1f, 0.7f, 0.8f),				// VkClearValue		initValue;
1709 						{
1710 							makeClearColorValue(format, 0.1f, 0.5f, 0.3f, 0.9f),				// VkClearValue		clearValue[0];
1711 							makeClearColorValue(format, 0.3f, 0.6f, 0.2f, 0.7f),				// VkClearValue		clearValue[1];
1712 						},
1713 						imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange,		// LayerRange       clearLayerRange;
1714 						allocationKind														// AllocationKind	allocationKind;
1715 					};
1716 
1717 					imageLayersGroup->addChild(new InstanceFactory1<ClearColorImageTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName, "Clear Color Image", testParams));
1718 				}
1719 				imageTypeGroup->addChild(imageLayersGroup.release());
1720 			}
1721 			colorImageClearTests->addChild(imageTypeGroup.release());
1722 		}
1723 		imageClearingTests->addChild(colorImageClearTests.release());
1724 	}
1725 
1726 	// Clear depth/stencil image
1727 	{
1728 		for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest; ++imageLayerParamsIndex)
1729 		{
1730 			de::MovePtr<TestCaseGroup> imageLayersGroup(new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName, ""));
1731 
1732 			for (size_t imageFormatIndex = 0; imageFormatIndex < numOfDepthStencilImageFormatsToTest; ++imageFormatIndex)
1733 			{
1734 				const VkFormat		format			= depthStencilImageFormatsToTest[imageFormatIndex];
1735 				const std::string	testCaseName	= getFormatCaseName(format);
1736 				const TestParams	testParams		=
1737 				{
1738 					true,																// bool				useSingleMipLevel;
1739 					VK_IMAGE_TYPE_2D,													// VkImageType		imageType;
1740 					format,																// VkFormat			format;
1741 					{ 256, 256, 1 },													// VkExtent3D		extent;
1742 					imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount,		// deUint32         imageLayerCount;
1743 					{
1744 						0u,
1745 						imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount
1746 					},																	// LayerRange		imageViewLayerRange;
1747 					makeClearValueDepthStencil(0.5f, 0x03),								// VkClearValue		initValue
1748 					{
1749 						makeClearValueDepthStencil(0.1f, 0x06),								// VkClearValue		clearValue[0];
1750 						makeClearValueDepthStencil(0.3f, 0x04),								// VkClearValue		clearValue[1];
1751 					},
1752 					imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange,		// LayerRange       clearLayerRange;
1753 					allocationKind														// AllocationKind	allocationKind;
1754 				};
1755 
1756 				imageLayersGroup->addChild(new InstanceFactory1<ClearDepthStencilImageTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName, "Clear Depth/Stencil Image", testParams));
1757 			}
1758 			depthStencilImageClearTests->addChild(imageLayersGroup.release());
1759 		}
1760 		imageClearingTests->addChild(depthStencilImageClearTests.release());
1761 	}
1762 
1763 	// Clear color attachment
1764 	{
1765 		for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfAttachmentLayerParamsToTest; ++imageLayerParamsIndex)
1766 		{
1767 			de::MovePtr<TestCaseGroup> colorAttachmentClearLayersGroup(new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName, ""));
1768 			de::MovePtr<TestCaseGroup> partialColorAttachmentClearLayersGroup(new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName, ""));
1769 
1770 			for (size_t imageFormatIndex = 0; imageFormatIndex < numOfColorImageFormatsToTest; ++imageFormatIndex)
1771 			{
1772 				const VkFormat		format			= colorImageFormatsToTest[imageFormatIndex];
1773 				const std::string	testCaseName	= getFormatCaseName(format);
1774 				const TestParams	testParams		=
1775 				{
1776 					true,															// bool				useSingleMipLevel;
1777 					VK_IMAGE_TYPE_2D,												// VkImageType		imageType;
1778 					format,															// VkFormat			format;
1779 					{ 256, 256, 1 },												// VkExtent3D		extent;
1780 					imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount,	// deUint32         imageLayerCount;
1781 					imageLayerParamsToTest[imageLayerParamsIndex].imageViewRange,	// LayerRange		imageViewLayerRange;
1782 					makeClearColorValue(format, 0.2f, 0.1f, 0.7f, 0.8f),			// VkClearValue		initValue
1783 					{
1784 						makeClearColorValue(format, 0.1f, 0.5f, 0.3f, 0.9f),			// VkClearValue		clearValue[0];
1785 						makeClearColorValue(format, 0.3f, 0.6f, 0.2f, 0.7f),			// VkClearValue		clearValue[1];
1786 					},
1787 					imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange,	// LayerRange       clearLayerRange;
1788 					allocationKind													// AllocationKind	allocationKind;
1789 				};
1790 
1791 				colorAttachmentClearLayersGroup->addChild(new InstanceFactory1<ClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName, "Clear Color Attachment", testParams));
1792 				partialColorAttachmentClearLayersGroup->addChild(new InstanceFactory1<PartialClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName, "Partial Clear Color Attachment", testParams));
1793 			}
1794 			colorAttachmentClearTests->addChild(colorAttachmentClearLayersGroup.release());
1795 			partialColorAttachmentClearTests->addChild(partialColorAttachmentClearLayersGroup.release());
1796 		}
1797 		imageClearingTests->addChild(colorAttachmentClearTests.release());
1798 		imageClearingTests->addChild(partialColorAttachmentClearTests.release());
1799 	}
1800 
1801 	// Clear depth/stencil attachment
1802 	{
1803 		for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfAttachmentLayerParamsToTest; ++imageLayerParamsIndex)
1804 		{
1805 			de::MovePtr<TestCaseGroup> depthStencilLayersGroup(new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName, ""));
1806 			de::MovePtr<TestCaseGroup> partialDepthStencilLayersGroup(new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName, ""));
1807 
1808 			for (size_t imageFormatIndex = 0; imageFormatIndex < numOfDepthStencilImageFormatsToTest; ++imageFormatIndex)
1809 			{
1810 				const VkFormat		format			= depthStencilImageFormatsToTest[imageFormatIndex];
1811 				const std::string	testCaseName	= getFormatCaseName(format);
1812 				const TestParams	testParams		=
1813 				{
1814 					true,															// bool				useSingleMipLevel;
1815 					VK_IMAGE_TYPE_2D,												// VkImageType		imageType;
1816 					format,															// VkFormat			format;
1817 					{ 256, 256, 1 },												// VkExtent3D		extent;
1818 					imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount,	// deUint32         imageLayerCount;
1819 					imageLayerParamsToTest[imageLayerParamsIndex].imageViewRange,	// LayerRange		imageViewLayerRange;
1820 					makeClearValueDepthStencil(0.5f, 0x03),							// VkClearValue		initValue
1821 					{
1822 						makeClearValueDepthStencil(0.1f, 0x06),							// VkClearValue		clearValue[0];
1823 						makeClearValueDepthStencil(0.3f, 0x04),							// VkClearValue		clearValue[1];
1824 					},
1825 					imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange,	// LayerRange       clearLayerRange;
1826 					allocationKind													// AllocationKind	allocationKind;
1827 				};
1828 
1829 				depthStencilLayersGroup->addChild(new InstanceFactory1<ClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName, "Clear Depth/Stencil Attachment", testParams));
1830 				partialDepthStencilLayersGroup->addChild(new InstanceFactory1<PartialClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName, "Parital Clear Depth/Stencil Attachment", testParams));
1831 			}
1832 			depthStencilAttachmentClearTests->addChild(depthStencilLayersGroup.release());
1833 			partialDepthStencilAttachmentClearTests->addChild(partialDepthStencilLayersGroup.release());
1834 		}
1835 		imageClearingTests->addChild(depthStencilAttachmentClearTests.release());
1836 		imageClearingTests->addChild(partialDepthStencilAttachmentClearTests.release());
1837 	}
1838 
1839 	return imageClearingTests;
1840 }
1841 
createCoreImageClearingTests(tcu::TestCaseGroup * group)1842 void createCoreImageClearingTests (tcu::TestCaseGroup* group)
1843 {
1844 	createImageClearingTestsCommon(group->getTestContext(), group, ALLOCATION_KIND_SUBALLOCATED);
1845 }
1846 
createDedicatedAllocationImageClearingTests(tcu::TestCaseGroup * group)1847 void createDedicatedAllocationImageClearingTests (tcu::TestCaseGroup* group)
1848 {
1849 	createImageClearingTestsCommon(group->getTestContext(), group, ALLOCATION_KIND_DEDICATED);
1850 }
1851 
1852 } // anonymous
1853 
createImageClearingTests(TestContext & testCtx)1854 TestCaseGroup* createImageClearingTests (TestContext& testCtx)
1855 {
1856 	de::MovePtr<TestCaseGroup>	imageClearingTests	(new TestCaseGroup(testCtx, "image_clearing", "Image Clearing Tests"));
1857 
1858 	imageClearingTests->addChild(createTestGroup(testCtx, "core",					"Core Image Clearing Tests",							createCoreImageClearingTests));
1859 	imageClearingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Image Clearing Tests For Dedicated Memory Allocation",	createDedicatedAllocationImageClearingTests));
1860 
1861 	return imageClearingTests.release();
1862 }
1863 
1864 } // api
1865 } // vkt
1866