/* * 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); } }