• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
getMemory(void) const57 	VkDeviceMemory			getMemory		(void) const { return m_memory;							}
58 
59 	//! Get offset in VkDeviceMemory for this allocation
getOffset(void) const60 	VkDeviceSize			getOffset		(void) const { return m_offset;							}
61 
62 	//! Get host pointer for this allocation. Only available for host-visible allocations
getHostPtr(void) const63 	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 
operator |(MemoryRequirement requirement) const90 	inline MemoryRequirement		operator|			(MemoryRequirement requirement) const
91 	{
92 		return MemoryRequirement(m_flags | requirement.m_flags);
93 	}
94 
operator &(MemoryRequirement requirement) const95 	inline MemoryRequirement		operator&			(MemoryRequirement requirement) const
96 	{
97 		return MemoryRequirement(m_flags & requirement.m_flags);
98 	}
99 
100 	bool							matchesHeap			(VkMemoryPropertyFlags heapFlags) const;
101 
operator bool(void) const102 	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:
Allocator(void)125 									Allocator	(void) {}
~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