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