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