Skip to content

Commit 2ac9c73

Browse files
authored
Move primitive type to pipeline descriptor (flutter#37315)
This is the correct abstraction for Vulkan as we need this during primitive assembly. We also know this ahead of time so its useful to just wire it in. Fixes flutter/flutter#106379
1 parent 9584880 commit 2ac9c73

23 files changed

+68
-52
lines changed

impeller/entity/contents/clip_contents.cc

+3-4
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ bool ClipContents::Render(const ContentContext& renderer,
8686
{
8787
cmd.label = "Difference Clip (Increment)";
8888

89-
cmd.primitive_type = PrimitiveType::kTriangleStrip;
9089
auto points = Rect(Size(pass.GetRenderTargetSize())).GetPoints();
9190
auto vertices =
9291
VertexBufferBuilder<VS::PerVertexData>{}
@@ -104,7 +103,6 @@ bool ClipContents::Render(const ContentContext& renderer,
104103
{
105104
cmd.label = "Difference Clip (Punch)";
106105

107-
cmd.primitive_type = PrimitiveType::kTriangle;
108106
cmd.stencil_reference = entity.GetStencilDepth() + 1;
109107
options.stencil_compare = CompareFunction::kEqual;
110108
options.stencil_operation = StencilOperation::kDecrementClamp;
@@ -115,12 +113,13 @@ bool ClipContents::Render(const ContentContext& renderer,
115113
options.stencil_operation = StencilOperation::kIncrementClamp;
116114
}
117115

116+
auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass);
117+
options.primitive_type = geometry_result.type;
118118
cmd.pipeline = renderer.GetClipPipeline(options);
119119

120120
auto allocator = renderer.GetContext()->GetResourceAllocator();
121-
auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass);
122121
cmd.BindVertices(geometry_result.vertex_buffer);
123-
cmd.primitive_type = geometry_result.type;
122+
124123
info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
125124
entity.GetTransformation();
126125
VS::BindVertInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info));

impeller/entity/contents/content_context.cc

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
127127
stencil.depth_stencil_pass = stencil_operation;
128128
desc.SetStencilAttachmentDescriptors(stencil);
129129
}
130+
131+
desc.SetPrimitiveType(primitive_type);
130132
}
131133

132134
template <typename PipelineT>

impeller/entity/contents/content_context.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,12 @@ struct ContentContextOptions {
170170
BlendMode blend_mode = BlendMode::kSourceOver;
171171
CompareFunction stencil_compare = CompareFunction::kEqual;
172172
StencilOperation stencil_operation = StencilOperation::kKeep;
173+
PrimitiveType primitive_type = PrimitiveType::kTriangle;
173174

174175
struct Hash {
175176
constexpr std::size_t operator()(const ContentContextOptions& o) const {
176177
return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare,
177-
o.stencil_operation);
178+
o.stencil_operation, o.primitive_type);
178179
}
179180
};
180181

@@ -184,7 +185,8 @@ struct ContentContextOptions {
184185
return lhs.sample_count == rhs.sample_count &&
185186
lhs.blend_mode == rhs.blend_mode &&
186187
lhs.stencil_compare == rhs.stencil_compare &&
187-
lhs.stencil_operation == rhs.stencil_operation;
188+
lhs.stencil_operation == rhs.stencil_operation &&
189+
lhs.primitive_type == rhs.primitive_type;
188190
}
189191
};
190192

impeller/entity/contents/contents.cc

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "fml/logging.h"
99
#include "impeller/entity/contents/content_context.h"
1010
#include "impeller/renderer/command_buffer.h"
11+
#include "impeller/renderer/formats.h"
1112
#include "impeller/renderer/render_pass.h"
1213

