Home | History | Annotate | Download | only in vk
      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, VkDeviceSize offset,
     42                           VkDeviceSize size);
     43     void InvalidateMappedAlloc(const GrVkGpu* gpu, const GrVkAlloc& alloc, VkDeviceSize offset,
     44                                VkDeviceSize size);
     45 }
     46 
     47 class GrVkFreeListAlloc {
     48 public:
     49     GrVkFreeListAlloc(VkDeviceSize size, VkDeviceSize alignment)
     50         : fSize(size)
     51         , fAlignment(alignment)
     52         , fFreeSize(size)
     53         , fLargestBlockSize(size)
     54         , fLargestBlockOffset(0) {
     55         Block* block = fFreeList.addToTail();
     56         block->fOffset = 0;
     57         block->fSize = fSize;
     58     }
     59     ~GrVkFreeListAlloc() {
     60         this->reset();
     61     }
     62 
     63     VkDeviceSize size() const { return fSize; }
     64     VkDeviceSize alignment() const { return fAlignment; }
     65     VkDeviceSize freeSize() const { return fFreeSize; }
     66     VkDeviceSize largestBlockSize() const { return fLargestBlockSize; }
     67 
     68     bool unallocated() const { return fSize == fFreeSize; }
     69 
     70 protected:
     71     bool alloc(VkDeviceSize requestedSize, VkDeviceSize* allocOffset, VkDeviceSize* allocSize);
     72     void free(VkDeviceSize allocOffset, VkDeviceSize allocSize);
     73 
     74     void reset() {
     75         fSize = 0;
     76         fAlignment = 0;
     77         fFreeSize = 0;
     78         fLargestBlockSize = 0;
     79         fFreeList.reset();
     80     }
     81 
     82     struct Block {
     83         VkDeviceSize fOffset;
     84         VkDeviceSize fSize;
     85     };
     86     typedef SkTLList<Block, 16> FreeList;
     87 
     88     VkDeviceSize   fSize;
     89     VkDeviceSize   fAlignment;
     90     VkDeviceSize   fFreeSize;
     91     VkDeviceSize   fLargestBlockSize;
     92     VkDeviceSize   fLargestBlockOffset;
     93     FreeList       fFreeList;
     94 };
     95 
     96 class GrVkSubHeap : public GrVkFreeListAlloc {
     97 public:
     98     GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex, uint32_t heapIndex,
     99                 VkDeviceSize size, VkDeviceSize alignment);
    100     ~GrVkSubHeap();
    101 
    102     uint32_t memoryTypeIndex() const { return fMemoryTypeIndex; }
    103     VkDeviceMemory memory() { return fAlloc; }
    104 
    105     bool alloc(VkDeviceSize requestedSize, GrVkAlloc* alloc);
    106     void free(const GrVkAlloc& alloc);
    107 
    108 private:
    109     const GrVkGpu* fGpu;
    110 #ifdef SK_DEBUG
    111     uint32_t       fHeapIndex;
    112 #endif
    113     uint32_t       fMemoryTypeIndex;
    114     VkDeviceMemory fAlloc;
    115 
    116     typedef GrVkFreeListAlloc INHERITED;
    117 };
    118 
    119 class GrVkHeap {
    120 public:
    121     enum Strategy {
    122         kSubAlloc_Strategy,       // alloc large subheaps and suballoc within them
    123         kSingleAlloc_Strategy     // alloc/recycle an individual subheap per object
    124     };
    125 
    126     GrVkHeap(const GrVkGpu* gpu, Strategy strategy, VkDeviceSize subHeapSize)
    127         : fGpu(gpu)
    128         , fSubHeapSize(subHeapSize)
    129         , fAllocSize(0)
    130         , fUsedSize(0) {
    131         if (strategy == kSubAlloc_Strategy) {
    132             fAllocFunc = &GrVkHeap::subAlloc;
    133         } else {
    134             fAllocFunc = &GrVkHeap::singleAlloc;
    135         }
    136     }
    137 
    138     ~GrVkHeap() {}
    139 
    140     VkDeviceSize allocSize() const { return fAllocSize; }
    141     VkDeviceSize usedSize() const { return fUsedSize; }
    142 
    143     bool alloc(VkDeviceSize size, VkDeviceSize alignment, uint32_t memoryTypeIndex,
    144                uint32_t heapIndex, GrVkAlloc* alloc) {
    145         SkASSERT(size > 0);
    146         alloc->fUsesSystemHeap = false;
    147         return (*this.*fAllocFunc)(size, alignment, memoryTypeIndex, heapIndex, alloc);
    148     }
    149     bool free(const GrVkAlloc& alloc);
    150 
    151 private:
    152     typedef bool (GrVkHeap::*AllocFunc)(VkDeviceSize size, VkDeviceSize alignment,
    153                                         uint32_t memoryTypeIndex, uint32_t heapIndex,
    154                                         GrVkAlloc* alloc);
    155 
    156     bool subAlloc(VkDeviceSize size, VkDeviceSize alignment,
    157                   uint32_t memoryTypeIndex, uint32_t heapIndex,
    158                   GrVkAlloc* alloc);
    159     bool singleAlloc(VkDeviceSize size, VkDeviceSize alignment,
    160                      uint32_t memoryTypeIndex, uint32_t heapIndex,
    161                      GrVkAlloc* alloc);
    162 
    163     const GrVkGpu*         fGpu;
    164     VkDeviceSize           fSubHeapSize;
    165     VkDeviceSize           fAllocSize;
    166     VkDeviceSize           fUsedSize;
    167     AllocFunc              fAllocFunc;
    168     SkTArray<std::unique_ptr<GrVkSubHeap>> fSubHeaps;
    169 };
    170 #endif
    171