1c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos/*-------------------------------------------------------------------------
2846cc3ce8e721a972ef38c44e24da49ea96110caPyry Haulos * Vulkan CTS Framework
3846cc3ce8e721a972ef38c44e24da49ea96110caPyry Haulos * --------------------
4c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
5846cc3ce8e721a972ef38c44e24da49ea96110caPyry Haulos * Copyright (c) 2015 Google Inc.
6c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
7978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
8978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License.
9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at
10c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
12c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
13978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software
14978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and
17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License.
18c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
19c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *//*!
20c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos * \file
21c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos * \brief Memory management utilities.
22c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *//*--------------------------------------------------------------------*/
23c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
24c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos#include "vkMemUtil.hpp"
25c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos#include "vkStrUtil.hpp"
26b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos#include "vkQueryUtil.hpp"
27b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos#include "vkRef.hpp"
284b11ca9132ae388bc41f83a8fceaff3791314769Jarkko Pöyry#include "vkRefUtil.hpp"
29b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos#include "deInt32.h"
30c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
31c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos#include <sstream>
32c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
33c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulosnamespace vk
34c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
35c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
367965292de01eac3af42c1de1e61b9442739eb188Pyry Haulosusing de::UniquePtr;
37c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulosusing de::MovePtr;
38c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
39b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulosnamespace
40b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos{
41b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos
427965292de01eac3af42c1de1e61b9442739eb188Pyry Haulosclass HostPtr
437965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos{
447965292de01eac3af42c1de1e61b9442739eb188Pyry Haulospublic:
457965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos								HostPtr		(const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags);
467965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos								~HostPtr	(void);
477965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
487965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	void*						get			(void) const { return m_ptr; }
497965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
507965292de01eac3af42c1de1e61b9442739eb188Pyry Haulosprivate:
517965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	const DeviceInterface&		m_vkd;
527965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	const VkDevice				m_device;
537965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	const VkDeviceMemory		m_memory;
547965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	void* const					m_ptr;
557965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos};
567965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
577965292de01eac3af42c1de1e61b9442739eb188Pyry HaulosHostPtr::HostPtr (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags)
587965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	: m_vkd		(vkd)
597965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	, m_device	(device)
607965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	, m_memory	(memory)
617965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	, m_ptr		(mapMemory(vkd, device, memory, offset, size, flags))
627965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos{
637965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos}
647965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
657965292de01eac3af42c1de1e61b9442739eb188Pyry HaulosHostPtr::~HostPtr (void)
667965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos{
677965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	m_vkd.unmapMemory(m_device, m_memory);
687965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos}
697965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
7080ab6a2656b30660734f5ef8decd81b9563eb045Jarkko PöyrydeUint32 selectMatchingMemoryType (const VkPhysicalDeviceMemoryProperties& deviceMemProps, deUint32 allowedMemTypeBits, MemoryRequirement requirement)
71b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos{
72bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	const deUint32	compatibleTypes	= getCompatibleMemoryTypes(deviceMemProps, requirement);
73bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	const deUint32	candidates		= allowedMemTypeBits & compatibleTypes;
74b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos
75bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	if (candidates == 0)
76bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi		TCU_THROW(NotSupportedError, "No compatible memory type found");
77bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi
78bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	return (deUint32)deCtz32(candidates);
79b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos}
80b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos
817965292de01eac3af42c1de1e61b9442739eb188Pyry Haulosbool isHostVisibleMemory (const VkPhysicalDeviceMemoryProperties& deviceMemProps, deUint32 memoryTypeNdx)
827965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos{
837965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	DE_ASSERT(memoryTypeNdx < deviceMemProps.memoryTypeCount);
847965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	return (deviceMemProps.memoryTypes[memoryTypeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
857965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos}
867965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
87b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos} // anonymous
88b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos
89c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos// Allocation
90c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
917965292de01eac3af42c1de1e61b9442739eb188Pyry HaulosAllocation::Allocation (VkDeviceMemory memory, VkDeviceSize offset, void* hostPtr)
92c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	: m_memory	(memory)
93c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	, m_offset	(offset)
947965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	, m_hostPtr	(hostPtr)
95c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
96c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
97c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
98c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry HaulosAllocation::~Allocation (void)
99c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
100c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
101c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
10280ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry// MemoryRequirement
10380ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
10480ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyryconst MemoryRequirement MemoryRequirement::Any				= MemoryRequirement(0x0u);
10580ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyryconst MemoryRequirement MemoryRequirement::HostVisible		= MemoryRequirement(MemoryRequirement::FLAG_HOST_VISIBLE);
10680ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyryconst MemoryRequirement MemoryRequirement::Coherent			= MemoryRequirement(MemoryRequirement::FLAG_COHERENT);
10780ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyryconst MemoryRequirement MemoryRequirement::LazilyAllocated	= MemoryRequirement(MemoryRequirement::FLAG_LAZY_ALLOCATION);
10869baa668275930f4e5fa19c29eb3501c1982e0bdPeter Galconst MemoryRequirement MemoryRequirement::Protected		= MemoryRequirement(MemoryRequirement::FLAG_PROTECTED);
10980ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
11080ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyrybool MemoryRequirement::matchesHeap (VkMemoryPropertyFlags heapFlags) const
11180ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry{
1125574b27a19dcebac00fd5e9b36275e824d9ca9e9Pyry Haulos	// sanity check
1135574b27a19dcebac00fd5e9b36275e824d9ca9e9Pyry Haulos	if ((m_flags & FLAG_COHERENT) && !(m_flags & FLAG_HOST_VISIBLE))
1145574b27a19dcebac00fd5e9b36275e824d9ca9e9Pyry Haulos		DE_FATAL("Coherent memory must be host-visible");
1155574b27a19dcebac00fd5e9b36275e824d9ca9e9Pyry Haulos	if ((m_flags & FLAG_HOST_VISIBLE) && (m_flags & FLAG_LAZY_ALLOCATION))
1165574b27a19dcebac00fd5e9b36275e824d9ca9e9Pyry Haulos		DE_FATAL("Lazily allocated memory cannot be mappable");
11769baa668275930f4e5fa19c29eb3501c1982e0bdPeter Gal	if ((m_flags & FLAG_PROTECTED) && (m_flags & FLAG_HOST_VISIBLE))
11869baa668275930f4e5fa19c29eb3501c1982e0bdPeter Gal		DE_FATAL("Protected memory cannot be mappable");
1195574b27a19dcebac00fd5e9b36275e824d9ca9e9Pyry Haulos
12080ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	// host-visible
12180ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	if ((m_flags & FLAG_HOST_VISIBLE) && !(heapFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
12280ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry		return false;
12380ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
12480ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	// coherent
12568e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos	if ((m_flags & FLAG_COHERENT) && !(heapFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
12680ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry		return false;
12780ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
12880ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	// lazy
12980ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	if ((m_flags & FLAG_LAZY_ALLOCATION) && !(heapFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT))
13080ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry		return false;
13180ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
13269baa668275930f4e5fa19c29eb3501c1982e0bdPeter Gal	// protected
13375052a3e1fecf3430a44e49ead3cf9dc564a67a0Alexander Galazin	if ((m_flags & FLAG_PROTECTED) && !(heapFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT))
13469baa668275930f4e5fa19c29eb3501c1982e0bdPeter Gal		return false;
13569baa668275930f4e5fa19c29eb3501c1982e0bdPeter Gal
13680ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	return true;
13780ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry}
13880ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
13980ab6a2656b30660734f5ef8decd81b9563eb045Jarkko PöyryMemoryRequirement::MemoryRequirement (deUint32 flags)
14080ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry	: m_flags(flags)
14180ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry{
14280ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry}
14380ab6a2656b30660734f5ef8decd81b9563eb045Jarkko Pöyry
144c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos// SimpleAllocator
145c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
146c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulosclass SimpleAllocation : public Allocation
147c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
148c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulospublic:
1497965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos									SimpleAllocation	(Move<VkDeviceMemory> mem, MovePtr<HostPtr> hostPtr);
150b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos	virtual							~SimpleAllocation	(void);
151c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
152c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulosprivate:
153b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos	const Unique<VkDeviceMemory>	m_memHolder;
1547965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	const UniquePtr<HostPtr>		m_hostPtr;
155c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos};
156c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
1577965292de01eac3af42c1de1e61b9442739eb188Pyry HaulosSimpleAllocation::SimpleAllocation (Move<VkDeviceMemory> mem, MovePtr<HostPtr> hostPtr)
1587965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	: Allocation	(*mem, (VkDeviceSize)0, hostPtr ? hostPtr->get() : DE_NULL)
159b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos	, m_memHolder	(mem)
1607965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	, m_hostPtr		(hostPtr)
161c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
162c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
163c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
164c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry HaulosSimpleAllocation::~SimpleAllocation (void)
165c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
166c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
167c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
168b1a7d2198497be32dfc22386f99945656ff4080ePyry HaulosSimpleAllocator::SimpleAllocator (const DeviceInterface& vk, VkDevice device, const VkPhysicalDeviceMemoryProperties& deviceMemProps)
169c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	: m_vk		(vk)
170c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	, m_device	(device)
171b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos	, m_memProps(deviceMemProps)
172c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
173c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
174c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
17568e7282426d639b54d15c4710d97ba97e72c76efPyry HaulosMovePtr<Allocation> SimpleAllocator::allocate (const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment)
176c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
177c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	DE_UNREF(alignment);
1787965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
17968e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos	Move<VkDeviceMemory>	mem		= allocateMemory(m_vk, m_device, &allocInfo);
1807965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	MovePtr<HostPtr>		hostPtr;
1817965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
1827965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	if (isHostVisibleMemory(m_memProps, allocInfo.memoryTypeIndex))
1837965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos		hostPtr = MovePtr<HostPtr>(new HostPtr(m_vk, m_device, *mem, 0u, allocInfo.allocationSize, 0u));
1847965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
1857965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	return MovePtr<Allocation>(new SimpleAllocation(mem, hostPtr));
186c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
187c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
18880ab6a2656b30660734f5ef8decd81b9563eb045Jarkko PöyryMovePtr<Allocation> SimpleAllocator::allocate (const VkMemoryRequirements& memReqs, MemoryRequirement requirement)
189c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
19068e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos	const deUint32				memoryTypeNdx	= selectMatchingMemoryType(m_memProps, memReqs.memoryTypeBits, requirement);
19168e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos	const VkMemoryAllocateInfo	allocInfo		=
192c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	{
19368e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
194c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos		DE_NULL,								//	const void*				pNext;
195b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos		memReqs.size,							//	VkDeviceSize			allocationSize;
196b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos		memoryTypeNdx,							//	deUint32				memoryTypeIndex;
197c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	};
198c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
19968e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos	Move<VkDeviceMemory>		mem				= allocateMemory(m_vk, m_device, &allocInfo);
20068e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos	MovePtr<HostPtr>			hostPtr;
2017965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
2027965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	if (requirement & MemoryRequirement::HostVisible)
2037965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	{
2047965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos		DE_ASSERT(isHostVisibleMemory(m_memProps, allocInfo.memoryTypeIndex));
2057965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos		hostPtr = MovePtr<HostPtr>(new HostPtr(m_vk, m_device, *mem, 0u, allocInfo.allocationSize, 0u));
2067965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	}
2077965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos
2087965292de01eac3af42c1de1e61b9442739eb188Pyry Haulos	return MovePtr<Allocation>(new SimpleAllocation(mem, hostPtr));
209c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
210c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
2119be333ef548eef1a4d9423c284a551858534e090Boris Zaninstatic MovePtr<Allocation> allocateDedicated (const InstanceInterface&		vki,
2129be333ef548eef1a4d9423c284a551858534e090Boris Zanin											  const DeviceInterface&		vkd,
2139be333ef548eef1a4d9423c284a551858534e090Boris Zanin											  const VkPhysicalDevice&		physDevice,
2149be333ef548eef1a4d9423c284a551858534e090Boris Zanin											  const VkDevice				device,
2159be333ef548eef1a4d9423c284a551858534e090Boris Zanin											  const VkMemoryRequirements&	memReqs,
2169be333ef548eef1a4d9423c284a551858534e090Boris Zanin											  const MemoryRequirement		requirement,
2179be333ef548eef1a4d9423c284a551858534e090Boris Zanin											  const void*					pNext)
2189be333ef548eef1a4d9423c284a551858534e090Boris Zanin{
2199be333ef548eef1a4d9423c284a551858534e090Boris Zanin	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physDevice);
2209be333ef548eef1a4d9423c284a551858534e090Boris Zanin	const deUint32							memoryTypeNdx		= selectMatchingMemoryType(memoryProperties, memReqs.memoryTypeBits, requirement);
2219be333ef548eef1a4d9423c284a551858534e090Boris Zanin	const VkMemoryAllocateInfo				allocInfo			=
2229be333ef548eef1a4d9423c284a551858534e090Boris Zanin	{
2239be333ef548eef1a4d9423c284a551858534e090Boris Zanin		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType
2249be333ef548eef1a4d9423c284a551858534e090Boris Zanin		pNext,									//	const void*		pNext
2259be333ef548eef1a4d9423c284a551858534e090Boris Zanin		memReqs.size,							//	VkDeviceSize	allocationSize
2269be333ef548eef1a4d9423c284a551858534e090Boris Zanin		memoryTypeNdx,							//	deUint32		memoryTypeIndex
2279be333ef548eef1a4d9423c284a551858534e090Boris Zanin	};
2289be333ef548eef1a4d9423c284a551858534e090Boris Zanin	Move<VkDeviceMemory>					mem					= allocateMemory(vkd, device, &allocInfo);
2299be333ef548eef1a4d9423c284a551858534e090Boris Zanin	MovePtr<HostPtr>						hostPtr;
2309be333ef548eef1a4d9423c284a551858534e090Boris Zanin
2319be333ef548eef1a4d9423c284a551858534e090Boris Zanin	if (requirement & MemoryRequirement::HostVisible)
2329be333ef548eef1a4d9423c284a551858534e090Boris Zanin	{
2339be333ef548eef1a4d9423c284a551858534e090Boris Zanin		DE_ASSERT(isHostVisibleMemory(memoryProperties, allocInfo.memoryTypeIndex));
2349be333ef548eef1a4d9423c284a551858534e090Boris Zanin		hostPtr = MovePtr<HostPtr>(new HostPtr(vkd, device, *mem, 0u, allocInfo.allocationSize, 0u));
2359be333ef548eef1a4d9423c284a551858534e090Boris Zanin	}
2369be333ef548eef1a4d9423c284a551858534e090Boris Zanin
2379be333ef548eef1a4d9423c284a551858534e090Boris Zanin	return MovePtr<Allocation>(new SimpleAllocation(mem, hostPtr));
2389be333ef548eef1a4d9423c284a551858534e090Boris Zanin}
2399be333ef548eef1a4d9423c284a551858534e090Boris Zanin
2409be333ef548eef1a4d9423c284a551858534e090Boris Zaninde::MovePtr<Allocation> allocateDedicated (const InstanceInterface&	vki,
2419be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const DeviceInterface&	vkd,
2429be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const VkPhysicalDevice&	physDevice,
2439be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const VkDevice			device,
2449be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const VkBuffer			buffer,
2459be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   MemoryRequirement		requirement)
2469be333ef548eef1a4d9423c284a551858534e090Boris Zanin{
24733b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const VkMemoryRequirements				memoryRequirements		= getBufferMemoryRequirements(vkd, device, buffer);
24833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const VkMemoryDedicatedAllocateInfo		dedicatedAllocationInfo	=
2499be333ef548eef1a4d9423c284a551858534e090Boris Zanin	{
2509be333ef548eef1a4d9423c284a551858534e090Boris Zanin		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
2519be333ef548eef1a4d9423c284a551858534e090Boris Zanin		DE_NULL,															// const void*			pNext
2529be333ef548eef1a4d9423c284a551858534e090Boris Zanin		DE_NULL,															// VkImage				image
2539be333ef548eef1a4d9423c284a551858534e090Boris Zanin		buffer																// VkBuffer				buffer
2549be333ef548eef1a4d9423c284a551858534e090Boris Zanin	};
2559be333ef548eef1a4d9423c284a551858534e090Boris Zanin
2569be333ef548eef1a4d9423c284a551858534e090Boris Zanin	return allocateDedicated(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
2579be333ef548eef1a4d9423c284a551858534e090Boris Zanin}
2589be333ef548eef1a4d9423c284a551858534e090Boris Zanin
2599be333ef548eef1a4d9423c284a551858534e090Boris Zaninde::MovePtr<Allocation> allocateDedicated (const InstanceInterface&	vki,
2609be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const DeviceInterface&	vkd,
2619be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const VkPhysicalDevice&	physDevice,
2629be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const VkDevice			device,
2639be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   const VkImage			image,
2649be333ef548eef1a4d9423c284a551858534e090Boris Zanin										   MemoryRequirement		requirement)
2659be333ef548eef1a4d9423c284a551858534e090Boris Zanin{
2669be333ef548eef1a4d9423c284a551858534e090Boris Zanin	const VkMemoryRequirements				memoryRequirements		= getImageMemoryRequirements(vkd, device, image);
26733b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const VkMemoryDedicatedAllocateInfo		dedicatedAllocationInfo	=
2689be333ef548eef1a4d9423c284a551858534e090Boris Zanin	{
2699be333ef548eef1a4d9423c284a551858534e090Boris Zanin		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,			// VkStructureType		sType
2709be333ef548eef1a4d9423c284a551858534e090Boris Zanin		DE_NULL,														// const void*			pNext
2719be333ef548eef1a4d9423c284a551858534e090Boris Zanin		image,															// VkImage				image
2729be333ef548eef1a4d9423c284a551858534e090Boris Zanin		DE_NULL															// VkBuffer				buffer
2739be333ef548eef1a4d9423c284a551858534e090Boris Zanin	};
2749be333ef548eef1a4d9423c284a551858534e090Boris Zanin
2759be333ef548eef1a4d9423c284a551858534e090Boris Zanin	return allocateDedicated(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
2769be333ef548eef1a4d9423c284a551858534e090Boris Zanin}
2779be333ef548eef1a4d9423c284a551858534e090Boris Zanin
27808b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulosvoid* mapMemory (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags)
27908b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos{
28008b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos	void* hostPtr = DE_NULL;
28108b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos	VK_CHECK(vkd.mapMemory(device, mem, offset, size, flags, &hostPtr));
28208b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos	TCU_CHECK(hostPtr);
28308b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos	return hostPtr;
28408b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos}
28508b8e2b72dd89548f9877a8ed5bba7c04c1d9732Pyry Haulos
28606a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulosvoid flushMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size)
28706a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos{
28806a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	const VkMappedMemoryRange	range	=
28906a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	{
29006a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
29106a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		DE_NULL,
29206a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		memory,
29306a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		offset,
29406a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		size
29506a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	};
29606a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos
29706a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &range));
29806a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos}
29906a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos
30006a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulosvoid invalidateMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size)
30106a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos{
30206a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	const VkMappedMemoryRange	range	=
30306a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	{
30406a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
30506a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		DE_NULL,
30606a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		memory,
30706a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		offset,
30806a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos		size
30906a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	};
31006a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos
31106a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos	VK_CHECK(vkd.invalidateMappedMemoryRanges(device, 1u, &range));
31206a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos}
31306a59e5eb5bc69e8b2eaa5fd959080805f2339b9Pyry Haulos
314bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika IsojärvideUint32 getCompatibleMemoryTypes (const VkPhysicalDeviceMemoryProperties& deviceMemProps, MemoryRequirement requirement)
315bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi{
316bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	deUint32	compatibleTypes	= 0u;
317bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi
318bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemProps.memoryTypeCount; memoryTypeNdx++)
319bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	{
320bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi		if (requirement.matchesHeap(deviceMemProps.memoryTypes[memoryTypeNdx].propertyFlags))
321bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi			compatibleTypes |= (1u << memoryTypeNdx);
322bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	}
323bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi
324bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi	return compatibleTypes;
325bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi}
326bea8458b4e48aa5e19b27b61ae2e061ad68e4b68Mika Isojärvi
327e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulosvoid bindImagePlaneMemory (const DeviceInterface&	vkd,
328e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos						   VkDevice					device,
329e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos						   VkImage					image,
330e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos						   VkDeviceMemory			memory,
331e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos						   VkDeviceSize				memoryOffset,
332e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos						   VkImageAspectFlagBits	planeAspect)
333e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos{
33433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const VkBindImagePlaneMemoryInfo	planeInfo	=
335e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos	{
336e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR,
337e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		DE_NULL,
338e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		planeAspect
339e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos	};
34033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const VkBindImageMemoryInfo			coreInfo	=
341e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos	{
342e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,
343e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		&planeInfo,
344e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		image,
345e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		memory,
346e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos		memoryOffset,
347e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos	};
348e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos
34933b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	VK_CHECK(vkd.bindImageMemory2(device, 1u, &coreInfo));
350e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos}
351e5cf8de067694afde10873b6fdbd7907486e5611Pyry Haulos
352c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos} // vk
353