From 3a7ba55407e5d23b6d7e14376ad0115ac7c7ae7d Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 30 May 2023 07:51:49 -0700 Subject: [PATCH 01/14] [Impeller] support non-interleaved vertex data. --- impeller/display_list/dl_vertices_geometry.cc | 76 +++++++++---------- impeller/display_list/dl_vertices_geometry.h | 9 ++- impeller/entity/contents/content_context.cc | 2 +- impeller/entity/contents/content_context.h | 12 +-- impeller/entity/contents/vertices_contents.cc | 7 +- impeller/entity/geometry/vertices_geometry.h | 18 ++++- .../backend/metal/pipeline_library_mtl.mm | 2 + .../backend/metal/vertex_descriptor_mtl.h | 3 + .../backend/metal/vertex_descriptor_mtl.mm | 61 ++++++++++----- impeller/renderer/command.cc | 11 +++ impeller/renderer/command.h | 4 + impeller/renderer/pipeline_builder.h | 3 +- impeller/renderer/pipeline_descriptor.cc | 12 ++- impeller/renderer/pipeline_descriptor.h | 5 ++ impeller/renderer/vertex_descriptor.cc | 12 ++- impeller/renderer/vertex_descriptor.h | 5 ++ 16 files changed, 165 insertions(+), 77 deletions(-) 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 55aa880923ceb..13cadda54256d 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -143,7 +143,7 @@ void ContentContextOptions::ApplyToPipelineDescriptor( } desc.SetPrimitiveType(primitive_type); - + desc.SetInterleavedVertexData(interleaved_vertex_data); desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill); } diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index bbfe56916f619..8ad715de6ef37 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -300,13 +300,14 @@ struct ContentContextOptions { std::optional color_attachment_pixel_format; bool has_stencil_attachment = true; bool wireframe = false; + bool interleaved_vertex_data = false; struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { - return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare, - o.stencil_operation, o.primitive_type, - o.color_attachment_pixel_format, - o.has_stencil_attachment, o.wireframe); + return fml::HashCombine( + o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation, + o.primitive_type, o.color_attachment_pixel_format, + o.has_stencil_attachment, o.wireframe, o.interleaved_vertex_data); } }; @@ -321,7 +322,8 @@ struct ContentContextOptions { lhs.color_attachment_pixel_format == rhs.color_attachment_pixel_format && lhs.has_stencil_attachment == rhs.has_stencil_attachment && - lhs.wireframe == rhs.wireframe; + lhs.wireframe == rhs.wireframe && + lhs.interleaved_vertex_data == rhs.interleaved_vertex_data; } }; diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 8b0dab9e6f252..5224af6447537 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -183,10 +183,15 @@ bool VerticesColorContents::Render(const ContentContext& renderer, auto geometry_result = geometry->GetPositionColorBuffer(renderer, entity, pass); auto opts = OptionsFromPassAndEntity(pass, entity); + opts.interleaved_vertex_data = false; opts.primitive_type = geometry_result.type; cmd.pipeline = renderer.GetGeometryColorPipeline(opts); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(geometry_result.vertex_buffer); + + cmd.BindVertexBuffer(geometry_result.position_buffer, 0u); + cmd.BindVertexBuffer(geometry_result.color_buffer, 1u); + 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/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/metal/pipeline_library_mtl.mm b/impeller/renderer/backend/metal/pipeline_library_mtl.mm index c65e31f1e7a43..878d783a3ae03 100644 --- a/impeller/renderer/backend/metal/pipeline_library_mtl.mm +++ b/impeller/renderer/backend/metal/pipeline_library_mtl.mm @@ -43,6 +43,8 @@ VertexDescriptorMTL vertex_descriptor_mtl; if (vertex_descriptor_mtl.SetStageInputs( vertex_descriptor->GetStageInputs())) { + vertex_descriptor_mtl.SetInterleavedVertexData( + vertex_descriptor->GetInterleavedVertexData()); descriptor.vertexDescriptor = vertex_descriptor_mtl.GetMTLVertexDescriptor(); } diff --git a/impeller/renderer/backend/metal/vertex_descriptor_mtl.h b/impeller/renderer/backend/metal/vertex_descriptor_mtl.h index 030d36fe8570f..36631823a0e5c 100644 --- a/impeller/renderer/backend/metal/vertex_descriptor_mtl.h +++ b/impeller/renderer/backend/metal/vertex_descriptor_mtl.h @@ -22,6 +22,8 @@ class VertexDescriptorMTL { bool SetStageInputs(const std::vector& inputs); + void SetInterleavedVertexData(bool value); + MTLVertexDescriptor* GetMTLVertexDescriptor() const; private: @@ -41,6 +43,7 @@ class VertexDescriptorMTL { }; }; std::set stage_inputs_; + bool interleaved_vertex_data_ = false; FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptorMTL); }; diff --git a/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm b/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm index a49a227324b26..7c0578c52b2ef 100644 --- a/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm +++ b/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm @@ -188,29 +188,52 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { return true; } +void VertexDescriptorMTL::SetInterleavedVertexData(bool value) { + interleaved_vertex_data_ = value; +} + MTLVertexDescriptor* VertexDescriptorMTL::GetMTLVertexDescriptor() const { auto descriptor = [MTLVertexDescriptor vertexDescriptor]; - const size_t vertex_buffer_index = - VertexDescriptor::kReservedVertexBufferIndex; - - size_t offset = 0u; - for (const auto& input : stage_inputs_) { - auto attrib = descriptor.attributes[input.location]; - attrib.format = input.format; - attrib.offset = offset; - // All vertex inputs are interleaved and tightly packed in one buffer at a - // reserved index. - attrib.bufferIndex = vertex_buffer_index; - offset += input.length; - } - - // Since it's all in one buffer, indicate its layout. - auto vertex_layout = descriptor.layouts[vertex_buffer_index]; - vertex_layout.stride = offset; - vertex_layout.stepRate = 1u; - vertex_layout.stepFunction = MTLVertexStepFunctionPerVertex; + if (interleaved_vertex_data_) { + const size_t vertex_buffer_index = + VertexDescriptor::kReservedVertexBufferIndex; + + size_t offset = 0u; + for (const auto& input : stage_inputs_) { + auto attrib = descriptor.attributes[input.location]; + attrib.format = input.format; + attrib.offset = offset; + // All vertex inputs are interleaved and tightly packed in one buffer at a + // reserved index. + attrib.bufferIndex = vertex_buffer_index; + offset += input.length; + } + // Since it's all in one buffer, indicate its layout. + auto vertex_layout = descriptor.layouts[vertex_buffer_index]; + vertex_layout.stride = offset; + vertex_layout.stepRate = 1u; + vertex_layout.stepFunction = MTLVertexStepFunctionPerVertex; + + } else { + // each piece of vertex data is in its own buffer. They are assigned + // starting at kReservedVertexBufferIndex counting backwards. + size_t vertex_buffer_index = VertexDescriptor::kReservedVertexBufferIndex; + + for (const auto& input : stage_inputs_) { + auto attrib = descriptor.attributes[input.location]; + attrib.format = input.format; + attrib.offset = 0u; + attrib.bufferIndex = vertex_buffer_index; + + auto vertex_layout = descriptor.layouts[vertex_buffer_index]; + vertex_layout.stride = input.length; + vertex_layout.stepRate = 1u; + vertex_layout.stepFunction = MTLVertexStepFunctionPerVertex; + vertex_buffer_index--; + } + } return descriptor; } diff --git a/impeller/renderer/command.cc b/impeller/renderer/command.cc index 068eb2fdf5578..9979d425d34e0 100644 --- a/impeller/renderer/command.cc +++ b/impeller/renderer/command.cc @@ -35,6 +35,17 @@ BufferView Command::GetVertexBuffer() const { return {}; } +void Command::BindIndexBuffer(IndexType type, BufferView buffer) { + index_type = type; + index_buffer = buffer; +} + +void Command::BindVertexBuffer(BufferView vertex_buffer, size_t offset) { + vertex_bindings + .buffers[VertexDescriptor::kReservedVertexBufferIndex - offset] = { + nullptr, vertex_buffer}; +} + bool Command::BindResource(ShaderStage stage, const ShaderUniformSlot& slot, const ShaderMetadata& metadata, diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index e44633f2365b7..dc2500b56a005 100644 --- a/impeller/renderer/command.h +++ b/impeller/renderer/command.h @@ -163,6 +163,10 @@ struct Command : public ResourceBinder { /// bool BindVertices(const VertexBuffer& buffer); + void BindIndexBuffer(IndexType index_type, BufferView index_buffer); + + void BindVertexBuffer(BufferView vertex_buffer, size_t offset); + // |ResourceBinder| bool BindResource(ShaderStage stage, const ShaderUniformSlot& slot, diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index ccc9e9b83a9f9..bd8d5fa14e2ac 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -107,7 +107,8 @@ struct PipelineBuilder { << VertexShader::kLabel << "'."; return false; } - + vertex_descriptor->SetInterleavedVertexData( + desc.GetInterleavedVertexData()); desc.SetVertexDescriptor(std::move(vertex_descriptor)); } diff --git a/impeller/renderer/pipeline_descriptor.cc b/impeller/renderer/pipeline_descriptor.cc index eef517b30c847..51a93ca870691 100644 --- a/impeller/renderer/pipeline_descriptor.cc +++ b/impeller/renderer/pipeline_descriptor.cc @@ -42,6 +42,7 @@ std::size_t PipelineDescriptor::GetHash() const { fml::HashCombineSeed(seed, cull_mode_); fml::HashCombineSeed(seed, primitive_type_); fml::HashCombineSeed(seed, polygon_mode_); + fml::HashCombineSeed(seed, interleaved_vertex_data_); return seed; } @@ -61,7 +62,8 @@ bool PipelineDescriptor::IsEqual(const PipelineDescriptor& other) const { winding_order_ == other.winding_order_ && cull_mode_ == other.cull_mode_ && primitive_type_ == other.primitive_type_ && - polygon_mode_ == other.polygon_mode_; + polygon_mode_ == other.polygon_mode_ && + interleaved_vertex_data_ == other.interleaved_vertex_data_; } PipelineDescriptor& PipelineDescriptor::SetLabel(std::string label) { @@ -277,4 +279,12 @@ PolygonMode PipelineDescriptor::GetPolygonMode() const { return polygon_mode_; } +void PipelineDescriptor::SetInterleavedVertexData(bool value) { + interleaved_vertex_data_ = value; +} + +bool PipelineDescriptor::GetInterleavedVertexData() const { + return interleaved_vertex_data_; +} + } // namespace impeller diff --git a/impeller/renderer/pipeline_descriptor.h b/impeller/renderer/pipeline_descriptor.h index 3d0eddf880e28..7196ffd7a95de 100644 --- a/impeller/renderer/pipeline_descriptor.h +++ b/impeller/renderer/pipeline_descriptor.h @@ -131,6 +131,10 @@ class PipelineDescriptor final : public Comparable { PolygonMode GetPolygonMode() const; + void SetInterleavedVertexData(bool value); + + bool GetInterleavedVertexData() const; + private: std::string label_; SampleCount sample_count_ = SampleCount::kCount1; @@ -149,6 +153,7 @@ class PipelineDescriptor final : public Comparable { back_stencil_attachment_descriptor_; PrimitiveType primitive_type_ = PrimitiveType::kTriangle; PolygonMode polygon_mode_ = PolygonMode::kFill; + bool interleaved_vertex_data_ = false; }; } // namespace impeller diff --git a/impeller/renderer/vertex_descriptor.cc b/impeller/renderer/vertex_descriptor.cc index 97dff83913a66..3c096ac043059 100644 --- a/impeller/renderer/vertex_descriptor.cc +++ b/impeller/renderer/vertex_descriptor.cc @@ -20,6 +20,10 @@ bool VertexDescriptor::SetStageInputs( return true; } +void VertexDescriptor::SetInterleavedVertexData(bool value) { + interleaved_vertex_data_ = value; +} + bool VertexDescriptor::RegisterDescriptorSetLayouts( const DescriptorSetLayout desc_set_layout[], size_t count) { @@ -36,18 +40,24 @@ size_t VertexDescriptor::GetHash() const { for (const auto& input : inputs_) { fml::HashCombineSeed(seed, input.GetHash()); } + fml::HashCombineSeed(seed, interleaved_vertex_data_); return seed; } // |Comparable| bool VertexDescriptor::IsEqual(const VertexDescriptor& other) const { - return inputs_ == other.inputs_; + return inputs_ == other.inputs_ && + other.interleaved_vertex_data_ == interleaved_vertex_data_; } const std::vector& VertexDescriptor::GetStageInputs() const { return inputs_; } +bool VertexDescriptor::GetInterleavedVertexData() const { + return interleaved_vertex_data_; +} + const std::vector& VertexDescriptor::GetDescriptorSetLayouts() const { return desc_set_layouts_; diff --git a/impeller/renderer/vertex_descriptor.h b/impeller/renderer/vertex_descriptor.h index e62b4d2552e2f..b2a90a0395cd0 100644 --- a/impeller/renderer/vertex_descriptor.h +++ b/impeller/renderer/vertex_descriptor.h @@ -50,6 +50,10 @@ class VertexDescriptor final : public Comparable { const std::vector& GetStageInputs() const; + void SetInterleavedVertexData(bool value); + + bool GetInterleavedVertexData() const; + const std::vector& GetDescriptorSetLayouts() const; // |Comparable| @@ -61,6 +65,7 @@ class VertexDescriptor final : public Comparable { private: std::vector inputs_; std::vector desc_set_layouts_; + bool interleaved_vertex_data_ = false; FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptor); }; From f572a493160fc953471b104a2904cb65c0c0cf1f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 31 May 2023 15:18:16 -0700 Subject: [PATCH 02/14] ++ --- .../backend/vulkan/pipeline_library_vk.cc | 78 +++++++++++++------ 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc index f68369a4fb0b9..cdc0105b85fb5 100644 --- a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc @@ -4,6 +4,7 @@ #include "impeller/renderer/backend/vulkan/pipeline_library_vk.h" +#include #include #include "flutter/fml/container.h" @@ -243,33 +244,64 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( //---------------------------------------------------------------------------- /// Vertex Input Setup /// - vk::VertexInputBindingDescription binding_description; - // Only 1 stream of data is supported for now. - binding_description.setBinding(0); - binding_description.setInputRate(vk::VertexInputRate::eVertex); - - std::vector attr_descs; - uint32_t offset = 0; + auto interleaved = desc.GetVertexDescriptor()->GetInterleavedVertexData(); const auto& stage_inputs = desc.GetVertexDescriptor()->GetStageInputs(); - for (const ShaderStageIOSlot& stage_in : stage_inputs) { - vk::VertexInputAttributeDescription attr_desc; - attr_desc.setBinding(stage_in.binding); - attr_desc.setLocation(stage_in.location); - attr_desc.setFormat(ToVertexDescriptorFormat(stage_in)); - attr_desc.setOffset(offset); - attr_descs.push_back(attr_desc); - uint32_t len = (stage_in.bit_width * stage_in.vec_size) / 8; - offset += len; - } - binding_description.setStride(offset); + if (interleaved) { + vk::VertexInputBindingDescription binding_description; + // Only 1 stream of data is supported for now. + binding_description.setBinding(0); + binding_description.setInputRate(vk::VertexInputRate::eVertex); + + std::vector attr_descs; + uint32_t offset = 0; + + for (const ShaderStageIOSlot& stage_in : stage_inputs) { + vk::VertexInputAttributeDescription attr_desc; + attr_desc.setBinding(stage_in.binding); + attr_desc.setLocation(stage_in.location); + attr_desc.setFormat(ToVertexDescriptorFormat(stage_in)); + attr_desc.setOffset(offset); + attr_descs.push_back(attr_desc); + uint32_t len = (stage_in.bit_width * stage_in.vec_size) / 8; + offset += len; + } - vk::PipelineVertexInputStateCreateInfo vertex_input_state; - vertex_input_state.setVertexAttributeDescriptions(attr_descs); - vertex_input_state.setVertexBindingDescriptionCount(1); - vertex_input_state.setPVertexBindingDescriptions(&binding_description); + binding_description.setStride(offset); - pipeline_info.setPVertexInputState(&vertex_input_state); + vk::PipelineVertexInputStateCreateInfo vertex_input_state; + vertex_input_state.setVertexAttributeDescriptions(attr_descs); + vertex_input_state.setVertexBindingDescriptionCount(1); + vertex_input_state.setPVertexBindingDescriptions(&binding_description); + + pipeline_info.setPVertexInputState(&vertex_input_state); + } else { + std::vector attr_descs; + std::vector binding_descs; + + for (const ShaderStageIOSlot& stage_in : stage_inputs) { + vk::VertexInputAttributeDescription attr_desc; + attr_desc.setBinding(stage_in.binding); + attr_desc.setLocation(stage_in.location); + attr_desc.setFormat(ToVertexDescriptorFormat(stage_in)); + attr_desc.setOffset(0); + attr_descs.push_back(attr_desc); + uint32_t len = (stage_in.bit_width * stage_in.vec_size) / 8; + + vk::VertexInputBindingDescription binding_description; + binding_description.setBinding(stage_in.binding); + binding_description.setInputRate(vk::VertexInputRate::eVertex); + binding_description.setStride(len); + + binding_descs.push_back(binding_description); + } + + vk::PipelineVertexInputStateCreateInfo vertex_input_state; + vertex_input_state.setVertexAttributeDescriptions(attr_descs); + vertex_input_state.setVertexBindingDescriptions(binding_descs); + + pipeline_info.setPVertexInputState(&vertex_input_state); + } //---------------------------------------------------------------------------- /// Pipeline Layout a.k.a the descriptor sets and uniforms. From d5d9bd94c84ab7bb78597d816df3a6103b97c1cf Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 31 May 2023 17:38:19 -0700 Subject: [PATCH 03/14] fixup --- impeller/entity/contents/vertices_contents.cc | 4 +- .../backend/vulkan/pipeline_library_vk.cc | 11 ++-- .../renderer/backend/vulkan/render_pass_vk.cc | 56 +++++++++++-------- impeller/renderer/command.cc | 6 -- impeller/renderer/command.h | 13 ++++- 5 files changed, 54 insertions(+), 36 deletions(-) diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 5224af6447537..d4ecb335e9f1f 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -188,8 +188,8 @@ bool VerticesColorContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetGeometryColorPipeline(opts); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertexBuffer(geometry_result.position_buffer, 0u); - cmd.BindVertexBuffer(geometry_result.color_buffer, 1u); + 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; diff --git a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc index cdc0105b85fb5..1d535c5435a8f 100644 --- a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc @@ -246,6 +246,8 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( /// auto interleaved = desc.GetVertexDescriptor()->GetInterleavedVertexData(); const auto& stage_inputs = desc.GetVertexDescriptor()->GetStageInputs(); + std::vector attr_descs; + std::vector binding_descs; if (interleaved) { vk::VertexInputBindingDescription binding_description; @@ -276,12 +278,10 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( pipeline_info.setPVertexInputState(&vertex_input_state); } else { - std::vector attr_descs; - std::vector binding_descs; - + size_t offset = 0u; for (const ShaderStageIOSlot& stage_in : stage_inputs) { vk::VertexInputAttributeDescription attr_desc; - attr_desc.setBinding(stage_in.binding); + attr_desc.setBinding(stage_in.binding + offset); attr_desc.setLocation(stage_in.location); attr_desc.setFormat(ToVertexDescriptorFormat(stage_in)); attr_desc.setOffset(0); @@ -289,11 +289,12 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( uint32_t len = (stage_in.bit_width * stage_in.vec_size) / 8; vk::VertexInputBindingDescription binding_description; - binding_description.setBinding(stage_in.binding); + binding_description.setBinding(stage_in.binding + offset); binding_description.setInputRate(vk::VertexInputRate::eVertex); binding_description.setStride(len); binding_descs.push_back(binding_description); + offset++; } vk::PipelineVertexInputStateCreateInfo vertex_input_state; diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index 40c8da7fe8420..e7452b7e385eb 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -338,7 +338,8 @@ static bool AllocateAndBindDescriptorSets(const ContextVK& context, &encoder, // &buffers, // &writes, // - &desc_set // + &desc_set, // + &command // ](const Bindings& bindings) -> bool { for (const auto& [buffer_index, view] : bindings.buffers) { const auto& buffer_view = view.resource.buffer; @@ -355,7 +356,7 @@ static bool AllocateAndBindDescriptorSets(const ContextVK& context, } // Reserved index used for per-vertex data. - if (buffer_index == VertexDescriptor::kReservedVertexBufferIndex) { + if (buffer_index >= command.last_vertex_index) { continue; } @@ -464,32 +465,43 @@ static bool EncodeCommand(const Context& context, 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 9979d425d34e0..5625ef29c1e2f 100644 --- a/impeller/renderer/command.cc +++ b/impeller/renderer/command.cc @@ -40,12 +40,6 @@ void Command::BindIndexBuffer(IndexType type, BufferView buffer) { index_buffer = buffer; } -void Command::BindVertexBuffer(BufferView vertex_buffer, size_t offset) { - vertex_bindings - .buffers[VertexDescriptor::kReservedVertexBufferIndex - offset] = { - nullptr, vertex_buffer}; -} - bool Command::BindResource(ShaderStage stage, const ShaderUniformSlot& slot, const ShaderMetadata& metadata, diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index dc2500b56a005..081fbe0b05fb2 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. /// @@ -165,7 +167,16 @@ struct Command : public ResourceBinder { void BindIndexBuffer(IndexType index_type, BufferView index_buffer); - void BindVertexBuffer(BufferView vertex_buffer, size_t offset); + 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, From d3c408c640371f5ec251914c22f404366a4b9962 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 31 May 2023 17:41:03 -0700 Subject: [PATCH 04/14] ++ --- impeller/renderer/command.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index 081fbe0b05fb2..2ddef8371017a 100644 --- a/impeller/renderer/command.h +++ b/impeller/renderer/command.h @@ -168,8 +168,7 @@ struct Command : public ResourceBinder { void BindIndexBuffer(IndexType index_type, BufferView index_buffer); template - void BindVertexBuffers( - std::array vertex_buffers) { + void BindVertexBuffers(std::array vertex_buffers) { for (auto i = 0u; i < N; i++) { vertex_bindings .buffers[VertexDescriptor::kReservedVertexBufferIndex - i] = { From 26fb36596da49e59e711eeec0f52c993ec568132 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 31 May 2023 21:09:02 -0700 Subject: [PATCH 05/14] gles --- .../backend/gles/buffer_bindings_gles.cc | 20 ++++++-- .../backend/gles/buffer_bindings_gles.h | 3 ++ .../renderer/backend/gles/pipeline_gles.cc | 2 + .../renderer/backend/gles/render_pass_gles.cc | 48 +++++++++++-------- .../renderer/backend/vulkan/render_pass_vk.cc | 2 +- impeller/renderer/command.cc | 9 ---- impeller/renderer/command.h | 2 - 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/impeller/renderer/backend/gles/buffer_bindings_gles.cc index a21140c433cc5..4606811b29659 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -47,17 +47,29 @@ bool BufferBindingsGLES::RegisterVertexStageInput( } attrib.type = type.value(); attrib.normalized = GL_FALSE; - attrib.offset = offset; - offset += (input.bit_width * input.vec_size) / 8; + auto width = (input.bit_width * input.vec_size) / 8; + if (interleaved_vertex_data_) { + attrib.offset = offset; + offset += width; + } else { + attrib.offset = 0u; + attrib.stride = width; + } vertex_attrib_arrays.emplace_back(attrib); } - for (auto& array : vertex_attrib_arrays) { - array.stride = offset; + if (interleaved_vertex_data_) { + for (auto& array : vertex_attrib_arrays) { + array.stride = offset; + } } vertex_attrib_arrays_ = std::move(vertex_attrib_arrays); return true; } +void BufferBindingsGLES::SetInterleavedVertexData(bool value) { + interleaved_vertex_data_ = value; +} + static std::string NormalizeUniformKey(const std::string& key) { std::string result; result.reserve(key.length()); diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.h b/impeller/renderer/backend/gles/buffer_bindings_gles.h index 5dc3536f3f685..c299dd2678d64 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.h +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.h @@ -25,6 +25,8 @@ class BufferBindingsGLES { ~BufferBindingsGLES(); + void SetInterleavedVertexData(bool value); + bool RegisterVertexStageInput(const ProcTableGLES& gl, const std::vector& inputs); @@ -54,6 +56,7 @@ class BufferBindingsGLES { }; std::vector vertex_attrib_arrays_; std::map uniform_locations_; + bool interleaved_vertex_data_ = true; bool BindUniformBuffer(const ProcTableGLES& gl, Allocator& transients_allocator, diff --git a/impeller/renderer/backend/gles/pipeline_gles.cc b/impeller/renderer/backend/gles/pipeline_gles.cc index 31063ce43d64f..c74741d750dcd 100644 --- a/impeller/renderer/backend/gles/pipeline_gles.cc +++ b/impeller/renderer/backend/gles/pipeline_gles.cc @@ -45,6 +45,8 @@ bool PipelineGLES::BuildVertexDescriptor(const ProcTableGLES& gl, return false; } auto vtx_desc = std::make_unique(); + vtx_desc->SetInterleavedVertexData( + GetDescriptor().GetVertexDescriptor()->GetInterleavedVertexData()); if (!vtx_desc->RegisterVertexStageInput( gl, GetDescriptor().GetVertexDescriptor()->GetStageInputs())) { return false; diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc index 2d06ad7126c1c..93b74ae051b1d 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, 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/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index e7452b7e385eb..88ce10e64df7b 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -355,7 +355,7 @@ static bool AllocateAndBindDescriptorSets(const ContextVK& context, return false; } - // Reserved index used for per-vertex data. + // Reserved indexes used for per-vertex data. if (buffer_index >= command.last_vertex_index) { continue; } diff --git a/impeller/renderer/command.cc b/impeller/renderer/command.cc index 5625ef29c1e2f..2f0b4036a7816 100644 --- a/impeller/renderer/command.cc +++ b/impeller/renderer/command.cc @@ -26,15 +26,6 @@ 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 = buffer; diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index 2ddef8371017a..64e53b799920d 100644 --- a/impeller/renderer/command.h +++ b/impeller/renderer/command.h @@ -207,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: From 5db851d9207d020a171133b45cff5d2c8804aad4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 5 Jun 2023 11:26:42 -0700 Subject: [PATCH 06/14] lint --- impeller/renderer/command.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/renderer/command.cc b/impeller/renderer/command.cc index 2f0b4036a7816..6d5734601de1e 100644 --- a/impeller/renderer/command.cc +++ b/impeller/renderer/command.cc @@ -28,7 +28,7 @@ bool Command::BindVertices(const VertexBuffer& buffer) { void Command::BindIndexBuffer(IndexType type, BufferView buffer) { index_type = type; - index_buffer = buffer; + index_buffer = std::move(buffer); } bool Command::BindResource(ShaderStage stage, From 92fdf4c227c651a72f3b2e7e754f5e448f879e0d Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 5 Jun 2023 12:05:15 -0700 Subject: [PATCH 07/14] fix gles --- .../backend/gles/buffer_bindings_gles.cc | 23 +++++++++++++++---- .../backend/gles/buffer_bindings_gles.h | 1 + .../renderer/backend/gles/render_pass_gles.cc | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/impeller/renderer/backend/gles/buffer_bindings_gles.cc index 4606811b29659..13758277aa64d 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -53,7 +53,7 @@ bool BufferBindingsGLES::RegisterVertexStageInput( offset += width; } else { attrib.offset = 0u; - attrib.stride = width; + attrib.stride = 0u; } vertex_attrib_arrays.emplace_back(attrib); } @@ -143,16 +143,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 (interleaved_vertex_data_) { + 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 c299dd2678d64..1b677268f1ad5 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 1e5c62558a20f..adbb74329a5fd 100644 --- a/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/impeller/renderer/backend/gles/render_pass_gles.cc @@ -383,7 +383,7 @@ struct RenderPassData { /// Bind vertex attribs. /// if (!vertex_desc_gles->BindVertexAttributes( - gl, vertex_buffer_view.range.offset)) { + gl, i, vertex_buffer_view.range.offset)) { return false; } } From 37c6e69582c881f20d0b331be49c8019217418d9 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 5 Jun 2023 16:47:58 -0700 Subject: [PATCH 08/14] fix defaults --- impeller/entity/contents/content_context.h | 3 +-- impeller/renderer/backend/metal/vertex_descriptor_mtl.h | 2 +- impeller/renderer/pipeline_builder.h | 2 -- impeller/renderer/pipeline_descriptor.cc | 1 + impeller/renderer/pipeline_descriptor.h | 4 ++-- impeller/renderer/vertex_descriptor.h | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 2d45ce5a4ed25..e72749c219810 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -299,7 +299,7 @@ struct ContentContextOptions { std::optional color_attachment_pixel_format; bool has_stencil_attachment = true; bool wireframe = false; - bool interleaved_vertex_data = false; + bool interleaved_vertex_data = true; struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { @@ -817,7 +817,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/renderer/backend/metal/vertex_descriptor_mtl.h b/impeller/renderer/backend/metal/vertex_descriptor_mtl.h index 36631823a0e5c..62a038d02d373 100644 --- a/impeller/renderer/backend/metal/vertex_descriptor_mtl.h +++ b/impeller/renderer/backend/metal/vertex_descriptor_mtl.h @@ -43,7 +43,7 @@ class VertexDescriptorMTL { }; }; std::set stage_inputs_; - bool interleaved_vertex_data_ = false; + bool interleaved_vertex_data_ = true; FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptorMTL); }; diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index bd8d5fa14e2ac..a6f7b80ac7f7d 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -107,8 +107,6 @@ struct PipelineBuilder { << VertexShader::kLabel << "'."; return false; } - vertex_descriptor->SetInterleavedVertexData( - desc.GetInterleavedVertexData()); desc.SetVertexDescriptor(std::move(vertex_descriptor)); } diff --git a/impeller/renderer/pipeline_descriptor.cc b/impeller/renderer/pipeline_descriptor.cc index 51a93ca870691..2ed98736717e8 100644 --- a/impeller/renderer/pipeline_descriptor.cc +++ b/impeller/renderer/pipeline_descriptor.cc @@ -213,6 +213,7 @@ PipelineDescriptor::GetColorAttachmentDescriptors() const { const std::shared_ptr& PipelineDescriptor::GetVertexDescriptor() const { + vertex_descriptor_->SetInterleavedVertexData(interleaved_vertex_data_); return vertex_descriptor_; } diff --git a/impeller/renderer/pipeline_descriptor.h b/impeller/renderer/pipeline_descriptor.h index 7196ffd7a95de..b3b4ef764548e 100644 --- a/impeller/renderer/pipeline_descriptor.h +++ b/impeller/renderer/pipeline_descriptor.h @@ -143,7 +143,7 @@ class PipelineDescriptor final : public Comparable { std::map> entrypoints_; std::map color_attachment_descriptors_; - std::shared_ptr vertex_descriptor_; + mutable std::shared_ptr vertex_descriptor_; PixelFormat depth_pixel_format_ = PixelFormat::kUnknown; PixelFormat stencil_pixel_format_ = PixelFormat::kUnknown; std::optional depth_attachment_descriptor_; @@ -153,7 +153,7 @@ class PipelineDescriptor final : public Comparable { back_stencil_attachment_descriptor_; PrimitiveType primitive_type_ = PrimitiveType::kTriangle; PolygonMode polygon_mode_ = PolygonMode::kFill; - bool interleaved_vertex_data_ = false; + bool interleaved_vertex_data_ = true; }; } // namespace impeller diff --git a/impeller/renderer/vertex_descriptor.h b/impeller/renderer/vertex_descriptor.h index b2a90a0395cd0..f0afcf139ec8b 100644 --- a/impeller/renderer/vertex_descriptor.h +++ b/impeller/renderer/vertex_descriptor.h @@ -65,7 +65,7 @@ class VertexDescriptor final : public Comparable { private: std::vector inputs_; std::vector desc_set_layouts_; - bool interleaved_vertex_data_ = false; + bool interleaved_vertex_data_ = true; FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptor); }; From 4ed004b5dd8638dc516e8204e60331919856aebb Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 5 Jun 2023 20:11:32 -0700 Subject: [PATCH 09/14] ++ --- .../backend/vulkan/pipeline_library_vk.cc | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc index b02101f2cf34a..801e64b8ccd9f 100644 --- a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc @@ -4,7 +4,6 @@ #include "impeller/renderer/backend/vulkan/pipeline_library_vk.h" -#include #include #include "flutter/fml/container.h" @@ -248,14 +247,9 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( const auto& stage_inputs = desc.GetVertexDescriptor()->GetStageInputs(); std::vector attr_descs; std::vector binding_descs; + vk::PipelineVertexInputStateCreateInfo vertex_input_state; if (interleaved) { - vk::VertexInputBindingDescription binding_description; - // Only 1 stream of data is supported for now. - binding_description.setBinding(0); - binding_description.setInputRate(vk::VertexInputRate::eVertex); - - std::vector attr_descs; uint32_t offset = 0; for (const ShaderStageIOSlot& stage_in : stage_inputs) { @@ -269,14 +263,16 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( offset += len; } + vk::VertexInputBindingDescription binding_description; + + binding_description.setBinding(0); + binding_description.setInputRate(vk::VertexInputRate::eVertex); binding_description.setStride(offset); + binding_descs.push_back(binding_description); - vk::PipelineVertexInputStateCreateInfo vertex_input_state; vertex_input_state.setVertexAttributeDescriptions(attr_descs); - vertex_input_state.setVertexBindingDescriptionCount(1); - vertex_input_state.setPVertexBindingDescriptions(&binding_description); + vertex_input_state.setVertexBindingDescriptions(binding_descs); - pipeline_info.setPVertexInputState(&vertex_input_state); } else { size_t offset = 0u; for (const ShaderStageIOSlot& stage_in : stage_inputs) { @@ -297,12 +293,10 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( offset++; } - vk::PipelineVertexInputStateCreateInfo vertex_input_state; vertex_input_state.setVertexAttributeDescriptions(attr_descs); vertex_input_state.setVertexBindingDescriptions(binding_descs); - - pipeline_info.setPVertexInputState(&vertex_input_state); } + pipeline_info.setPVertexInputState(&vertex_input_state); //---------------------------------------------------------------------------- /// Pipeline Layout a.k.a the descriptor sets and uniforms. From 21fb24d1867a4e774d2a55ac6c816d1d9e20155c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 6 Jun 2023 10:59:48 -0700 Subject: [PATCH 10/14] add vertex layout test --- impeller/entity/entity_unittests.cc | 76 +++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 6d92c3edcaffe..efb4e67168e28 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" @@ -2638,6 +2639,81 @@ TEST_P(EntityTest, PointFieldGeometryDivisions) { ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u); } +TEST_P(EntityTest, CanCustomizeVertexLayout) { + auto callback = [&](ContentContext& context, RenderPass& pass) { + using VS = GeometryColorPipeline::VertexShader; + using FS = GeometryColorPipeline::FragmentShader; + + auto contents = AnonymousContents::Make( + [](const ContentContext& renderer, const Entity& entity, + RenderPass& pass) { + auto r = Rect::MakeLTRB(0, 0, 400, 400).GetLTRB(); + + std::vector position_data = { + {Point(r[0], r[1])}, // + {Point(r[2], r[1])}, // + {Point(r[2], r[3])}, // + {Point(r[0], r[1])}, // + {Point(r[2], r[3])}, // + {Point(r[0], r[3])} // + }; + std::vector color_data = { + Color::Red(), // + Color::Green(), // + Color::Red(), // + Color::Green(), // + Color::Red(), // + Color::Green() // + }; + + auto& host_buffer = pass.GetTransientsBuffer(); + auto position_view = host_buffer.Emplace( + reinterpret_cast(position_data.data()), + position_data.size() * sizeof(Point), alignof(Point)); + + auto color_view = host_buffer.Emplace( + reinterpret_cast(color_data.data()), + color_data.size() * sizeof(Color), alignof(Color)); + + Command cmd; + cmd.label = "Per Vertex Colors"; + auto options = OptionsFromPass(pass); + options.primitive_type = PrimitiveType::kTriangle; + options.interleaved_vertex_data = false; + + cmd.pipeline = renderer.GetGeometryColorPipeline(options); + cmd.BindVertexBuffers<2>({ + position_view, + color_view, + }); + cmd.BindIndexBuffer(IndexType::kNone, {}); + cmd.vertex_count = 6; + + VS::FrameInfo frame_info; + frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()); + VS::BindFrameInfo( + cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + + FS::FragInfo frag_info; + frag_info.alpha = 1.0; + FS::BindFragInfo( + cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + + return pass.AddCommand(std::move(cmd)); + }, + [](const Entity& entity) { + return Rect::MakeLTRB(0, 0, 400, 400) + .TransformBounds(entity.GetTransformation()); + }); + + Entity entity; + entity.SetContents(contents); + return entity.Render(context, pass); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + } // namespace testing } // namespace impeller From 2ac557f1a4bf44eea4ec7c736252675455531853 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Jun 2023 13:32:16 -0700 Subject: [PATCH 11/14] remove interleaved flag --- impeller/entity/contents/content_context.cc | 1 - impeller/entity/contents/content_context.h | 6 ++---- impeller/entity/contents/vertices_contents.cc | 1 - impeller/entity/entity_unittests.cc | 1 - .../renderer/backend/gles/buffer_bindings_gles.cc | 6 +----- .../renderer/backend/gles/buffer_bindings_gles.h | 1 - impeller/renderer/backend/gles/pipeline_gles.cc | 2 -- .../renderer/backend/metal/vertex_descriptor_mtl.h | 2 -- .../renderer/backend/metal/vertex_descriptor_mtl.mm | 4 ---- impeller/renderer/pipeline_descriptor.cc | 13 +------------ impeller/renderer/pipeline_descriptor.h | 7 +------ impeller/renderer/vertex_descriptor.h | 1 - 12 files changed, 5 insertions(+), 40 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 6db4298da6667..d9c3a13354b5f 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -137,7 +137,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor( } desc.SetPrimitiveType(primitive_type); - desc.SetInterleavedVertexData(interleaved_vertex_data); desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill); } diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index e72749c219810..1d04977417fe1 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -299,14 +299,13 @@ struct ContentContextOptions { std::optional color_attachment_pixel_format; bool has_stencil_attachment = true; bool wireframe = false; - bool interleaved_vertex_data = true; struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { return fml::HashCombine( o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation, o.primitive_type, o.color_attachment_pixel_format, - o.has_stencil_attachment, o.wireframe, o.interleaved_vertex_data); + o.has_stencil_attachment, o.wireframe); } }; @@ -321,8 +320,7 @@ struct ContentContextOptions { lhs.color_attachment_pixel_format == rhs.color_attachment_pixel_format && lhs.has_stencil_attachment == rhs.has_stencil_attachment && - lhs.wireframe == rhs.wireframe && - lhs.interleaved_vertex_data == rhs.interleaved_vertex_data; + lhs.wireframe == rhs.wireframe; } }; diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 41501e164b361..712b46b2d6f52 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -183,7 +183,6 @@ bool VerticesColorContents::Render(const ContentContext& renderer, auto geometry_result = geometry->GetPositionColorBuffer(renderer, entity, pass); auto opts = OptionsFromPassAndEntity(pass, entity); - opts.interleaved_vertex_data = false; opts.primitive_type = geometry_result.type; cmd.pipeline = renderer.GetGeometryColorPipeline(opts); cmd.stencil_reference = entity.GetStencilDepth(); diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index c61c6d9dac960..2be33dd59beee 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2456,7 +2456,6 @@ TEST_P(EntityTest, CanCustomizeVertexLayout) { cmd.label = "Per Vertex Colors"; auto options = OptionsFromPass(pass); options.primitive_type = PrimitiveType::kTriangle; - options.interleaved_vertex_data = false; cmd.pipeline = renderer.GetGeometryColorPipeline(options); cmd.BindVertexBuffers<2>({ diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/impeller/renderer/backend/gles/buffer_bindings_gles.cc index 1fdef20d7af2e..a902d7a7f5f9b 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -50,10 +50,6 @@ bool BufferBindingsGLES::RegisterVertexStageInput( return true; } -void BufferBindingsGLES::SetInterleavedVertexData(bool value) { - interleaved_vertex_data_ = value; -} - static std::string NormalizeUniformKey(const std::string& key) { std::string result; result.reserve(key.length()); @@ -129,7 +125,7 @@ bool BufferBindingsGLES::ReadUniformsBindings(const ProcTableGLES& gl, bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl, size_t vertex_index, size_t vertex_offset) const { - if (interleaved_vertex_data_) { + if (true) { for (const auto& array : vertex_attrib_arrays_) { gl.EnableVertexAttribArray(array.index); gl.VertexAttribPointer( diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.h b/impeller/renderer/backend/gles/buffer_bindings_gles.h index e4d2f44f04987..bb6686202e2f9 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.h +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.h @@ -57,7 +57,6 @@ class BufferBindingsGLES { }; std::vector vertex_attrib_arrays_; std::map uniform_locations_; - bool interleaved_vertex_data_ = true; bool BindUniformBuffer(const ProcTableGLES& gl, Allocator& transients_allocator, diff --git a/impeller/renderer/backend/gles/pipeline_gles.cc b/impeller/renderer/backend/gles/pipeline_gles.cc index 294a64ade194d..79efe7454d5ae 100644 --- a/impeller/renderer/backend/gles/pipeline_gles.cc +++ b/impeller/renderer/backend/gles/pipeline_gles.cc @@ -45,8 +45,6 @@ bool PipelineGLES::BuildVertexDescriptor(const ProcTableGLES& gl, return false; } auto vtx_desc = std::make_unique(); - vtx_desc->SetInterleavedVertexData( - GetDescriptor().GetVertexDescriptor()->GetInterleavedVertexData()); if (!vtx_desc->RegisterVertexStageInput( gl, GetDescriptor().GetVertexDescriptor()->GetStageInputs(), GetDescriptor().GetVertexDescriptor()->GetStageLayouts())) { diff --git a/impeller/renderer/backend/metal/vertex_descriptor_mtl.h b/impeller/renderer/backend/metal/vertex_descriptor_mtl.h index a2f709589cdf1..22c4f71542c1c 100644 --- a/impeller/renderer/backend/metal/vertex_descriptor_mtl.h +++ b/impeller/renderer/backend/metal/vertex_descriptor_mtl.h @@ -24,8 +24,6 @@ class VertexDescriptorMTL { const std::vector& inputs, const std::vector& layouts); - void SetInterleavedVertexData(bool value); - MTLVertexDescriptor* GetMTLVertexDescriptor() const; private: diff --git a/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm b/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm index 780f8d33e024b..b5948830f9abf 100644 --- a/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm +++ b/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm @@ -203,10 +203,6 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { return true; } -void VertexDescriptorMTL::SetInterleavedVertexData(bool value) { - interleaved_vertex_data_ = value; -} - MTLVertexDescriptor* VertexDescriptorMTL::GetMTLVertexDescriptor() const { return descriptor_; } diff --git a/impeller/renderer/pipeline_descriptor.cc b/impeller/renderer/pipeline_descriptor.cc index 2ed98736717e8..eef517b30c847 100644 --- a/impeller/renderer/pipeline_descriptor.cc +++ b/impeller/renderer/pipeline_descriptor.cc @@ -42,7 +42,6 @@ std::size_t PipelineDescriptor::GetHash() const { fml::HashCombineSeed(seed, cull_mode_); fml::HashCombineSeed(seed, primitive_type_); fml::HashCombineSeed(seed, polygon_mode_); - fml::HashCombineSeed(seed, interleaved_vertex_data_); return seed; } @@ -62,8 +61,7 @@ bool PipelineDescriptor::IsEqual(const PipelineDescriptor& other) const { winding_order_ == other.winding_order_ && cull_mode_ == other.cull_mode_ && primitive_type_ == other.primitive_type_ && - polygon_mode_ == other.polygon_mode_ && - interleaved_vertex_data_ == other.interleaved_vertex_data_; + polygon_mode_ == other.polygon_mode_; } PipelineDescriptor& PipelineDescriptor::SetLabel(std::string label) { @@ -213,7 +211,6 @@ PipelineDescriptor::GetColorAttachmentDescriptors() const { const std::shared_ptr& PipelineDescriptor::GetVertexDescriptor() const { - vertex_descriptor_->SetInterleavedVertexData(interleaved_vertex_data_); return vertex_descriptor_; } @@ -280,12 +277,4 @@ PolygonMode PipelineDescriptor::GetPolygonMode() const { return polygon_mode_; } -void PipelineDescriptor::SetInterleavedVertexData(bool value) { - interleaved_vertex_data_ = value; -} - -bool PipelineDescriptor::GetInterleavedVertexData() const { - return interleaved_vertex_data_; -} - } // namespace impeller diff --git a/impeller/renderer/pipeline_descriptor.h b/impeller/renderer/pipeline_descriptor.h index b3b4ef764548e..3d0eddf880e28 100644 --- a/impeller/renderer/pipeline_descriptor.h +++ b/impeller/renderer/pipeline_descriptor.h @@ -131,10 +131,6 @@ class PipelineDescriptor final : public Comparable { PolygonMode GetPolygonMode() const; - void SetInterleavedVertexData(bool value); - - bool GetInterleavedVertexData() const; - private: std::string label_; SampleCount sample_count_ = SampleCount::kCount1; @@ -143,7 +139,7 @@ class PipelineDescriptor final : public Comparable { std::map> entrypoints_; std::map color_attachment_descriptors_; - mutable std::shared_ptr vertex_descriptor_; + std::shared_ptr vertex_descriptor_; PixelFormat depth_pixel_format_ = PixelFormat::kUnknown; PixelFormat stencil_pixel_format_ = PixelFormat::kUnknown; std::optional depth_attachment_descriptor_; @@ -153,7 +149,6 @@ class PipelineDescriptor final : public Comparable { back_stencil_attachment_descriptor_; PrimitiveType primitive_type_ = PrimitiveType::kTriangle; PolygonMode polygon_mode_ = PolygonMode::kFill; - bool interleaved_vertex_data_ = true; }; } // namespace impeller diff --git a/impeller/renderer/vertex_descriptor.h b/impeller/renderer/vertex_descriptor.h index 3856b18836581..43e2f00d193e3 100644 --- a/impeller/renderer/vertex_descriptor.h +++ b/impeller/renderer/vertex_descriptor.h @@ -68,7 +68,6 @@ class VertexDescriptor final : public Comparable { std::vector inputs_; std::vector layouts_; std::vector desc_set_layouts_; - bool interleaved_vertex_data_ = true; FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptor); }; From 778c604fcdb544757685af0c5112940ab7c90bd8 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Jun 2023 13:32:47 -0700 Subject: [PATCH 12/14] ++ --- impeller/entity/contents/content_context.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 1d04977417fe1..eb2157dd3cd2b 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -302,10 +302,10 @@ struct ContentContextOptions { struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { - return fml::HashCombine( - o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation, - o.primitive_type, o.color_attachment_pixel_format, - o.has_stencil_attachment, o.wireframe); + return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare, + o.stencil_operation, o.primitive_type, + o.color_attachment_pixel_format, + o.has_stencil_attachment, o.wireframe); } }; From 8ba85dd79d00bd8f0a1f8edb3c3fdf2041b07c93 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Jun 2023 17:48:34 -0700 Subject: [PATCH 13/14] ++ --- impeller/entity/contents/content_context.cc | 23 +++++++++ impeller/entity/contents/content_context.h | 7 +++ impeller/entity/contents/vertices_contents.cc | 2 +- impeller/entity/contents/vertices_contents.h | 47 +++++++++++++++++++ impeller/renderer/pipeline_builder.h | 27 ++++++++++- 5 files changed, 103 insertions(+), 3 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index d9c3a13354b5f..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" @@ -155,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()), @@ -285,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 eb2157dd3cd2b..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. diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 712b46b2d6f52..c87b225cfdd3b 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -184,7 +184,7 @@ 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.BindVertexBuffers<2>( 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/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( From 4664eead3c0891b9f5644abbef0aee5182ec41f7 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Jun 2023 17:53:19 -0700 Subject: [PATCH 14/14] ++ --- impeller/entity/entity_unittests.cc | 74 ----------------------------- 1 file changed, 74 deletions(-) diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 2be33dd59beee..05cac84896f55 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2416,80 +2416,6 @@ TEST_P(EntityTest, PointFieldGeometryDivisions) { ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u); } -TEST_P(EntityTest, CanCustomizeVertexLayout) { - auto callback = [&](ContentContext& context, RenderPass& pass) { - using VS = GeometryColorPipeline::VertexShader; - using FS = GeometryColorPipeline::FragmentShader; - - auto contents = AnonymousContents::Make( - [](const ContentContext& renderer, const Entity& entity, - RenderPass& pass) { - auto r = Rect::MakeLTRB(0, 0, 400, 400).GetLTRB(); - - std::vector position_data = { - {Point(r[0], r[1])}, // - {Point(r[2], r[1])}, // - {Point(r[2], r[3])}, // - {Point(r[0], r[1])}, // - {Point(r[2], r[3])}, // - {Point(r[0], r[3])} // - }; - std::vector color_data = { - Color::Red(), // - Color::Green(), // - Color::Red(), // - Color::Green(), // - Color::Red(), // - Color::Green() // - }; - - auto& host_buffer = pass.GetTransientsBuffer(); - auto position_view = host_buffer.Emplace( - reinterpret_cast(position_data.data()), - position_data.size() * sizeof(Point), alignof(Point)); - - auto color_view = host_buffer.Emplace( - reinterpret_cast(color_data.data()), - color_data.size() * sizeof(Color), alignof(Color)); - - Command cmd; - cmd.label = "Per Vertex Colors"; - auto options = OptionsFromPass(pass); - options.primitive_type = PrimitiveType::kTriangle; - - cmd.pipeline = renderer.GetGeometryColorPipeline(options); - cmd.BindVertexBuffers<2>({ - position_view, - color_view, - }); - cmd.BindIndexBuffer(IndexType::kNone, {}); - cmd.vertex_count = 6; - - VS::FrameInfo frame_info; - frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()); - VS::BindFrameInfo( - cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); - - FS::FragInfo frag_info; - frag_info.alpha = 1.0; - FS::BindFragInfo( - cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); - - return pass.AddCommand(std::move(cmd)); - }, - [](const Entity& entity) { - return Rect::MakeLTRB(0, 0, 400, 400) - .TransformBounds(entity.GetTransformation()); - }); - - Entity entity; - entity.SetContents(contents); - return entity.Render(context, pass); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - } // namespace testing } // namespace impeller