7 #include <Metal/Metal.h>
9 #include "flutter/fml/build_config.h"
10 #include "flutter/fml/container.h"
27 auto descriptor = [[MTLRenderPipelineDescriptor alloc] init];
28 descriptor.label = @(desc.
GetLabel().c_str());
29 descriptor.rasterSampleCount =
static_cast<NSUInteger
>(desc.
GetSampleCount());
33 descriptor.vertexFunction =
37 descriptor.fragmentFunction =
45 vertex_descriptor->GetStageInputs(),
46 vertex_descriptor->GetStageLayouts())) {
47 descriptor.vertexDescriptor =
53 descriptor.colorAttachments[item.first] =
57 descriptor.depthAttachmentPixelFormat =
59 descriptor.stencilAttachmentPixelFormat =
67 auto descriptor = [[MTLComputePipelineDescriptor alloc] init];
68 descriptor.label = @(desc.
GetLabel().c_str());
69 descriptor.computeFunction =
77 id<MTLDevice> device) {
83 return [device newDepthStencilStateWithDescriptor:descriptor];
87 bool PipelineLibraryMTL::IsValid()
const {
88 return device_ !=
nullptr;
92 PipelineFuture<PipelineDescriptor> PipelineLibraryMTL::GetPipeline(
93 PipelineDescriptor descriptor) {
94 if (
auto found = pipelines_.find(descriptor); found != pipelines_.end()) {
101 RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr)};
104 auto promise = std::make_shared<
105 std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
106 auto pipeline_future =
107 PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
108 pipelines_[descriptor] = pipeline_future;
109 auto weak_this = weak_from_this();
111 auto completion_handler =
112 ^(id<MTLRenderPipelineState> _Nullable render_pipeline_state,
113 NSError* _Nullable error) {
116 << descriptor.GetLabel() <<
" :"
117 << error.localizedDescription.UTF8String;
118 promise->set_value(
nullptr);
122 auto strong_this = weak_this.lock();
124 promise->set_value(
nullptr);
128 auto new_pipeline = std::shared_ptr<PipelineMTL>(
new PipelineMTL(
131 render_pipeline_state,
134 promise->set_value(new_pipeline);
138 [device_ newRenderPipelineStateWithDescriptor:mtl_descriptor
139 completionHandler:completion_handler];
143 NSError* error = nil;
144 auto render_pipeline_state =
145 [device_ newRenderPipelineStateWithDescriptor:mtl_descriptor
147 completion_handler(render_pipeline_state, error);
149 return pipeline_future;
152 PipelineFuture<ComputePipelineDescriptor> PipelineLibraryMTL::GetPipeline(
153 ComputePipelineDescriptor descriptor) {
154 if (
auto found = compute_pipelines_.find(descriptor);
155 found != compute_pipelines_.end()) {
156 return found->second;
162 RealizedFuture<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>(
166 auto promise = std::make_shared<
167 std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
168 auto pipeline_future = PipelineFuture<ComputePipelineDescriptor>{
169 descriptor, promise->get_future()};
170 compute_pipelines_[descriptor] = pipeline_future;
171 auto weak_this = weak_from_this();
173 auto completion_handler =
174 ^(id<MTLComputePipelineState> _Nullable compute_pipeline_state,
175 MTLComputePipelineReflection* _Nullable reflection,
176 NSError* _Nullable error) {
179 << error.localizedDescription.UTF8String;
180 promise->set_value(
nullptr);
184 auto strong_this = weak_this.lock();
186 VALIDATION_LOG <<
"Library was collected before a pending pipeline "
187 "creation could finish.";
188 promise->set_value(
nullptr);
192 auto new_pipeline = std::shared_ptr<ComputePipelineMTL>(
193 new ComputePipelineMTL(weak_this,
195 compute_pipeline_state
197 promise->set_value(new_pipeline);
202 options:MTLPipelineOptionNone
203 completionHandler:completion_handler];
204 return pipeline_future;
208 void PipelineLibraryMTL::RemovePipelinesWithEntryPoint(
209 std::shared_ptr<const ShaderFunction>
function) {
210 fml::erase_if(pipelines_, [&](
auto item) {
211 return item->first.GetEntrypointForStage(function->GetStage())
212 ->IsEqual(*
function);