• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2015 Google Inc.
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 GrVkMemory_DEFINED
9 #define GrVkMemory_DEFINED
10 
11 #include "GrVkBuffer.h"
12 #include "SkTArray.h"
13 #include "SkTLList.h"
14 #include "vk/GrVkDefines.h"
15 #include "vk/GrVkTypes.h"
16 
17 class GrVkGpu;
18 
19 namespace GrVkMemory {
20     /**
21     * Allocates vulkan device memory and binds it to the gpu's device for the given object.
22     * Returns true if allocation succeeded.
23     */
24     bool AllocAndBindBufferMemory(const GrVkGpu* gpu,
25                                   VkBuffer buffer,
26                                   GrVkBuffer::Type type,
27                                   bool dynamic,
28                                   GrVkAlloc* alloc);
29     void FreeBufferMemory(const GrVkGpu* gpu, GrVkBuffer::Type type, const GrVkAlloc& alloc);
30 
31     bool AllocAndBindImageMemory(const GrVkGpu* gpu,
32                                  VkImage image,
33                                  bool linearTiling,
34                                  GrVkAlloc* alloc);
35     void FreeImageMemory(const GrVkGpu* gpu, bool linearTiling, const GrVkAlloc& alloc);
36 
37     VkPipelineStageFlags LayoutToPipelineStageFlags(const VkImageLayout layout);
38 
39     VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
40 
41     void FlushMappedAlloc(const GrVkGpu* gpu, const GrVkAlloc& alloc);
42     void InvalidateMappedAlloc(const GrVkGpu* gpu, const GrVkAlloc& alloc);
43 }
44 
45 class GrVkFreeListAlloc {
46 public:
GrVkFreeListAlloc(VkDeviceSize size,VkDeviceSize alignment)47     GrVkFreeListAlloc(VkDeviceSize size, VkDeviceSize alignment)
48         : fSize(size)
49         , fAlignment(alignment)
50         , fFreeSize(size)
51         , fLargestBlockSize(size)
52         , fLargestBlockOffset(0) {
53         Block* block = fFreeList.addToTail();
54         block->fOffset = 0;
55         block->fSize = fSize;
56     }
~GrVkFreeListAlloc()57     ~GrVkFreeListAlloc() {
58         this->reset();
59     }
60 
size()61     VkDeviceSize size() const { return fSize; }
alignment()62     VkDeviceSize alignment() const { return fAlignment; }
freeSize()63     VkDeviceSize freeSize() const { return fFreeSize; }
largestBlockSize()64     VkDeviceSize largestBlockSize() const { return fLargestBlockSize; }
65 
unallocated()66     bool unallocated() const { return fSize == fFreeSize; }
67 
68 protected:
69     bool alloc(VkDeviceSize requestedSize, VkDeviceSize* allocOffset, VkDeviceSize* allocSize);
70     void free(VkDeviceSize allocOffset, VkDeviceSize allocSize);
71 
reset()72     void reset() {
73         fSize = 0;
74         fAlignment = 0;
75         fFreeSize = 0;
76         fLargestBlockSize = 0;
77         fFreeList.reset();
78     }
79 
80     struct Block {
81         VkDeviceSize fOffset;
82         VkDeviceSize fSize;
83     };
84     typedef SkTLList<Block, 16> FreeList;
85 
86     VkDeviceSize   fSize;
87     VkDeviceSize   fAlignment;
88     VkDeviceSize   fFreeSize;
89     VkDeviceSize   fLargestBlockSize;
90     VkDeviceSize   fLargestBlockOffset;
91     FreeList       fFreeList;
92 };
93 
94 class GrVkSubHeap : public GrVkFreeListAlloc {
95 public:
96     GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex, uint32_t heapIndex,
97                 VkDeviceSize size, VkDeviceSize alignment);
98     ~GrVkSubHeap();
99 
memoryTypeIndex()100     uint32_t memoryTypeIndex() const { return fMemoryTypeIndex; }
memory()101     VkDeviceMemory memory() { return fAlloc; }
102 
103     bool alloc(VkDeviceSize requestedSize, GrVkAlloc* alloc);
104     void free(const GrVkAlloc& alloc);
105 
106 private:
107     const GrVkGpu* fGpu;
108 #ifdef SK_DEBUG
109     uint32_t       fHeapIndex;
110 #endif
111     uint32_t       fMemoryTypeIndex;
112     VkDeviceMemory fAlloc;
113 
114     typedef GrVkFreeListAlloc INHERITED;
115 };
116 
117 class GrVkHeap {
118 public:
119     enum Strategy {
120         kSubAlloc_Strategy,       // alloc large subheaps and suballoc within them
121         kSingleAlloc_Strategy     // alloc/recycle an individual subheap per object
122     };
123 
GrVkHeap(const GrVkGpu * gpu,Strategy strategy,VkDeviceSize subHeapSize)124     GrVkHeap(const GrVkGpu* gpu, Strategy strategy, VkDeviceSize subHeapSize)
125         : fGpu(gpu)
126         , fSubHeapSize(subHeapSize)
127         , fAllocSize(0)
128         , fUsedSize(0) {
129         if (strategy == kSubAlloc_Strategy) {
130             fAllocFunc = &GrVkHeap::subAlloc;
131         } else {
132             fAllocFunc = &GrVkHeap::singleAlloc;
133         }
134     }
135 
~GrVkHeap()136     ~GrVkHeap() {}
137 
allocSize()138     VkDeviceSize allocSize() const { return fAllocSize; }
usedSize()139     VkDeviceSize usedSize() const { return fUsedSize; }
140 
alloc(VkDeviceSize size,VkDeviceSize alignment,uint32_t memoryTypeIndex,uint32_t heapIndex,GrVkAlloc * alloc)141     bool alloc(VkDeviceSize size, VkDeviceSize alignment, uint32_t memoryTypeIndex,
142                uint32_t heapIndex, GrVkAlloc* alloc) {
143         SkASSERT(size > 0);
144         return (*this.*fAllocFunc)(size, alignment, memoryTypeIndex, heapIndex, alloc);
145     }
146     bool free(const GrVkAlloc& alloc);
147 
148 private:
149     typedef bool (GrVkHeap::*AllocFunc)(VkDeviceSize size, VkDeviceSize alignment,
150                                         uint32_t memoryTypeIndex, uint32_t heapIndex,
151                                         GrVkAlloc* alloc);
152 
153     bool subAlloc(VkDeviceSize size, VkDeviceSize alignment,
154                   uint32_t memoryTypeIndex, uint32_t heapIndex,
155                   GrVkAlloc* alloc);
156     bool singleAlloc(VkDeviceSize size, VkDeviceSize alignment,
157                      uint32_t memoryTypeIndex, uint32_t heapIndex,
158                      GrVkAlloc* alloc);
159 
160     const GrVkGpu*         fGpu;
161     VkDeviceSize           fSubHeapSize;
162     VkDeviceSize           fAllocSize;
163     VkDeviceSize           fUsedSize;
164     AllocFunc              fAllocFunc;
165     SkTArray<std::unique_ptr<GrVkSubHeap>> fSubHeaps;
166 };
167 #endif
168