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

#include "src/gpu/graphite/compute/DispatchGroup.h"

#include "include/core/SkColorType.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "include/private/base/SkSpan_impl.h"
#include "include/private/base/SkTo.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/graphite/BufferManager.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/ComputePipeline.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/Resource.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/Sampler.h"
#include "src/gpu/graphite/Texture.h"  // IWYU pragma: keep
#include "src/gpu/graphite/TextureProxy.h"
#include "src/gpu/graphite/UniformManager.h"
#include "src/gpu/graphite/task/ClearBuffersTask.h"

#include <utility>

namespace skgpu::graphite {

DispatchGroup::~DispatchGroup() = default;

bool DispatchGroup::prepareResources(ResourceProvider* resourceProvider) {
    fPipelines.reserve(fPipelines.size() + fPipelineDescs.size());
    for (const ComputePipelineDesc& desc : fPipelineDescs) {
        auto pipeline = resourceProvider->findOrCreateComputePipeline(desc);
        if (!pipeline) {
            SKGPU_LOG_W("Failed to create ComputePipeline for dispatch group. Dropping group!");
            return false;
        }
        fPipelines.push_back(std::move(pipeline));
    }

    for (int i = 0; i < fTextures.size(); ++i) {
        if (!fTextures[i]->textureInfo().isValid()) {
            SKGPU_LOG_W("Failed to validate bound texture. Dropping dispatch group!");
            return false;
        }
        if (!TextureProxy::InstantiateIfNotLazy(resourceProvider, fTextures[i].get())) {
            SKGPU_LOG_W("Failed to instantiate bound texture. Dropping dispatch group!");
            return false;
        }
    }

    for (const SamplerDesc& desc : fSamplerDescs) {
        sk_sp<Sampler> sampler = resourceProvider->findOrCreateCompatibleSampler(desc);
        if (!sampler) {
            SKGPU_LOG_W("Failed to create sampler. Dropping dispatch group!");
            return false;
        }
        fSamplers.push_back(std::move(sampler));
    }

    // The DispatchGroup may be long lived on a Recording and we no longer need the descriptors
    // once we've created pipelines.
    fPipelineDescs.clear();
    fSamplerDescs.clear();

    return true;
}

void DispatchGroup::addResourceRefs(CommandBuffer* commandBuffer) const {
    for (int i = 0; i < fPipelines.size(); ++i) {
        commandBuffer->trackResource(fPipelines[i]);
    }
    for (int i = 0; i < fTextures.size(); ++i) {
        commandBuffer->trackResource(fTextures[i]->refTexture());
    }
}

sk_sp<Task> DispatchGroup::snapChildTask() {
    if (fClearList.empty()) {
        return nullptr;
    }
    return ClearBuffersTask::Make(std::move(fClearList));
}

const Texture* DispatchGroup::getTexture(size_t index) const {
    SkASSERT(index < SkToSizeT(fTextures.size()));
    SkASSERT(fTextures[index]);
    SkASSERT(fTextures[index]->texture());
    return fTextures[index]->texture();
}

const Sampler* DispatchGroup::getSampler(size_t index) const {
    SkASSERT(index < SkToSizeT(fSamplers.size()));
    SkASSERT(fSamplers[index]);
    return fSamplers[index].get();
}

using Builder = DispatchGroup::Builder;

Builder::Builder(Recorder* recorder) : fObj(new DispatchGroup()), fRecorder(recorder) {
    SkASSERT(fRecorder);
}

bool Builder::appendStep(const ComputeStep* step, std::optional<WorkgroupSize> globalSize) {
    return this->appendStepInternal(step,
                                    globalSize ? *globalSize : step->calculateGlobalDispatchSize());
}

bool Builder::appendStepIndirect(const ComputeStep* step, BindBufferInfo indirectBuffer) {
    return this->appendStepInternal(step, indirectBuffer);
}

bool Builder::appendStepInternal(
        const ComputeStep* step,
        const std::variant<WorkgroupSize, BindBufferInfo>& globalSizeOrIndirect) {
    SkASSERT(fObj);
    SkASSERT(step);

    Dispatch dispatch;

    // Process the step's resources.
    auto resources = step->resources();
    dispatch.fBindings.reserve(resources.size());

    // `nextIndex` matches the declaration order of resources as specified by the ComputeStep.
    int nextIndex = 0;

    // We assign buffer, texture, and sampler indices from separate ranges. This is compatible with
    // how Graphite assigns indices on Metal, as these map directly to the buffer/texture/sampler
    // index ranges. On Dawn/Vulkan buffers and textures/samplers are allocated from separate bind
    // groups/descriptor sets but texture and sampler indices need to not overlap.
    const auto& bindingReqs = fRecorder->priv().caps()->resourceBindingRequirements();
    const bool separateSampler = bindingReqs.fSeparateTextureAndSamplerBinding;
    const bool texturesUseDistinctIdxRanges = bindingReqs.fComputeUsesDistinctIdxRangesForTextures;
    // Some binding index determination logic relies upon the fact that we do not expect to
    // encounter a backend that both uses separate sampler bindings AND requires separate index
    // ranges for textures.
    SkASSERT(!(separateSampler && texturesUseDistinctIdxRanges));

    int bufferOrGlobalIndex = 0;
    int texIndex = 0;
    // NOTE: SkSL Metal codegen always assigns the same binding index to a texture and its sampler.
    // TODO: This could cause sampler indices to not be tightly packed if the sampler2D declaration
    // comes after 1 or more storage texture declarations (which don't have samplers).
    for (const ComputeStep::ResourceDesc& r : resources) {
        SkASSERT(r.fSlot == -1 || (r.fSlot >= 0 && r.fSlot < kMaxComputeDataFlowSlots));
        const int index = nextIndex++;

        DispatchResourceOptional maybeResource;

        using DataFlow = ComputeStep::DataFlow;
        using Type = ComputeStep::ResourceType;
        switch (r.fFlow) {
            case DataFlow::kPrivate:
                // A sampled or fetched-type readonly texture must either get assigned via
                // `assignSharedTexture()` or internally allocated as a storage texture of a
                // preceding step. Such a texture always has a data slot.
                SkASSERT(r.fType != Type::kReadOnlyTexture);
                SkASSERT(r.fType != Type::kSampledTexture);
                maybeResource = this->allocateResource(step, r, index);
                break;
            case DataFlow::kShared: {
                SkASSERT(r.fSlot >= 0);
                // Allocate a new resource only if the shared slot is empty (except for a
                // SampledTexture which needs its sampler to be allocated internally).
                DispatchResourceOptional* slot = &fOutputTable.fSharedSlots[r.fSlot];
                if (std::holds_alternative<std::monostate>(*slot)) {
                    SkASSERT(r.fType != Type::kReadOnlyTexture);
                    SkASSERT(r.fType != Type::kSampledTexture);
                    maybeResource = this->allocateResource(step, r, index);
                    *slot = maybeResource;
                } else {
                    SkASSERT(((r.fType == Type::kUniformBuffer ||
                               r.fType == Type::kStorageBuffer ||
                               r.fType == Type::kReadOnlyStorageBuffer ||
                               r.fType == Type::kIndirectBuffer) &&
                              std::holds_alternative<BindBufferInfo>(*slot)) ||
                             ((r.fType == Type::kReadOnlyTexture ||
                               r.fType == Type::kSampledTexture ||
                               r.fType == Type::kWriteOnlyStorageTexture) &&
                              std::holds_alternative<TextureIndex>(*slot)));
#ifdef SK_DEBUG
                    // Ensure that the texture has the right format if it was assigned via
                    // `assignSharedTexture()`.
                    const TextureIndex* texIdx = std::get_if<TextureIndex>(slot);
                    if (texIdx && r.fType == Type::kWriteOnlyStorageTexture) {
                        const TextureProxy* t = fObj->fTextures[texIdx->fValue].get();
                        SkASSERT(t);
                        auto [_, colorType] = step->calculateTextureParameters(index, r);
                        SkASSERT(t->textureInfo().canBeFulfilledBy(
                                fRecorder->priv().caps()->getDefaultStorageTextureInfo(colorType)));
                    }
#endif  // SK_DEBUG

                    maybeResource = *slot;

                    if (r.fType == Type::kSampledTexture) {
                        // The shared slot holds the texture part of the sampled texture but we
                        // still need to allocate the sampler.
                        SkASSERT(std::holds_alternative<TextureIndex>(*slot));
                        auto samplerResource = this->allocateResource(step, r, index);
                        const SamplerIndex* samplerIdx =
                                std::get_if<SamplerIndex>(&samplerResource);
                        SkASSERT(samplerIdx);
                        int bindingIndex = texturesUseDistinctIdxRanges ? texIndex :
                                                        separateSampler ? bufferOrGlobalIndex++
                                                                        : bufferOrGlobalIndex;
                        dispatch.fBindings.push_back(
                                {static_cast<BindingIndex>(bindingIndex), *samplerIdx});
                    }
                }
                break;
            }
        }

        int bindingIndex = 0;
        DispatchResource dispatchResource;
        if (const BindBufferInfo* buffer = std::get_if<BindBufferInfo>(&maybeResource)) {
            dispatchResource = *buffer;
            bindingIndex = bufferOrGlobalIndex++;
        } else if (const TextureIndex* texIdx = std::get_if<TextureIndex>(&maybeResource)) {
            dispatchResource = *texIdx;
            bindingIndex = texturesUseDistinctIdxRanges ? texIndex++ : bufferOrGlobalIndex++;
        } else {
            SKGPU_LOG_W("Failed to allocate resource for compute dispatch");
            return false;
        }
        dispatch.fBindings.push_back({static_cast<BindingIndex>(bindingIndex), dispatchResource});
    }

    auto wgBufferDescs = step->workgroupBuffers();
    if (!wgBufferDescs.empty()) {
        dispatch.fWorkgroupBuffers.push_back_n(wgBufferDescs.size(), wgBufferDescs.data());
    }

    // We need to switch pipelines if this step uses a different pipeline from the previous step.
    if (fObj->fPipelineDescs.empty() ||
        fObj->fPipelineDescs.back().uniqueID() != step->uniqueID()) {
        fObj->fPipelineDescs.push_back(ComputePipelineDesc(step));
    }

    dispatch.fPipelineIndex = fObj->fPipelineDescs.size() - 1;
    dispatch.fLocalSize = step->localDispatchSize();
    dispatch.fGlobalSizeOrIndirect = globalSizeOrIndirect;

    fObj->fDispatchList.push_back(std::move(dispatch));

    return true;
}

void Builder::assignSharedBuffer(BindBufferInfo buffer, unsigned int slot, ClearBuffer cleared) {
    SkASSERT(fObj);
    SkASSERT(buffer);
    SkASSERT(buffer.fSize);

    fOutputTable.fSharedSlots[slot] = buffer;
    if (cleared == ClearBuffer::kYes) {
        fObj->fClearList.push_back(buffer);
    }
}

void Builder::assignSharedTexture(sk_sp<TextureProxy> texture, unsigned int slot) {
    SkASSERT(fObj);
    SkASSERT(texture);

    fObj->fTextures.push_back(std::move(texture));
    fOutputTable.fSharedSlots[slot] = TextureIndex{fObj->fTextures.size() - 1u};
}

std::unique_ptr<DispatchGroup> Builder::finalize() {
    auto obj = std::move(fObj);
    fOutputTable.reset();
    return obj;
}

#if defined(GPU_TEST_UTILS)
void Builder::reset() {
    fOutputTable.reset();
    fObj.reset(new DispatchGroup);
}
#endif

BindBufferInfo Builder::getSharedBufferResource(unsigned int slot) const {
    SkASSERT(fObj);

    BindBufferInfo info;
    if (const BindBufferInfo* slotValue =
                std::get_if<BindBufferInfo>(&fOutputTable.fSharedSlots[slot])) {
        info = *slotValue;
    }
    return info;
}

sk_sp<TextureProxy> Builder::getSharedTextureResource(unsigned int slot) const {
    SkASSERT(fObj);

    const TextureIndex* idx = std::get_if<TextureIndex>(&fOutputTable.fSharedSlots[slot]);
    if (!idx) {
        return nullptr;
    }

    SkASSERT(idx->fValue < SkToSizeT(fObj->fTextures.size()));
    return fObj->fTextures[idx->fValue];
}

DispatchResourceOptional Builder::allocateResource(const ComputeStep* step,
                                                   const ComputeStep::ResourceDesc& resource,
                                                   int resourceIdx) {
    SkASSERT(step);
    SkASSERT(fObj);
    using Type = ComputeStep::ResourceType;
    using ResourcePolicy = ComputeStep::ResourcePolicy;

    DrawBufferManager* bufferMgr = fRecorder->priv().drawBufferManager();
    DispatchResourceOptional result;
    switch (resource.fType) {
        case Type::kReadOnlyStorageBuffer:
        case Type::kStorageBuffer: {
            size_t bufferSize = step->calculateBufferSize(resourceIdx, resource);
            SkASSERT(bufferSize);
            if (resource.fPolicy == ResourcePolicy::kMapped) {
                auto [writer, bufInfo, _] =
                    bufferMgr->getMappedStorageBuffer(bufferSize, /*stride=*/1);
                if (writer) {
                    step->prepareStorageBuffer(resourceIdx, resource, std::move(writer));
                    result = bufInfo;
                }
            } else {
                auto bufInfo = bufferMgr->getStorage(bufferSize,
                                                     resource.fPolicy == ResourcePolicy::kClear
                                                             ? ClearBuffer::kYes
                                                             : ClearBuffer::kNo);
                if (bufInfo) {
                    result = bufInfo;
                }
            }
            break;
        }
        case Type::kIndirectBuffer: {
            SkASSERT(resource.fPolicy != ResourcePolicy::kMapped);

            size_t bufferSize = step->calculateBufferSize(resourceIdx, resource);
            SkASSERT(bufferSize);
            auto bufInfo = bufferMgr->getIndirectStorage(bufferSize,
                                                         resource.fPolicy == ResourcePolicy::kClear
                                                                 ? ClearBuffer::kYes
                                                                 : ClearBuffer::kNo);
            if (bufInfo) {
                result = bufInfo;
            }
            break;
        }
        case Type::kUniformBuffer: {
            SkASSERT(resource.fPolicy == ResourcePolicy::kMapped);

            const auto& resourceReqs = fRecorder->priv().caps()->resourceBindingRequirements();
            UniformManager uboMgr(resourceReqs.fUniformBufferLayout);
            step->prepareUniformBuffer(resourceIdx, resource, &uboMgr);

            auto dataBlock = uboMgr.finish();
            SkASSERT(!dataBlock.empty());

            auto [writer, bufInfo, _] =
                    bufferMgr->getMappedUniformBuffer(dataBlock.size(), /*stride=*/1);
            if (bufInfo) {
                writer.write(dataBlock.data(), dataBlock.size());
                result = bufInfo;
            }
            break;
        }
        case Type::kWriteOnlyStorageTexture: {
            auto [size, colorType] = step->calculateTextureParameters(resourceIdx, resource);
            SkASSERT(!size.isEmpty());
            SkASSERT(colorType != kUnknown_SkColorType);

            auto textureInfo = fRecorder->priv().caps()->getDefaultStorageTextureInfo(colorType);
            sk_sp<TextureProxy> texture = TextureProxy::Make(
                    fRecorder->priv().caps(), fRecorder->priv().resourceProvider(),
                    size, textureInfo, "DispatchWriteOnlyStorageTexture", skgpu::Budgeted::kYes);
            if (texture) {
                fObj->fTextures.push_back(std::move(texture));
                result = TextureIndex{fObj->fTextures.size() - 1u};
            }
            break;
        }
        case Type::kReadOnlyTexture:
            // This resource type is meant to be populated externally (e.g. by an upload or a render
            // pass) and only read/sampled by a ComputeStep. It's not meaningful to allocate an
            // internal texture for a DispatchGroup if none of the ComputeSteps will write to it.
            //
            // Instead of using internal allocation, this texture must be assigned explicitly to a
            // slot by calling the Builder::assignSharedTexture() method.
            //
            // Note: A ComputeStep is allowed to read/sample from a storage texture that a previous
            // ComputeStep has written to.
            SK_ABORT("a readonly texture must be externally assigned to a ComputeStep");
            break;
        case Type::kSampledTexture: {
            fObj->fSamplerDescs.push_back(step->calculateSamplerParameters(resourceIdx, resource));
            result = SamplerIndex{fObj->fSamplerDescs.size() - 1u};
            break;
        }
    }
    return result;
}

}  // namespace skgpu::graphite
