30 auto descriptor = [[MTLRenderPipelineDescriptor alloc] init];
31 descriptor.label = @(desc.GetLabel().c_str());
32 descriptor.rasterSampleCount =
static_cast<NSUInteger
>(desc.GetSampleCount());
33 bool created_specialized_function =
false;
35 if (
const auto& vertex_descriptor = desc.GetVertexDescriptor()) {
38 vertex_descriptor->GetStageInputs(),
39 vertex_descriptor->GetStageLayouts())) {
40 descriptor.vertexDescriptor =
45 for (
const auto& item : desc.GetColorAttachmentDescriptors()) {
46 descriptor.colorAttachments[item.first] =
50 descriptor.depthAttachmentPixelFormat =
52 descriptor.stencilAttachmentPixelFormat =
55 const auto& constants = desc.GetSpecializationConstants();
56 for (
const auto& entry : desc.GetStageEntrypoints()) {
57 if (entry.first == ShaderStage::kVertex) {
58 descriptor.vertexFunction =
59 ShaderFunctionMTL::Cast(*entry.second).GetMTLFunction();
61 if (entry.first == ShaderStage::kFragment) {
62 if (constants.empty()) {
63 descriptor.fragmentFunction =
64 ShaderFunctionMTL::Cast(*entry.second).GetMTLFunction();
68 created_specialized_function =
true;
69 ShaderFunctionMTL::Cast(*entry.second)
70 .GetMTLFunctionSpecialized(
72 descriptor.fragmentFunction =
function;
79 if (!created_specialized_function) {
113 if (
auto found = pipelines_.find(descriptor); found != pipelines_.end()) {
114 return found->second;
120 RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr)};
123 auto promise = std::make_shared<
124 std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
125 auto pipeline_future =
127 pipelines_[descriptor] = pipeline_future;
128 auto weak_this = weak_from_this();
130 auto completion_handler =
131 ^(id<MTLRenderPipelineState> _Nullable render_pipeline_state,
132 NSError* _Nullable
error) {
136 <<
error.localizedDescription.UTF8String;
137 promise->set_value(
nullptr);
141 auto strong_this = weak_this.lock();
143 promise->set_value(
nullptr);
147 auto new_pipeline = std::shared_ptr<PipelineMTL>(
new PipelineMTL(
150 render_pipeline_state,
153 promise->set_value(new_pipeline);
156 descriptor, [
device = device_, completion_handler](
157 MTLRenderPipelineDescriptor* descriptor) {
158 [
device newRenderPipelineStateWithDescriptor:descriptor
159 completionHandler:completion_handler];
161 return pipeline_future;
166 if (
auto found = compute_pipelines_.find(descriptor);
167 found != compute_pipelines_.end()) {
168 return found->second;
174 RealizedFuture<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>(
178 auto promise = std::make_shared<
179 std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
181 descriptor, promise->get_future()};
182 compute_pipelines_[descriptor] = pipeline_future;
183 auto weak_this = weak_from_this();
185 auto completion_handler =
186 ^(id<MTLComputePipelineState> _Nullable compute_pipeline_state,
187 MTLComputePipelineReflection* _Nullable reflection,
188 NSError* _Nullable
error) {
191 <<
error.localizedDescription.UTF8String;
192 promise->set_value(
nullptr);
196 auto strong_this = weak_this.lock();
198 VALIDATION_LOG <<
"Library was collected before a pending pipeline "
199 "creation could finish.";
200 promise->set_value(
nullptr);
204 auto new_pipeline = std::shared_ptr<ComputePipelineMTL>(
207 compute_pipeline_state
209 promise->set_value(new_pipeline);
215 completionHandler:completion_handler];
216 return pipeline_future;
const uint8_t uint32_t uint32_t GError ** error