1314
namespace impeller {

impeller/entity/contents/linear_gradient_contents.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ bool LinearGradientContents::Render(const ContentContext& renderer,
8282
options.stencil_compare = CompareFunction::kEqual;
8383
options.stencil_operation = StencilOperation::kIncrementClamp;
8484
}
85+
options.primitive_type = geometry_result.type;
8586
cmd.pipeline = renderer.GetLinearGradientFillPipeline(options);
8687

8788
cmd.BindVertices(geometry_result.vertex_buffer);
88-
cmd.primitive_type = geometry_result.type;
8989
FS::BindGradientInfo(
9090
cmd, pass.GetTransientsBuffer().EmplaceUniform(gradient_info));
9191
SamplerDescriptor sampler_desc;

impeller/entity/contents/radial_gradient_contents.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ bool RadialGradientContents::Render(const ContentContext& renderer,
8282
options.stencil_compare = CompareFunction::kEqual;
8383
options.stencil_operation = StencilOperation::kIncrementClamp;
8484
}
85+
options.primitive_type = geometry_result.type;
8586
cmd.pipeline = renderer.GetRadialGradientFillPipeline(options);
8687

8788
cmd.BindVertices(geometry_result.vertex_buffer);
88-
cmd.primitive_type = geometry_result.type;
8989
FS::BindGradientInfo(
9090
cmd, pass.GetTransientsBuffer().EmplaceUniform(gradient_info));
9191
SamplerDescriptor sampler_desc;

impeller/entity/contents/rrect_shadow_contents.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ bool RRectShadowContents::Render(const ContentContext& renderer,
7979

8080
Command cmd;
8181
cmd.label = "RRect Shadow";
82-
cmd.pipeline =
83-
renderer.GetRRectBlurPipeline(OptionsFromPassAndEntity(pass, entity));
82+
auto opts = OptionsFromPassAndEntity(pass, entity);
83+
opts.primitive_type = PrimitiveType::kTriangle;
84+
cmd.pipeline = renderer.GetRRectBlurPipeline(opts);
8485
cmd.stencil_reference = entity.GetStencilDepth();
8586

86-
cmd.primitive_type = PrimitiveType::kTriangle;
8787
cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
8888

8989
VS::VertInfo vert_info;

impeller/entity/contents/runtime_effect_contents.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
122122
options.stencil_compare = CompareFunction::kEqual;
123123
options.stencil_operation = StencilOperation::kIncrementClamp;
124124
}
125+
options.primitive_type = geometry_result.type;
125126
options.ApplyToPipelineDescriptor(desc);
126127

127128
auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).get();
@@ -135,7 +136,6 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
135136
cmd.pipeline = pipeline;
136137
cmd.stencil_reference = entity.GetStencilDepth();
137138
cmd.BindVertices(geometry_result.vertex_buffer);
138-
cmd.primitive_type = geometry_result.type;
139139

140140
//--------------------------------------------------------------------------
141141
/// Vertex stage uniforms.

impeller/entity/contents/solid_color_contents.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ bool SolidColorContents::Render(const ContentContext& renderer,
6666
options.stencil_operation = StencilOperation::kIncrementClamp;
6767
}
6868

69+
options.primitive_type = geometry_result.type;
6970
cmd.pipeline = renderer.GetSolidFillPipeline(options);
7071
cmd.BindVertices(geometry_result.vertex_buffer);
71-
cmd.primitive_type = geometry_result.type;
7272

7373
VS::VertInfo vert_info;
7474
vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *

impeller/entity/contents/sweep_gradient_contents.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ bool SweepGradientContents::Render(const ContentContext& renderer,
8888
options.stencil_compare = CompareFunction::kEqual;
8989
options.stencil_operation = StencilOperation::kIncrementClamp;
9090
}
91+
options.primitive_type = geometry_result.type;
9192
cmd.pipeline = renderer.GetSweepGradientFillPipeline(options);
9293

9394
cmd.BindVertices(geometry_result.vertex_buffer);
94-
cmd.primitive_type = geometry_result.type;
9595
FS::BindGradientInfo(
9696
cmd, pass.GetTransientsBuffer().EmplaceUniform(gradient_info));
9797
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));

impeller/entity/contents/text_contents.cc

