blob: ecec39ad62a8d2b28e9285911dfba79493eb4b8b [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 Google Inc.
* Copyright (c) 2018 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*--------------------------------------------------------------------*/
#include "vktApiMemoryRequirementInvarianceTests.hpp"
#include "vktApiBufferAndImageAllocationUtil.hpp"
#include "deRandom.h"
#include "tcuTestLog.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkImageUtil.hpp"
namespace vkt
{
namespace api
{
using namespace vk;
// Number of items to allocate
const unsigned int testCycles = 1000u;
// All legal memory combinations (spec chapter 10.2: Device Memory)
const unsigned int legalMemoryTypeCount = 11u;
const MemoryRequirement legalMemoryTypes[legalMemoryTypeCount] =
{
MemoryRequirement::Any,
MemoryRequirement::HostVisible | MemoryRequirement::Coherent,
MemoryRequirement::HostVisible | MemoryRequirement::Cached,
MemoryRequirement::HostVisible | MemoryRequirement::Cached | MemoryRequirement::Coherent,
MemoryRequirement::Local,
MemoryRequirement::Local | MemoryRequirement::HostVisible | MemoryRequirement::Coherent,
MemoryRequirement::Local | MemoryRequirement::HostVisible | MemoryRequirement::Cached,
MemoryRequirement::Local | MemoryRequirement::HostVisible | MemoryRequirement::Cached | MemoryRequirement::Coherent,
MemoryRequirement::Local | MemoryRequirement::LazilyAllocated,
MemoryRequirement::Protected,
MemoryRequirement::Protected | MemoryRequirement::Local
};
class IObjectAllocator
{
public:
IObjectAllocator () {};
virtual ~IObjectAllocator () {};
virtual void allocate (Context& context) = 0;
virtual void deallocate (Context& context) = 0;
virtual size_t getSize (Context& context) = 0;
};
class BufferAllocator : public IObjectAllocator
{
public:
BufferAllocator (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes);
virtual ~BufferAllocator ();
virtual void allocate (Context& context);
virtual void deallocate (Context& context);
virtual size_t getSize (Context& context);
private:
bool m_dedicated;
Move<VkBuffer> m_buffer;
VkDeviceSize m_size;
VkBufferUsageFlags m_usage;
int m_memoryType;
de::MovePtr<Allocation> m_bufferAlloc;
};
BufferAllocator::BufferAllocator (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes)
{
// If dedicated allocation is supported, randomly pick it
m_dedicated = dedicated && deRandom_getBool(&random);
// Random buffer sizes to find potential issues caused by strange alignment
m_size = (deRandom_getUint32(&random) % 1024) + 7;
// Pick a random usage from the 9 VkBufferUsageFlags.
m_usage = 1 << (deRandom_getUint32(&random) % 9);
// Pick random memory type from the supported ones
m_memoryType = memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
}
BufferAllocator::~BufferAllocator ()
{
}
void BufferAllocator::allocate (Context& context)
{
Allocator& memAlloc = context.getDefaultAllocator();
IBufferAllocator* allocator = 0;
MemoryRequirement requirement = legalMemoryTypes[m_memoryType];
if (m_dedicated)
allocator = new BufferDedicatedAllocation;
else
allocator = new BufferSuballocation;
allocator->createTestBuffer(
m_size,
m_usage,
context,
memAlloc,
m_buffer,
requirement,
m_bufferAlloc);
delete allocator;
}
void BufferAllocator::deallocate (Context& context)
{
const DeviceInterface& vk = context.getDeviceInterface();
const vk::VkDevice& device = context.getDevice();
vk.destroyBuffer(device, m_buffer.disown(), DE_NULL);
vk.freeMemory(device, m_bufferAlloc.get()->getMemory(), (const VkAllocationCallbacks*)DE_NULL);
m_bufferAlloc.release();
}
size_t BufferAllocator::getSize (Context &context)
{
const DeviceInterface& vk = context.getDeviceInterface();
const vk::VkDevice& device = context.getDevice();
VkMemoryRequirements memReq;
vk.getBufferMemoryRequirements(device, *m_buffer, &memReq);
return (size_t)memReq.size;
}
class ImageAllocator : public IObjectAllocator
{
public:
ImageAllocator (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes);
virtual ~ImageAllocator ();
virtual void allocate (Context& context);
virtual void deallocate (Context& context);
virtual size_t getSize (Context& context);
private:
deBool m_dedicated;
deBool m_linear;
Move<vk::VkImage> m_image;
tcu::IVec2 m_size;
vk::VkFormat m_colorFormat;
de::MovePtr<Allocation> m_imageAlloc;
int m_memoryType;
};
ImageAllocator::ImageAllocator (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes)
{
// If dedicated allocation is supported, pick it randomly
m_dedicated = dedicated && deRandom_getBool(&random);
// If linear formats are supported, pick it randomly
m_linear = (linearformats.size() > 0) && deRandom_getBool(&random);
if (m_linear)
m_colorFormat = (VkFormat)linearformats[deRandom_getUint32(&random) % linearformats.size()];
else
m_colorFormat = (VkFormat)optimalformats[deRandom_getUint32(&random) % optimalformats.size()];
int widthAlignment = (isYCbCr420Format(m_colorFormat) || isYCbCr422Format(m_colorFormat)) ? 2 : 1;
int heightAlignment = isYCbCr420Format(m_colorFormat) ? 2 : 1;
// Random small size for causing potential alignment issues
m_size = tcu::IVec2((deRandom_getUint32(&random) % 16 + 3) & ~(widthAlignment - 1),
(deRandom_getUint32(&random) % 16 + 3) & ~(heightAlignment - 1));
// Pick random memory type from the supported set
m_memoryType = memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
}
ImageAllocator::~ImageAllocator ()
{
}
void ImageAllocator::allocate (Context& context)
{
Allocator& memAlloc = context.getDefaultAllocator();
IImageAllocator* allocator = 0;
MemoryRequirement requirement = legalMemoryTypes[m_memoryType];
if (m_dedicated)
allocator = new ImageDedicatedAllocation;
else
allocator = new ImageSuballocation;
allocator->createTestImage(
m_size,
m_colorFormat,
context,
memAlloc,
m_image,
requirement,
m_imageAlloc,
m_linear ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL);
delete allocator;
}
void ImageAllocator::deallocate (Context& context)
{
const DeviceInterface& vk = context.getDeviceInterface();
const VkDevice& device = context.getDevice();
vk.destroyImage(device, m_image.disown(), DE_NULL);
vk.freeMemory(device, m_imageAlloc.get()->getMemory(), (const VkAllocationCallbacks*)DE_NULL);
m_imageAlloc.release();
}
size_t ImageAllocator::getSize (Context &context)
{
const DeviceInterface& vk = context.getDeviceInterface();
const VkDevice& device = context.getDevice();
VkMemoryRequirements memReq;
vk.getImageMemoryRequirements(device, *m_image, &memReq);
return (size_t)memReq.size;
}
class InvarianceInstance : public vkt::TestInstance
{
public:
InvarianceInstance (Context& context,
const deUint32 seed);
virtual ~InvarianceInstance (void);
virtual tcu::TestStatus iterate (void);
private:
deRandom m_random;
};
InvarianceInstance::InvarianceInstance (Context& context,
const deUint32 seed)
: vkt::TestInstance (context)
{
deRandom_init(&m_random, seed);
}
InvarianceInstance::~InvarianceInstance (void)
{
}
tcu::TestStatus InvarianceInstance::iterate (void)
{
IObjectAllocator* objs[testCycles];
size_t refSizes[testCycles];
unsigned int order[testCycles];
bool success = true;
const deBool isDedicatedAllocationSupported =
m_context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation");
const deBool isYcbcrSupported =
m_context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion");
std::vector<int> optimalFormats;
std::vector<int> linearFormats;
std::vector<int> memoryTypes;
vk::VkPhysicalDeviceMemoryProperties memProperties;
// List of all VkFormat enums
const unsigned int formatlist[] = {
VK_FORMAT_UNDEFINED,
VK_FORMAT_R4G4_UNORM_PACK8,
VK_FORMAT_R4G4B4A4_UNORM_PACK16,
VK_FORMAT_B4G4R4A4_UNORM_PACK16,
VK_FORMAT_R5G6B5_UNORM_PACK16,
VK_FORMAT_B5G6R5_UNORM_PACK16,
VK_FORMAT_R5G5B5A1_UNORM_PACK16,
VK_FORMAT_B5G5R5A1_UNORM_PACK16,
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
VK_FORMAT_R8_UNORM,
VK_FORMAT_R8_SNORM,
VK_FORMAT_R8_USCALED,
VK_FORMAT_R8_SSCALED,
VK_FORMAT_R8_UINT,
VK_FORMAT_R8_SINT,
VK_FORMAT_R8_SRGB,
VK_FORMAT_R8G8_UNORM,
VK_FORMAT_R8G8_SNORM,
VK_FORMAT_R8G8_USCALED,
VK_FORMAT_R8G8_SSCALED,
VK_FORMAT_R8G8_UINT,
VK_FORMAT_R8G8_SINT,
VK_FORMAT_R8G8_SRGB,
VK_FORMAT_R8G8B8_UNORM,
VK_FORMAT_R8G8B8_SNORM,
VK_FORMAT_R8G8B8_USCALED,
VK_FORMAT_R8G8B8_SSCALED,
VK_FORMAT_R8G8B8_UINT,
VK_FORMAT_R8G8B8_SINT,
VK_FORMAT_R8G8B8_SRGB,
VK_FORMAT_B8G8R8_UNORM,
VK_FORMAT_B8G8R8_SNORM,
VK_FORMAT_B8G8R8_USCALED,
VK_FORMAT_B8G8R8_SSCALED,
VK_FORMAT_B8G8R8_UINT,
VK_FORMAT_B8G8R8_SINT,
VK_FORMAT_B8G8R8_SRGB,
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_R8G8B8A8_SNORM,
VK_FORMAT_R8G8B8A8_USCALED,
VK_FORMAT_R8G8B8A8_SSCALED,
VK_FORMAT_R8G8B8A8_UINT,
VK_FORMAT_R8G8B8A8_SINT,
VK_FORMAT_R8G8B8A8_SRGB,
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_B8G8R8A8_SNORM,
VK_FORMAT_B8G8R8A8_USCALED,
VK_FORMAT_B8G8R8A8_SSCALED,
VK_FORMAT_B8G8R8A8_UINT,
VK_FORMAT_B8G8R8A8_SINT,
VK_FORMAT_B8G8R8A8_SRGB,
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
VK_FORMAT_A8B8G8R8_SNORM_PACK32,
VK_FORMAT_A8B8G8R8_USCALED_PACK32,
VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
VK_FORMAT_A8B8G8R8_UINT_PACK32,
VK_FORMAT_A8B8G8R8_SINT_PACK32,
VK_FORMAT_A8B8G8R8_SRGB_PACK32,
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
VK_FORMAT_A2R10G10B10_SNORM_PACK32,
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
VK_FORMAT_A2R10G10B10_UINT_PACK32,
VK_FORMAT_A2R10G10B10_SINT_PACK32,
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
VK_FORMAT_A2B10G10R10_SNORM_PACK32,
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
VK_FORMAT_A2B10G10R10_UINT_PACK32,
VK_FORMAT_A2B10G10R10_SINT_PACK32,
VK_FORMAT_R16_UNORM,
VK_FORMAT_R16_SNORM,
VK_FORMAT_R16_USCALED,
VK_FORMAT_R16_SSCALED,
VK_FORMAT_R16_UINT,
VK_FORMAT_R16_SINT,
VK_FORMAT_R16_SFLOAT,
VK_FORMAT_R16G16_UNORM,
VK_FORMAT_R16G16_SNORM,
VK_FORMAT_R16G16_USCALED,
VK_FORMAT_R16G16_SSCALED,
VK_FORMAT_R16G16_UINT,
VK_FORMAT_R16G16_SINT,
VK_FORMAT_R16G16_SFLOAT,
VK_FORMAT_R16G16B16_UNORM,
VK_FORMAT_R16G16B16_SNORM,
VK_FORMAT_R16G16B16_USCALED,
VK_FORMAT_R16G16B16_SSCALED,
VK_FORMAT_R16G16B16_UINT,
VK_FORMAT_R16G16B16_SINT,
VK_FORMAT_R16G16B16_SFLOAT,
VK_FORMAT_R16G16B16A16_UNORM,
VK_FORMAT_R16G16B16A16_SNORM,
VK_FORMAT_R16G16B16A16_USCALED,
VK_FORMAT_R16G16B16A16_SSCALED,
VK_FORMAT_R16G16B16A16_UINT,
VK_FORMAT_R16G16B16A16_SINT,
VK_FORMAT_R16G16B16A16_SFLOAT,
VK_FORMAT_R32_UINT,
VK_FORMAT_R32_SINT,
VK_FORMAT_R32_SFLOAT,
VK_FORMAT_R32G32_UINT,
VK_FORMAT_R32G32_SINT,
VK_FORMAT_R32G32_SFLOAT,
VK_FORMAT_R32G32B32_UINT,
VK_FORMAT_R32G32B32_SINT,
VK_FORMAT_R32G32B32_SFLOAT,
VK_FORMAT_R32G32B32A32_UINT,
VK_FORMAT_R32G32B32A32_SINT,
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_FORMAT_R64_UINT,
VK_FORMAT_R64_SINT,
VK_FORMAT_R64_SFLOAT,
VK_FORMAT_R64G64_UINT,
VK_FORMAT_R64G64_SINT,
VK_FORMAT_R64G64_SFLOAT,
VK_FORMAT_R64G64B64_UINT,
VK_FORMAT_R64G64B64_SINT,
VK_FORMAT_R64G64B64_SFLOAT,
VK_FORMAT_R64G64B64A64_UINT,
VK_FORMAT_R64G64B64A64_SINT,
VK_FORMAT_R64G64B64A64_SFLOAT,
VK_FORMAT_B10G11R11_UFLOAT_PACK32,
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
VK_FORMAT_D16_UNORM,
VK_FORMAT_X8_D24_UNORM_PACK32,
VK_FORMAT_D32_SFLOAT,
VK_FORMAT_S8_UINT,
VK_FORMAT_D16_UNORM_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_BC1_RGB_UNORM_BLOCK,
VK_FORMAT_BC1_RGB_SRGB_BLOCK,
VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
VK_FORMAT_BC2_UNORM_BLOCK,
VK_FORMAT_BC2_SRGB_BLOCK,
VK_FORMAT_BC3_UNORM_BLOCK,
VK_FORMAT_BC3_SRGB_BLOCK,
VK_FORMAT_BC4_UNORM_BLOCK,
VK_FORMAT_BC4_SNORM_BLOCK,
VK_FORMAT_BC5_UNORM_BLOCK,
VK_FORMAT_BC5_SNORM_BLOCK,
VK_FORMAT_BC6H_UFLOAT_BLOCK,
VK_FORMAT_BC6H_SFLOAT_BLOCK,
VK_FORMAT_BC7_UNORM_BLOCK,
VK_FORMAT_BC7_SRGB_BLOCK,
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
VK_FORMAT_EAC_R11_UNORM_BLOCK,
VK_FORMAT_EAC_R11_SNORM_BLOCK,
VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
VK_FORMAT_G8B8G8R8_422_UNORM,
VK_FORMAT_B8G8R8G8_422_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
VK_FORMAT_R10X6_UNORM_PACK16,
VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
VK_FORMAT_R12X4_UNORM_PACK16,
VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
VK_FORMAT_G16B16G16R16_422_UNORM,
VK_FORMAT_B16G16R16G16_422_UNORM,
VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,
VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,
VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,
VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,
VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,
VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,
VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG
};
int formatCount = (int)(sizeof(formatlist) / sizeof(unsigned int));
// If ycbcr is not supported, only use the standard texture formats
if (!isYcbcrSupported)
formatCount = 184;
// Find supported image formats
for (int i = 0; i < formatCount; i++)
{
vk::VkImageFormatProperties imageformatprops;
// Check for support in linear tiling mode
if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
m_context.getPhysicalDevice(),
(VkFormat)formatlist[i],
VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_LINEAR,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
0,
&imageformatprops) == VK_SUCCESS)
linearFormats.push_back(formatlist[i]);
// Check for support in optimal tiling mode
if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
m_context.getPhysicalDevice(),
(VkFormat)formatlist[i],
VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
0,
&imageformatprops) == VK_SUCCESS)
optimalFormats.push_back(formatlist[i]);
}
// Check for supported heap types
m_context.getInstanceInterface().getPhysicalDeviceMemoryProperties(m_context.getPhysicalDevice(), &memProperties);
for (unsigned int j = 0; j < legalMemoryTypeCount; j++)
{
bool found = false;
for (unsigned int i = 0; !found && i < memProperties.memoryTypeCount; i++)
{
if (legalMemoryTypes[j].matchesHeap(memProperties.memoryTypes[i].propertyFlags))
{
memoryTypes.push_back(j);
found = true;
}
}
}
// Log the used image types and heap types
tcu::TestLog& log = m_context.getTestContext().getLog();
{
std::ostringstream values;
for (unsigned int i = 0; i < linearFormats.size(); i++)
values << " " << linearFormats[i];
log << tcu::TestLog::Message << "Using linear formats:" << values.str() << tcu::TestLog::EndMessage;
}
{
std::ostringstream values;
for (unsigned int i = 0; i < optimalFormats.size(); i++)
values << " " << optimalFormats[i];
log << tcu::TestLog::Message << "Using optimal formats:" << values.str() << tcu::TestLog::EndMessage;
}
{
std::ostringstream values;
for (unsigned int i = 0; i < memoryTypes.size(); i++)
values << " " << memoryTypes[i];
log << tcu::TestLog::Message << "Using memory types:" << values.str() << tcu::TestLog::EndMessage;
}
for (unsigned int i = 0; i < testCycles; i++)
{
if (deRandom_getBool(&m_random))
objs[i] = new BufferAllocator(m_random, isDedicatedAllocationSupported, memoryTypes);
else
objs[i] = new ImageAllocator(m_random, isDedicatedAllocationSupported, linearFormats, optimalFormats, memoryTypes);
order[i] = i;
}
// First get reference values for the object sizes
for (unsigned int i = 0; i < testCycles; i++)
{
objs[i]->allocate(m_context);
refSizes[i] = objs[i]->getSize(m_context);
objs[i]->deallocate(m_context);
}
// Shuffle order by swapping random pairs
for (unsigned int i = 0; i < testCycles; i++)
{
int a = deRandom_getUint32(&m_random) % testCycles;
int b = deRandom_getUint32(&m_random) % testCycles;
DE_SWAP(int, order[a], order[b]);
}
// Allocate objects in shuffled order
for (unsigned int i = 0; i < testCycles; i++)
objs[order[i]]->allocate(m_context);
// Check for size mismatches
for (unsigned int i = 0; i < testCycles; i++)
{
size_t val = objs[order[i]]->getSize(m_context);
if (val != refSizes[order[i]])
{
success = false;
log << tcu::TestLog::Message
<< "Object "
<< order[i]
<< " size mismatch ("
<< val
<< " != "
<< refSizes[order[i]]
<< ")"
<< tcu::TestLog::EndMessage;
}
}
// Clean up
for (unsigned int i = 0; i < testCycles; i++)
objs[order[i]]->deallocate(m_context);
if (success)
return tcu::TestStatus::pass("Pass");
return tcu::TestStatus::fail("One or more allocation is not invariant");
}
class InvarianceCase : public vkt::TestCase
{
public:
InvarianceCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description);
virtual ~InvarianceCase (void);
virtual TestInstance* createInstance (Context& context) const;
};
InvarianceCase::InvarianceCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description)
: vkt::TestCase(testCtx, name, description)
{
}
InvarianceCase::~InvarianceCase()
{
}
TestInstance* InvarianceCase::createInstance (Context& context) const
{
return new InvarianceInstance(context, 0x600613);
}
tcu::TestCaseGroup* createMemoryRequirementInvarianceTests (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> invarianceTests(new tcu::TestCaseGroup(testCtx, "invariance", "Memory requirement invariance tests"));
// Only one child, leaving room for potential targeted cases later on.
invarianceTests->addChild(new InvarianceCase(testCtx, "random", std::string("Random case")));
return invarianceTests.release();
}
} // api
} // vkt