Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] Support access the descriptor of PipelineFuture directly #37415

Merged
merged 6 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 3 additions & 5 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,9 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
yuv_to_rgb_filter_pipelines_[{}] =
CreateDefaultPipeline<YUVToRGBFilterPipeline>(*context_);

// Pipelines that are variants of the base pipelines with custom descriptors.
// TODO(98684): Rework this API to allow fetching the descriptor without
// waiting for the pipeline to build.
if (auto solid_fill_pipeline = solid_fill_pipelines_[{}]->WaitAndGet()) {
auto clip_pipeline_descriptor = solid_fill_pipeline->GetDescriptor();
if (solid_fill_pipelines_[{}]->GetDescriptor().has_value()) {
auto clip_pipeline_descriptor =
solid_fill_pipelines_[{}]->GetDescriptor().value();
clip_pipeline_descriptor.SetLabel("Clip Pipeline");
// Disable write to all color attachments.
auto color_attachments =
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/runtime_effect_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
options.primitive_type = geometry_result.type;
options.ApplyToPipelineDescriptor(desc);

auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).get();
auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
if (!pipeline) {
VALIDATION_LOG << "Failed to get or create runtime effect pipeline.";
return false;
Expand Down
2 changes: 1 addition & 1 deletion impeller/playground/imgui/imgui_impl_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ bool ImGui_ImplImpeller_Init(
}

bd->pipeline =
context->GetPipelineLibrary()->GetPipeline(std::move(desc)).get();
context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
IM_ASSERT(bd->pipeline != nullptr && "Could not create ImGui pipeline.");

bd->sampler = context->GetSamplerLibrary()->GetSampler({});
Expand Down
21 changes: 11 additions & 10 deletions impeller/renderer/backend/gles/pipeline_library_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ PipelineFuture<PipelineDescriptor> PipelineLibraryGLES::GetPipeline(
}

if (!reactor_) {
return RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr);
return {
descriptor,
RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(nullptr)};
}

auto vert_function = descriptor.GetEntrypointForStage(ShaderStage::kVertex);
Expand All @@ -190,14 +191,16 @@ PipelineFuture<PipelineDescriptor> PipelineLibraryGLES::GetPipeline(
if (!vert_function || !frag_function) {
VALIDATION_LOG
<< "Could not find stage entrypoint functions in pipeline descriptor.";
return RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr);
return {
descriptor,
RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(nullptr)};
}

auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
auto future = PipelineFuture<PipelineDescriptor>{promise->get_future()};
pipelines_[descriptor] = future;
auto pipeline_future =
PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
pipelines_[descriptor] = pipeline_future;
auto weak_this = weak_from_this();

auto result = reactor_->AddOperation(
Expand Down Expand Up @@ -243,19 +246,17 @@ PipelineFuture<PipelineDescriptor> PipelineLibraryGLES::GetPipeline(
});
FML_CHECK(result);

return future;
return pipeline_future;
}

// |PipelineLibrary|
PipelineFuture<ComputePipelineDescriptor> PipelineLibraryGLES::GetPipeline(
ComputePipelineDescriptor descriptor) {
auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
auto future =
PipelineFuture<ComputePipelineDescriptor>{promise->get_future()};
// TODO(dnfield): implement compute for GLES.
promise->set_value(nullptr);
return future;
return {descriptor, promise->get_future()};
}

// |PipelineLibrary|
Expand Down
26 changes: 15 additions & 11 deletions impeller/renderer/backend/metal/pipeline_library_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,16 @@
}

if (!IsValid()) {
return RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr);
return {
descriptor,
RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(nullptr)};
}

auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
auto future = PipelineFuture<PipelineDescriptor>{promise->get_future()};
pipelines_[descriptor] = future;
auto pipeline_future =
PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
pipelines_[descriptor] = pipeline_future;
auto weak_this = weak_from_this();

auto completion_handler =
Expand Down Expand Up @@ -132,7 +134,7 @@
[device_ newRenderPipelineStateWithDescriptor:GetMTLRenderPipelineDescriptor(
descriptor)
completionHandler:completion_handler];
return future;
return pipeline_future;
}

PipelineFuture<ComputePipelineDescriptor> PipelineLibraryMTL::GetPipeline(
Expand All @@ -143,15 +145,17 @@
}

