| Flutter Impeller |

Classes | Public Member Functions | List of all members
impeller::PassBindingsCache Class Reference

Ensures that bindings on the pass are not redundantly set or updated. Avoids making the driver do additional checks and makes the frame insights during profiling and instrumentation not complain about the same. More...

`#include <pass_bindings_cache.h>`

## Public Member Functions
| PassBindingsCache (id< MTLRenderCommandEncoder > encoder)
| PassBindingsCache (const PassBindingsCache &)=delete
| PassBindingsCache (PassBindingsCache &&)=delete
void | SetRenderPipelineState (id< MTLRenderPipelineState > pipeline)
void | SetDepthStencilState (id< MTLDepthStencilState > depth_stencil)
bool | SetBuffer (ShaderStage stage, uint64_t index, uint64_t offset, id< MTLBuffer > buffer)
bool | SetTexture (ShaderStage stage, uint64_t index, id< MTLTexture > texture)
bool | SetSampler (ShaderStage stage, uint64_t index, id< MTLSamplerState > sampler)
void | SetViewport (const Viewport &viewport)
void | SetScissor (const IRect &scissor)
void | BindPipeline (vk::CommandBuffer command_buffer, vk::PipelineBindPoint pipeline_bind_point, vk::Pipeline pipeline)
void | SetStencilReference (vk::CommandBuffer command_buffer, vk::StencilFaceFlags face_mask, uint32_t reference)
void | SetScissor (vk::CommandBuffer command_buffer, uint32_t first_scissor, uint32_t scissor_count, const vk::Rect2D *scissors)
void | SetViewport (vk::CommandBuffer command_buffer, uint32_t first_viewport, uint32_t viewport_count, const vk::Viewport *viewports)

## Detailed Description

Ensures that bindings on the pass are not redundantly set or updated. Avoids making the driver do additional checks and makes the frame insights during profiling and instrumentation not complain about the same.

There should be no change to rendering if this caching was absent.

Definition at line 194 of file render_pass_mtl.mm.

## Constructor & Destructor Documentation

## ◆ PassBindingsCache() [1/3]

impeller::PassBindingsCache::PassBindingsCache | ( | id< MTLRenderCommandEncoder > | encoder | ) |
| inline explicit

Definition at line 195 of file render_pass_mtl.mm.

196 : encoder_(encoder) {}

## ◆ PassBindingsCache() [2/3]

impeller::PassBindingsCache::PassBindingsCache | ( | const PassBindingsCache & |  | ) |
| delete

## ◆ PassBindingsCache() [3/3]

impeller::PassBindingsCache::PassBindingsCache | ( | PassBindingsCache && |  | ) |
| delete

## Member Function Documentation

## ◆ BindPipeline()

void impeller::PassBindingsCache::BindPipeline | ( | vk::CommandBuffer | command_buffer,
|  | vk::PipelineBindPoint | pipeline_bind_point,
|  | vk::Pipeline | pipeline
| ) |  |

Definition at line 8 of file pass_bindings_cache.cc.

10 {
11 switch (pipeline_bind_point) {
12 case vk::PipelineBindPoint::eGraphics:
13 if (graphics_pipeline_.has_value() &&
14 graphics_pipeline_.value() == pipeline) {
15 return;
16 }
17 graphics_pipeline_ = pipeline;
18 break;
19 case vk::PipelineBindPoint::eCompute:
20 if (compute_pipeline_.has_value() &&
21 compute_pipeline_.value() == pipeline) {
22 return;
23 }
24 compute_pipeline_ = pipeline;
25 break;
26 default:
27 break;
28 }
29 command_buffer.bindPipeline(pipeline_bind_point, pipeline);
30 }

Referenced by impeller::EncodeCommand(), and impeller::testing::TEST().

## ◆ SetBuffer()

bool impeller::PassBindingsCache::SetBuffer | ( | ShaderStage | stage,
|  | uint64_t | index,
|  | uint64_t | offset,
|  | id< MTLBuffer > | buffer
| ) |  |
| inline

Definition at line 218 of file render_pass_mtl.mm.

