1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2018 Google Inc.
6 * Copyright (c) 2018 The Khronos Group Inc.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 *//*--------------------------------------------------------------------*/
22 #include "vktApiMemoryRequirementInvarianceTests.hpp"
23 #include "vktApiBufferAndImageAllocationUtil.hpp"
25 #include "tcuTestLog.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vkMemUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkImageUtil.hpp"
39 // Number of items to allocate
40 const unsigned int testCycles = 1000u;
42 // All legal memory combinations (spec chapter 10.2: Device Memory)
43 const unsigned int legalMemoryTypeCount = 11u;
44 const MemoryRequirement legalMemoryTypes[legalMemoryTypeCount] =
46 MemoryRequirement::Any,
47 MemoryRequirement::HostVisible | MemoryRequirement::Coherent,
48 MemoryRequirement::HostVisible | MemoryRequirement::Cached,
49 MemoryRequirement::HostVisible | MemoryRequirement::Cached | MemoryRequirement::Coherent,
50 MemoryRequirement::Local,
51 MemoryRequirement::Local | MemoryRequirement::HostVisible | MemoryRequirement::Coherent,
52 MemoryRequirement::Local | MemoryRequirement::HostVisible | MemoryRequirement::Cached,
53 MemoryRequirement::Local | MemoryRequirement::HostVisible | MemoryRequirement::Cached | MemoryRequirement::Coherent,
54 MemoryRequirement::Local | MemoryRequirement::LazilyAllocated,
55 MemoryRequirement::Protected,
56 MemoryRequirement::Protected | MemoryRequirement::Local
59 class IObjectAllocator
62 IObjectAllocator () {};
63 virtual ~IObjectAllocator () {};
64 virtual void allocate (Context& context) = 0;
65 virtual void deallocate (Context& context) = 0;
66 virtual size_t getSize (Context& context) = 0;
69 class BufferAllocator : public IObjectAllocator
72 BufferAllocator (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes);
73 virtual ~BufferAllocator ();
74 virtual void allocate (Context& context);
75 virtual void deallocate (Context& context);
76 virtual size_t getSize (Context& context);
79 Move<VkBuffer> m_buffer;
81 VkBufferUsageFlags m_usage;
83 de::MovePtr<Allocation> m_bufferAlloc;
86 BufferAllocator::BufferAllocator (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes)
88 // If dedicated allocation is supported, randomly pick it
89 m_dedicated = dedicated && deRandom_getBool(&random);
90 // Random buffer sizes to find potential issues caused by strange alignment
91 m_size = (deRandom_getUint32(&random) % 1024) + 7;
92 // Pick a random usage from the 9 VkBufferUsageFlags.
93 m_usage = 1 << (deRandom_getUint32(&random) % 9);
94 // Pick random memory type from the supported ones
95 m_memoryType = memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
98 BufferAllocator::~BufferAllocator ()
102 void BufferAllocator::allocate (Context& context)
104 Allocator& memAlloc = context.getDefaultAllocator();
105 IBufferAllocator* allocator = 0;
106 MemoryRequirement requirement = legalMemoryTypes[m_memoryType];
109 allocator = new BufferDedicatedAllocation;
111 allocator = new BufferSuballocation;
113 allocator->createTestBuffer(
125 void BufferAllocator::deallocate (Context& context)
127 const DeviceInterface& vk = context.getDeviceInterface();
128 const vk::VkDevice& device = context.getDevice();
130 vk.destroyBuffer(device, m_buffer.disown(), DE_NULL);
131 vk.freeMemory(device, m_bufferAlloc.get()->getMemory(), (const VkAllocationCallbacks*)DE_NULL);
132 m_bufferAlloc.release();
135 size_t BufferAllocator::getSize (Context &context)
137 const DeviceInterface& vk = context.getDeviceInterface();
138 const vk::VkDevice& device = context.getDevice();
139 VkMemoryRequirements memReq;
141 vk.getBufferMemoryRequirements(device, *m_buffer, &memReq);
143 return (size_t)memReq.size;
146 class ImageAllocator : public IObjectAllocator
149 ImageAllocator (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes);
150 virtual ~ImageAllocator ();
151 virtual void allocate (Context& context);
152 virtual void deallocate (Context& context);
153 virtual size_t getSize (Context& context);
157 Move<vk::VkImage> m_image;
159 vk::VkFormat m_colorFormat;
160 de::MovePtr<Allocation> m_imageAlloc;
164 ImageAllocator::ImageAllocator (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes)
166 // If dedicated allocation is supported, pick it randomly
167 m_dedicated = dedicated && deRandom_getBool(&random);
168 // If linear formats are supported, pick it randomly
169 m_linear = (linearformats.size() > 0) && deRandom_getBool(&random);
172 m_colorFormat = (VkFormat)linearformats[deRandom_getUint32(&random) % linearformats.size()];
174 m_colorFormat = (VkFormat)optimalformats[deRandom_getUint32(&random) % optimalformats.size()];
176 int widthAlignment = (isYCbCr420Format(m_colorFormat) || isYCbCr422Format(m_colorFormat)) ? 2 : 1;
177 int heightAlignment = isYCbCr420Format(m_colorFormat) ? 2 : 1;
179 // Random small size for causing potential alignment issues
180 m_size = tcu::IVec2((deRandom_getUint32(&random) % 16 + 3) & ~(widthAlignment - 1),
181 (deRandom_getUint32(&random) % 16 + 3) & ~(heightAlignment - 1));
182 // Pick random memory type from the supported set
183 m_memoryType = memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
186 ImageAllocator::~ImageAllocator ()
190 void ImageAllocator::allocate (Context& context)
192 Allocator& memAlloc = context.getDefaultAllocator();
193 IImageAllocator* allocator = 0;
194 MemoryRequirement requirement = legalMemoryTypes[m_memoryType];
197 allocator = new ImageDedicatedAllocation;
199 allocator = new ImageSuballocation;
201 allocator->createTestImage(
209 m_linear ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL);
214 void ImageAllocator::deallocate (Context& context)
216 const DeviceInterface& vk = context.getDeviceInterface();
217 const VkDevice& device = context.getDevice();
219 vk.destroyImage(device, m_image.disown(), DE_NULL);
220 vk.freeMemory(device, m_imageAlloc.get()->getMemory(), (const VkAllocationCallbacks*)DE_NULL);
221 m_imageAlloc.release();
224 size_t ImageAllocator::getSize (Context &context)
226 const DeviceInterface& vk = context.getDeviceInterface();
227 const VkDevice& device = context.getDevice();
228 VkMemoryRequirements memReq;
230 vk.getImageMemoryRequirements(device, *m_image, &memReq);
232 return (size_t)memReq.size;
235 class InvarianceInstance : public vkt::TestInstance
238 InvarianceInstance (Context& context,
239 const deUint32 seed);
240 virtual ~InvarianceInstance (void);
241 virtual tcu::TestStatus iterate (void);
246 InvarianceInstance::InvarianceInstance (Context& context,
248 : vkt::TestInstance (context)
250 deRandom_init(&m_random, seed);
253 InvarianceInstance::~InvarianceInstance (void)
257 tcu::TestStatus InvarianceInstance::iterate (void)
259 IObjectAllocator* objs[testCycles];
260 size_t refSizes[testCycles];
261 unsigned int order[testCycles];
263 const std::vector<std::string>& extensions = m_context.getDeviceExtensions();
264 const deBool isDedicatedAllocationSupported =
265 isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_dedicated_allocation");
266 const deBool isYcbcrSupported =
267 isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_sampler_ycbcr_conversion");
268 std::vector<int> optimalFormats;
269 std::vector<int> linearFormats;
270 std::vector<int> memoryTypes;
271 vk::VkPhysicalDeviceMemoryProperties memProperties;
273 // List of all VkFormat enums
274 const unsigned int formatlist[] = {
276 VK_FORMAT_R4G4_UNORM_PACK8,
277 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
278 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
279 VK_FORMAT_R5G6B5_UNORM_PACK16,
280 VK_FORMAT_B5G6R5_UNORM_PACK16,
281 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
282 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
283 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
286 VK_FORMAT_R8_USCALED,
287 VK_FORMAT_R8_SSCALED,
291 VK_FORMAT_R8G8_UNORM,
292 VK_FORMAT_R8G8_SNORM,
293 VK_FORMAT_R8G8_USCALED,
294 VK_FORMAT_R8G8_SSCALED,
298 VK_FORMAT_R8G8B8_UNORM,
299 VK_FORMAT_R8G8B8_SNORM,
300 VK_FORMAT_R8G8B8_USCALED,
301 VK_FORMAT_R8G8B8_SSCALED,
302 VK_FORMAT_R8G8B8_UINT,
303 VK_FORMAT_R8G8B8_SINT,
304 VK_FORMAT_R8G8B8_SRGB,
305 VK_FORMAT_B8G8R8_UNORM,
306 VK_FORMAT_B8G8R8_SNORM,
307 VK_FORMAT_B8G8R8_USCALED,
308 VK_FORMAT_B8G8R8_SSCALED,
309 VK_FORMAT_B8G8R8_UINT,
310 VK_FORMAT_B8G8R8_SINT,
311 VK_FORMAT_B8G8R8_SRGB,
312 VK_FORMAT_R8G8B8A8_UNORM,
313 VK_FORMAT_R8G8B8A8_SNORM,
314 VK_FORMAT_R8G8B8A8_USCALED,
315 VK_FORMAT_R8G8B8A8_SSCALED,
316 VK_FORMAT_R8G8B8A8_UINT,
317 VK_FORMAT_R8G8B8A8_SINT,
318 VK_FORMAT_R8G8B8A8_SRGB,
319 VK_FORMAT_B8G8R8A8_UNORM,
320 VK_FORMAT_B8G8R8A8_SNORM,
321 VK_FORMAT_B8G8R8A8_USCALED,
322 VK_FORMAT_B8G8R8A8_SSCALED,
323 VK_FORMAT_B8G8R8A8_UINT,
324 VK_FORMAT_B8G8R8A8_SINT,
325 VK_FORMAT_B8G8R8A8_SRGB,
326 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
327 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
328 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
329 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
330 VK_FORMAT_A8B8G8R8_UINT_PACK32,
331 VK_FORMAT_A8B8G8R8_SINT_PACK32,
332 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
333 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
334 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
335 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
336 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
337 VK_FORMAT_A2R10G10B10_UINT_PACK32,
338 VK_FORMAT_A2R10G10B10_SINT_PACK32,
339 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
340 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
341 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
342 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
343 VK_FORMAT_A2B10G10R10_UINT_PACK32,
344 VK_FORMAT_A2B10G10R10_SINT_PACK32,
347 VK_FORMAT_R16_USCALED,
348 VK_FORMAT_R16_SSCALED,
351 VK_FORMAT_R16_SFLOAT,
352 VK_FORMAT_R16G16_UNORM,
353 VK_FORMAT_R16G16_SNORM,
354 VK_FORMAT_R16G16_USCALED,
355 VK_FORMAT_R16G16_SSCALED,
356 VK_FORMAT_R16G16_UINT,
357 VK_FORMAT_R16G16_SINT,
358 VK_FORMAT_R16G16_SFLOAT,
359 VK_FORMAT_R16G16B16_UNORM,
360 VK_FORMAT_R16G16B16_SNORM,
361 VK_FORMAT_R16G16B16_USCALED,
362 VK_FORMAT_R16G16B16_SSCALED,
363 VK_FORMAT_R16G16B16_UINT,
364 VK_FORMAT_R16G16B16_SINT,
365 VK_FORMAT_R16G16B16_SFLOAT,
366 VK_FORMAT_R16G16B16A16_UNORM,
367 VK_FORMAT_R16G16B16A16_SNORM,
368 VK_FORMAT_R16G16B16A16_USCALED,
369 VK_FORMAT_R16G16B16A16_SSCALED,
370 VK_FORMAT_R16G16B16A16_UINT,
371 VK_FORMAT_R16G16B16A16_SINT,
372 VK_FORMAT_R16G16B16A16_SFLOAT,
375 VK_FORMAT_R32_SFLOAT,
376 VK_FORMAT_R32G32_UINT,
377 VK_FORMAT_R32G32_SINT,
378 VK_FORMAT_R32G32_SFLOAT,
379 VK_FORMAT_R32G32B32_UINT,
380 VK_FORMAT_R32G32B32_SINT,
381 VK_FORMAT_R32G32B32_SFLOAT,
382 VK_FORMAT_R32G32B32A32_UINT,
383 VK_FORMAT_R32G32B32A32_SINT,
384 VK_FORMAT_R32G32B32A32_SFLOAT,
387 VK_FORMAT_R64_SFLOAT,
388 VK_FORMAT_R64G64_UINT,
389 VK_FORMAT_R64G64_SINT,
390 VK_FORMAT_R64G64_SFLOAT,
391 VK_FORMAT_R64G64B64_UINT,
392 VK_FORMAT_R64G64B64_SINT,
393 VK_FORMAT_R64G64B64_SFLOAT,
394 VK_FORMAT_R64G64B64A64_UINT,
395 VK_FORMAT_R64G64B64A64_SINT,
396 VK_FORMAT_R64G64B64A64_SFLOAT,
397 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
398 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
400 VK_FORMAT_X8_D24_UNORM_PACK32,
401 VK_FORMAT_D32_SFLOAT,
403 VK_FORMAT_D16_UNORM_S8_UINT,
404 VK_FORMAT_D24_UNORM_S8_UINT,
405 VK_FORMAT_D32_SFLOAT_S8_UINT,
406 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
407 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
408 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
409 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
410 VK_FORMAT_BC2_UNORM_BLOCK,
411 VK_FORMAT_BC2_SRGB_BLOCK,
412 VK_FORMAT_BC3_UNORM_BLOCK,
413 VK_FORMAT_BC3_SRGB_BLOCK,
414 VK_FORMAT_BC4_UNORM_BLOCK,
415 VK_FORMAT_BC4_SNORM_BLOCK,
416 VK_FORMAT_BC5_UNORM_BLOCK,
417 VK_FORMAT_BC5_SNORM_BLOCK,
418 VK_FORMAT_BC6H_UFLOAT_BLOCK,
419 VK_FORMAT_BC6H_SFLOAT_BLOCK,
420 VK_FORMAT_BC7_UNORM_BLOCK,
421 VK_FORMAT_BC7_SRGB_BLOCK,
422 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
423 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
424 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
425 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
426 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
427 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
428 VK_FORMAT_EAC_R11_UNORM_BLOCK,
429 VK_FORMAT_EAC_R11_SNORM_BLOCK,
430 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
431 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
432 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
433 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
434 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
435 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
436 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
437 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
438 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
439 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
440 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
441 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
442 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
443 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
444 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
445 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
446 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
447 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
448 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
449 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
450 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
451 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
452 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
453 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
454 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
455 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
456 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
457 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
458 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
459 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
460 VK_FORMAT_G8B8G8R8_422_UNORM,
461 VK_FORMAT_B8G8R8G8_422_UNORM,
462 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
463 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
464 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
465 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
466 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
467 VK_FORMAT_R10X6_UNORM_PACK16,
468 VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
469 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
470 VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
471 VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
472 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
473 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
474 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
475 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
476 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
477 VK_FORMAT_R12X4_UNORM_PACK16,
478 VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
479 VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
480 VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
481 VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
482 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
483 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
484 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
485 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
486 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
487 VK_FORMAT_G16B16G16R16_422_UNORM,
488 VK_FORMAT_B16G16R16G16_422_UNORM,
489 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
490 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
491 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
492 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
493 VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
494 VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
495 VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,
496 VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,
497 VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,
498 VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,
499 VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,
500 VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,
501 VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG
503 int formatCount = (int)(sizeof(formatlist) / sizeof(unsigned int));
505 // If ycbcr is not supported, only use the standard texture formats
506 if (!isYcbcrSupported)
509 // Find supported image formats
510 for (int i = 0; i < formatCount; i++)
512 vk::VkImageFormatProperties imageformatprops;
514 // Check for support in linear tiling mode
515 if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
516 m_context.getPhysicalDevice(),
517 (VkFormat)formatlist[i],
519 VK_IMAGE_TILING_LINEAR,
520 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
522 &imageformatprops) == VK_SUCCESS)
523 linearFormats.push_back(formatlist[i]);
525 // Check for support in optimal tiling mode
526 if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
527 m_context.getPhysicalDevice(),
528 (VkFormat)formatlist[i],
530 VK_IMAGE_TILING_OPTIMAL,
531 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
533 &imageformatprops) == VK_SUCCESS)
534 optimalFormats.push_back(formatlist[i]);
537 // Check for supported heap types
538 m_context.getInstanceInterface().getPhysicalDeviceMemoryProperties(m_context.getPhysicalDevice(), &memProperties);
540 for (unsigned int j = 0; j < legalMemoryTypeCount; j++)
543 for (unsigned int i = 0; !found && i < memProperties.memoryTypeCount; i++)
545 if (legalMemoryTypes[j].matchesHeap(memProperties.memoryTypes[i].propertyFlags))
547 memoryTypes.push_back(j);
553 // Log the used image types and heap types
554 tcu::TestLog& log = m_context.getTestContext().getLog();
557 std::ostringstream values;
558 for (unsigned int i = 0; i < linearFormats.size(); i++)
559 values << " " << linearFormats[i];
560 log << tcu::TestLog::Message << "Using linear formats:" << values.str() << tcu::TestLog::EndMessage;
564 std::ostringstream values;
565 for (unsigned int i = 0; i < optimalFormats.size(); i++)
566 values << " " << optimalFormats[i];
567 log << tcu::TestLog::Message << "Using optimal formats:" << values.str() << tcu::TestLog::EndMessage;
571 std::ostringstream values;
572 for (unsigned int i = 0; i < memoryTypes.size(); i++)
573 values << " " << memoryTypes[i];
574 log << tcu::TestLog::Message << "Using memory types:" << values.str() << tcu::TestLog::EndMessage;
577 for (unsigned int i = 0; i < testCycles; i++)
579 if (deRandom_getBool(&m_random))
580 objs[i] = new BufferAllocator(m_random, isDedicatedAllocationSupported, memoryTypes);
582 objs[i] = new ImageAllocator(m_random, isDedicatedAllocationSupported, linearFormats, optimalFormats, memoryTypes);
586 // First get reference values for the object sizes
587 for (unsigned int i = 0; i < testCycles; i++)
589 objs[i]->allocate(m_context);
590 refSizes[i] = objs[i]->getSize(m_context);
591 objs[i]->deallocate(m_context);
594 // Shuffle order by swapping random pairs
595 for (unsigned int i = 0; i < testCycles; i++)
597 int a = deRandom_getUint32(&m_random) % testCycles;
598 int b = deRandom_getUint32(&m_random) % testCycles;
599 DE_SWAP(int, order[a], order[b]);
602 // Allocate objects in shuffled order
603 for (unsigned int i = 0; i < testCycles; i++)
604 objs[order[i]]->allocate(m_context);
606 // Check for size mismatches
607 for (unsigned int i = 0; i < testCycles; i++)
609 size_t val = objs[order[i]]->getSize(m_context);
611 if (val != refSizes[order[i]])
614 log << tcu::TestLog::Message
617 << " size mismatch ("
620 << refSizes[order[i]]
622 << tcu::TestLog::EndMessage;
627 for (unsigned int i = 0; i < testCycles; i++)
628 objs[order[i]]->deallocate(m_context);
631 return tcu::TestStatus::pass("Pass");
633 return tcu::TestStatus::fail("One or more allocation is not invariant");
636 class InvarianceCase : public vkt::TestCase
639 InvarianceCase (tcu::TestContext& testCtx,
640 const std::string& name,
641 const std::string& description);
642 virtual ~InvarianceCase (void);
644 virtual TestInstance* createInstance (Context& context) const;
647 InvarianceCase::InvarianceCase (tcu::TestContext& testCtx,
648 const std::string& name,
649 const std::string& description)
650 : vkt::TestCase(testCtx, name, description)
654 InvarianceCase::~InvarianceCase()
658 TestInstance* InvarianceCase::createInstance (Context& context) const
660 return new InvarianceInstance(context, 0x600613);
663 tcu::TestCaseGroup* createMemoryRequirementInvarianceTests (tcu::TestContext& testCtx)
665 de::MovePtr<tcu::TestCaseGroup> invarianceTests(new tcu::TestCaseGroup(testCtx, "invariance", "Memory requirement invariance tests"));
667 // Only one child, leaving room for potential targeted cases later on.
668 invarianceTests->addChild(new InvarianceCase(testCtx, "random", std::string("Random case")));
670 return invarianceTests.release();