Home | History | Annotate | Download | only in vulkan
      1 #ifndef _VKMEMUTIL_HPP
      2 #define _VKMEMUTIL_HPP
      3 /*-------------------------------------------------------------------------
      4  * Vulkan CTS Framework
      5  * --------------------
      6  *
      7  * Copyright (c) 2015 Google Inc.
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Memory management utilities.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "vkDefs.hpp"
     27 #include "deUniquePtr.hpp"
     28 
     29 namespace vk
     30 {
     31 
     32 /*--------------------------------------------------------------------*//*!
     33  * \brief Memory allocation interface
     34  *
     35  * Allocation represents block of device memory and is allocated by
     36  * Allocator implementation. Test code should use Allocator for allocating
     37  * memory, unless there is a reason not to (for example testing vkAllocMemory).
     38  *
     39  * Allocation doesn't necessarily correspond to a whole VkDeviceMemory, but
     40  * instead it may represent sub-allocation. Thus whenever VkDeviceMemory
     41  * (getMemory()) managed by Allocation is passed to Vulkan API calls,
     42  * offset given by getOffset() must be used.
     43  *
     44  * If host-visible memory was requested, host pointer to the memory can
     45  * be queried with getHostPtr(). No offset is needed when accessing host
     46  * pointer, i.e. the pointer is already adjusted in case of sub-allocation.
     47  *
     48  * Memory mappings are managed solely by Allocation, i.e. unmapping or
     49  * re-mapping VkDeviceMemory owned by Allocation is not allowed.
     50  *//*--------------------------------------------------------------------*/
     51 class Allocation
     52 {
     53 public:
     54 	virtual					~Allocation		(void);
     55 
     56 	//! Get VkDeviceMemory backing this allocation
     57 	VkDeviceMemory			getMemory		(void) const { return m_memory;							}
     58 
     59 	//! Get offset in VkDeviceMemory for this allocation
     60 	VkDeviceSize			getOffset		(void) const { return m_offset;							}
     61 
     62 	//! Get host pointer for this allocation. Only available for host-visible allocations
     63 	void*					getHostPtr		(void) const { DE_ASSERT(m_hostPtr); return m_hostPtr;	}
     64 
     65 protected:
     66 							Allocation		(VkDeviceMemory memory, VkDeviceSize offset, void* hostPtr);
     67 
     68 private:
     69 	const VkDeviceMemory	m_memory;
     70 	const VkDeviceSize		m_offset;
     71 	void* const				m_hostPtr;
     72 };
     73 
     74 void	flushAlloc		(const DeviceInterface& vkd, VkDevice device, const Allocation& alloc);
     75 void	invalidateAlloc	(const DeviceInterface& vkd, VkDevice device, const Allocation& alloc);
     76 
     77 //! Memory allocation requirements
     78 class MemoryRequirement
     79 {
     80 public:
     81 	static const MemoryRequirement	Any;
     82 	static const MemoryRequirement	HostVisible;
     83 	static const MemoryRequirement	Coherent;
     84 	static const MemoryRequirement	LazilyAllocated;
     85 	static const MemoryRequirement	Protected;
     86 	static const MemoryRequirement	Local;
     87 	static const MemoryRequirement	Cached;
     88 	static const MemoryRequirement	NonLocal;
     89 
     90 	inline MemoryRequirement		operator|			(MemoryRequirement requirement) const
     91 	{
     92 		return MemoryRequirement(m_flags | requirement.m_flags);
     93 	}
     94 
     95 	inline MemoryRequirement		operator&			(MemoryRequirement requirement) const
     96 	{
     97 		return MemoryRequirement(m_flags & requirement.m_flags);
     98 	}
     99 
    100 	bool							matchesHeap			(VkMemoryPropertyFlags heapFlags) const;
    101 
    102 	inline operator					bool				(void) const { return m_flags != 0u; }
    103 
    104 private:
    105 	explicit						MemoryRequirement	(deUint32 flags);
    106 
    107 	const deUint32					m_flags;
    108 
    109 	enum Flags
    110 	{
    111 		FLAG_HOST_VISIBLE		= 1u << 0u,
    112 		FLAG_COHERENT			= 1u << 1u,
    113 		FLAG_LAZY_ALLOCATION	= 1u << 2u,
    114 		FLAG_PROTECTED			= 1u << 3u,
    115 		FLAG_LOCAL				= 1u << 4u,
    116 		FLAG_CACHED				= 1u << 5u,
    117 		FLAG_NON_LOCAL			= 1u << 6u,
    118 	};
    119 };
    120 
    121 //! Memory allocator interface
    122 class Allocator
    123 {
    124 public:
    125 									Allocator	(void) {}
    126 	virtual							~Allocator	(void) {}
    127 
    128 	virtual de::MovePtr<Allocation>	allocate	(const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment) = 0;
    129 	virtual de::MovePtr<Allocation>	allocate	(const VkMemoryRequirements& memRequirements, MemoryRequirement requirement) = 0;
    130 };
    131 
    132 //! Allocator that backs every allocation with its own VkDeviceMemory
    133 class SimpleAllocator : public Allocator
    134 {
    135 public:
    136 											SimpleAllocator	(const DeviceInterface& vk, VkDevice device, const VkPhysicalDeviceMemoryProperties& deviceMemProps);
    137 
    138 	de::MovePtr<Allocation>					allocate		(const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment);
    139 	de::MovePtr<Allocation>					allocate		(const VkMemoryRequirements& memRequirements, MemoryRequirement requirement);
    140 
    141 private:
    142 	const DeviceInterface&					m_vk;
    143 	const VkDevice							m_device;
    144 	const VkPhysicalDeviceMemoryProperties	m_memProps;
    145 };
    146 
    147 de::MovePtr<Allocation>	allocateDedicated			(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkBuffer buffer, MemoryRequirement requirement);
    148 de::MovePtr<Allocation>	allocateDedicated			(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkImage image, MemoryRequirement requirement);
    149 
    150 void*					mapMemory					(const DeviceInterface& vkd, VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags);
    151 void					flushMappedMemoryRange		(const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size);
    152 void					invalidateMappedMemoryRange	(const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size);
    153 
    154 deUint32				getCompatibleMemoryTypes	(const VkPhysicalDeviceMemoryProperties& deviceMemProps, MemoryRequirement requirement);
    155 void					bindImagePlaneMemory		(const DeviceInterface&	vkd, VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset, VkImageAspectFlagBits planeAspect);
    156 
    157 } // vk
    158 
    159 #endif // _VKMEMUTIL_HPP
    160