221 {
222 auto& buffers_map = buffers_[stage];
223 auto found = buffers_map.find(index);
224 if (found != buffers_map.end() && found->second.buffer == buffer) {
225 // The right buffer is bound. Check if its offset needs to be updated.
226 if (found->second.offset == offset) {
227 // Buffer and its offset is identical. Nothing to do.
228 return true;
229 }
230
231 // Only the offset needs to be updated.
232 found->second.offset = offset;
233
234 switch (stage) {
235 case ShaderStage::kVertex:
236 [encoder_ setVertexBufferOffset:offset atIndex:index];
237 return true;
238 case ShaderStage::kFragment:
239 [encoder_ setFragmentBufferOffset:offset atIndex:index];
240 return true;
241 default:
242 VALIDATION_LOG << "Cannot update buffer offset of an unknown stage.";
243 return false;
244 }
245 return true;
246 }
247 buffers_map[index] = {buffer, static_cast<size_t>(offset)};
248 switch (stage) {
249 case ShaderStage::kVertex:
250 [encoder_ setVertexBuffer:buffer offset:offset atIndex:index];
251 return true;
252 case ShaderStage::kFragment:
253 [encoder_ setFragmentBuffer:buffer offset:offset atIndex:index];
254 return true;
255 default:
256 VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
257 return false;
258 }
259 return false;
260 }

References VALIDATION_LOG.

Referenced by impeller::Bind().

## ◆ SetDepthStencilState()

void impeller::PassBindingsCache::SetDepthStencilState | ( | id< MTLDepthStencilState > | depth_stencil | ) |
| inline

Definition at line 210 of file render_pass_mtl.mm.

210 {
211 if (depth_stencil_ == depth_stencil) {
212 return;
213 }
214 depth_stencil_ = depth_stencil;
215 [encoder_ setDepthStencilState:depth_stencil_];
216 }

## ◆ SetRenderPipelineState()

void impeller::PassBindingsCache::SetRenderPipelineState | ( | id< MTLRenderPipelineState > | pipeline | ) |
| inline

Definition at line 202 of file render_pass_mtl.mm.

202 {
203 if (pipeline == pipeline_) {
204 return;
205 }
206 pipeline_ = pipeline;
207 [encoder_ setRenderPipelineState:pipeline_];
208 }

## ◆ SetSampler()

bool impeller::PassBindingsCache::SetSampler | ( | ShaderStage | stage,
|  | uint64_t | index,
|  | id< MTLSamplerState > | sampler
| ) |  |
| inline

Definition at line 284 of file render_pass_mtl.mm.

286 {
287 auto& sampler_map = samplers_[stage];
288 auto found = sampler_map.find(index);
289 if (found != sampler_map.end() && found->second == sampler) {
290 // Already bound.
291 return true;
292 }
293 sampler_map[index] = sampler;
294 switch (stage) {
295 case ShaderStage::kVertex:
296 [encoder_ setVertexSamplerState:sampler atIndex:index];
297 return true;
298 case ShaderStage::kFragment:
299 [encoder_ setFragmentSamplerState:sampler atIndex:index];
300 return true;
301 default:
302 VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
303 return false;
304 }
305 return false;
306 }

References VALIDATION_LOG.

Referenced by impeller::Bind().

## ◆ SetScissor() [1/2]

void impeller::PassBindingsCache::SetScissor | ( | const IRect & | scissor | ) |
| inline

Definition at line 323 of file render_pass_mtl.mm.

323 {
324 if (scissor_.has_value() && scissor_.value() == scissor) {
325 return;
326 }
327 [encoder_
328 setScissorRect:MTLScissorRect{
329 .x = static_cast<NSUInteger>(scissor.origin.x),
330 .y = static_cast<NSUInteger>(scissor.origin.y),
331 .width = static_cast<NSUInteger>(scissor.size.width),
332 .height =
333 static_cast<NSUInteger>(scissor.size.height),
334 }];
335 scissor_ = scissor;
336 }

References impeller::TSize< T >::height, impeller::TRect< T >::origin, impeller::TRect< T >::size, impeller::TSize< T >::width, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::SetViewportAndScissor(), and impeller::testing::TEST().

## ◆ SetScissor() [2/2]

void impeller::PassBindingsCache::SetScissor | ( | vk::CommandBuffer | command_buffer,
|  | uint32_t | first_scissor,
|  | uint32_t | scissor_count,
|  | const vk::Rect2D * | scissors
| ) |  |

