blob: ac013f7dfe7a8b3ae178d992eec5a3dd4892c3f9 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
jvanverth4c6e47a2016-07-22 10:34:52 -070011#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
Greg Daniel164a9f02016-02-22 09:56:40 -050012
jvanverth4c6e47a2016-07-22 10:34:52 -070013GrVkUniformBuffer* GrVkUniformBuffer::Create(GrVkGpu* gpu, size_t size) {
Greg Daniel164a9f02016-02-22 09:56:40 -050014 if (0 == size) {
15 return nullptr;
16 }
jvanverth4c6e47a2016-07-22 10:34:52 -070017 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) {
Greg Daniel164a9f02016-02-22 09:56:40 -050024 return nullptr;
25 }
26
jvanverth4c6e47a2016-07-22 10:34:52 -070027 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);
Greg Daniel164a9f02016-02-22 09:56:40 -050033 if (!buffer) {
jvanverth4c6e47a2016-07-22 10:34:52 -070034 // this will destroy anything we got from the resource provider,
35 // but this avoids a conditional
36 resource->unref(gpu);
Greg Daniel164a9f02016-02-22 09:56:40 -050037 }
38 return buffer;
jvanverth4c6e47a2016-07-22 10:34:52 -070039}
40
41// We implement our own creation function for special buffer resource type
42const 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
egdaniel31bc7df2016-07-29 10:46:06 -070085const 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
jvanverth4c6e47a2016-07-22 10:34:52 -070097void 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}