/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "GrVkDescriptorSetManager.h"

#include "GrVkDescriptorPool.h"
#include "GrVkDescriptorSet.h"
#include "GrVkGpu.h"
#include "GrVkUniformHandler.h"
#include "glsl/GrGLSLSampler.h"

GrVkDescriptorSetManager::GrVkDescriptorSetManager(GrVkGpu* gpu,
                                                   VkDescriptorType type,
                                                   const GrVkUniformHandler* uniformHandler)
    : fPoolManager(type, gpu, uniformHandler) {
    if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
        SkASSERT(uniformHandler);
        for (int i = 0; i < uniformHandler->numSamplers(); ++i) {
            fBindingVisibilities.push_back(uniformHandler->getSampler(i).visibility());
        }
    } else {
        SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
        // We set the visibility of the first binding to the vertex shader and the second to the
        // fragment shader.
        fBindingVisibilities.push_back(kVertex_GrShaderFlag);
        fBindingVisibilities.push_back(kFragment_GrShaderFlag);
    }
}

const GrVkDescriptorSet* GrVkDescriptorSetManager::getDescriptorSet(GrVkGpu* gpu,
                                                                    const Handle& handle) {
    const GrVkDescriptorSet* ds = nullptr;
    int count = fFreeSets.count();
    if (count > 0) {
        ds = fFreeSets[count - 1];
        fFreeSets.removeShuffle(count - 1);
    } else {
        VkDescriptorSet vkDS;
        fPoolManager.getNewDescriptorSet(gpu, &vkDS);

        ds = new GrVkDescriptorSet(vkDS, fPoolManager.fPool, handle);
    }
    SkASSERT(ds);
    return ds;
}

void GrVkDescriptorSetManager::recycleDescriptorSet(const GrVkDescriptorSet* descSet) {
    SkASSERT(descSet);
    fFreeSets.push_back(descSet);
}

void GrVkDescriptorSetManager::release(const GrVkGpu* gpu) {
    fPoolManager.freeGPUResources(gpu);

    for (int i = 0; i < fFreeSets.count(); ++i) {
        fFreeSets[i]->unref(gpu);
    }
    fFreeSets.reset();
}

void GrVkDescriptorSetManager::abandon() {
    fPoolManager.abandonGPUResources();

    for (int i = 0; i < fFreeSets.count(); ++i) {
        fFreeSets[i]->unrefAndAbandon();
    }
    fFreeSets.reset();
}

bool GrVkDescriptorSetManager::isCompatible(VkDescriptorType type,
                                            const GrVkUniformHandler* uniHandler) const {
    SkASSERT(uniHandler);
    if (type != fPoolManager.fDescType) {
        return false;
    }

    if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
        if (fBindingVisibilities.count() != uniHandler->numSamplers()) {
            return false;
        }
        for (int i = 0; i < uniHandler->numSamplers(); ++i) {
            if (uniHandler->getSampler(i).visibility() != fBindingVisibilities[i]) {
                return false;
            }
        }
    }
    return true;
}

////////////////////////////////////////////////////////////////////////////////

VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
    VkShaderStageFlags flags = 0;

    if (visibility & kVertex_GrShaderFlag) {
        flags |= VK_SHADER_STAGE_VERTEX_BIT;
    }
    if (visibility & kGeometry_GrShaderFlag) {
        flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
    }
    if (visibility & kFragment_GrShaderFlag) {
        flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
    }
    return flags;
}

