/src/skia/include/gpu/vk/VulkanMemoryAllocator.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2022 Google LLC. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license that can be |
5 | | * found in the LICENSE file. |
6 | | */ |
7 | | |
8 | | #ifndef skgpu_VulkanMemoryAllocator_DEFINED |
9 | | #define skgpu_VulkanMemoryAllocator_DEFINED |
10 | | |
11 | | #include "include/core/SkRefCnt.h" |
12 | | #include "include/gpu/GpuTypes.h" |
13 | | #include "include/gpu/vk/VulkanTypes.h" |
14 | | |
15 | | namespace skgpu { |
16 | | |
17 | | class VulkanMemoryAllocator : public SkRefCnt { |
18 | | public: |
19 | | enum AllocationPropertyFlags { |
20 | | kNone_AllocationPropertyFlag = 0b0000, |
21 | | // Allocation will be placed in its own VkDeviceMemory and not suballocated from some larger |
22 | | // block. |
23 | | kDedicatedAllocation_AllocationPropertyFlag = 0b0001, |
24 | | // Says that the backing memory can only be accessed by the device. Additionally the device |
25 | | // may lazily allocate the memory. This cannot be used with buffers that will be host |
26 | | // visible. Setting this flag does not guarantee that we will allocate memory that respects |
27 | | // it, but we will try to prefer memory that can respect it. |
28 | | kLazyAllocation_AllocationPropertyFlag = 0b0010, |
29 | | // The allocation will be mapped immediately and stay mapped until it is destroyed. This |
30 | | // flag is only valid for buffers which are host visible (i.e. must have a usage other than |
31 | | // BufferUsage::kGpuOnly). |
32 | | kPersistentlyMapped_AllocationPropertyFlag = 0b0100, |
33 | | // Allocation can only be accessed by the device using a protected context. |
34 | | kProtected_AllocationPropertyFlag = 0b1000, |
35 | | }; |
36 | | |
37 | | enum class BufferUsage { |
38 | | // Buffers that will only be accessed from the device (large const buffers) will always be |
39 | | // in device local memory. |
40 | | kGpuOnly, |
41 | | // Buffers that typically will be updated multiple times by the host and read on the gpu |
42 | | // (e.g. uniform or vertex buffers). CPU writes will generally be sequential in the buffer |
43 | | // and will try to take advantage of the write-combined nature of the gpu buffers. Thus this |
44 | | // will always be mappable and coherent memory, and it will prefer to be in device local |
45 | | // memory. |
46 | | kCpuWritesGpuReads, |
47 | | // Buffers that will be accessed on the host and copied to another GPU resource (transfer |
48 | | // buffers). Will always be mappable and coherent memory. |
49 | | kTransfersFromCpuToGpu, |
50 | | // Buffers which are typically writted to by the GPU and then read on the host. Will always |
51 | | // be mappable memory, and will prefer cached memory. |
52 | | kTransfersFromGpuToCpu, |
53 | | }; |
54 | | |
55 | | virtual VkResult allocateImageMemory(VkImage image, |
56 | | uint32_t allocationPropertyFlags, |
57 | | skgpu::VulkanBackendMemory* memory) = 0; |
58 | | |
59 | | virtual VkResult allocateBufferMemory(VkBuffer buffer, |
60 | | BufferUsage usage, |
61 | | uint32_t allocationPropertyFlags, |
62 | | skgpu::VulkanBackendMemory* memory) = 0; |
63 | | |
64 | | // Fills out the passed in skgpu::VulkanAlloc struct for the passed in |
65 | | // skgpu::VulkanBackendMemory. |
66 | | virtual void getAllocInfo(const skgpu::VulkanBackendMemory&, skgpu::VulkanAlloc*) const = 0; |
67 | | |
68 | | // Maps the entire allocation and returns a pointer to the start of the allocation. The |
69 | | // implementation may map more memory than just the allocation, but the returned pointer must |
70 | | // point at the start of the memory for the requested allocation. |
71 | 0 | virtual void* mapMemory(const skgpu::VulkanBackendMemory&) { return nullptr; } |
72 | 0 | virtual VkResult mapMemory(const skgpu::VulkanBackendMemory& memory, void** data) { |
73 | 0 | *data = this->mapMemory(memory); |
74 | | // VK_ERROR_INITIALIZATION_FAILED is a bogus result to return from this function, but it is |
75 | | // just something to return that is not VK_SUCCESS and can't be interpreted by a caller to |
76 | | // mean something specific happened like device lost or oom. This will be removed once we |
77 | | // update clients to implement this virtual. |
78 | 0 | return *data ? VK_SUCCESS : VK_ERROR_INITIALIZATION_FAILED; |
79 | 0 | } |
80 | | virtual void unmapMemory(const skgpu::VulkanBackendMemory&) = 0; |
81 | | |
82 | | // The following two calls are used for managing non-coherent memory. The offset is relative to |
83 | | // the start of the allocation and not the underlying VkDeviceMemory. Additionaly the client |
84 | | // must make sure that the offset + size passed in is less that or equal to the allocation size. |
85 | | // It is the responsibility of the implementation to make sure all alignment requirements are |
86 | | // followed. The client should not have to deal with any sort of alignment issues. |
87 | 0 | virtual void flushMappedMemory(const skgpu::VulkanBackendMemory&, VkDeviceSize, VkDeviceSize) {} |
88 | | virtual VkResult flushMemory(const skgpu::VulkanBackendMemory& memory, |
89 | | VkDeviceSize offset, |
90 | 0 | VkDeviceSize size) { |
91 | 0 | this->flushMappedMemory(memory, offset, size); |
92 | 0 | return VK_SUCCESS; |
93 | 0 | } |
94 | | virtual void invalidateMappedMemory(const skgpu::VulkanBackendMemory&, |
95 | | VkDeviceSize, |
96 | 0 | VkDeviceSize) {} |
97 | | virtual VkResult invalidateMemory(const skgpu::VulkanBackendMemory& memory, |
98 | | VkDeviceSize offset, |
99 | 0 | VkDeviceSize size) { |
100 | 0 | this->invalidateMappedMemory(memory, offset, size); |
101 | 0 | return VK_SUCCESS; |
102 | 0 | } |
103 | | |
104 | | virtual void freeMemory(const skgpu::VulkanBackendMemory&) = 0; |
105 | | |
106 | | // Returns the total amount of memory that is allocated as well as total |
107 | | // amount of memory in use by an allocation from this allocator. |
108 | | // Return 1st param is total allocated memory, 2nd is total used memory. |
109 | | virtual std::pair<uint64_t, uint64_t> totalAllocatedAndUsedMemory() const = 0; |
110 | | }; |
111 | | |
112 | | } // namespace skgpu |
113 | | |
114 | | #endif // skgpu_VulkanMemoryAllocator_DEFINED |