Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixup.
  • Loading branch information
jonahwilliams committed Nov 4, 2023
commit 94f65486b6493b162f5d0fb484357a1b4759ad1e
1 change: 1 addition & 0 deletions impeller/docs/specialization_constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Only 32bit ints are supported as const values and can be used to represent:

* true/false via 0/1.
* function selection, such as advanced blends. The specialization value maps to a specific blend function. For example, 0 maps to screen and 1 to overlay via a giant if/else macro.
* Only fragment shaders can be specialized. This limitation could be removed with more investment.

*AVOID* adding specialization constants for color values or anything more complex.

Expand Down
15 changes: 8 additions & 7 deletions impeller/renderer/backend/metal/pipeline_library_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static void GetMTLRenderPipelineDescriptor(const PipelineDescriptor& desc,
auto descriptor = [[MTLRenderPipelineDescriptor alloc] init];
descriptor.label = @(desc.GetLabel().c_str());
descriptor.rasterSampleCount = static_cast<NSUInteger>(desc.GetSampleCount());
bool async = false;
bool created_specialized_function = false;

if (const auto& vertex_descriptor = desc.GetVertexDescriptor()) {
VertexDescriptorMTL vertex_descriptor_mtl;
Expand All @@ -55,7 +55,7 @@ static void GetMTLRenderPipelineDescriptor(const PipelineDescriptor& desc,

// This latch is used to ensure that GetMTLFunctionSpecialized does not finish
// before the descriptor is completely set up.
fml::CountDownLatch latch(1u);
auto latch = std::make_shared<fml::CountDownLatch>(1u);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing appears to be waiting on this latch, and I'm not sure why we'd need one. It looks like the descriptor is already done being set up by the time we call GetMTLFunctionSpecialized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed. This was left over from an earlier iteration.

const auto& constants = desc.GetSpecializationConstants();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still a bit iffy, but we improve performance by not blocking on the specialization, it all goes into the same pipeline future which is only blocking once we actually trry to use it.

Since the compilation is out of process anyway, blocking on it is pointless and only serves to park the thread.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like we're writing javascript here with this chain of nested completion callbacks. ;) Looks safe to me, though.

for (const auto& entry : desc.GetStageEntrypoints()) {
if (entry.first == ShaderStage::kVertex) {
Expand All @@ -67,21 +67,22 @@ static void GetMTLRenderPipelineDescriptor(const PipelineDescriptor& desc,
descriptor.fragmentFunction =
ShaderFunctionMTL::Cast(*entry.second).GetMTLFunction();
} else {
async = true;
// This code only expects a single specialized function per pipeline.
FML_CHECK(!created_specialized_function);
created_specialized_function = true;
ShaderFunctionMTL::Cast(*entry.second)
.GetMTLFunctionSpecialized(
constants,
[callback, descriptor, &latch](id<MTLFunction> function) {
[callback, descriptor, latch](id<MTLFunction> function) {
descriptor.fragmentFunction = function;
latch.Wait();
callback(descriptor);
});
}
}
}

latch.CountDown();
if (!async) {
latch->CountDown();
if (!created_specialized_function) {
callback(descriptor);
}
}
Expand Down
3 changes: 2 additions & 1 deletion impeller/renderer/backend/metal/shader_function_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
atIndex:index];
index++;
}
CompileCallback callback_value = callback;
[library_ newFunctionWithName:@(GetName().data())
constantValues:constantValues
completionHandler:^(id<MTLFunction> _Nullable function,
NSError* _Nullable error) {
callback(function);
callback_value(function);
}];
}

Expand Down