if (!IsValid()) {
return RealizedFuture<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>(
nullptr);
return {
descriptor,
RealizedFuture<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>(
nullptr)};
}

auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
auto future =
PipelineFuture<ComputePipelineDescriptor>{promise->get_future()};
compute_pipelines_[descriptor] = future;
auto pipeline_future = PipelineFuture<ComputePipelineDescriptor>{
descriptor, promise->get_future()};
compute_pipelines_[descriptor] = pipeline_future;
auto weak_this = weak_from_this();

auto completion_handler =
Expand Down Expand Up @@ -185,7 +189,7 @@ new ComputePipelineMTL(weak_this,
descriptor)
options:MTLPipelineOptionNone
completionHandler:completion_handler];
return future;
return pipeline_future;
}

// |PipelineLibrary|
Expand Down
16 changes: 8 additions & 8 deletions impeller/renderer/backend/vulkan/pipeline_library_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@ PipelineFuture<PipelineDescriptor> PipelineLibraryVK::GetPipeline(
}

if (!IsValid()) {
return RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr);
return {
descriptor,
RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(nullptr)};
}

auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
auto future = PipelineFuture<PipelineDescriptor>{promise->get_future()};
pipelines_[descriptor] = future;
auto pipeline_future =
PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
pipelines_[descriptor] = pipeline_future;

auto weak_this = weak_from_this();

Expand All @@ -86,19 +88,17 @@ PipelineFuture<PipelineDescriptor> PipelineLibraryVK::GetPipeline(
weak_this, descriptor, std::move(pipeline_create_info)));
});

return future;
return pipeline_future;
}

// |PipelineLibrary|
PipelineFuture<ComputePipelineDescriptor> PipelineLibraryVK::GetPipeline(
ComputePipelineDescriptor descriptor) {
auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
auto future =
PipelineFuture<ComputePipelineDescriptor>{promise->get_future()};
// TODO(dnfield): implement compute for GLES.
promise->set_value(nullptr);
return future;
return {descriptor, promise->get_future()};
}

static vk::AttachmentDescription CreatePlaceholderAttachmentDescription(
Expand Down
6 changes: 0 additions & 6 deletions impeller/renderer/compute_pipeline_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,4 @@ class ComputePipelineDescriptor final
std::shared_ptr<const ShaderFunction> entrypoint_;
};

using ComputePipelineMap = std::unordered_map<
ComputePipelineDescriptor,
std::shared_future<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>,
ComparableHash<ComputePipelineDescriptor>,
ComparableEqual<ComputePipelineDescriptor>>;

} // namespace impeller
2 changes: 1 addition & 1 deletion impeller/renderer/compute_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ TEST_P(ComputeTest, CanCreateComputePass) {
SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
ASSERT_TRUE(pipeline_desc.has_value());
auto compute_pipeline =
context->GetPipelineLibrary()->GetPipeline(pipeline_desc).get();
context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
ASSERT_TRUE(compute_pipeline);

auto cmd_buffer = context->CreateCommandBuffer();
Expand Down
16 changes: 10 additions & 6 deletions impeller/renderer/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "impeller/renderer/pipeline.h"
#include <optional>

#include "compute_pipeline_descriptor.h"
#include "impeller/base/promise.h"
Expand All @@ -24,8 +25,8 @@ PipelineFuture<PipelineDescriptor> CreatePipelineFuture(
const Context& context,
std::optional<PipelineDescriptor> desc) {
if (!context.IsValid()) {
return RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr);
return {desc, RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr)};
}

