18#include "impeller/entity/runtime_effect.vert.h"
30 const uint8_t* source_data,
33 size_t minimum_uniform_alignment =
35 size_t alignment = std::max(uniform.
bit_width / 8, minimum_uniform_alignment);
45 return data_host_buffer.
Emplace(
47 [&uniform, source_data](uint8_t* destination) {
48 size_t count = uniform.array_elements.value_or(1);
53 size_t uniform_byte_index = 0u;
54 size_t struct_float_index = 0u;
55 auto* float_destination =
reinterpret_cast<float*
>(destination);
56 auto* float_source =
reinterpret_cast<const float*
>(source_data);
58 for (
size_t i = 0;
i < count;
i++) {
61 float_destination[struct_float_index++] = 0.f;
64 float_destination[struct_float_index++] =
65 float_source[uniform_byte_index++];
72RuntimeEffectContents::RuntimeEffectContents(
const Geometry* geometry)
73 : geometry_(geometry) {}
82 std::shared_ptr<RuntimeStage> runtime_stage) {
83 runtime_stage_ = std::move(runtime_stage);
92 runtime_stage_->GetEntrypoint());
94 scoped_fragment_name_.clear();
99 std::shared_ptr<std::vector<uint8_t>> uniform_data) {
100 uniform_data_ = std::move(uniform_data);
104 std::vector<TextureInput> texture_inputs) {
105 texture_inputs_ = std::move(texture_inputs);
121 std::unique_ptr<ShaderMetadata> metadata = std::make_unique<ShaderMetadata>();
122 metadata->name = uniform.
name;
126 std::optional<size_t> array_elements;
141 .byte_length = member_size * array_elements.value_or(1),
142 .array_elements = array_elements,
143 .float_type = float_type,
151 if (!RegisterShader(renderer)) {
156 renderer.
GetContext()->GetCapabilities()->GetDefaultColorFormat();
157 CreatePipeline(renderer, options,
true);
161bool RuntimeEffectContents::RegisterShader(
163 const std::shared_ptr<Context>& context = renderer.
GetContext();
164 const std::shared_ptr<ShaderLibrary>& library = context->GetShaderLibrary();
166 std::shared_ptr<const ShaderFunction>
function =
173 if (function && runtime_stage_->IsDirty()) {
175 context->GetPipelineLibrary()->RemovePipelinesWithEntryPoint(function);
182 std::promise<bool> promise;
183 auto future = promise.get_future();
185 library->RegisterFunction(
186 scoped_fragment_name_,
ToShaderStage(runtime_stage_->GetShaderStage()),
187 runtime_stage_->GetCodeMapping(),
189 promise.set_value(result);
194 << runtime_stage_->GetEntrypoint() <<
")";
202 <<
"Failed to fetch runtime effect function immediately after "
203 "registering it (entry point: "
204 << runtime_stage_->GetEntrypoint() <<
")";
208 runtime_stage_->SetClean();
213std::shared_ptr<Pipeline<PipelineDescriptor>>
214RuntimeEffectContents::CreatePipeline(
const ContentContext& renderer,
215 ContentContextOptions options,
217 const std::shared_ptr<Context>& context = renderer.GetContext();
218 const std::shared_ptr<ShaderLibrary>& library = context->GetShaderLibrary();
219 const std::shared_ptr<const Capabilities>& caps = context->GetCapabilities();
220 const PixelFormat color_attachment_format = caps->GetDefaultColorFormat();
222 caps->GetDefaultDepthStencilFormat();
224 using VS = RuntimeEffectVertexShader;
226 PipelineDescriptor desc;
227 desc.SetLabel(
"Runtime Stage");
228 desc.AddStageEntrypoint(
230 desc.AddStageEntrypoint(
233 std::shared_ptr<VertexDescriptor> vertex_descriptor =
234 std::make_shared<VertexDescriptor>();
235 vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
236 VS::kInterleavedBufferLayout);
237 vertex_descriptor->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
238 vertex_descriptor->RegisterDescriptorSetLayouts(
239 runtime_stage_->GetDescriptorSetLayouts().data(),
240 runtime_stage_->GetDescriptorSetLayouts().size());
241 desc.SetVertexDescriptor(std::move(vertex_descriptor));
242 desc.SetColorAttachmentDescriptor(
243 0u, {.format = color_attachment_format, .blending_enabled =
true});
245 desc.SetStencilAttachmentDescriptors(StencilAttachmentDescriptor{});
246 desc.SetStencilPixelFormat(stencil_attachment_format);
248 desc.SetDepthStencilAttachmentDescriptor(DepthAttachmentDescriptor{});
249 desc.SetDepthPixelFormat(stencil_attachment_format);
251 options.ApplyToPipelineDescriptor(desc);
253 context->GetPipelineLibrary()->GetPipeline(desc, async);
257 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc, async).Get();
259 VALIDATION_LOG <<
"Failed to get or create runtime effect pipeline.";
269 const std::shared_ptr<Context>& context = renderer.
GetContext();
270 const std::shared_ptr<ShaderLibrary>& library = context->GetShaderLibrary();
277 if (!RegisterShader(renderer)) {
286 size_t buffer_index = 0;
287 size_t buffer_offset = 0;
288 size_t sampler_location = 0;
289 size_t buffer_location = 0;
299 for (
const auto& uniform : runtime_stage_->GetUniforms()) {
301 switch (uniform.type) {
303 FML_DCHECK(sampler_location < texture_inputs_.size());
304 auto&
input = texture_inputs_[sampler_location];
307 context->GetSamplerLibrary()->GetSampler(
308 input.sampler_descriptor);
311 image_slot.
name = uniform.name.c_str();
312 image_slot.
binding = uniform.binding;
316 std::move(metadata),
input.texture, sampler);
323 <<
"Uniform " << uniform.name
324 <<
" had unexpected type kFloat for Vulkan backend.";
327 uniform_data_->data() + buffer_offset, data_host_buffer, uniform);
330 uniform_slot.
name = uniform.name.c_str();
331 uniform_slot.
ext_res_0 = buffer_location;
334 std::move(metadata), std::move(buffer_view));
336 buffer_offset += uniform.GetDartSize();
344 uniform_slot.
binding = uniform.location;
345 uniform_slot.
name = uniform.name.c_str();
349 uniform_slot,
nullptr,
350 EmplaceUniform(uniform_data_->data(), data_host_buffer, uniform));
359 using VS = RuntimeEffectVertexShader;
365 scoped_fragment_name_, options, [&]() {
366 return CreatePipeline(renderer, options,
false);
370 return ColorSourceContents::DrawGeometry<VS>(renderer, entity, pass,
372 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.
size_t GetMinimumUniformAlignment() const
Retrieve the minimum uniform buffer alignment in bytes.
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)
static BufferView EmplaceUniform(const uint8_t *source_data, HostBuffer &host_buffer, const RuntimeUniformDescription &uniform)
void SetUniformData(std::shared_ptr< std::vector< uint8_t > > uniform_data)
const Geometry * GetGeometry() const override
Get the geometry that this contents will use to render.
~RuntimeEffectContents() override
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 std::optional< ShaderFloatType > DeriveShaderFloatType(ShaderType type, size_t vec_size, size_t columns)
Derive the ShaderFloatType from the base ShaderType and the (vec_size, columns) dimensions reported b...
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
impeller::ShaderType type
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.
static std::string MakeUserScopedName(std::string_view scope, std::string_view library_id, std::string_view entrypoint)
static constexpr std::string_view kScopeRuntimeEffect