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 GrVkBuffer_DEFINED
9 #define GrVkBuffer_DEFINED
10 
11 #include "include/gpu/vk/GrVkTypes.h"
12 #include "src/gpu/vk/GrVkResource.h"
13 
14 class GrVkGpu;
15 
16 /**
17  * This class serves as the base of GrVk*Buffer classes. It was written to avoid code
18  * duplication in those classes.
19  */
20 class GrVkBuffer : public SkNoncopyable {
21 public:
~GrVkBuffer()22     virtual ~GrVkBuffer() {
23         // either release or abandon should have been called by the owner of this object.
24         SkASSERT(!fResource);
25         delete [] (unsigned char*)fMapPtr;
26     }
27 
buffer()28     VkBuffer                    buffer() const { return fResource->fBuffer; }
alloc()29     const GrVkAlloc&            alloc() const { return fResource->fAlloc; }
resource()30     const GrVkRecycledResource* resource() const { return fResource; }
size()31     size_t                      size() const { return fDesc.fSizeInBytes; }
offset()32     VkDeviceSize                offset() const { return fOffset;  }
33 
34     void addMemoryBarrier(const GrVkGpu* gpu,
35                           VkAccessFlags srcAccessMask,
36                           VkAccessFlags dstAccessMask,
37                           VkPipelineStageFlags srcStageMask,
38                           VkPipelineStageFlags dstStageMask,
39                           bool byRegion) const;
40 
41     enum Type {
42         kVertex_Type,
43         kIndex_Type,
44         kUniform_Type,
45         kTexel_Type,
46         kCopyRead_Type,
47         kCopyWrite_Type,
48     };
49 
50 protected:
51     struct Desc {
52         size_t      fSizeInBytes;
53         Type        fType;         // vertex buffer, index buffer, etc.
54         bool        fDynamic;
55     };
56 
57     class Resource : public GrVkRecycledResource {
58     public:
Resource(VkBuffer buf,const GrVkAlloc & alloc,Type type)59         Resource(VkBuffer buf, const GrVkAlloc& alloc, Type type)
60             : INHERITED(), fBuffer(buf), fAlloc(alloc), fType(type) {}
61 
62 #ifdef SK_TRACE_VK_RESOURCES
dumpInfo()63         void dumpInfo() const override {
64             SkDebugf("GrVkBuffer: %d (%d refs)\n", fBuffer, this->getRefCnt());
65         }
66 #endif
67         VkBuffer           fBuffer;
68         GrVkAlloc          fAlloc;
69         Type               fType;
70 
71     private:
72         void freeGPUData(GrVkGpu* gpu) const override;
73 
onRecycle(GrVkGpu * gpu)74         void onRecycle(GrVkGpu* gpu) const override { this->unref(gpu); }
75 
76         typedef GrVkRecycledResource INHERITED;
77     };
78 
79     // convenience routine for raw buffer creation
80     static const Resource* Create(const GrVkGpu* gpu,
81                                   const Desc& descriptor);
82 
GrVkBuffer(const Desc & desc,const GrVkBuffer::Resource * resource)83     GrVkBuffer(const Desc& desc, const GrVkBuffer::Resource* resource)
84         : fDesc(desc), fResource(resource), fOffset(0), fMapPtr(nullptr) {
85     }
86 
vkMap(GrVkGpu * gpu)87     void* vkMap(GrVkGpu* gpu) {
88         this->internalMap(gpu, fDesc.fSizeInBytes);
89         return fMapPtr;
90     }
vkUnmap(GrVkGpu * gpu)91     void vkUnmap(GrVkGpu* gpu) { this->internalUnmap(gpu, this->size()); }
92 
93     // If the caller passes in a non null createdNewBuffer, this function will set the bool to true
94     // if it creates a new VkBuffer to upload the data to.
95     bool vkUpdateData(GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
96                       bool* createdNewBuffer = nullptr);
97 
98     void vkAbandon();
99     void vkRelease(const GrVkGpu* gpu);
100 
101 private:
createResource(GrVkGpu * gpu,const Desc & descriptor)102     virtual const Resource* createResource(GrVkGpu* gpu,
103                                            const Desc& descriptor) {
104         return Create(gpu, descriptor);
105     }
106 
107     void internalMap(GrVkGpu* gpu, size_t size, bool* createdNewBuffer = nullptr);
108     void internalUnmap(GrVkGpu* gpu, size_t size);
109     void copyCpuDataToGpuBuffer(GrVkGpu* gpu, const void* srcData, size_t size);
110 
111     void validate() const;
112     bool vkIsMapped() const;
113 
114     Desc                    fDesc;
115     const Resource*         fResource;
116     VkDeviceSize            fOffset;
117     void*                   fMapPtr;
118 
119     typedef SkNoncopyable INHERITED;
120 };
121 
122 #endif
123