Flutter Engine
 
Loading...
Searching...
No Matches
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
12namespace impeller {
13
14RenderPass::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
30
34
38
42
46
50
54
55void 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
81
82const 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
97void 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
107void RenderPass::SetBaseVertex(uint64_t value) {
108 pending_.base_vertex = value;
109}
110
112 pending_.viewport = viewport;
113}
114
116 pending_.scissor = scissor;
117}
118
119void RenderPass::SetElementCount(size_t count) {
120 pending_.element_count = count;
121}
122
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 }
134 SetElementCount(buffer.vertex_count);
135
136 return true;
137}
138
140 return SetVertexBuffer(&vertex_buffer, 1);
141}
142
143bool 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
164bool 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
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
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 }
221 "Failed to encode command");
222}
223
224// |ResourceBinder|
227 const ShaderUniformSlot& slot,
228 const ShaderMetadata* metadata,
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,
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
290bool 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
302bool 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,performance-unnecessary-value-param)
310 .sampler = std::move(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
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition pipeline.h:52
std::vector< TextureAndSampler > bound_textures_
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.
const bool has_depth_attachment_
static bool ValidateIndexBuffer(const BufferView &index_buffer, IndexType index_type)
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
virtual bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot &slot, const ShaderMetadata *metadata, BufferView view) override
const bool has_stencil_attachment_
virtual void SetStencilReference(uint32_t value)
virtual void SetScissor(IRect32 scissor)
const RenderTarget & GetRenderTarget() const
SampleCount GetSampleCount() const
The sample count of the attached render target.
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 ...
bool AddCommand(Command &&command)
Record a command for subsequent encoding to the underlying command buffer. No work is encoded into th...
const SampleCount sample_count_
virtual bool OnEncodeCommands(const Context &context) const =0
PixelFormat GetRenderTargetPixelFormat() const
The pixel format of the attached render target.
const Matrix & GetOrthographicTransform() const
RenderPass(std::shared_ptr< const Context > context, const RenderTarget &target)
std::vector< Command > commands_
const std::shared_ptr< const Context > context_
std::vector< BufferResource > bound_buffers_
static bool ValidateVertexBuffers(const BufferView vertex_buffers[], size_t vertex_buffer_count)
bool HasStencilAttachment() const
Whether the render target has an stencil attachment.
virtual void OnSetLabel(std::string_view label)=0
const Matrix orthographic_
void SetLabel(std::string_view label)
std::vector< BufferView > vertex_buffers_
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
const ISize render_target_size_
ISize GetRenderTargetSize() const
virtual void SetInstanceCount(size_t count)
virtual fml::Status Draw()
Record the currently pending command.
bool HasDepthAttachment() const
Whether the render target has a depth attachment.
virtual void SetElementCount(size_t count)
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
bool EncodeCommands() const
Encode the recorded commands to the underlying command buffer.
const std::shared_ptr< const Context > & GetContext() const
virtual void SetBaseVertex(uint64_t value)
virtual void SetViewport(Viewport viewport)
const RenderTarget render_target_
const PixelFormat pixel_format_
static Resource MakeDynamic(std::unique_ptr< ShaderMetadata > metadata, ResourceType p_resource)
Definition command.h:38
static constexpr size_t kReservedVertexBufferIndex
int32_t value
FlView * view
uint32_t * target
#define FML_DCHECK(condition)
Definition logging.h:122
FlTexture * texture
@ kNone
Does not use the index buffer.
Resource< std::shared_ptr< const Texture > > TextureResource
Definition command.h:56
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
Definition pipeline.h:88
Resource< BufferView > BufferResource
Definition command.h:55
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 ref_ptr.h:261
An object used to specify work to the GPU along with references to resources the GPU will used when d...
Definition command.h:80
Range bound_textures
Definition command.h:93
uint32_t element_count
Definition command.h:131
std::optional< IRect32 > scissor
Definition command.h:114
uint64_t base_vertex
Definition command.h:126
uint32_t stencil_reference
Definition command.h:149
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
Definition command.h:88
std::optional< Viewport > viewport
Definition command.h:107
uint32_t instance_count
Definition command.h:140
Range vertex_buffers
Definition command.h:99
Range bound_buffers
Definition command.h:92
PipelineRef pipeline
Definition command.h:84
IndexType index_type
Definition command.h:154
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.
Metadata required to bind a buffer.
size_t ext_res_0
ext_res_0 is the Metal binding value.
std::shared_ptr< const fml::Mapping > data
#define VALIDATION_LOG
Definition validation.h:91