+6-6
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ bool TextContents::RenderSdf(const ContentContext& renderer,
189189
// Information shared by all glyph draw calls.
190190
Command cmd;
191191
cmd.label = "TextFrameSDF";
192-
cmd.primitive_type = PrimitiveType::kTriangle;
193-
cmd.pipeline =
194-
renderer.GetGlyphAtlasSdfPipeline(OptionsFromPassAndEntity(pass, entity));
192+
auto opts = OptionsFromPassAndEntity(pass, entity);
193+
opts.primitive_type = PrimitiveType::kTriangle;
194+
cmd.pipeline = renderer.GetGlyphAtlasSdfPipeline(opts);
195195
cmd.stencil_reference = entity.GetStencilDepth();
196196

197197
return CommonRender<GlyphAtlasSdfPipeline>(renderer, entity, pass, color_,
@@ -224,9 +224,9 @@ bool TextContents::Render(const ContentContext& renderer,
224224
// Information shared by all glyph draw calls.
225225
Command cmd;
226226
cmd.label = "TextFrame";
227-
cmd.primitive_type = PrimitiveType::kTriangle;
228-
cmd.pipeline =
229-
renderer.GetGlyphAtlasPipeline(OptionsFromPassAndEntity(pass, entity));
227+
auto opts = OptionsFromPassAndEntity(pass, entity);
228+
opts.primitive_type = PrimitiveType::kTriangle;
229+
cmd.pipeline = renderer.GetGlyphAtlasPipeline(opts);
230230
cmd.stencil_reference = entity.GetStencilDepth();
231231

232232
return CommonRender<GlyphAtlasPipeline>(renderer, entity, pass, color_,

impeller/entity/contents/tiled_texture_contents.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
7777
options.stencil_compare = CompareFunction::kEqual;
7878
options.stencil_operation = StencilOperation::kIncrementClamp;
7979
}
80+
options.primitive_type = geometry_result.type;
8081
cmd.pipeline = renderer.GetTiledTexturePipeline(options);
8182

8283
cmd.BindVertices(geometry_result.vertex_buffer);
83-
cmd.primitive_type = geometry_result.type;
8484
VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info));
8585
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
8686
FS::BindTextureSampler(cmd, texture_,

impeller/entity/contents/vertices_contents.cc

+6-6
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,16 @@ bool VerticesContents::Render(const ContentContext& renderer,
4747
cmd.label = "Vertices";
4848
cmd.stencil_reference = entity.GetStencilDepth();
4949

50+
auto opts = OptionsFromPassAndEntity(pass, entity);
51+
5052
switch (vertex_type) {
5153
case GeometryVertexType::kColor: {
5254
using VS = GeometryColorPipeline::VertexShader;
5355

5456
auto geometry_result = geometry_->GetPositionColorBuffer(
5557
renderer, entity, pass, color_, blend_mode_);
56-
cmd.pipeline = renderer.GetGeometryColorPipeline(
57-
OptionsFromPassAndEntity(pass, entity));
58-
cmd.primitive_type = geometry_result.type;
58+
opts.primitive_type = geometry_result.type;
59+
cmd.pipeline = renderer.GetGeometryColorPipeline(opts);
5960
cmd.BindVertices(geometry_result.vertex_buffer);
6061

6162
VS::VertInfo vert_info;
@@ -70,9 +71,8 @@ bool VerticesContents::Render(const ContentContext& renderer,
7071

7172
auto geometry_result =
7273
geometry_->GetPositionBuffer(renderer, entity, pass);
73-
cmd.pipeline = renderer.GetGeometryPositionPipeline(
74-
OptionsFromPassAndEntity(pass, entity));
75-
cmd.primitive_type = geometry_result.type;
74+
opts.primitive_type = geometry_result.type;
75+
cmd.pipeline = renderer.GetGeometryPositionPipeline(opts);
7676
cmd.BindVertices(geometry_result.vertex_buffer);
7777

7878
VS::VertInfo vert_info;

impeller/entity/entity_unittests.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ TEST_P(EntityTest, BlendingModeOptions) {
757757
cmd.label = "Blended Rectangle";
758758
auto options = OptionsFromPass(pass);
759759
options.blend_mode = blend_mode;
760+
options.primitive_type = PrimitiveType::kTriangle;
760761
cmd.pipeline = context.GetSolidFillPipeline(options);
761762
cmd.BindVertices(
762763
vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
@@ -772,8 +773,6 @@ TEST_P(EntityTest, BlendingModeOptions) {
772773
FS::BindFragInfo(cmd,
773774
pass.GetTransientsBuffer().EmplaceUniform(frag_info));
774775

775-
cmd.primitive_type = PrimitiveType::kTriangle;
776-
777776
return pass.AddCommand(std::move(cmd));
778777
};
779778

impeller/playground/imgui/imgui_impl_impeller.cc

-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data,
264264
vertex_buffer.index_type = impeller::IndexType::k16bit;
265265
cmd.BindVertices(vertex_buffer);
266266
cmd.base_vertex = pcmd->VtxOffset;
267-
cmd.primitive_type = impeller::PrimitiveType::kTriangle;
268267

269268
render_pass.AddCommand(std::move(cmd));
270269
}

impeller/renderer/backend/gles/render_pass_gles.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ struct RenderPassData {
411411
//--------------------------------------------------------------------------
412412
/// Finally! Invoke the draw call.
413413
///
414-
gl.DrawElements(ToMode(command.primitive_type), // mode
414+
PrimitiveType primitive_type = pipeline.GetDescriptor().GetPrimitiveType();
415+
gl.DrawElements(ToMode(primitive_type), // mode
415416
command.index_count, // count
416417
ToIndexType(command.index_type), // type
417418
reinterpret_cast<const GLvoid*>(static_cast<GLsizei>(

impeller/renderer/backend/metal/render_pass_mtl.mm

+4-2
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ static bool Bind(PassBindingsCache& pass,
494494
return false;
495495
}
496496

497+
const PrimitiveType primitive_type = pipeline_desc.GetPrimitiveType();
498+
497499
FML_DCHECK(command.index_count *
498500
(command.index_type == IndexType::k16bit ? 2 : 4) ==
499501
command.index_buffer.range.length);
@@ -503,7 +505,7 @@ static bool Bind(PassBindingsCache& pass,
503505
VALIDATION_LOG << "iOS Simulator does not support instanced rendering.";
504506
return false;
505507
#endif
506-
[encoder drawIndexedPrimitives:ToMTLPrimitiveType(command.primitive_type)
508+
[encoder drawIndexedPrimitives:ToMTLPrimitiveType(primitive_type)
507509
indexCount:command.index_count
508510
indexType:ToMTLIndexType(command.index_type)
509511
indexBuffer:mtl_index_buffer
@@ -512,7 +514,7 @@ static bool Bind(PassBindingsCache& pass,
512514
baseVertex:command.base_vertex
513515
baseInstance:0u];
514516
} else {
515-
[encoder drawIndexedPrimitives:ToMTLPrimitiveType(command.primitive_type)
517+
[encoder drawIndexedPrimitives:ToMTLPrimitiveType(primitive_type)
516518
indexCount:command.index_count
517519
indexType:ToMTLIndexType(command.index_type)
518520
indexBuffer:mtl_index_buffer

impeller/renderer/backend/vulkan/formats_vk.h

+15
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,19 @@ constexpr vk::IndexType ToVKIndexType(IndexType index_type) {
311311
}
312312
}
313313

314+
constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive) {
315+
switch (primitive) {
316+
case PrimitiveType::kTriangle:
317+
return vk::PrimitiveTopology::eTriangleList;
318+
case PrimitiveType::kTriangleStrip:
319+
return vk::PrimitiveTopology::eTriangleStrip;
320+
case PrimitiveType::kLine:
321+
return vk::PrimitiveTopology::eLineList;
322+
case PrimitiveType::kLineStrip:
323+
return vk::PrimitiveTopology::eLineStrip;
324+
case PrimitiveType::kPoint:
325+
return vk::PrimitiveTopology::ePointList;
326+
}
327+
}
328+
314329
} // namespace impeller

impeller/renderer/backend/vulkan/pipeline_library_vk.cc

+2-4
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,9 @@ std::unique_ptr<PipelineCreateInfoVK> PipelineLibraryVK::CreatePipeline(
281281

282282
//----------------------------------------------------------------------------
283283
/// Primitive Input Assembly State
284-
/// TODO(106379): Move primitive topology to the the pipeline instead of it
285-
/// being on the draw call. This is hard-coded right now.
286-
///
287284
vk::PipelineInputAssemblyStateCreateInfo input_assembly;
288-
input_assembly.setTopology(vk::PrimitiveTopology::eTriangleList);
285+
const auto topology = ToVKPrimitiveTopology(desc.GetPrimitiveType());
286+
input_assembly.setTopology(topology);
289287
pipeline_info.setPInputAssemblyState(&input_assembly);
290288

291289
//----------------------------------------------------------------------------

impeller/renderer/command.h

-7
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,6 @@ struct Command {
103103
///
104104
std::string label;
105105
//----------------------------------------------------------------------------
106-
/// The type of primitives in the vertex buffer. Set the vertex and index
107-
/// buffers using a call to `BindVertices`.
108-
///
109-
/// @see `BindVertices`
110-
///
111-
PrimitiveType primitive_type = PrimitiveType::kTriangle;
112-
//----------------------------------------------------------------------------
113106
/// The reference value to use in stenciling operations. Stencil configuration
114107
/// is part of pipeline setup and can be read from the pipelines descriptor.
115108
///

impeller/renderer/pipeline_descriptor.cc

+8
Original file line numberDiff line numberDiff line change
@@ -229,4 +229,12 @@ WindingOrder PipelineDescriptor::GetWindingOrder() const {
229229
return winding_order_;
230230
}
231231

232+
void PipelineDescriptor::SetPrimitiveType(PrimitiveType type) {
233+
primitive_type_ = type;
234+
}
235+
236+
PrimitiveType PipelineDescriptor::GetPrimitiveType() const {
237+
return primitive_type_;
238+
}
239+
232240
} // namespace impeller

impeller/renderer/pipeline_descriptor.h

+5
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ class PipelineDescriptor final : public Comparable<PipelineDescriptor> {
115115

116116
WindingOrder GetWindingOrder() const;
117117

118+
void SetPrimitiveType(PrimitiveType type);
119+
120+
PrimitiveType GetPrimitiveType() const;
121+
118122
private:
119123
std::string label_;
120124
SampleCount sample_count_ = SampleCount::kCount1;
@@ -131,6 +135,7 @@ class PipelineDescriptor final : public Comparable<PipelineDescriptor> {
131135
front_stencil_attachment_descriptor_;
132136
std::optional<StencilAttachmentDescriptor>
133137
back_stencil_attachment_descriptor_;
138+
PrimitiveType primitive_type_ = PrimitiveType::kTriangle;
134139
};
135140

136141
using PipelineMap = std::unordered_map<

impeller/renderer/renderer_unittests.cc

-8
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ TEST_P(RendererTest, CanCreateBoxPrimitive) {
101101
pass.GetTransientsBuffer().EmplaceUniform(frame_info));
102102
FS::BindContents1(cmd, boston, sampler);
103103
FS::BindContents2(cmd, bridge, sampler);
104-
105-
cmd.primitive_type = PrimitiveType::kTriangle;
106104
if (!pass.AddCommand(std::move(cmd))) {
107105
return false;
108106
}
@@ -192,8 +190,6 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) {
192190
Matrix::MakeRotationZ(Radians(euler_angles.z));
193191
VS::BindUniformBuffer(cmd,
194192
pass.GetTransientsBuffer().EmplaceUniform(uniforms));
195-
196-
cmd.primitive_type = PrimitiveType::kTriangle;
197193
if (!pass.AddCommand(std::move(cmd))) {
198194
return false;
199195
}
@@ -254,8 +250,6 @@ TEST_P(RendererTest, CanRenderMultiplePrimitives) {
254250
FS::BindContents1(cmd, boston, sampler);
255251
FS::BindContents2(cmd, bridge, sampler);
256252

257-
cmd.primitive_type = PrimitiveType::kTriangle;
258-
259253
for (size_t i = 0; i < 1; i++) {
260254
for (size_t j = 0; j < 1; j++) {
261255
VS::UniformBuffer uniforms;
@@ -369,8 +363,6 @@ TEST_P(RendererTest, CanRenderToTexture) {
369363
FS::BindContents1(cmd, boston, sampler);
370364
FS::BindContents2(cmd, bridge, sampler);
371365

372-
cmd.primitive_type = PrimitiveType::kTriangle;
373-
374366
VS::UniformBuffer uniforms;
375367
uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
376368
Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});

0 commit comments

Comments
 (0)