GrVkDescriptorSetManager::DescriptorPoolManager::DescriptorPoolManager(
        VkDescriptorType type,
        GrVkGpu* gpu,
        const GrVkUniformHandler* uniformHandler)
    : fDescType(type)
    , fCurrentDescriptorCount(0)
    , fPool(nullptr) {
    if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
        SkASSERT(uniformHandler);
        uint32_t numSamplers = (uint32_t)uniformHandler->numSamplers();

        SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
                new VkDescriptorSetLayoutBinding[numSamplers]);
        for (uint32_t i = 0; i < numSamplers; ++i) {
            const GrVkGLSLSampler& sampler =
                    static_cast<const GrVkGLSLSampler&>(uniformHandler->getSampler(i));
            SkASSERT(sampler.binding() == i);
            dsSamplerBindings[i].binding = sampler.binding();
            dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
            dsSamplerBindings[i].descriptorCount = 1;
            dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(sampler.visibility());
            dsSamplerBindings[i].pImmutableSamplers = nullptr;
        }

        VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
        memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
        dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
        dsSamplerLayoutCreateInfo.pNext = nullptr;
        dsSamplerLayoutCreateInfo.flags = 0;
        dsSamplerLayoutCreateInfo.bindingCount = numSamplers;
        // Setting to nullptr fixes an error in the param checker validation layer. Even though
        // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is
        // null.
        dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr;

        GR_VK_CALL_ERRCHECK(gpu->vkInterface(),
                            CreateDescriptorSetLayout(gpu->device(),
                                                      &dsSamplerLayoutCreateInfo,
                                                      nullptr,
                                                      &fDescLayout));
        fDescCountPerSet = numSamplers;
    } else {
        SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
        // Create Uniform Buffer Descriptor
        // The vertex uniform buffer will have binding 0 and the fragment binding 1.
        VkDescriptorSetLayoutBinding dsUniBindings[kUniformDescPerSet];
        memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding));
        dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding;
        dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
        dsUniBindings[0].descriptorCount = 1;
        dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
        dsUniBindings[0].pImmutableSamplers = nullptr;
        dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding;
        dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
        dsUniBindings[1].descriptorCount = 1;
        dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
        dsUniBindings[1].pImmutableSamplers = nullptr;

        VkDescriptorSetLayoutCreateInfo uniformLayoutCreateInfo;
        memset(&uniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
        uniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
        uniformLayoutCreateInfo.pNext = nullptr;
        uniformLayoutCreateInfo.flags = 0;
        uniformLayoutCreateInfo.bindingCount = 2;
        uniformLayoutCreateInfo.pBindings = dsUniBindings;

        GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateDescriptorSetLayout(gpu->device(),
                                                                          &uniformLayoutCreateInfo,
                                                                          nullptr,
                                                                          &fDescLayout));
        fDescCountPerSet = kUniformDescPerSet;
    }

    SkASSERT(fDescCountPerSet < kStartNumDescriptors);
    fMaxDescriptors = kStartNumDescriptors;
    SkASSERT(fMaxDescriptors > 0);
    this->getNewPool(gpu);
}

void GrVkDescriptorSetManager::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) {
    if (fPool) {
        fPool->unref(gpu);
        uint32_t newPoolSize = fMaxDescriptors + ((fMaxDescriptors + 1) >> 1);
        if (newPoolSize < kMaxDescriptors) {
            fMaxDescriptors = newPoolSize;
        } else {
            fMaxDescriptors = kMaxDescriptors;
        }

    }
    fPool = gpu->resourceProvider().findOrCreateCompatibleDescriptorPool(fDescType,
                                                                         fMaxDescriptors);
    SkASSERT(fPool);
}

void GrVkDescriptorSetManager::DescriptorPoolManager::getNewDescriptorSet(GrVkGpu* gpu,
                                                                          VkDescriptorSet* ds) {
    if (!fMaxDescriptors) {
        return;
    }
    fCurrentDescriptorCount += fDescCountPerSet;
    if (fCurrentDescriptorCount > fMaxDescriptors) {
        this->getNewPool(gpu);
        fCurrentDescriptorCount = fDescCountPerSet;
    }

    VkDescriptorSetAllocateInfo dsAllocateInfo;
    memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
    dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    dsAllocateInfo.pNext = nullptr;
    dsAllocateInfo.descriptorPool = fPool->descPool();
    dsAllocateInfo.descriptorSetCount = 1;
    dsAllocateInfo.pSetLayouts = &fDescLayout;
    GR_VK_CALL_ERRCHECK(gpu->vkInterface(), AllocateDescriptorSets(gpu->device(),
                                                                   &dsAllocateInfo,
                                                                   ds));
}

void GrVkDescriptorSetManager::DescriptorPoolManager::freeGPUResources(const GrVkGpu* gpu) {
    if (fDescLayout) {
        GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDescLayout,
                                                                  nullptr));
        fDescLayout = VK_NULL_HANDLE;
    }

    if (fPool) {
        fPool->unref(gpu);
        fPool = nullptr;
    }
}

void GrVkDescriptorSetManager::DescriptorPoolManager::abandonGPUResources() {
    fDescLayout = VK_NULL_HANDLE;
    if (fPool) {
        fPool->unrefAndAbandon();
        fPool = nullptr;
    }
}
