3 /*-------------------------------------------------------------------------
7 * Copyright (c) 2015 Google Inc.
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * \brief Memory management utilities.
24 *//*--------------------------------------------------------------------*/
27 #include "deUniquePtr.hpp"
32 /*--------------------------------------------------------------------*//*!
33 * \brief Memory allocation interface
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).
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.
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.
48 * Memory mappings are managed solely by Allocation, i.e. unmapping or
49 * re-mapping VkDeviceMemory owned by Allocation is not allowed.
50 *//*--------------------------------------------------------------------*/
54 virtual ~Allocation (void);
56 //! Get VkDeviceMemory backing this allocation
57 VkDeviceMemory getMemory (void) const { return m_memory; }
59 //! Get offset in VkDeviceMemory for this allocation
60 VkDeviceSize getOffset (void) const { return m_offset; }
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; }
66 Allocation (VkDeviceMemory memory, VkDeviceSize offset, void* hostPtr);
69 const VkDeviceMemory m_memory;
70 const VkDeviceSize m_offset;
71 void* const m_hostPtr;
74 //! Memory allocation requirements
75 class MemoryRequirement
78 static const MemoryRequirement Any;
79 static const MemoryRequirement HostVisible;
80 static const MemoryRequirement Coherent;
81 static const MemoryRequirement LazilyAllocated;
83 inline MemoryRequirement operator| (MemoryRequirement requirement) const
85 return MemoryRequirement(m_flags | requirement.m_flags);
88 inline MemoryRequirement operator& (MemoryRequirement requirement) const
90 return MemoryRequirement(m_flags & requirement.m_flags);
93 bool matchesHeap (VkMemoryPropertyFlags heapFlags) const;
95 inline operator bool (void) const { return m_flags != 0u; }
98 explicit MemoryRequirement (deUint32 flags);
100 const deUint32 m_flags;
104 FLAG_HOST_VISIBLE = 1u << 0u,
105 FLAG_COHERENT = 1u << 1u,
106 FLAG_LAZY_ALLOCATION = 1u << 2u,
110 //! Memory allocator interface
115 virtual ~Allocator (void) {}
117 virtual de::MovePtr<Allocation> allocate (const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment) = 0;
118 virtual de::MovePtr<Allocation> allocate (const VkMemoryRequirements& memRequirements, MemoryRequirement requirement) = 0;
121 //! Allocator that backs every allocation with its own VkDeviceMemory
122 class SimpleAllocator : public Allocator
125 SimpleAllocator (const DeviceInterface& vk, VkDevice device, const VkPhysicalDeviceMemoryProperties& deviceMemProps);
127 de::MovePtr<Allocation> allocate (const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment);
128 de::MovePtr<Allocation> allocate (const VkMemoryRequirements& memRequirements, MemoryRequirement requirement);
131 const DeviceInterface& m_vk;
132 const VkDevice m_device;
133 const VkPhysicalDeviceMemoryProperties m_memProps;
136 de::MovePtr<Allocation> allocateDedicated (const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkBuffer buffer, MemoryRequirement requirement);
137 de::MovePtr<Allocation> allocateDedicated (const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkImage image, MemoryRequirement requirement);
139 void* mapMemory (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags);
140 void flushMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size);
141 void invalidateMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size);
142 deUint32 getCompatibleMemoryTypes (const VkPhysicalDeviceMemoryProperties& deviceMemProps, MemoryRequirement requirement);
146 #endif // _VKMEMUTIL_HPP