| 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 195 of file render_pass_mtl.mm.

## Constructor & Destructor Documentation

## ◆ PassBindingsCache() [1/3]

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

Definition at line 196 of file render_pass_mtl.mm.

197 : 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::testing::TEST().

## ◆ SetBuffer()

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

Definition at line 219 of file render_pass_mtl.mm.

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

References VALIDATION_LOG.

Referenced by impeller::Bind().

## ◆ SetDepthStencilState()

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

Definition at line 211 of file render_pass_mtl.mm.

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

## ◆ SetRenderPipelineState()

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

Definition at line 203 of file render_pass_mtl.mm.

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

## ◆ SetSampler()

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

Definition at line 285 of file render_pass_mtl.mm.

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

References VALIDATION_LOG.

Referenced by impeller::Bind().

## ◆ SetScissor() [1/2]

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

Definition at line 324 of file render_pass_mtl.mm.

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

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), and impeller::TRect< T >::GetY().

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::testing::TEST().

## ◆ SetTexture()

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

Definition at line 263 of file render_pass_mtl.mm.

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

References VALIDATION_LOG.

Referenced by impeller::Bind().

## ◆ SetViewport() [1/2]

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

Definition at line 309 of file render_pass_mtl.mm.

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

References impeller::Viewport::depth_range, impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::Viewport::rect, 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:67
impeller::ShaderStage::kVertex
@ kVertex