| /* | |
| * Copyright 2015 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "GrVkUniformBuffer.h" | |
| #include "GrVkGpu.h" | |
| #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) | |
| GrVkUniformBuffer* GrVkUniformBuffer::Create(GrVkGpu* gpu, size_t size) { | |
| if (0 == size) { | |
| return nullptr; | |
| } | |
| const GrVkResource* resource = nullptr; | |
| if (size <= GrVkUniformBuffer::kStandardSize) { | |
| resource = gpu->resourceProvider().findOrCreateStandardUniformBufferResource(); | |
| } else { | |
| resource = CreateResource(gpu, size); | |
| } | |
| if (!resource) { | |
| return nullptr; | |
| } | |
| GrVkBuffer::Desc desc; | |
| desc.fDynamic = true; | |
| desc.fType = GrVkBuffer::kUniform_Type; | |
| desc.fSizeInBytes = size; | |
| GrVkUniformBuffer* buffer = new GrVkUniformBuffer(gpu, desc, | |
| (const GrVkUniformBuffer::Resource*) resource); | |
| if (!buffer) { | |
| // this will destroy anything we got from the resource provider, | |
| // but this avoids a conditional | |
| resource->unref(gpu); | |
| } | |
| return buffer; | |
| } | |
| // We implement our own creation function for special buffer resource type | |
| const GrVkResource* GrVkUniformBuffer::CreateResource(GrVkGpu* gpu, size_t size) { | |
| if (0 == size) { | |
| return nullptr; | |
| } | |
| VkBuffer buffer; | |
| GrVkAlloc alloc; | |
| // create the buffer object | |
| VkBufferCreateInfo bufInfo; | |
| memset(&bufInfo, 0, sizeof(VkBufferCreateInfo)); | |
| bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; | |
| bufInfo.flags = 0; | |
| bufInfo.size = size; | |
| bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; | |
| bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; | |
| bufInfo.queueFamilyIndexCount = 0; | |
| bufInfo.pQueueFamilyIndices = nullptr; | |
| VkResult err; | |
| err = VK_CALL(gpu, CreateBuffer(gpu->device(), &bufInfo, nullptr, &buffer)); | |
| if (err) { | |
| return nullptr; | |
| } | |
| if (!GrVkMemory::AllocAndBindBufferMemory(gpu, | |
| buffer, | |
| kUniform_Type, | |
| true, // dynamic | |
| &alloc)) { | |
| return nullptr; | |
| } | |
| const GrVkResource* resource = new GrVkUniformBuffer::Resource(buffer, alloc); | |
| if (!resource) { | |
| VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); | |
| GrVkMemory::FreeBufferMemory(gpu, kUniform_Type, alloc); | |
| return nullptr; | |
| } | |
| return resource; | |
| } | |
| const GrVkBuffer::Resource* GrVkUniformBuffer::createResource(GrVkGpu* gpu, | |
| const GrVkBuffer::Desc& descriptor) { | |
| const GrVkResource* vkResource; | |
| if (descriptor.fSizeInBytes <= GrVkUniformBuffer::kStandardSize) { | |
| GrVkResourceProvider& provider = gpu->resourceProvider(); | |
| vkResource = provider.findOrCreateStandardUniformBufferResource(); | |
| } else { | |
| vkResource = CreateResource(gpu, descriptor.fSizeInBytes); | |
| } | |
| return (const GrVkBuffer::Resource*) vkResource; | |
| } | |
| void GrVkUniformBuffer::Resource::onRecycle(GrVkGpu* gpu) const { | |
| if (fAlloc.fSize <= GrVkUniformBuffer::kStandardSize) { | |
| gpu->resourceProvider().recycleStandardUniformBufferResource(this); | |
| } else { | |
| this->unref(gpu); | |
| } | |
| } |