/*
 * Copyright 2022 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/mtl/MtlComputePipeline.h"

#include "include/gpu/ShaderErrorHandler.h"
#include "src/gpu/graphite/ComputePipelineDesc.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/mtl/MtlGpu.h"
#include "src/gpu/graphite/mtl/MtlUtils.h"

namespace skgpu::graphite {

// static
sk_sp<MtlComputePipeline> MtlComputePipeline::Make(MtlResourceProvider* resourceProvider,
                                                   const MtlGpu* gpu,
                                                   const ComputePipelineDesc& pipelineDesc) {
    sk_cfp<MTLComputePipelineDescriptor*> psoDescriptor([MTLComputePipelineDescriptor new]);

    std::string msl;
    SkSL::Program::Inputs inputs;
    SkSL::ProgramSettings settings;

    ShaderErrorHandler* errorHandler = gpu->caps()->shaderErrorHandler();
    if (!SkSLToMSL(gpu,
                   pipelineDesc.sksl(),
                   SkSL::ProgramKind::kCompute,
                   settings,
                   &msl,
                   &inputs,
                   errorHandler)) {
        return nullptr;
    }

    sk_cfp<id<MTLLibrary>> shaderLibrary = MtlCompileShaderLibrary(gpu, msl, errorHandler);
    if (!shaderLibrary) {
        return nullptr;
    }

    (*psoDescriptor).label = @(pipelineDesc.name().c_str());
    (*psoDescriptor).computeFunction = [shaderLibrary.get() newFunctionWithName:@"computeMain"];

    // TODO(b/240604614): Populate input data attribute and buffer layout descriptors using the
    // `stageInputDescriptor` property based on the contents of `pipelineDesc` (on iOS 10+ or
    // macOS 10.12+).

    // TODO(b/240604614): Define input buffer mutability using the `buffers` property based on
    // the contents of `pipelineDesc` (on iOS 11+ or macOS 10.13+).

    // TODO(b/240615224): Metal docs claim that setting the
    // `threadGroupSizeIsMultipleOfThreadExecutionWidth` to YES may improve performance, IF we can
    // guarantee that the thread group size used in a dispatch command is a multiple of
    // `threadExecutionWidth` property of the pipeline state object (otherwise this will cause UB).

    NSError* error;
    sk_cfp<id<MTLComputePipelineState>> pso([gpu->device()
            newComputePipelineStateWithDescriptor:psoDescriptor.get()
                                          options:MTLPipelineOptionNone
                                       reflection:NULL
                                            error:&error]);
    if (!pso) {
        SKGPU_LOG_E("Compute pipeline creation failure:\n%s", error.debugDescription.UTF8String);
        return nullptr;
    }

    return sk_sp<MtlComputePipeline>(new MtlComputePipeline(gpu, std::move(pso)));
}

void MtlComputePipeline::freeGpuData() { fPipelineState.reset(); }

}  // namespace skgpu::graphite
