Flutter Impeller
render_pass.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <utility>
8 #include "fml/status.h"
11 
12 namespace impeller {
13 
14 RenderPass::RenderPass(std::shared_ptr<const Context> context,
15  const RenderTarget& target)
16  : context_(std::move(context)),
17  sample_count_(target.GetSampleCount()),
18  pixel_format_(target.GetRenderTargetPixelFormat()),
19  has_depth_attachment_(target.GetDepthAttachment().has_value()),
20  has_stencil_attachment_(target.GetStencilAttachment().has_value()),
21  render_target_size_(target.GetRenderTargetSize()),
22  render_target_(target),
23  orthographic_(Matrix::MakeOrthographic(render_target_size_)) {}
24 
26 
28  return sample_count_;
29 }
30 
32  return pixel_format_;
33 }
34 
36  return has_depth_attachment_;
37 }
38 
41 }
42 
44  return render_target_;
45 }
46 
48  return render_target_size_;
49 }
50 
52  return orthographic_;
53 }
54 
55 void RenderPass::SetLabel(std::string_view label) {
56  if (label.empty()) {
57  return;
58  }
59  OnSetLabel(label);
60 }
61 
63  if (!command.IsValid()) {
64  VALIDATION_LOG << "Attempted to add an invalid command to the render pass.";
65  return false;
66  }
67 
68  if (command.element_count == 0u || command.instance_count == 0u) {
69  // Essentially a no-op. Don't record the command but this is not necessary
70  // an error either.
71  return true;
72  }
73 
74  commands_.emplace_back(std::move(command));
75  return true;
76 }
77 
79  return OnEncodeCommands(*context_);
80 }
81 
82 const std::shared_ptr<const Context>& RenderPass::GetContext() const {
83  return context_;
84 }
85 
87  // On debug this makes a difference, but not on release builds.
88  // NOLINTNEXTLINE(performance-move-const-arg)
89  pending_.pipeline = std::move(pipeline);
90 }
91 
93  const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
94  SetPipeline(PipelineRef(pipeline));
95 }
96 
97 void RenderPass::SetCommandLabel(std::string_view label) {
98 #ifdef IMPELLER_DEBUG
99  pending_.label = std::string(label);
100 #endif // IMPELLER_DEBUG
101 }
102 
104  pending_.stencil_reference = value;
105 }
106 
108  pending_.base_vertex = value;
109 }
110 
112  pending_.viewport = viewport;
113 }
114 
116  pending_.scissor = scissor;
117 }
118 
119 void RenderPass::SetElementCount(size_t count) {
120  pending_.element_count = count;
121 }
122 
123 void RenderPass::SetInstanceCount(size_t count) {
124  pending_.instance_count = count;
125 }
126 
128  if (!SetVertexBuffer(&buffer.vertex_buffer, 1u)) {
129  return false;
130  }
131  if (!SetIndexBuffer(buffer.index_buffer, buffer.index_type)) {
132  return false;
133  }
135 
136  return true;
137 }
138 
140  return SetVertexBuffer(&vertex_buffer, 1);
141 }
142 
143 bool RenderPass::SetVertexBuffer(std::vector<BufferView> vertex_buffers) {
144  return SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
145 }
146 
148  size_t vertex_buffer_count) {
149  if (!ValidateVertexBuffers(vertex_buffers, vertex_buffer_count)) {
150  return false;
151  }
152 
153  if (!vertex_buffers_start_.has_value()) {
154  vertex_buffers_start_ = vertex_buffers_.size();
155  }
156 
157  pending_.vertex_buffers.length += vertex_buffer_count;
158  for (size_t i = 0; i < vertex_buffer_count; i++) {
159  vertex_buffers_.push_back(vertex_buffers[i]);
160  }
161  return true;
162 }
163 
164 bool RenderPass::SetIndexBuffer(BufferView index_buffer, IndexType index_type) {
165  if (!ValidateIndexBuffer(index_buffer, index_type)) {
166  return false;
167  }
168 
169  pending_.index_buffer = std::move(index_buffer);
170  pending_.index_type = index_type;
171  return true;
172 }
173 
174 bool RenderPass::ValidateVertexBuffers(const BufferView vertex_buffers[],
175  size_t vertex_buffer_count) {
176  if (vertex_buffer_count > kMaxVertexBuffers) {
177  VALIDATION_LOG << "Attempted to bind " << vertex_buffer_count
178  << " vertex buffers, but the maximum is "
179  << kMaxVertexBuffers << ".";
180  return false;
181  }
182 
183  for (size_t i = 0; i < vertex_buffer_count; i++) {
184  if (!vertex_buffers[i]) {
185  VALIDATION_LOG << "Attempted to bind an invalid vertex buffer.";
186  return false;
187  }
188  }
189 
190  return true;
191 }
192 
194  IndexType index_type) {
195  if (index_type == IndexType::kUnknown) {
196  VALIDATION_LOG << "Cannot bind an index buffer with an unknown index type.";
197  return false;
198  }
199 
200  if (index_type != IndexType::kNone && !index_buffer) {
201  VALIDATION_LOG << "Attempted to bind an invalid index buffer.";
202  return false;
203  }
204 
205  return true;
206 }
207 
208 fml::Status RenderPass::Draw() {
209  pending_.bound_buffers.offset = bound_buffers_start_.value_or(0u);
210  pending_.bound_textures.offset = bound_textures_start_.value_or(0u);
211  pending_.vertex_buffers.offset = vertex_buffers_start_.value_or(0u);
212  auto result = AddCommand(std::move(pending_));
213  pending_ = Command{};
214  bound_textures_start_ = std::nullopt;
215  bound_buffers_start_ = std::nullopt;
216  vertex_buffers_start_ = std::nullopt;
217  if (result) {
218  return fml::Status();
219  }
220  return fml::Status(fml::StatusCode::kInvalidArgument,
221  "Failed to encode command");
222 }
223 
224 // |ResourceBinder|
227  const ShaderUniformSlot& slot,
228  const ShaderMetadata* metadata,
229  BufferView view) {
231  if (!view) {
232  return false;
233  }
234  BufferResource resouce = BufferResource(metadata, std::move(view));
235  return BindBuffer(stage, slot, std::move(resouce));
236 }
237 
238 // |ResourceBinder|
241  const SampledImageSlot& slot,
242  const ShaderMetadata* metadata,
243  std::shared_ptr<const Texture> texture,
244  raw_ptr<const Sampler> sampler) {
245  if (!sampler) {
246  return false;
247  }
248  if (!texture || !texture->IsValid()) {
249  return false;
250  }
251  TextureResource resource = TextureResource(metadata, std::move(texture));
252  return BindTexture(stage, slot, std::move(resource), sampler);
253 }
254 
257  const ShaderUniformSlot& slot,
258  std::unique_ptr<ShaderMetadata> metadata,
259  BufferView view) {
261  if (!view) {
262  return false;
263  }
264  BufferResource resouce =
265  BufferResource::MakeDynamic(std::move(metadata), std::move(view));
266 
267  return BindBuffer(stage, slot, std::move(resouce));
268 }
269 
271  ShaderStage stage,
273  const SampledImageSlot& slot,
274  std::unique_ptr<ShaderMetadata> metadata,
275  std::shared_ptr<const Texture> texture,
277  sampler // NOLINT(performance-unnecessary-value-param)
278 ) {
279  if (!sampler) {
280  return false;
281  }
282  if (!texture || !texture->IsValid()) {
283  return false;
284  }
285  TextureResource resource =
286  TextureResource::MakeDynamic(std::move(metadata), std::move(texture));
287  return BindTexture(stage, slot, std::move(resource), sampler);
288 }
289 
290 bool RenderPass::BindBuffer(ShaderStage stage,
291  const ShaderUniformSlot& slot,
292  BufferResource resource) {
293  if (!bound_buffers_start_.has_value()) {
294  bound_buffers_start_ = bound_buffers_.size();
295  }
296 
297  pending_.bound_buffers.length++;
298  bound_buffers_.push_back(std::move(resource));
299  return true;
300 }
301 
302 bool RenderPass::BindTexture(ShaderStage stage,
303  const SampledImageSlot& slot,
304  TextureResource resource,
305  raw_ptr<const Sampler> sampler) {
306  TextureAndSampler data = TextureAndSampler{
307  .stage = stage,
308  .texture = std::move(resource),
309  // NOLINTNEXTLINE(performance-move-const-arg)
310  .sampler = sampler,
311  };
312 
313  if (!bound_textures_start_.has_value()) {
314  bound_textures_start_ = bound_textures_.size();
315  }
316 
317  pending_.bound_textures.length++;
318  bound_textures_.push_back(std::move(data));
319  return true;
320 }
321 
322 } // namespace impeller
GLenum type
std::vector< TextureAndSampler > bound_textures_
Definition: render_pass.h:251
virtual bool BindDynamicResource(ShaderStage stage, DescriptorType type, const SampledImageSlot &slot, std::unique_ptr< ShaderMetadata > metadata, std::shared_ptr< const Texture > texture, raw_ptr< const Sampler >)
Bind with dynamically generated shader metadata.
Definition: render_pass.cc:270
const bool has_depth_attachment_
Definition: render_pass.h:244
static bool ValidateIndexBuffer(const BufferView &index_buffer, IndexType index_type)
Definition: render_pass.cc:193
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: render_pass.cc:127
virtual bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot &slot, const ShaderMetadata *metadata, BufferView view) override
Definition: render_pass.cc:225
const bool has_stencil_attachment_
Definition: render_pass.h:245
virtual void SetStencilReference(uint32_t value)
Definition: render_pass.cc:103
const RenderTarget & GetRenderTarget() const
Definition: render_pass.cc:43
SampleCount GetSampleCount() const
The sample count of the attached render target.
Definition: render_pass.cc:27
virtual bool SetIndexBuffer(BufferView index_buffer, IndexType index_type)
Specify an index buffer to use for this command. To unset the index buffer, pass IndexType::kNone to ...
Definition: render_pass.cc:164
bool AddCommand(Command &&command)
Record a command for subsequent encoding to the underlying command buffer. No work is encoded into th...
Definition: render_pass.cc:62
const SampleCount sample_count_
Definition: render_pass.h:242
virtual bool OnEncodeCommands(const Context &context) const =0
virtual void SetScissor(IRect scissor)
Definition: render_pass.cc:115
PixelFormat GetRenderTargetPixelFormat() const
The pixel format of the attached render target.
Definition: render_pass.cc:31
const Matrix & GetOrthographicTransform() const
Definition: render_pass.cc:51
RenderPass(std::shared_ptr< const Context > context, const RenderTarget &target)
Definition: render_pass.cc:14
std::vector< Command > commands_
Definition: render_pass.h:248
const std::shared_ptr< const Context > context_
Definition: render_pass.h:236
std::vector< BufferResource > bound_buffers_
Definition: render_pass.h:250
static bool ValidateVertexBuffers(const BufferView vertex_buffers[], size_t vertex_buffer_count)
Definition: render_pass.cc:174
bool HasStencilAttachment() const
Whether the render target has an stencil attachment.
Definition: render_pass.cc:39
virtual void OnSetLabel(std::string_view label)=0
const Matrix orthographic_
Definition: render_pass.h:252
void SetLabel(std::string_view label)
Definition: render_pass.cc:55
std::vector< BufferView > vertex_buffers_
Definition: render_pass.h:249
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
Definition: render_pass.cc:86
const ISize render_target_size_
Definition: render_pass.h:246
ISize GetRenderTargetSize() const
Definition: render_pass.cc:47
virtual void SetInstanceCount(size_t count)
Definition: render_pass.cc:123
virtual fml::Status Draw()
Record the currently pending command.
Definition: render_pass.cc:208
bool HasDepthAttachment() const
Whether the render target has a depth attachment.
Definition: render_pass.cc:35
virtual void SetElementCount(size_t count)
Definition: render_pass.cc:119
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
bool EncodeCommands() const
Encode the recorded commands to the underlying command buffer.
Definition: render_pass.cc:78
const std::shared_ptr< const Context > & GetContext() const
Definition: render_pass.cc:82
virtual void SetBaseVertex(uint64_t value)
Definition: render_pass.cc:107
virtual void SetViewport(Viewport viewport)
Definition: render_pass.cc:111
const RenderTarget render_target_
Definition: render_pass.h:247
const PixelFormat pixel_format_
Definition: render_pass.h:243
static Resource MakeDynamic(std::unique_ptr< ShaderMetadata > metadata, ResourceType p_resource)
Definition: command.h:38
static constexpr size_t kReservedVertexBufferIndex
int32_t value
@ kNone
Does not use the index buffer.
Resource< std::shared_ptr< const Texture > > TextureResource
Definition: command.h:55
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
Definition: pipeline.h:88
Resource< BufferView > BufferResource
Definition: command.h:54
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
constexpr size_t kMaxVertexBuffers
Definition: vertex_buffer.h:13
SampleCount
Definition: formats.h:295
Definition: comparable.h:95
An object used to specify work to the GPU along with references to resources the GPU will used when d...
Definition: command.h:79
Range bound_textures
Definition: command.h:88
uint64_t base_vertex
Definition: command.h:108
uint32_t stencil_reference
Definition: command.h:104
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
Definition: command.h:139
std::optional< Viewport > viewport
Definition: command.h:115
Range vertex_buffers
Definition: command.h:135
Range bound_buffers
Definition: command.h:87
PipelineRef pipeline
Definition: command.h:83
std::optional< IRect > scissor
Definition: command.h:121
IndexType index_type
Definition: command.h:149
size_t element_count
Definition: command.h:144
size_t instance_count
Definition: command.h:129
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
size_t length
Definition: range.h:15
size_t offset
Definition: range.h:14
Metadata required to bind a combined texture and sampler.
Definition: shader_types.h:98
Metadata required to bind a buffer.
Definition: shader_types.h:81
size_t ext_res_0
ext_res_0 is the Metal binding value.
Definition: shader_types.h:86
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
Definition: vertex_buffer.h:20
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68
#define VALIDATION_LOG
Definition: validation.h:91