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