18#include "impeller/entity/runtime_effect.vert.h"
28constexpr char kPaddingType = 0;
29constexpr char kFloatType = 1;
34 const std::shared_ptr<
const std::vector<uint8_t>>& input_data,
37 size_t minimum_uniform_alignment) {
40 std::vector<float> uniform_buffer;
42 size_t uniform_byte_index = 0u;
44 if (byte_type == kPaddingType) {
45 uniform_buffer.push_back(0.f);
48 uniform_buffer.push_back(
reinterpret_cast<const float*
>(
49 input_data->data())[uniform_byte_index++]);
53 return data_host_buffer.
Emplace(
54 reinterpret_cast<const void*
>(uniform_buffer.data()),
55 sizeof(
float) * uniform_buffer.size(), minimum_uniform_alignment);
59 std::shared_ptr<RuntimeStage> runtime_stage) {
60 runtime_stage_ = std::move(runtime_stage);
64 std::shared_ptr<std::vector<uint8_t>> uniform_data) {
65 uniform_data_ = std::move(uniform_data);
69 std::vector<TextureInput> texture_inputs) {
70 texture_inputs_ = std::move(texture_inputs);
86 std::unique_ptr<ShaderMetadata> metadata = std::make_unique<ShaderMetadata>();
87 metadata->name = uniform.
name;
102 if (!RegisterShader(renderer)) {
107 renderer.
GetContext()->GetCapabilities()->GetDefaultColorFormat();
108 CreatePipeline(renderer, options,
true);
112bool RuntimeEffectContents::RegisterShader(
114 const std::shared_ptr<Context>& context = renderer.
GetContext();
115 const std::shared_ptr<ShaderLibrary>& library = context->GetShaderLibrary();
117 std::shared_ptr<const ShaderFunction>
function = library->GetFunction(
124 if (function && runtime_stage_->IsDirty()) {
126 context->GetPipelineLibrary()->RemovePipelinesWithEntryPoint(function);
127 library->UnregisterFunction(runtime_stage_->GetEntrypoint(),
134 std::promise<bool> promise;
135 auto future = promise.get_future();
137 library->RegisterFunction(
138 runtime_stage_->GetEntrypoint(),
140 runtime_stage_->GetCodeMapping(),
142 promise.set_value(result);
147 << runtime_stage_->GetEntrypoint() <<
")";
151 function = library->GetFunction(runtime_stage_->GetEntrypoint(),
155 <<
"Failed to fetch runtime effect function immediately after "
156 "registering it (entry point: "
157 << runtime_stage_->GetEntrypoint() <<
")";
161 runtime_stage_->SetClean();
166std::shared_ptr<Pipeline<PipelineDescriptor>>
167RuntimeEffectContents::CreatePipeline(
const ContentContext& renderer,
168 ContentContextOptions options,
170 const std::shared_ptr<Context>& context = renderer.GetContext();
171 const std::shared_ptr<ShaderLibrary>& library = context->GetShaderLibrary();
172 const std::shared_ptr<const Capabilities>& caps = context->GetCapabilities();
173 const PixelFormat color_attachment_format = caps->GetDefaultColorFormat();
175 caps->GetDefaultDepthStencilFormat();
177 using VS = RuntimeEffectVertexShader;
179 PipelineDescriptor desc;
180 desc.SetLabel(
"Runtime Stage");
181 desc.AddStageEntrypoint(
183 desc.AddStageEntrypoint(library->GetFunction(runtime_stage_->GetEntrypoint(),
186 std::shared_ptr<VertexDescriptor> vertex_descriptor =
187 std::make_shared<VertexDescriptor>();
188 vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
189 VS::kInterleavedBufferLayout);
190 vertex_descriptor->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
191 vertex_descriptor->RegisterDescriptorSetLayouts(
192 runtime_stage_->GetDescriptorSetLayouts().data(),
193 runtime_stage_->GetDescriptorSetLayouts().size());
194 desc.SetVertexDescriptor(std::move(vertex_descriptor));
195 desc.SetColorAttachmentDescriptor(
196 0u, {.format = color_attachment_format, .blending_enabled =
true});
198 desc.SetStencilAttachmentDescriptors(StencilAttachmentDescriptor{});
199 desc.SetStencilPixelFormat(stencil_attachment_format);
201 desc.SetDepthStencilAttachmentDescriptor(DepthAttachmentDescriptor{});
202 desc.SetDepthPixelFormat(stencil_attachment_format);
204 options.ApplyToPipelineDescriptor(desc);
206 context->GetPipelineLibrary()->GetPipeline(desc, async);
210 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc, async).Get();
212 VALIDATION_LOG <<
"Failed to get or create runtime effect pipeline.";
222 const std::shared_ptr<Context>& context = renderer.
GetContext();
223 const std::shared_ptr<ShaderLibrary>& library = context->GetShaderLibrary();
230 if (!RegisterShader(renderer)) {
239 size_t buffer_index = 0;
240 size_t buffer_offset = 0;
241 size_t sampler_location = 0;
242 size_t buffer_location = 0;
252 for (
const auto& uniform : runtime_stage_->GetUniforms()) {
254 switch (uniform.type) {
256 FML_DCHECK(sampler_location < texture_inputs_.size());
257 auto&
input = texture_inputs_[sampler_location];
260 context->GetSamplerLibrary()->GetSampler(
261 input.sampler_descriptor);
264 image_slot.
name = uniform.name.c_str();
265 image_slot.
binding = uniform.binding;
269 std::move(metadata),
input.texture, sampler);
276 <<
"Uniform " << uniform.name
277 <<
" had unexpected type kFloat for Vulkan backend.";
280 std::max(uniform.bit_width / 8,
281 data_host_buffer.GetMinimumUniformAlignment());
283 data_host_buffer.Emplace(uniform_data_->data() + buffer_offset,
284 uniform.GetSize(), alignment);
287 uniform_slot.
name = uniform.name.c_str();
288 uniform_slot.
ext_res_0 = buffer_location;
293 buffer_offset += uniform.GetSize();
301 uniform_slot.
binding = uniform.location;
302 uniform_slot.
name = uniform.name.c_str();
308 uniform_data_, data_host_buffer, uniform,
309 data_host_buffer.GetMinimumUniformAlignment()));
318 using VS = RuntimeEffectVertexShader;
324 runtime_stage_->GetEntrypoint(), options, [&]() {
325 return CreatePipeline(renderer, options,
false);
329 return ColorSourceContents::DrawGeometry<VS>(renderer, entity, pass,
331 VS::FrameInfo{}, bind_callback);
std::function< PipelineRef(ContentContextOptions)> PipelineBuilderCallback
std::function< bool(RenderPass &pass)> BindFragmentCallback
HostBuffer & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
void ClearCachedRuntimeEffectPipeline(const std::string &unique_entrypoint_name) const
PipelineRef GetCachedRuntimeEffectPipeline(const std::string &unique_entrypoint_name, const ContentContextOptions &options, const std::function< std::shared_ptr< Pipeline< PipelineDescriptor > >()> &create_callback) const
std::shared_ptr< Context > GetContext() const
BufferView Emplace(const BufferType &buffer, size_t alignment=0)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
Render passes encode render commands directed as one specific render target into an underlying comman...
virtual bool BindDynamicResource(ShaderStage stage, DescriptorType type, const SampledImageSlot &slot, std::unique_ptr< ShaderMetadata > metadata, std::shared_ptr< const Texture > texture, raw_ptr< const Sampler >)
Bind with dynamically generated shader metadata.
virtual bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot &slot, const ShaderMetadata *metadata, BufferView view) override
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
bool BootstrapShader(const ContentContext &renderer) const
Load the runtime effect and ensure a default PSO is initialized.
void SetRuntimeStage(std::shared_ptr< RuntimeStage > runtime_stage)
void SetTextureInputs(std::vector< TextureInput > texture_inputs)
void SetUniformData(std::shared_ptr< std::vector< uint8_t > > uniform_data)
static BufferView EmplaceVulkanUniform(const std::shared_ptr< const std::vector< uint8_t > > &input_data, HostBuffer &host_buffer, const RuntimeUniformDescription &uniform, size_t minimum_uniform_alignment)
A wrapper around a raw ptr that adds additional unopt mode only checks.
#define FML_DCHECK(condition)
Dart_NativeFunction function
internal::CopyableLambda< T > MakeCopyable(T lambda)
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
static ShaderType GetShaderType(RuntimeUniformType type)
static std::unique_ptr< ShaderMetadata > MakeShaderMetadata(const RuntimeUniformDescription &uniform)
LinePipeline::VertexShader VS
PixelFormat color_attachment_pixel_format
Metadata required to bind a combined texture and sampler.
size_t texture_index
ext_res_0 is the Metal binding value.
const char * name
The name of the uniform slot.
size_t binding
The Vulkan binding value.