blob: e20c9a4405b78405c1dfdf3b4cba984d8729c9dc [file] [log] [blame]
/*
* 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