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