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 "GrVkUniformBuffer.h"
9 #include "GrVkGpu.h"
10
11 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
12
Create(GrVkGpu * gpu,size_t size)13 GrVkUniformBuffer* GrVkUniformBuffer::Create(GrVkGpu* gpu, size_t size) {
14 if (0 == size) {
15 return nullptr;
16 }
17 const GrVkResource* resource = nullptr;
18 if (size <= GrVkUniformBuffer::kStandardSize) {
19 resource = gpu->resourceProvider().findOrCreateStandardUniformBufferResource();
20 } else {
21 resource = CreateResource(gpu, size);
22 }
23 if (!resource) {
24 return nullptr;
25 }
26
27 GrVkBuffer::Desc desc;
28 desc.fDynamic = true;
29 desc.fType = GrVkBuffer::kUniform_Type;
30 desc.fSizeInBytes = size;
31 GrVkUniformBuffer* buffer = new GrVkUniformBuffer(gpu, desc,
32 (const GrVkUniformBuffer::Resource*) resource);
33 if (!buffer) {
34 // this will destroy anything we got from the resource provider,
35 // but this avoids a conditional
36 resource->unref(gpu);
37 }
38 return buffer;
39 }
40
41 // We implement our own creation function for special buffer resource type
CreateResource(GrVkGpu * gpu,size_t size)42 const GrVkResource* GrVkUniformBuffer::CreateResource(GrVkGpu* gpu, size_t size) {
43 if (0 == size) {
44 return nullptr;
45 }
46
47 VkBuffer buffer;
48 GrVkAlloc alloc;
49
50 // create the buffer object
51 VkBufferCreateInfo bufInfo;
52 memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
53 bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
54 bufInfo.flags = 0;
55 bufInfo.size = size;
56 bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
57 bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
58 bufInfo.queueFamilyIndexCount = 0;
59 bufInfo.pQueueFamilyIndices = nullptr;
60
61 VkResult err;
62 err = VK_CALL(gpu, CreateBuffer(gpu->device(), &bufInfo, nullptr, &buffer));
63 if (err) {
64 return nullptr;
65 }
66
67 if (!GrVkMemory::AllocAndBindBufferMemory(gpu,
68 buffer,
69 kUniform_Type,
70 true, // dynamic
71 &alloc)) {
72 return nullptr;
73 }
74
75 const GrVkResource* resource = new GrVkUniformBuffer::Resource(buffer, alloc);
76 if (!resource) {
77 VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr));
78 GrVkMemory::FreeBufferMemory(gpu, kUniform_Type, alloc);
79 return nullptr;
80 }
81
82 return resource;
83 }
84
createResource(GrVkGpu * gpu,const GrVkBuffer::Desc & descriptor)85 const GrVkBuffer::Resource* GrVkUniformBuffer::createResource(GrVkGpu* gpu,
86 const GrVkBuffer::Desc& descriptor) {
87 const GrVkResource* vkResource;
88 if (descriptor.fSizeInBytes <= GrVkUniformBuffer::kStandardSize) {
89 GrVkResourceProvider& provider = gpu->resourceProvider();
90 vkResource = provider.findOrCreateStandardUniformBufferResource();
91 } else {
92 vkResource = CreateResource(gpu, descriptor.fSizeInBytes);
93 }
94 return (const GrVkBuffer::Resource*) vkResource;
95 }
96
onRecycle(GrVkGpu * gpu) const97 void GrVkUniformBuffer::Resource::onRecycle(GrVkGpu* gpu) const {
98 if (fAlloc.fSize <= GrVkUniformBuffer::kStandardSize) {
99 gpu->resourceProvider().recycleStandardUniformBufferResource(this);
100 } else {
101 this->unref(gpu);
102 }
103 }
104