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 //! Memory allocation requirements 75 class MemoryRequirement 76 { 77 public: 78 static const MemoryRequirement Any; 79 static const MemoryRequirement HostVisible; 80 static const MemoryRequirement Coherent; 81 static const MemoryRequirement LazilyAllocated; 82 83 inline MemoryRequirement operator| (MemoryRequirement requirement) const 84 { 85 return MemoryRequirement(m_flags | requirement.m_flags); 86 } 87 88 inline MemoryRequirement operator& (MemoryRequirement requirement) const 89 { 90 return MemoryRequirement(m_flags & requirement.m_flags); 91 } 92 93 bool matchesHeap (VkMemoryPropertyFlags heapFlags) const; 94 95 inline operator bool (void) const { return m_flags != 0u; } 96 97 private: 98 explicit MemoryRequirement (deUint32 flags); 99 100 const deUint32 m_flags; 101 102 enum Flags 103 { 104 FLAG_HOST_VISIBLE = 1u << 0u, 105 FLAG_COHERENT = 1u << 1u, 106 FLAG_LAZY_ALLOCATION = 1u << 2u, 107 }; 108 }; 109 110 //! Memory allocator interface 111 class Allocator 112 { 113 public: 114 Allocator (void) {} 115 virtual ~Allocator (void) {} 116 117 virtual de::MovePtr<Allocation> allocate (const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment) = 0; 118 virtual de::MovePtr<Allocation> allocate (const VkMemoryRequirements& memRequirements, MemoryRequirement requirement) = 0; 119 }; 120 121 //! Allocator that backs every allocation with its own VkDeviceMemory 122 class SimpleAllocator : public Allocator 123 { 124 public: 125 SimpleAllocator (const DeviceInterface& vk, VkDevice device, const VkPhysicalDeviceMemoryProperties& deviceMemProps); 126 127 de::MovePtr<Allocation> allocate (const VkMemoryAllocateInfo& allocInfo, VkDeviceSize alignment); 128 de::MovePtr<Allocation> allocate (const VkMemoryRequirements& memRequirements, MemoryRequirement requirement); 129 130 private: 131 const DeviceInterface& m_vk; 132 const VkDevice m_device; 133 const VkPhysicalDeviceMemoryProperties m_memProps; 134 }; 135 136 void flushMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size); 137 void invalidateMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size); 138 139 } // vk 140 141 #endif // _VKMEMUTIL_HPP 142