diff --git a/impeller/display_list/dl_vertices_geometry.cc b/impeller/display_list/dl_vertices_geometry.cc index 52c70c7475752..4e241ca7d1d7d 100644 --- a/impeller/display_list/dl_vertices_geometry.cc +++ b/impeller/display_list/dl_vertices_geometry.cc @@ -7,7 +7,6 @@ #include "impeller/core/device_buffer.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" -#include "impeller/entity/position_color.vert.h" #include "impeller/entity/texture_fill.vert.h" #include "impeller/geometry/matrix.h" #include "impeller/geometry/path_builder.h" @@ -160,9 +159,8 @@ GeometryResult DlVerticesGeometry::GetPositionBuffer( Range{0, total_vtx_bytes}, 0)) { return {}; } - if (!buffer->CopyHostBuffer( - reinterpret_cast(const_cast(dl_indices)), - Range{0, total_idx_bytes}, total_vtx_bytes)) { + if (!buffer->CopyHostBuffer(reinterpret_cast(dl_indices), + Range{0, total_idx_bytes}, total_vtx_bytes)) { return {}; } @@ -184,12 +182,10 @@ GeometryResult DlVerticesGeometry::GetPositionBuffer( }; } -GeometryResult DlVerticesGeometry::GetPositionColorBuffer( +PositionColorBufferResult DlVerticesGeometry::GetPositionColorBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - using VS = GeometryColorPipeline::VertexShader; - auto index_count = normalized_indices_.size() == 0 ? vertices_->index_count() : normalized_indices_.size(); @@ -200,56 +196,54 @@ GeometryResult DlVerticesGeometry::GetPositionColorBuffer( auto* dl_vertices = vertices_->vertices(); auto* dl_colors = vertices_->colors(); - std::vector vertex_data(vertex_count); - { - for (auto i = 0; i < vertex_count; i++) { - auto dl_color = dl_colors[i]; - auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), - dl_color.getBlueF(), dl_color.getAlphaF()) - .Premultiply(); - auto sk_point = dl_vertices[i]; - vertex_data[i] = { - .position = Point(sk_point.x(), sk_point.y()), - .color = color, - }; - } - } - - size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData); + size_t total_position_bytes = vertex_count * sizeof(float) * 2; + size_t total_color_bytes = vertex_count * sizeof(float) * 4; + size_t total_vtx_bytes = total_position_bytes + total_color_bytes; size_t total_idx_bytes = index_count * sizeof(uint16_t); DeviceBufferDescriptor buffer_desc; - buffer_desc.size = total_vtx_bytes + total_idx_bytes; + buffer_desc.size = total_position_bytes + total_color_bytes + total_idx_bytes; buffer_desc.storage_mode = StorageMode::kHostVisible; auto buffer = renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - if (!buffer->CopyHostBuffer(reinterpret_cast(vertex_data.data()), - Range{0, total_vtx_bytes}, 0)) { + if (!buffer->CopyHostBuffer(reinterpret_cast(dl_vertices), + Range{0, total_position_bytes}, 0)) { return {}; } - if (!buffer->CopyHostBuffer( - reinterpret_cast(const_cast(dl_indices)), - Range{0, total_idx_bytes}, total_vtx_bytes)) { + // This conversion is still necessary because dl_color is backed by a unit32 + // instead of 4 floats and is not premupltiplied. + std::vector colors(vertex_count); + for (auto i = 0; i < vertex_count; i++) { + auto dl_color = dl_colors[i]; + colors[i] = Color(dl_color.getRedF(), dl_color.getGreenF(), + dl_color.getBlueF(), dl_color.getAlphaF()) + .Premultiply(); + } + + if (!buffer->CopyHostBuffer(reinterpret_cast(colors.data()), + Range{0, total_color_bytes}, + total_position_bytes)) { + return {}; + } + if (!buffer->CopyHostBuffer(reinterpret_cast(dl_indices), + Range{0, total_idx_bytes}, total_vtx_bytes)) { return {}; } - return GeometryResult{ + return PositionColorBufferResult{ + .index_buffer = {.buffer = buffer, + .range = Range{total_vtx_bytes, total_idx_bytes}}, + .position_buffer = {.buffer = buffer, + .range = Range{0, total_position_bytes}}, + .color_buffer = {.buffer = buffer, + .range = Range{total_position_bytes, total_color_bytes}}, .type = GetPrimitiveType(vertices_), - .vertex_buffer = - { - .vertex_buffer = {.buffer = buffer, - .range = Range{0, total_vtx_bytes}}, - .index_buffer = {.buffer = buffer, - .range = - Range{total_vtx_bytes, total_idx_bytes}}, - .vertex_count = index_count, - .index_type = IndexType::k16bit, - }, + .vertex_count = index_count, + .index_type = IndexType::k16bit, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), - .prevent_overdraw = false, }; } diff --git a/impeller/display_list/dl_vertices_geometry.h b/impeller/display_list/dl_vertices_geometry.h index 538b65a6d501b..bb40d0be45d85 100644 --- a/impeller/display_list/dl_vertices_geometry.h +++ b/impeller/display_list/dl_vertices_geometry.h @@ -27,11 +27,12 @@ class DlVerticesGeometry : public VerticesGeometry { const flutter::DlVertices* vertices); // |VerticesGeometry| - GeometryResult GetPositionColorBuffer(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) override; + PositionColorBufferResult GetPositionColorBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) override; - // |VerticesGeometry| + // |Geometry| GeometryResult GetPositionUVBuffer(Rect texture_coverage, Matrix effect_transform, const ContentContext& renderer, diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 68011388e661b..86bbf453154d7 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -9,6 +9,7 @@ #include "impeller/base/strings.h" #include "impeller/core/formats.h" +#include "impeller/entity/contents/vertices_contents.h" #include "impeller/entity/entity.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/pipeline_library.h" @@ -137,7 +138,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor( } desc.SetPrimitiveType(primitive_type); - desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill); } @@ -156,6 +156,24 @@ static std::unique_ptr CreateDefaultPipeline( return std::make_unique(context, desc); } +template +static std::unique_ptr CreateCustomizedPipeline( + const Context& context, + std::array vertex_inputs, + std::array vertex_layouts) { + auto desc = PipelineT::Builder::MakeCustomizedPipelineDescriptor( + context, vertex_inputs, vertex_layouts); + if (!desc.has_value()) { + return nullptr; + } + // Apply default ContentContextOptions to the descriptor. + const auto default_color_fmt = + context.GetCapabilities()->GetDefaultColorFormat(); + ContentContextOptions{.color_attachment_pixel_format = default_color_fmt} + .ApplyToPipelineDescriptor(*desc); + return std::make_unique(context, desc); +} + ContentContext::ContentContext(std::shared_ptr context) : context_(std::move(context)), tessellator_(std::make_shared()), @@ -286,6 +304,10 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); geometry_color_pipelines_[{}] = CreateDefaultPipeline(*context_); + geometry_color_non_interleaved_pipelines_[{}] = + CreateCustomizedPipeline( + *context_, VerticesBindings::kAllShaderStageInputs, + VerticesBindings::kNonInterleavedBufferLayout); yuv_to_rgb_filter_pipelines_[{}] = CreateDefaultPipeline(*context_); porter_duff_blend_pipelines_[{}] = diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 706d77a6c1adb..bb3234f828525 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -487,6 +487,11 @@ class ContentContext { return GetPipeline(geometry_color_pipelines_, opts); } + std::shared_ptr> + GetGeometryColorPipelineNonInterleaved(ContentContextOptions opts) const { + return GetPipeline(geometry_color_non_interleaved_pipelines_, opts); + } + std::shared_ptr> GetYUVToRGBFilterPipeline( ContentContextOptions opts) const { return GetPipeline(yuv_to_rgb_filter_pipelines_, opts); @@ -750,6 +755,8 @@ class ContentContext { mutable Variants glyph_atlas_pipelines_; mutable Variants glyph_atlas_color_pipelines_; mutable Variants geometry_color_pipelines_; + mutable Variants + geometry_color_non_interleaved_pipelines_; mutable Variants yuv_to_rgb_filter_pipelines_; mutable Variants porter_duff_blend_pipelines_; // Advanced blends. @@ -815,7 +822,6 @@ class ContentContext { if (wireframe_) { opts.wireframe = true; } - if (auto found = container.find(opts); found != container.end()) { return found->second->WaitAndGet(); } diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index b01716c00f260..c87b225cfdd3b 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -184,9 +184,13 @@ bool VerticesColorContents::Render(const ContentContext& renderer, geometry->GetPositionColorBuffer(renderer, entity, pass); auto opts = OptionsFromPassAndEntity(pass, entity); opts.primitive_type = geometry_result.type; - cmd.pipeline = renderer.GetGeometryColorPipeline(opts); + cmd.pipeline = renderer.GetGeometryColorPipelineNonInterleaved(opts); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(geometry_result.vertex_buffer); + + cmd.BindVertexBuffers<2>( + {geometry_result.position_buffer, geometry_result.color_buffer}); + cmd.BindIndexBuffer(geometry_result.index_type, geometry_result.index_buffer); + cmd.vertex_count = geometry_result.vertex_count; VS::FrameInfo frame_info; frame_info.mvp = geometry_result.transform; diff --git a/impeller/entity/contents/vertices_contents.h b/impeller/entity/contents/vertices_contents.h index 2909176879675..f9fe086af008b 100644 --- a/impeller/entity/contents/vertices_contents.h +++ b/impeller/entity/contents/vertices_contents.h @@ -20,6 +20,53 @@ namespace impeller { +namespace VerticesBindings { + +static constexpr auto kInputPosition = ShaderStageIOSlot{ + // position + "position", // name + 0u, // attribute location + 0u, // attribute set + 0u, // attribute binding + ShaderType::kFloat, // type + 32u, // bit width of type + 2u, // vec size + 1u, // number of columns + 0u, // offset for interleaved layout +}; + +static constexpr auto kInputColor = ShaderStageIOSlot{ + // color + "color", // name + 1u, // attribute location + 0u, // attribute set + 1u, // attribute binding + ShaderType::kFloat, // type + 32u, // bit width of type + 4u, // vec size + 1u, // number of columns + 0u, // offset for interleaved layout +}; + +static constexpr std::array kAllShaderStageInputs = + { + &kInputPosition, // position + &kInputColor, // color +}; + +static constexpr auto kInputBuffer = ShaderStageBufferLayout{ + sizeof(Vector2), // stride for interleaved layout + 0u, // attribute binding +}; +static constexpr auto kColorBuffer = ShaderStageBufferLayout{ + sizeof(Color), // stride for interleaved layout + 1u, // attribute binding +}; +static constexpr std::array + kNonInterleavedBufferLayout = {&kInputBuffer, &kColorBuffer}; + +} // namespace VerticesBindings + class VerticesContents final : public Contents { public: VerticesContents(); diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index bbe4ce286828a..05cac84896f55 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -13,6 +13,7 @@ #include "fml/logging.h" #include "fml/time/time_point.h" #include "gtest/gtest.h" +#include "impeller/entity/contents/anonymous_contents.h" #include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/conical_gradient_contents.h" diff --git a/impeller/entity/geometry/vertices_geometry.h b/impeller/entity/geometry/vertices_geometry.h index 09a6b377659e5..027ea6d4085ae 100644 --- a/impeller/entity/geometry/vertices_geometry.h +++ b/impeller/entity/geometry/vertices_geometry.h @@ -8,12 +8,24 @@ namespace impeller { +struct PositionColorBufferResult { + BufferView index_buffer; + BufferView position_buffer; + BufferView color_buffer; + + PrimitiveType type; + size_t vertex_count; + IndexType index_type; + Matrix transform; +}; + /// @brief A geometry that is created from a vertices object. class VerticesGeometry : public Geometry { public: - virtual GeometryResult GetPositionColorBuffer(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) = 0; + virtual PositionColorBufferResult GetPositionColorBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) = 0; virtual bool HasVertexColors() const = 0; diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/impeller/renderer/backend/gles/buffer_bindings_gles.cc index c72c34f807aeb..a902d7a7f5f9b 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -123,16 +123,31 @@ bool BufferBindingsGLES::ReadUniformsBindings(const ProcTableGLES& gl, } bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl, + size_t vertex_index, size_t vertex_offset) const { - for (const auto& array : vertex_attrib_arrays_) { + if (true) { + for (const auto& array : vertex_attrib_arrays_) { + gl.EnableVertexAttribArray(array.index); + gl.VertexAttribPointer( + array.index, // index + array.size, // size (must be 1, 2, 3, or 4) + array.type, // type + array.normalized, // normalized + array.stride, // stride + reinterpret_cast( + static_cast(vertex_offset + array.offset)) // pointer + ); + } + } else { + auto array = vertex_attrib_arrays_[vertex_index]; gl.EnableVertexAttribArray(array.index); gl.VertexAttribPointer(array.index, // index array.size, // size (must be 1, 2, 3, or 4) array.type, // type array.normalized, // normalized array.stride, // stride - reinterpret_cast(static_cast( - vertex_offset + array.offset)) // pointer + reinterpret_cast( + static_cast(vertex_offset)) // pointer ); } diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.h b/impeller/renderer/backend/gles/buffer_bindings_gles.h index b556364b9ea86..bb6686202e2f9 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.h +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.h @@ -33,6 +33,7 @@ class BufferBindingsGLES { bool ReadUniformsBindings(const ProcTableGLES& gl, GLuint program); bool BindVertexAttributes(const ProcTableGLES& gl, + size_t vertex_index, size_t vertex_offset) const; bool BindUniformData(const ProcTableGLES& gl, diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc index 31515b1537e0b..adbb74329a5fd 100644 --- a/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/impeller/renderer/backend/gles/render_pass_gles.cc @@ -355,23 +355,37 @@ struct RenderPassData { //-------------------------------------------------------------------------- /// Bind vertex and index buffers. /// - auto vertex_buffer_view = command.GetVertexBuffer(); + auto vertex_buffer_count = VertexDescriptor::kReservedVertexBufferIndex - + command.last_vertex_index + 1; + for (auto i = 0u; i < vertex_buffer_count; i++) { + auto vertex_buffer_view = + command.vertex_bindings.buffers + .find(VertexDescriptor::kReservedVertexBufferIndex - i) + ->second.resource; + if (!vertex_buffer_view) { + return false; + } - if (!vertex_buffer_view) { - return false; - } + auto vertex_buffer = + vertex_buffer_view.buffer->GetDeviceBuffer(*transients_allocator); - auto vertex_buffer = - vertex_buffer_view.buffer->GetDeviceBuffer(*transients_allocator); + if (!vertex_buffer) { + return false; + } - if (!vertex_buffer) { - return false; - } + const auto& vertex_buffer_gles = DeviceBufferGLES::Cast(*vertex_buffer); + if (!vertex_buffer_gles.BindAndUploadDataIfNecessary( + DeviceBufferGLES::BindingType::kArrayBuffer)) { + return false; + } - const auto& vertex_buffer_gles = DeviceBufferGLES::Cast(*vertex_buffer); - if (!vertex_buffer_gles.BindAndUploadDataIfNecessary( - DeviceBufferGLES::BindingType::kArrayBuffer)) { - return false; + //-------------------------------------------------------------------------- + /// Bind vertex attribs. + /// + if (!vertex_desc_gles->BindVertexAttributes( + gl, i, vertex_buffer_view.range.offset)) { + return false; + } } //-------------------------------------------------------------------------- @@ -381,14 +395,6 @@ struct RenderPassData { return false; } - //-------------------------------------------------------------------------- - /// Bind vertex attribs. - /// - if (!vertex_desc_gles->BindVertexAttributes( - gl, vertex_buffer_view.range.offset)) { - return false; - } - //-------------------------------------------------------------------------- /// Bind uniform data. /// diff --git a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc index 2cf6a0fed89e4..ec9aacc14151d 100644 --- a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc @@ -268,7 +268,6 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( vk::PipelineVertexInputStateCreateInfo vertex_input_state; vertex_input_state.setVertexAttributeDescriptions(attr_descs); vertex_input_state.setVertexBindingDescriptions(buffer_descs); - pipeline_info.setPVertexInputState(&vertex_input_state); //---------------------------------------------------------------------------- diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index a7d1ee633831d..63d763829f4d2 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -337,12 +337,13 @@ static bool AllocateAndBindDescriptorSets(const ContextVK& context, return true; }; - auto bind_buffers = [&allocator, // - &encoder, // - &buffers, // - &writes, // - &desc_set, // - &vk_desc_set // + auto bind_buffers = [&allocator, // + &encoder, // + &buffers, // + &writes, // + &desc_set, // + &vk_desc_set, // + &command // ](const Bindings& bindings) -> bool { for (const auto& [buffer_index, view] : bindings.buffers) { const auto& buffer_view = view.resource.buffer; @@ -358,8 +359,8 @@ static bool AllocateAndBindDescriptorSets(const ContextVK& context, return false; } - // Reserved index used for per-vertex data. - if (buffer_index == VertexDescriptor::kReservedVertexBufferIndex) { + // Reserved indexes used for per-vertex data. + if (buffer_index >= command.last_vertex_index) { continue; } @@ -480,32 +481,43 @@ static bool EncodeCommand(const Context& context, cmd_buffer, vk::StencilFaceFlagBits::eVkStencilFrontAndBack, command.stencil_reference); - // Configure vertex and index and buffers for binding. - auto vertex_buffer_view = command.GetVertexBuffer(); + auto& allocator = *context.GetResourceAllocator(); - if (!vertex_buffer_view) { - return false; - } + // Configure vertex and index and buffers for binding. + auto vertex_buffer_count = VertexDescriptor::kReservedVertexBufferIndex - + command.last_vertex_index + 1; + std::vector vertex_buffers; + std::vector vertex_buffer_offsets; + for (auto i = 0u; i < vertex_buffer_count; i++) { + auto vertex_buffer_view = + command.vertex_bindings.buffers + .find(VertexDescriptor::kReservedVertexBufferIndex - i) + ->second.resource; + + if (!vertex_buffer_view) { + return false; + } - auto& allocator = *context.GetResourceAllocator(); + auto vertex_buffer = vertex_buffer_view.buffer->GetDeviceBuffer(allocator); - auto vertex_buffer = vertex_buffer_view.buffer->GetDeviceBuffer(allocator); + if (!vertex_buffer) { + VALIDATION_LOG << "Failed to acquire device buffer" + << " for vertex buffer view"; + return false; + } - if (!vertex_buffer) { - VALIDATION_LOG << "Failed to acquire device buffer" - << " for vertex buffer view"; - return false; - } + if (!encoder.Track(vertex_buffer)) { + return false; + } - if (!encoder.Track(vertex_buffer)) { - return false; + // Bind the vertex buffer. + auto vertex_buffer_handle = + DeviceBufferVK::Cast(*vertex_buffer).GetBuffer(); + vertex_buffers.push_back(vertex_buffer_handle); + vertex_buffer_offsets.push_back(vertex_buffer_view.range.offset); } - - // Bind the vertex buffer. - auto vertex_buffer_handle = DeviceBufferVK::Cast(*vertex_buffer).GetBuffer(); - vk::Buffer vertex_buffers[] = {vertex_buffer_handle}; - vk::DeviceSize vertex_buffer_offsets[] = {vertex_buffer_view.range.offset}; - cmd_buffer.bindVertexBuffers(0u, 1u, vertex_buffers, vertex_buffer_offsets); + cmd_buffer.bindVertexBuffers(0u, vertex_buffer_count, vertex_buffers.data(), + vertex_buffer_offsets.data()); if (command.index_type != IndexType::kNone) { // Bind the index buffer. diff --git a/impeller/renderer/command.cc b/impeller/renderer/command.cc index 068eb2fdf5578..6d5734601de1e 100644 --- a/impeller/renderer/command.cc +++ b/impeller/renderer/command.cc @@ -26,13 +26,9 @@ bool Command::BindVertices(const VertexBuffer& buffer) { return true; } -BufferView Command::GetVertexBuffer() const { - auto found = vertex_bindings.buffers.find( - VertexDescriptor::kReservedVertexBufferIndex); - if (found != vertex_bindings.buffers.end()) { - return found->second.resource; - } - return {}; +void Command::BindIndexBuffer(IndexType type, BufferView buffer) { + index_type = type; + index_buffer = std::move(buffer); } bool Command::BindResource(ShaderStage stage, diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index e44633f2365b7..64e53b799920d 100644 --- a/impeller/renderer/command.h +++ b/impeller/renderer/command.h @@ -154,6 +154,8 @@ struct Command : public ResourceBinder { /// size_t instance_count = 1u; + size_t last_vertex_index = VertexDescriptor::kReservedVertexBufferIndex; + //---------------------------------------------------------------------------- /// @brief Specify the vertex and index buffer to use for this command. /// @@ -163,6 +165,18 @@ struct Command : public ResourceBinder { /// bool BindVertices(const VertexBuffer& buffer); + void BindIndexBuffer(IndexType index_type, BufferView index_buffer); + + template + void BindVertexBuffers(std::array vertex_buffers) { + for (auto i = 0u; i < N; i++) { + vertex_bindings + .buffers[VertexDescriptor::kReservedVertexBufferIndex - i] = { + nullptr, vertex_buffers[i]}; + } + last_vertex_index = VertexDescriptor::kReservedVertexBufferIndex - N + 1; + }; + // |ResourceBinder| bool BindResource(ShaderStage stage, const ShaderUniformSlot& slot, @@ -193,8 +207,6 @@ struct Command : public ResourceBinder { const std::shared_ptr& texture, const std::shared_ptr& sampler) override; - BufferView GetVertexBuffer() const; - constexpr operator bool() const { return pipeline && pipeline->IsValid(); } private: diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index 593df8057ff75..77dd7000cee21 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -56,9 +56,33 @@ struct PipelineBuilder { return std::nullopt; } + template + static std::optional MakeCustomizedPipelineDescriptor( + const Context& context, + std::array vertex_inputs, + std::array vertex_layouts) { + PipelineDescriptor desc; + if (InitializePipelineDescriptor(context, desc, vertex_inputs, + vertex_layouts)) { + return {std::move(desc)}; + } + return std::nullopt; + } + [[nodiscard]] static bool InitializePipelineDescriptorDefaults( const Context& context, PipelineDescriptor& desc) { + return InitializePipelineDescriptor(context, desc, + VertexShader::kAllShaderStageInputs, + VertexShader::kInterleavedBufferLayout); + } + + template + [[nodiscard]] static bool InitializePipelineDescriptor( + const Context& context, + PipelineDescriptor& desc, + std::array vertex_inputs, + std::array vertex_layouts) { // Setup debug instrumentation. desc.SetLabel(SPrintF("%s Pipeline", FragmentShader::kLabel.data())); @@ -85,8 +109,7 @@ struct PipelineBuilder { // Setup the vertex descriptor from reflected information. { auto vertex_descriptor = std::make_shared(); - vertex_descriptor->SetStageInputs(VertexShader::kAllShaderStageInputs, - VertexShader::kInterleavedBufferLayout); + vertex_descriptor->SetStageInputs(vertex_inputs, vertex_layouts); vertex_descriptor->RegisterDescriptorSetLayouts( VertexShader::kDescriptorSetLayouts); vertex_descriptor->RegisterDescriptorSetLayouts(