return context.GetPipelineLibrary()->GetPipeline(std::move(desc));
Expand All @@ -35,8 +36,10 @@ PipelineFuture<ComputePipelineDescriptor> CreatePipelineFuture(
const Context& context,
std::optional<ComputePipelineDescriptor> desc) {
if (!context.IsValid()) {
return RealizedFuture<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>(
nullptr);
return {
desc,
RealizedFuture<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>(
nullptr)};
}

return context.GetPipelineLibrary()->GetPipeline(std::move(desc));
Expand All @@ -51,7 +54,8 @@ template <typename T>
PipelineFuture<T> Pipeline<T>::CreateVariant(
std::function<void(T& desc)> descriptor_callback) const {
if (!descriptor_callback) {
return RealizedFuture<std::shared_ptr<Pipeline<T>>>(nullptr);
return {std::nullopt,
RealizedFuture<std::shared_ptr<Pipeline<T>>>(nullptr)};
}

auto copied_desc = desc_;
Expand All @@ -62,7 +66,7 @@ PipelineFuture<T> Pipeline<T>::CreateVariant(
if (!library) {
VALIDATION_LOG << "The library from which this pipeline was created was "
"already collected.";
return RealizedFuture<std::shared_ptr<Pipeline<T>>>(nullptr);
return {desc_, RealizedFuture<std::shared_ptr<Pipeline<T>>>(nullptr)};
}

return library->GetPipeline(std::move(copied_desc));
Expand Down
29 changes: 17 additions & 12 deletions impeller/renderer/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ class PipelineLibrary;
template <typename PipelineDescriptor_>
class Pipeline;

// TODO(csg): Using a simple future is sub-optimal since callers that want to
// eagerly create and cache pipeline variants will have to await on the future
// to get its pipeline descriptor (unless they have explicitly cached it). This
// would be a concurrency pessimization.
//
// Use a struct that stores the future and the descriptor separately.
template <class T>
using PipelineFuture = std::shared_future<std::shared_ptr<Pipeline<T>>>;
template <typename T>
struct PipelineFuture {
std::optional<T> descriptor;
std::shared_future<std::shared_ptr<Pipeline<T>>> future;

const std::shared_ptr<Pipeline<T>> Get() const { return future.get(); }

bool IsValid() const { return future.valid(); }
};

//------------------------------------------------------------------------------
/// @brief Describes the fixed function and programmable aspects of
Expand Down Expand Up @@ -107,12 +108,16 @@ class RenderPipelineT {
return pipeline_;
}
did_wait_ = true;
if (pipeline_future_.valid()) {
pipeline_ = pipeline_future_.get();
if (pipeline_future_.IsValid()) {
pipeline_ = pipeline_future_.Get();
}
return pipeline_;
}

std::optional<PipelineDescriptor> GetDescriptor() const {
return pipeline_future_.descriptor;
}

private:
PipelineFuture<PipelineDescriptor> pipeline_future_;
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
Expand Down Expand Up @@ -145,8 +150,8 @@ class ComputePipelineT {
return pipeline_;
}
did_wait_ = true;
if (pipeline_future_.valid()) {
pipeline_ = pipeline_future_.get();
if (pipeline_future_.IsValid()) {
pipeline_ = pipeline_future_.Get();
}
return pipeline_;
}
Expand Down
6 changes: 0 additions & 6 deletions impeller/renderer/pipeline_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,4 @@ class PipelineDescriptor final : public Comparable<PipelineDescriptor> {
PrimitiveType primitive_type_ = PrimitiveType::kTriangle;
};

using PipelineMap = std::unordered_map<
PipelineDescriptor,
std::shared_future<std::shared_ptr<Pipeline<PipelineDescriptor>>>,
ComparableHash<PipelineDescriptor>,
ComparableEqual<PipelineDescriptor>>;

} // namespace impeller
4 changes: 2 additions & 2 deletions impeller/renderer/pipeline_library.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ PipelineFuture<PipelineDescriptor> PipelineLibrary::GetPipeline(
auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
promise->set_value(nullptr);
return promise->get_future();
return {descriptor, promise->get_future()};
}

PipelineFuture<ComputePipelineDescriptor> PipelineLibrary::GetPipeline(
Expand All @@ -29,7 +29,7 @@ PipelineFuture<ComputePipelineDescriptor> PipelineLibrary::GetPipeline(
auto promise = std::make_shared<
std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
promise->set_value(nullptr);
return promise->get_future();
return {descriptor, promise->get_future()};
}

} // namespace impeller
11 changes: 11 additions & 0 deletions impeller/renderer/pipeline_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ namespace impeller {

class Context;

using PipelineMap = std::unordered_map<PipelineDescriptor,
PipelineFuture<PipelineDescriptor>,
ComparableHash<PipelineDescriptor>,
ComparableEqual<PipelineDescriptor>>;

using ComputePipelineMap =
std::unordered_map<ComputePipelineDescriptor,
PipelineFuture<ComputePipelineDescriptor>,
ComparableHash<ComputePipelineDescriptor>,
ComparableEqual<ComputePipelineDescriptor>>;

class PipelineLibrary : public std::enable_shared_from_this<PipelineLibrary> {
public:
virtual ~PipelineLibrary();
Expand Down
Loading