• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  * Copyright (c) 2018 The Khronos Group Inc.
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 
22 #include "vktApiMemoryRequirementInvarianceTests.hpp"
23 #include "vktApiBufferAndImageAllocationUtil.hpp"
24 #include "deRandom.h"
25 #include "tcuTestLog.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vkMemUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkImageUtil.hpp"
30 
31 
32 namespace vkt
33 {
34 namespace api
35 {
36 
37 using namespace vk;
38 
39 // Number of items to allocate
40 #ifndef CTS_USES_VULKANSC
41 const unsigned int		testCycles								= 1000u;
42 #else
43 const unsigned int		testCycles								= 100u;
44 #endif // CTS_USES_VULKANSC
45 
46 // All legal memory combinations (spec chapter 10.2: Device Memory)
47 const unsigned int		legalMemoryTypeCount					= 11u;
48 const MemoryRequirement	legalMemoryTypes[legalMemoryTypeCount]	=
49 {
50 	MemoryRequirement::Any,
51 	MemoryRequirement::HostVisible	| MemoryRequirement::Coherent,
52 	MemoryRequirement::HostVisible	| MemoryRequirement::Cached,
53 	MemoryRequirement::HostVisible	| MemoryRequirement::Cached			| MemoryRequirement::Coherent,
54 	MemoryRequirement::Local,
55 	MemoryRequirement::Local		| MemoryRequirement::HostVisible	| MemoryRequirement::Coherent,
56 	MemoryRequirement::Local		| MemoryRequirement::HostVisible	| MemoryRequirement::Cached,
57 	MemoryRequirement::Local		| MemoryRequirement::HostVisible	| MemoryRequirement::Cached		| MemoryRequirement::Coherent,
58 	MemoryRequirement::Local		| MemoryRequirement::LazilyAllocated,
59 	MemoryRequirement::Protected,
60 	MemoryRequirement::Protected	| MemoryRequirement::Local
61 };
62 
63 class IObjectAllocator
64 {
65 public:
IObjectAllocator()66 					IObjectAllocator	()	{}
~IObjectAllocator()67 	virtual			~IObjectAllocator	()	{}
68 	virtual void	allocate			(Context&	context)	= 0;
69 	virtual void	deallocate			(Context&	context)	= 0;
70 	virtual	size_t	getSize				(Context&	context)	= 0;
71 };
72 
73 class BufferAllocator : public IObjectAllocator
74 {
75 public:
76 					BufferAllocator		(deRandom& random, deBool dedicated, std::vector<int>& memoryTypes);
77 	virtual			~BufferAllocator	();
78 	virtual void	allocate			(Context&	context);
79 	virtual void	deallocate			(Context&	context);
80 	virtual	size_t	getSize				(Context&	context);
81 private:
82 	bool					m_dedicated;
83 	Move<VkBuffer>			m_buffer;
84 	VkDeviceSize			m_size;
85 	VkBufferUsageFlags		m_usage;
86 	int						m_memoryType;
87 	de::MovePtr<Allocation>	m_bufferAlloc;
88 };
89 
BufferAllocator(deRandom & random,deBool dedicated,std::vector<int> & memoryTypes)90 BufferAllocator::BufferAllocator (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes)
91 {
92 	// If dedicated allocation is supported, randomly pick it
93 	m_dedicated		= dedicated && deRandom_getBool(&random);
94 	// Random buffer sizes to find potential issues caused by strange alignment
95 	m_size			= (deRandom_getUint32(&random) % 1024) + 7;
96 	// Pick a random usage from the 9 VkBufferUsageFlags.
97 	m_usage			= 1 << (deRandom_getUint32(&random) % 9);
98 	// Pick random memory type from the supported ones
99 	m_memoryType	= memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
100 }
101 
~BufferAllocator()102 BufferAllocator::~BufferAllocator ()
103 {
104 }
105 
allocate(Context & context)106 void BufferAllocator::allocate (Context& context)
107 {
108 	const DeviceInterface&			vk					= context.getDeviceInterface();
109 	VkDevice						vkDevice			= context.getDevice();
110 	deUint32						queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
111 	Allocator&						memAlloc			= context.getDefaultAllocator();
112 	de::MovePtr<IBufferAllocator>	allocator;
113 	MemoryRequirement				requirement			= legalMemoryTypes[m_memoryType];
114 
115 	if (m_dedicated)
116 		allocator = de::MovePtr<IBufferAllocator>(new BufferDedicatedAllocation);
117 	else
118 		allocator = de::MovePtr<IBufferAllocator>(new BufferSuballocation);
119 
120 	allocator->createTestBuffer(
121 		vk,
122 		vkDevice,
123 		queueFamilyIndex,
124 		m_size,
125 		m_usage,
126 		context,
127 		memAlloc,
128 		m_buffer,
129 		requirement,
130 		m_bufferAlloc);
131 }
132 
deallocate(Context & context)133 void BufferAllocator::deallocate (Context& context)
134 {
135 	const DeviceInterface&	vk		= context.getDeviceInterface();
136 	const vk::VkDevice&		device	= context.getDevice();
137 
138 	vk.destroyBuffer(device, m_buffer.disown(), DE_NULL);
139 	m_bufferAlloc.clear();
140 }
141 
getSize(Context & context)142 size_t BufferAllocator::getSize (Context &context)
143 {
144 	const DeviceInterface&	vk		= context.getDeviceInterface();
145 	const vk::VkDevice&		device	= context.getDevice();
146 	VkMemoryRequirements	memReq;
147 
148 	vk.getBufferMemoryRequirements(device, *m_buffer, &memReq);
149 
150 	return (size_t)memReq.size;
151 }
152 
153 class ImageAllocator : public IObjectAllocator
154 {
155 public:
156 					ImageAllocator	(deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes);
157 	virtual			~ImageAllocator	();
158 	virtual void	allocate		(Context&	context);
159 	virtual void	deallocate		(Context&	context);
160 	virtual	size_t	getSize			(Context&	context);
161 private:
162 	deBool					m_dedicated;
163 	deBool					m_linear;
164 	Move<vk::VkImage>		m_image;
165 	tcu::IVec2				m_size;
166 	vk::VkFormat			m_colorFormat;
167 	de::MovePtr<Allocation>	m_imageAlloc;
168 	int						m_memoryType;
169 };
170 
ImageAllocator(deRandom & random,deBool dedicated,std::vector<int> & linearformats,std::vector<int> & optimalformats,std::vector<int> & memoryTypes)171 ImageAllocator::ImageAllocator (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes)
172 {
173 	// If dedicated allocation is supported, pick it randomly
174 	m_dedicated		= dedicated && deRandom_getBool(&random);
175 	// If linear formats are supported, pick it randomly
176 	m_linear		= (linearformats.size() > 0) && deRandom_getBool(&random);
177 
178 	if (m_linear)
179 		m_colorFormat = (VkFormat)linearformats[deRandom_getUint32(&random) % linearformats.size()];
180 	else
181 		m_colorFormat = (VkFormat)optimalformats[deRandom_getUint32(&random) % optimalformats.size()];
182 
183 	int	widthAlignment	= (isYCbCr420Format(m_colorFormat) || isYCbCr422Format(m_colorFormat)) ? 2 : 1;
184 	int	heightAlignment	= isYCbCr420Format(m_colorFormat) ? 2 : 1;
185 
186 	// Random small size for causing potential alignment issues
187 	m_size			= tcu::IVec2((deRandom_getUint32(&random) % 16 + 3) & ~(widthAlignment - 1),
188 								 (deRandom_getUint32(&random) % 16 + 3) & ~(heightAlignment - 1));
189 	// Pick random memory type from the supported set
190 	m_memoryType	= memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
191 }
192 
~ImageAllocator()193 ImageAllocator::~ImageAllocator ()
194 {
195 }
196 
allocate(Context & context)197 void ImageAllocator::allocate (Context& context)
198 {
199 	Allocator&						memAlloc	= context.getDefaultAllocator();
200 	de::MovePtr<IImageAllocator>	allocator;
201 	MemoryRequirement				requirement	= legalMemoryTypes[m_memoryType];
202 
203 	if (m_dedicated)
204 		allocator = de::MovePtr<IImageAllocator>(new ImageDedicatedAllocation);
205 	else
206 		allocator = de::MovePtr<IImageAllocator>(new ImageSuballocation);
207 
208 	allocator->createTestImage(
209 		m_size,
210 		m_colorFormat,
211 		context,
212 		memAlloc,
213 		m_image,
214 		requirement,
215 		m_imageAlloc,
216 		m_linear ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL);
217 }
218 
deallocate(Context & context)219 void ImageAllocator::deallocate (Context& context)
220 {
221 	const DeviceInterface&	vk		= context.getDeviceInterface();
222 	const VkDevice&			device	= context.getDevice();
223 
224 	vk.destroyImage(device, m_image.disown(), DE_NULL);
225 	m_imageAlloc.clear();
226 }
227 
getSize(Context & context)228 size_t ImageAllocator::getSize (Context &context)
229 {
230 	const DeviceInterface&	vk		= context.getDeviceInterface();
231 	const VkDevice&			device	= context.getDevice();
232 	VkMemoryRequirements	memReq;
233 
234 	vk.getImageMemoryRequirements(device, *m_image, &memReq);
235 
236 	return (size_t)memReq.size;
237 }
238 
239 class InvarianceInstance : public vkt::TestInstance
240 {
241 public:
242 							InvarianceInstance			(Context&		context,
243 														 const deUint32	seed);
244 	virtual					~InvarianceInstance			(void);
245 	virtual	tcu::TestStatus	iterate						(void);
246 private:
247 	deRandom	m_random;
248 };
249 
InvarianceInstance(Context & context,const deUint32 seed)250 InvarianceInstance::InvarianceInstance	(Context&		context,
251 										 const deUint32	seed)
252 	: vkt::TestInstance	(context)
253 {
254 	deRandom_init(&m_random, seed);
255 }
256 
~InvarianceInstance(void)257 InvarianceInstance::~InvarianceInstance (void)
258 {
259 }
260 
iterate(void)261 tcu::TestStatus InvarianceInstance::iterate (void)
262 {
263 	de::MovePtr<IObjectAllocator>			objs[testCycles];
264 	size_t									refSizes[testCycles];
265 	unsigned int							order[testCycles];
266 	bool									supported[testCycles];
267 	bool									allUnsupported					= true;
268 	bool									success							= true;
269 	const deBool							isDedicatedAllocationSupported	= m_context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation");
270 	const deBool							isYcbcrSupported				= m_context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion");
271 	const deBool							isYcbcrExtensionSupported		= m_context.isDeviceFunctionalitySupported("VK_EXT_ycbcr_2plane_444_formats");
272 	const deBool							isPvrtcSupported				= m_context.isDeviceFunctionalitySupported("VK_IMG_format_pvrtc");
273 #ifndef CTS_USES_VULKANSC
274 	const bool								isMaintenance5Supported			= m_context.isDeviceFunctionalitySupported("VK_KHR_maintenance5");
275 #endif // CTS_USES_VULKANSC
276 	std::vector<int>						optimalFormats;
277 	std::vector<int>						linearFormats;
278 	std::vector<int>						memoryTypes;
279 	vk::VkPhysicalDeviceMemoryProperties	memProperties;
280 
281 	// List of all VkFormat enums
282 	const unsigned int						formatlist[]					= {
283 		VK_FORMAT_UNDEFINED,
284 		VK_FORMAT_R4G4_UNORM_PACK8,
285 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
286 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
287 		VK_FORMAT_R5G6B5_UNORM_PACK16,
288 		VK_FORMAT_B5G6R5_UNORM_PACK16,
289 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
290 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
291 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
292 #ifndef CTS_USES_VULKANSC
293 		VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
294 #endif // CTS_USES_VULKANSC
295 		VK_FORMAT_R8_UNORM,
296 		VK_FORMAT_R8_SNORM,
297 		VK_FORMAT_R8_USCALED,
298 		VK_FORMAT_R8_SSCALED,
299 		VK_FORMAT_R8_UINT,
300 		VK_FORMAT_R8_SINT,
301 		VK_FORMAT_R8_SRGB,
302 #ifndef CTS_USES_VULKANSC
303 		VK_FORMAT_A8_UNORM_KHR,
304 #endif // CTS_USES_VULKANSC
305 		VK_FORMAT_R8G8_UNORM,
306 		VK_FORMAT_R8G8_SNORM,
307 		VK_FORMAT_R8G8_USCALED,
308 		VK_FORMAT_R8G8_SSCALED,
309 		VK_FORMAT_R8G8_UINT,
310 		VK_FORMAT_R8G8_SINT,
311 		VK_FORMAT_R8G8_SRGB,
312 		VK_FORMAT_R8G8B8_UNORM,
313 		VK_FORMAT_R8G8B8_SNORM,
314 		VK_FORMAT_R8G8B8_USCALED,
315 		VK_FORMAT_R8G8B8_SSCALED,
316 		VK_FORMAT_R8G8B8_UINT,
317 		VK_FORMAT_R8G8B8_SINT,
318 		VK_FORMAT_R8G8B8_SRGB,
319 		VK_FORMAT_B8G8R8_UNORM,
320 		VK_FORMAT_B8G8R8_SNORM,
321 		VK_FORMAT_B8G8R8_USCALED,
322 		VK_FORMAT_B8G8R8_SSCALED,
323 		VK_FORMAT_B8G8R8_UINT,
324 		VK_FORMAT_B8G8R8_SINT,
325 		VK_FORMAT_B8G8R8_SRGB,
326 		VK_FORMAT_R8G8B8A8_UNORM,
327 		VK_FORMAT_R8G8B8A8_SNORM,
328 		VK_FORMAT_R8G8B8A8_USCALED,
329 		VK_FORMAT_R8G8B8A8_SSCALED,
330 		VK_FORMAT_R8G8B8A8_UINT,
331 		VK_FORMAT_R8G8B8A8_SINT,
332 		VK_FORMAT_R8G8B8A8_SRGB,
333 		VK_FORMAT_B8G8R8A8_UNORM,
334 		VK_FORMAT_B8G8R8A8_SNORM,
335 		VK_FORMAT_B8G8R8A8_USCALED,
336 		VK_FORMAT_B8G8R8A8_SSCALED,
337 		VK_FORMAT_B8G8R8A8_UINT,
338 		VK_FORMAT_B8G8R8A8_SINT,
339 		VK_FORMAT_B8G8R8A8_SRGB,
340 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
341 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
342 		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
343 		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
344 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
345 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
346 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
347 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
348 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
349 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
350 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
351 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
352 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
353 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
354 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
355 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
356 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
357 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
358 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
359 		VK_FORMAT_R16_UNORM,
360 		VK_FORMAT_R16_SNORM,
361 		VK_FORMAT_R16_USCALED,
362 		VK_FORMAT_R16_SSCALED,
363 		VK_FORMAT_R16_UINT,
364 		VK_FORMAT_R16_SINT,
365 		VK_FORMAT_R16_SFLOAT,
366 		VK_FORMAT_R16G16_UNORM,
367 		VK_FORMAT_R16G16_SNORM,
368 		VK_FORMAT_R16G16_USCALED,
369 		VK_FORMAT_R16G16_SSCALED,
370 		VK_FORMAT_R16G16_UINT,
371 		VK_FORMAT_R16G16_SINT,
372 		VK_FORMAT_R16G16_SFLOAT,
373 		VK_FORMAT_R16G16B16_UNORM,
374 		VK_FORMAT_R16G16B16_SNORM,
375 		VK_FORMAT_R16G16B16_USCALED,
376 		VK_FORMAT_R16G16B16_SSCALED,
377 		VK_FORMAT_R16G16B16_UINT,
378 		VK_FORMAT_R16G16B16_SINT,
379 		VK_FORMAT_R16G16B16_SFLOAT,
380 		VK_FORMAT_R16G16B16A16_UNORM,
381 		VK_FORMAT_R16G16B16A16_SNORM,
382 		VK_FORMAT_R16G16B16A16_USCALED,
383 		VK_FORMAT_R16G16B16A16_SSCALED,
384 		VK_FORMAT_R16G16B16A16_UINT,
385 		VK_FORMAT_R16G16B16A16_SINT,
386 		VK_FORMAT_R16G16B16A16_SFLOAT,
387 		VK_FORMAT_R32_UINT,
388 		VK_FORMAT_R32_SINT,
389 		VK_FORMAT_R32_SFLOAT,
390 		VK_FORMAT_R32G32_UINT,
391 		VK_FORMAT_R32G32_SINT,
392 		VK_FORMAT_R32G32_SFLOAT,
393 		VK_FORMAT_R32G32B32_UINT,
394 		VK_FORMAT_R32G32B32_SINT,
395 		VK_FORMAT_R32G32B32_SFLOAT,
396 		VK_FORMAT_R32G32B32A32_UINT,
397 		VK_FORMAT_R32G32B32A32_SINT,
398 		VK_FORMAT_R32G32B32A32_SFLOAT,
399 		VK_FORMAT_R64_UINT,
400 		VK_FORMAT_R64_SINT,
401 		VK_FORMAT_R64_SFLOAT,
402 		VK_FORMAT_R64G64_UINT,
403 		VK_FORMAT_R64G64_SINT,
404 		VK_FORMAT_R64G64_SFLOAT,
405 		VK_FORMAT_R64G64B64_UINT,
406 		VK_FORMAT_R64G64B64_SINT,
407 		VK_FORMAT_R64G64B64_SFLOAT,
408 		VK_FORMAT_R64G64B64A64_UINT,
409 		VK_FORMAT_R64G64B64A64_SINT,
410 		VK_FORMAT_R64G64B64A64_SFLOAT,
411 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
412 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
413 		VK_FORMAT_D16_UNORM,
414 		VK_FORMAT_X8_D24_UNORM_PACK32,
415 		VK_FORMAT_D32_SFLOAT,
416 		VK_FORMAT_S8_UINT,
417 		VK_FORMAT_D16_UNORM_S8_UINT,
418 		VK_FORMAT_D24_UNORM_S8_UINT,
419 		VK_FORMAT_D32_SFLOAT_S8_UINT,
420 		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
421 		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
422 		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
423 		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
424 		VK_FORMAT_BC2_UNORM_BLOCK,
425 		VK_FORMAT_BC2_SRGB_BLOCK,
426 		VK_FORMAT_BC3_UNORM_BLOCK,
427 		VK_FORMAT_BC3_SRGB_BLOCK,
428 		VK_FORMAT_BC4_UNORM_BLOCK,
429 		VK_FORMAT_BC4_SNORM_BLOCK,
430 		VK_FORMAT_BC5_UNORM_BLOCK,
431 		VK_FORMAT_BC5_SNORM_BLOCK,
432 		VK_FORMAT_BC6H_UFLOAT_BLOCK,
433 		VK_FORMAT_BC6H_SFLOAT_BLOCK,
434 		VK_FORMAT_BC7_UNORM_BLOCK,
435 		VK_FORMAT_BC7_SRGB_BLOCK,
436 		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
437 		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
438 		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
439 		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
440 		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
441 		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
442 		VK_FORMAT_EAC_R11_UNORM_BLOCK,
443 		VK_FORMAT_EAC_R11_SNORM_BLOCK,
444 		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
445 		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
446 		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
447 		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
448 		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
449 		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
450 		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
451 		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
452 		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
453 		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
454 		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
455 		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
456 		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
457 		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
458 		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
459 		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
460 		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
461 		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
462 		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
463 		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
464 		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
465 		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
466 		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
467 		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
468 		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
469 		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
470 		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
471 		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
472 		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
473 		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
474 		VK_FORMAT_G8B8G8R8_422_UNORM,
475 		VK_FORMAT_B8G8R8G8_422_UNORM,
476 		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
477 		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
478 		VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
479 		VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
480 		VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
481 		VK_FORMAT_R10X6_UNORM_PACK16,
482 		VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
483 		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
484 		VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
485 		VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
486 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
487 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
488 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
489 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
490 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
491 		VK_FORMAT_R12X4_UNORM_PACK16,
492 		VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
493 		VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
494 		VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
495 		VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
496 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
497 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
498 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
499 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
500 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
501 		VK_FORMAT_G16B16G16R16_422_UNORM,
502 		VK_FORMAT_B16G16R16G16_422_UNORM,
503 		VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
504 		VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
505 		VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
506 		VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
507 		VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
508 #ifndef CTS_USES_VULKANSC
509 		// Removed from Vulkan SC test set: VK_IMG_format_pvrtc extension does not exist in Vulkan SC
510 		VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
511 		VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,
512 		VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,
513 		VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,
514 		VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,
515 		VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,
516 		VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,
517 		VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,
518 		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
519 		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
520 		VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,
521 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT,
522 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT,
523 		VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT,
524 #endif
525 	};
526 	int										formatCount						= (int)(sizeof(formatlist) / sizeof(unsigned int));
527 
528 	// Find supported image formats
529 	for (int i = 0; i < formatCount; i++)
530 	{
531 		if (isYCbCrFormat((VkFormat)formatlist[i]) && !isYcbcrSupported)
532 			continue;
533 
534 		if (isYCbCrExtensionFormat((VkFormat)formatlist[i]) && !isYcbcrExtensionSupported)
535 			continue;
536 
537 		if (isPvrtcFormat((VkFormat)formatlist[i]) && !isPvrtcSupported)
538 			continue;
539 
540 #ifndef CTS_USES_VULKANSC
541 		if (!isMaintenance5Supported)
542 		{
543 			if (formatlist[i] == VK_FORMAT_A8_UNORM_KHR ||
544 				formatlist[i] == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
545 				continue;
546 		}
547 #endif // CTS_USES_VULKANSC
548 
549 		vk::VkImageFormatProperties imageformatprops;
550 
551 		// Check for support in linear tiling mode
552 		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
553 			m_context.getPhysicalDevice(),
554 			(VkFormat)formatlist[i],
555 			VK_IMAGE_TYPE_2D,
556 			VK_IMAGE_TILING_LINEAR,
557 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
558 			0,
559 			&imageformatprops) == VK_SUCCESS)
560 			linearFormats.push_back(formatlist[i]);
561 
562 		// Check for support in optimal tiling mode
563 		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
564 			m_context.getPhysicalDevice(),
565 			(VkFormat)formatlist[i],
566 			VK_IMAGE_TYPE_2D,
567 			VK_IMAGE_TILING_OPTIMAL,
568 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
569 			0,
570 			&imageformatprops) == VK_SUCCESS)
571 			optimalFormats.push_back(formatlist[i]);
572 	}
573 
574 	// Check for supported heap types
575 	m_context.getInstanceInterface().getPhysicalDeviceMemoryProperties(m_context.getPhysicalDevice(), &memProperties);
576 
577 	for (unsigned int j = 0; j < legalMemoryTypeCount; j++)
578 	{
579 		bool found = false;
580 		for (unsigned int i = 0; !found && i < memProperties.memoryTypeCount; i++)
581 		{
582 			if (legalMemoryTypes[j].matchesHeap(memProperties.memoryTypes[i].propertyFlags))
583 			{
584 				memoryTypes.push_back(j);
585 				found = true;
586 			}
587 		}
588 	}
589 
590 	// Log the used image types and heap types
591 	tcu::TestLog& log = m_context.getTestContext().getLog();
592 
593 	{
594 		std::ostringstream values;
595 		for (unsigned int i = 0; i < linearFormats.size(); i++)
596 			values << " " << linearFormats[i];
597 		log << tcu::TestLog::Message << "Using linear formats:" << values.str() << tcu::TestLog::EndMessage;
598 	}
599 
600 	{
601 		std::ostringstream values;
602 		for (unsigned int i = 0; i < optimalFormats.size(); i++)
603 			values << " " << optimalFormats[i];
604 		log << tcu::TestLog::Message << "Using optimal formats:" << values.str() << tcu::TestLog::EndMessage;
605 	}
606 
607 	{
608 		std::ostringstream values;
609 		for (unsigned int i = 0; i < memoryTypes.size(); i++)
610 			values << " " << memoryTypes[i];
611 		log << tcu::TestLog::Message << "Using memory types:" << values.str() << tcu::TestLog::EndMessage;
612 	}
613 
614 	for (unsigned int i = 0; i < testCycles; i++)
615 	{
616 		if (deRandom_getBool(&m_random))
617 			objs[i] = de::MovePtr<IObjectAllocator>(new BufferAllocator(m_random, isDedicatedAllocationSupported, memoryTypes));
618 		else
619 			objs[i] = de::MovePtr<IObjectAllocator>(new ImageAllocator(m_random, isDedicatedAllocationSupported, linearFormats, optimalFormats, memoryTypes));
620 		order[i] = i;
621 	}
622 
623 	// First get reference values for the object sizes
624 	for (unsigned int i = 0; i < testCycles; i++)
625 	{
626 		try
627 		{
628 			objs[i]->allocate(m_context);
629 			refSizes[i] = objs[i]->getSize(m_context);
630 			objs[i]->deallocate(m_context);
631 			supported[i] = true;
632 			allUnsupported = false;
633 		}
634 		catch (const tcu::NotSupportedError&)
635 		{
636 			supported[i] = false;
637 		}
638 	}
639 
640 	if (allUnsupported)
641 		TCU_THROW(NotSupportedError, "All allocations unsupported");
642 
643 	// Shuffle order by swapping random pairs
644 	for (unsigned int i = 0; i < testCycles; i++)
645 	{
646 		int a = deRandom_getUint32(&m_random) % testCycles;
647 		int b = deRandom_getUint32(&m_random) % testCycles;
648 		std::swap(order[a], order[b]);
649 	}
650 
651 	// Allocate objects in shuffled order
652 	for (unsigned int i = 0; i < testCycles; i++)
653 	{
654 		if (supported[order[i]])
655 			objs[order[i]]->allocate(m_context);
656 	}
657 
658 	// Check for size mismatches
659 	for (unsigned int i = 0; i < testCycles; i++)
660 	{
661 		if (!supported[order[i]])
662 			continue;
663 
664 		size_t val = objs[order[i]]->getSize(m_context);
665 
666 		if (val != refSizes[order[i]])
667 		{
668 			success = false;
669 			log	<< tcu::TestLog::Message
670 				<< "Object "
671 				<< order[i]
672 				<< " size mismatch ("
673 				<< val
674 				<< " != "
675 				<< refSizes[order[i]]
676 				<< ")"
677 				<< tcu::TestLog::EndMessage;
678 		}
679 	}
680 
681 	// Clean up
682 	for (unsigned int i = 0; i < testCycles; i++)
683 	{
684 		if (supported[order[i]])
685 			objs[order[i]]->deallocate(m_context);
686 	}
687 
688 	if (success)
689 		return tcu::TestStatus::pass("Pass");
690 
691 	return tcu::TestStatus::fail("One or more allocation is not invariant");
692 }
693 
694 class AlignmentMatchingInstance : public vkt::TestInstance
695 {
696 public:
697 							AlignmentMatchingInstance	(Context& context);
698 	virtual					~AlignmentMatchingInstance	(void) = default;
699 	virtual	tcu::TestStatus	iterate						(void);
700 };
701 
AlignmentMatchingInstance(Context & context)702 AlignmentMatchingInstance::AlignmentMatchingInstance(Context& context)
703 	: vkt::TestInstance(context)
704 {
705 }
706 
iterate(void)707 tcu::TestStatus AlignmentMatchingInstance::iterate(void)
708 {
709 	const VkDevice			device			= m_context.getDevice();
710 	const DeviceInterface&	vk				= m_context.getDeviceInterface();
711 	const deUint32			objectsCount	= 5;
712 	tcu::TestLog&			log				= m_context.getTestContext().getLog();
713 	bool					success			= true;
714 	VkExtent3D				baseExtent		= { 32, 31, 1 };
715 	VkDeviceSize			baseSize		= 1023;
716 
717 	VkImageCreateInfo imageCreateInfo
718 	{
719 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
720 		DE_NULL,								// const void*			pNext;
721 		0u,										// VkImageCreateFlags	flags;
722 		VK_IMAGE_TYPE_2D,						// VkImageType			imageType;
723 		VK_FORMAT_R8G8B8A8_UNORM,				// VkFormat				format;
724 		baseExtent,								// VkExtent3D			extent;
725 		1u,										// deUint32				mipLevels;
726 		1u,										// deUint32				arraySize;
727 		VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
728 		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
729 		VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags	usage;
730 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
731 		0u,										// deUint32				queueFamilyCount;
732 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
733 		VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
734 	};
735 
736 	VkBufferCreateInfo bufferCreateInfo
737 	{
738 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
739 		DE_NULL,								// const void*			pNext
740 		0u,										// VkBufferCreateFlags	flags
741 		baseSize,								// VkDeviceSize			size
742 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage
743 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
744 		0u,										// uint32_t				queueFamilyIndexCount
745 		DE_NULL									// const uint32_t*		pQueueFamilyIndices
746 	};
747 
748 	Move<VkImage>			baseImage				= createImage (vk, device, &imageCreateInfo);
749 	Move<VkBuffer>			baseBuffer				= createBuffer(vk, device, &bufferCreateInfo);
750 
751 	VkMemoryRequirements	baseImageRequirements	= getImageMemoryRequirements (vk, device, *baseImage);
752 	VkMemoryRequirements	baseBufferRequirements	= getBufferMemoryRequirements(vk, device, *baseBuffer);
753 
754 	// Create a bunch of VkBuffer and VkImage objects with the same
755 	// create infos and make sure their alignments all match.
756 	{
757 		std::vector<Move<VkImage>>	images (objectsCount);
758 		std::vector<Move<VkBuffer>>	buffers(objectsCount);
759 
760 		for (deUint32 idx = 0; idx < objectsCount; ++idx)
761 		{
762 			images [idx]	= createImage (vk, device, &imageCreateInfo);
763 			buffers[idx]	= createBuffer(vk, device, &bufferCreateInfo);
764 
765 			VkMemoryRequirements imageRequirements		= getImageMemoryRequirements (vk, device, *images[idx]);
766 			VkMemoryRequirements buffersRequirements	= getBufferMemoryRequirements(vk, device, *buffers[idx]);
767 
768 			if (baseImageRequirements.alignment != imageRequirements.alignment)
769 			{
770 				success = false;
771 				log << tcu::TestLog::Message
772 					<< "Alignments for all VkImage objects created with the same create infos should match\n"
773 					<< tcu::TestLog::EndMessage;
774 			}
775 			if (baseBufferRequirements.alignment != buffersRequirements.alignment)
776 			{
777 				success = false;
778 				log << tcu::TestLog::Message
779 					<< "Alignments for all VkBuffer objects created with the same create infos should match\n"
780 					<< tcu::TestLog::EndMessage;
781 			}
782 		}
783 	}
784 
785 	if (m_context.isDeviceFunctionalitySupported("VK_KHR_get_memory_requirements2"))
786 	{
787 #ifndef CTS_USES_VULKANSC
788 		VkBufferMemoryRequirementsInfo2 bufferMemoryRequirementsInfo
789 		{
790 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,		// VkStructureType	sType
791 			DE_NULL,													// const void*		pNext
792 			*baseBuffer													// VkBuffer			buffer
793 		};
794 		VkImageMemoryRequirementsInfo2 imageMemoryRequirementsInfo
795 		{
796 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,			// VkStructureType	sType
797 			DE_NULL,													// const void*		pNext
798 			*baseImage													// VkImage			image
799 		};
800 		std::vector<VkMemoryRequirements2> requirements2(2,
801 			{
802 				VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,				// VkStructureType		sType
803 				DE_NULL,												// void*				pNext
804 				{0, 0, 0}												// VkMemoryRequirements	memoryRequirements
805 			});
806 
807 		auto areRequirementsTheSame = [](VkMemoryRequirements2& a, VkMemoryRequirements2& b)
808 		{
809 			return ((a.memoryRequirements.size == b.memoryRequirements.size) &&
810 					(a.memoryRequirements.alignment == b.memoryRequirements.alignment) &&
811 					(a.memoryRequirements.memoryTypeBits == b.memoryRequirements.memoryTypeBits));
812 		};
813 
814 		// The memory requirements returned by vkGetBufferCreateInfoMemoryRequirementsKHR are identical to those that
815 		// would be returned by vkGetBufferMemoryRequirements2 if it were called with a VkBuffer created with the same
816 		// VkBufferCreateInfo values.
817 		vk.getBufferMemoryRequirements2(device, &bufferMemoryRequirementsInfo, &requirements2[0]);
818 		const VkDeviceBufferMemoryRequirementsKHR bufferMemInfo =
819 		{
820 			VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR,
821 			DE_NULL,
822 			&bufferCreateInfo
823 		};
824 		vk.getDeviceBufferMemoryRequirements(device, &bufferMemInfo, &requirements2[1]);
825 
826 		if (!areRequirementsTheSame(requirements2[0], requirements2[1]))
827 		{
828 			success = false;
829 			log << tcu::TestLog::Message
830 				<< "vkGetDeviceBufferMemoryRequirements and vkGetBufferMemoryRequirements2\n"
831 				   "report diferent memory requirements\n"
832 				<< tcu::TestLog::EndMessage;
833 		}
834 
835 		// Similarly, vkGetImageCreateInfoMemoryRequirementsKHR will report the same memory requirements as
836 		// vkGetImageMemoryRequirements2 would if called with a VkImage created with the supplied VkImageCreateInfo
837 		vk.getImageMemoryRequirements2(device, &imageMemoryRequirementsInfo, &requirements2[0]);
838 		const VkDeviceImageMemoryRequirementsKHR imageMemInfo =
839 		{
840 			VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR,
841 			DE_NULL,
842 			&imageCreateInfo,
843 			vk::VkImageAspectFlagBits(0)
844 		};
845 		vk.getDeviceImageMemoryRequirements(device, &imageMemInfo, &requirements2[1]);
846 
847 		if (!areRequirementsTheSame(requirements2[0], requirements2[1]))
848 		{
849 			success = false;
850 			log << tcu::TestLog::Message
851 				<< "vkGetDeviceImageMemoryRequirements and vkGetImageMemoryRequirements2\n"
852 				   "report diferent memory requirements\n"
853 				<< tcu::TestLog::EndMessage;
854 		}
855 #endif // CTS_USES_VULKANSC
856 	}
857 
858 	// For a VkImage, the size memory requirement is never greater than that of another VkImage created with
859 	// a greater or equal extent dimension specified in VkImageCreateInfo, all other creation parameters being identical.
860 	// For a VkBuffer, the size memory requirement is never greater than that of another VkBuffer created with
861 	// a greater or equal size specified in VkBufferCreateInfo, all other creation parameters being identical.
862 	{
863 		std::vector<Move<VkImage>>	images (objectsCount);
864 		std::vector<Move<VkBuffer>>	buffers(objectsCount);
865 
866 		for (deUint32 idx = 0; idx < objectsCount; ++idx)
867 		{
868 			imageCreateInfo.extent	= { baseExtent.width + (idx % 2) * idx, baseExtent.height + idx, 1u };
869 			bufferCreateInfo.size	= baseSize + idx;
870 
871 			images [idx]	= createImage(vk, device, &imageCreateInfo);
872 			buffers[idx]	= createBuffer(vk, device, &bufferCreateInfo);
873 
874 			VkMemoryRequirements imageRequirements		= getImageMemoryRequirements(vk, device, *images[idx]);
875 			VkMemoryRequirements buffersRequirements	= getBufferMemoryRequirements(vk, device, *buffers[idx]);
876 
877 			if (baseImageRequirements.size > imageRequirements.size)
878 			{
879 				success = false;
880 				log << tcu::TestLog::Message
881 					<< "Size memory requiremen for VkImage should never be greater than that of another VkImage\n"
882 					   "created with a greater or equal extent dimension specified in VkImageCreateInfo when all\n"
883 					   "other creation parameters are identical\n"
884 					<< tcu::TestLog::EndMessage;
885 			}
886 			if (baseBufferRequirements.size > buffersRequirements.size)
887 			{
888 				success = false;
889 				log << tcu::TestLog::Message
890 					<< "Size memory requiremen for VkBuffer should never be greater than that of another VkBuffer\n"
891 					   "created with a greater or size specified in VkImageCreateInfo when all\n"
892 					   "other creation parameters are identical\n"
893 					<< tcu::TestLog::EndMessage;
894 			}
895 		}
896 	}
897 
898 	if (success)
899 		return tcu::TestStatus::pass("Pass");
900 
901 	return tcu::TestStatus::fail("Fail");
902 }
903 
904 enum TestType
905 {
906 	TT_BASIC_INVARIANCE = 0,
907 	TT_REQUIREMENTS_MATCHING
908 };
909 
910 class InvarianceCase : public vkt::TestCase
911 {
912 public:
913 							InvarianceCase	(tcu::TestContext&	testCtx,
914 											 const std::string&	name,
915 											 TestType			testType);
916 	virtual					~InvarianceCase	(void) = default;
917 
918 	virtual TestInstance*	createInstance	(Context&			context) const;
919 	virtual void			checkSupport	(Context& context) const;
920 
921 protected:
922 	TestType m_testType;
923 };
924 
InvarianceCase(tcu::TestContext & testCtx,const std::string & name,TestType testType)925 InvarianceCase::InvarianceCase	(tcu::TestContext&	testCtx,
926 								 const std::string&	name,
927 								 TestType			testType)
928 	: vkt::TestCase	(testCtx, name)
929 	, m_testType	(testType)
930 {
931 }
932 
createInstance(Context & context) const933 TestInstance* InvarianceCase::createInstance (Context& context) const
934 {
935 	if (TT_REQUIREMENTS_MATCHING == m_testType)
936 		return new AlignmentMatchingInstance(context);
937 
938 	return new InvarianceInstance(context, 0x600613);
939 }
940 
checkSupport(Context & context) const941 void InvarianceCase::checkSupport(Context& context) const
942 {
943 	if (TT_REQUIREMENTS_MATCHING == m_testType)
944 		context.requireDeviceFunctionality("VK_KHR_maintenance4");
945 }
946 
createMemoryRequirementInvarianceTests(tcu::TestContext & testCtx)947 tcu::TestCaseGroup* createMemoryRequirementInvarianceTests (tcu::TestContext& testCtx)
948 {
949 	de::MovePtr<tcu::TestCaseGroup> invarianceTests(new tcu::TestCaseGroup(testCtx, "invariance"));
950 
951 	invarianceTests->addChild(new InvarianceCase(testCtx, "random", TT_BASIC_INVARIANCE));
952 	invarianceTests->addChild(new InvarianceCase(testCtx, "memory_requirements_matching", TT_REQUIREMENTS_MATCHING));
953 
954 	return invarianceTests.release();
955 }
956 
957 } // api
958 } // vkt
959