• 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 #include "GrVkBuffer.h"
9 #include "GrVkGpu.h"
10 #include "GrVkMemory.h"
11 #include "GrVkUtil.h"
12 
13 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
14 
15 #ifdef SK_DEBUG
16 #define VALIDATE() this->validate()
17 #else
18 #define VALIDATE() do {} while(false)
19 #endif
20 
Create(const GrVkGpu * gpu,const Desc & desc)21 const GrVkBuffer::Resource* GrVkBuffer::Create(const GrVkGpu* gpu, const Desc& desc) {
22     VkBuffer       buffer;
23     VkDeviceMemory alloc;
24 
25     // create the buffer object
26     VkBufferCreateInfo bufInfo;
27     memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
28     bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
29     bufInfo.flags = 0;
30     bufInfo.size = desc.fSizeInBytes;
31     switch (desc.fType) {
32     case kVertex_Type:
33         bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
34         break;
35     case kIndex_Type:
36         bufInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
37         break;
38     case kUniform_Type:
39         bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
40         break;
41     case kCopyRead_Type:
42         bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
43         break;
44     case kCopyWrite_Type:
45         bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
46         break;
47 
48     }
49     bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
50     bufInfo.queueFamilyIndexCount = 0;
51     bufInfo.pQueueFamilyIndices = nullptr;
52 
53     VkResult err;
54     err = VK_CALL(gpu, CreateBuffer(gpu->device(), &bufInfo, nullptr, &buffer));
55     if (err) {
56         return nullptr;
57     }
58 
59     VkMemoryPropertyFlags requiredMemProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
60                                              VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
61 
62     if (!GrVkMemory::AllocAndBindBufferMemory(gpu,
63                                               buffer,
64                                               requiredMemProps,
65                                               &alloc)) {
66         VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr));
67         return nullptr;
68     }
69 
70     const GrVkBuffer::Resource* resource = new GrVkBuffer::Resource(buffer, alloc);
71     if (!resource) {
72         VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr));
73         VK_CALL(gpu, FreeMemory(gpu->device(), alloc, nullptr));
74         return nullptr;
75     }
76 
77     return resource;
78 }
79 
80 
addMemoryBarrier(const GrVkGpu * gpu,VkAccessFlags srcAccessMask,VkAccessFlags dstAccesMask,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,bool byRegion) const81 void GrVkBuffer::addMemoryBarrier(const GrVkGpu* gpu,
82                                   VkAccessFlags srcAccessMask,
83                                   VkAccessFlags dstAccesMask,
84                                   VkPipelineStageFlags srcStageMask,
85                                   VkPipelineStageFlags dstStageMask,
86                                   bool byRegion) const {
87     VkBufferMemoryBarrier bufferMemoryBarrier = {
88         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType
89         NULL,                                    // pNext
90         srcAccessMask,                           // srcAccessMask
91         dstAccesMask,                            // dstAccessMask
92         VK_QUEUE_FAMILY_IGNORED,                 // srcQueueFamilyIndex
93         VK_QUEUE_FAMILY_IGNORED,                 // dstQueueFamilyIndex
94         this->buffer(),                          // buffer
95         0,                                       // offset
96         fDesc.fSizeInBytes,                      // size
97     };
98 
99     // TODO: restrict to area of buffer we're interested in
100     gpu->addBufferMemoryBarrier(srcStageMask, dstStageMask, byRegion, &bufferMemoryBarrier);
101 }
102 
freeGPUData(const GrVkGpu * gpu) const103 void GrVkBuffer::Resource::freeGPUData(const GrVkGpu* gpu) const {
104     SkASSERT(fBuffer);
105     SkASSERT(fAlloc);
106     VK_CALL(gpu, DestroyBuffer(gpu->device(), fBuffer, nullptr));
107     VK_CALL(gpu, FreeMemory(gpu->device(), fAlloc, nullptr));
108 }
109 
vkRelease(const GrVkGpu * gpu)110 void GrVkBuffer::vkRelease(const GrVkGpu* gpu) {
111     VALIDATE();
112     fResource->unref(gpu);
113     fResource = nullptr;
114     fMapPtr = nullptr;
115     VALIDATE();
116 }
117 
vkAbandon()118 void GrVkBuffer::vkAbandon() {
119     fResource->unrefAndAbandon();
120     fMapPtr = nullptr;
121     VALIDATE();
122 }
123 
vkMap(const GrVkGpu * gpu)124 void* GrVkBuffer::vkMap(const GrVkGpu* gpu) {
125     VALIDATE();
126     SkASSERT(!this->vkIsMapped());
127 
128     VkResult err = VK_CALL(gpu, MapMemory(gpu->device(), alloc(), 0, VK_WHOLE_SIZE, 0, &fMapPtr));
129     if (err) {
130         fMapPtr = nullptr;
131     }
132 
133     VALIDATE();
134     return fMapPtr;
135 }
136 
vkUnmap(const GrVkGpu * gpu)137 void GrVkBuffer::vkUnmap(const GrVkGpu* gpu) {
138     VALIDATE();
139     SkASSERT(this->vkIsMapped());
140 
141     VK_CALL(gpu, UnmapMemory(gpu->device(), alloc()));
142 
143     fMapPtr = nullptr;
144 }
145 
vkIsMapped() const146 bool GrVkBuffer::vkIsMapped() const {
147     VALIDATE();
148     return SkToBool(fMapPtr);
149 }
150 
vkUpdateData(const GrVkGpu * gpu,const void * src,size_t srcSizeInBytes)151 bool GrVkBuffer::vkUpdateData(const GrVkGpu* gpu, const void* src, size_t srcSizeInBytes) {
152     SkASSERT(!this->vkIsMapped());
153     VALIDATE();
154     if (srcSizeInBytes > fDesc.fSizeInBytes) {
155         return false;
156     }
157 
158     void* mapPtr;
159     VkResult err = VK_CALL(gpu, MapMemory(gpu->device(), alloc(), 0, srcSizeInBytes, 0, &mapPtr));
160 
161     if (VK_SUCCESS != err) {
162         return false;
163     }
164 
165     memcpy(mapPtr, src, srcSizeInBytes);
166 
167     VK_CALL(gpu, UnmapMemory(gpu->device(), alloc()));
168 
169     return true;
170 }
171 
validate() const172 void GrVkBuffer::validate() const {
173     SkASSERT(!fResource || kVertex_Type == fDesc.fType || kIndex_Type == fDesc.fType
174              || kCopyRead_Type == fDesc.fType || kCopyWrite_Type == fDesc.fType
175              || kUniform_Type == fDesc.fType);
176 }
177 
178