Definition at line 45 of file pass_bindings_cache.cc.

48 {
49 if (first_scissor == 0 && scissor_count == 1) {
50 if (scissors_.has_value() && scissors_.value() == scissors[0]) {
51 return;
52 }
53 scissors_ = scissors[0];
54 }
55 command_buffer.setScissor(first_scissor, scissor_count, scissors);
56 }

## ◆ SetStencilReference()

void impeller::PassBindingsCache::SetStencilReference | ( | vk::CommandBuffer | command_buffer,
|  | vk::StencilFaceFlags | face_mask,
|  | uint32_t | reference
| ) |  |

Definition at line 32 of file pass_bindings_cache.cc.

34 {
35 if (stencil_face_flags_.has_value() &&
36 face_mask == stencil_face_flags_.value() &&
37 reference == stencil_reference_) {
38 return;
39 }
40 stencil_face_flags_ = face_mask;
41 stencil_reference_ = reference;
42 command_buffer.setStencilReference(face_mask, reference);
43 }

Referenced by impeller::EncodeCommand(), and impeller::testing::TEST().

## ◆ SetTexture()

bool impeller::PassBindingsCache::SetTexture | ( | ShaderStage | stage,
|  | uint64_t | index,
|  | id< MTLTexture > | texture
| ) |  |
| inline

Definition at line 262 of file render_pass_mtl.mm.

262 {
263 auto& texture_map = textures_[stage];
264 auto found = texture_map.find(index);
265 if (found != texture_map.end() && found->second == texture) {
266 // Already bound.
267 return true;
268 }
269 texture_map[index] = texture;
270 switch (stage) {
271 case ShaderStage::kVertex:
272 [encoder_ setVertexTexture:texture atIndex:index];
273 return true;
274 case ShaderStage::kFragment:
275 [encoder_ setFragmentTexture:texture atIndex:index];
276 return true;
277 default:
278 VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
279 return false;
280 }
281 return false;
282 }

References VALIDATION_LOG.

Referenced by impeller::Bind().

## ◆ SetViewport() [1/2]

void impeller::PassBindingsCache::SetViewport | ( | const Viewport & | viewport | ) |
| inline

Definition at line 308 of file render_pass_mtl.mm.

308 {
309 if (viewport_.has_value() && viewport_.value() == viewport) {
310 return;
311 }
312 [encoder_ setViewport:MTLViewport{
313 .originX = viewport.rect.origin.x,
314 .originY = viewport.rect.origin.y,
315 .width = viewport.rect.size.width,
316 .height = viewport.rect.size.height,
317 .znear = viewport.depth_range.z_near,
318 .zfar = viewport.depth_range.z_far,
319 }];
320 viewport_ = viewport;
321 }

References impeller::Viewport::depth_range, impeller::TSize< T >::height, impeller::TRect< T >::origin, impeller::Viewport::rect, impeller::TRect< T >::size, impeller::TSize< T >::width, impeller::TPoint< T >::x, impeller::TPoint< T >::y, impeller::DepthRange::z_far, and impeller::DepthRange::z_near.

Referenced by impeller::SetViewportAndScissor(), and impeller::testing::TEST().

## ◆ SetViewport() [2/2]

void impeller::PassBindingsCache::SetViewport | ( | vk::CommandBuffer | command_buffer,
|  | uint32_t | first_viewport,
|  | uint32_t | viewport_count,
|  | const vk::Viewport * | viewports
| ) |  |

Definition at line 58 of file pass_bindings_cache.cc.

61 {
62 if (first_viewport == 0 && viewport_count == 1) {
63 // Note that this is doing equality checks on floating point numbers.
64 if (viewport_.has_value() && viewport_.value() == viewports[0]) {
65 return;
66 }
67 viewport_ = viewports[0];
68 }
69 command_buffer.setViewport(first_viewport, viewport_count, viewports);
70 }

The documentation for this class was generated from the following files:

- impeller/renderer/backend/metal/render_pass_mtl.mm
- impeller/renderer/backend/vulkan/pass_bindings_cache.h
- impeller/renderer/backend/vulkan/pass_bindings_cache.cc

impeller::ShaderStage::kFragment
@ kFragment
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::ShaderStage::kVertex
@ kVertex