| Flutter Impeller |

pass_bindings_cache_mtl.mm
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
5 #include "impeller/renderer/backend/metal/pass_bindings_cache_mtl.h"
6
7 namespace impeller {
8
9 void PassBindingsCacheMTL::SetEncoder(id<MTLRenderCommandEncoder> encoder) {
10 encoder_ = encoder;
11 }
12
13 void PassBindingsCacheMTL::SetRenderPipelineState(
14 id<MTLRenderPipelineState> pipeline) {
15 if (pipeline == pipeline_) {
16 return;
17 }
18 pipeline_ = pipeline;
19 [encoder_ setRenderPipelineState:pipeline_];
20 }
21
22 void PassBindingsCacheMTL::SetDepthStencilState(
23 id<MTLDepthStencilState> depth_stencil) {
24 if (depth_stencil_ == depth_stencil) {
25 return;
26 }
27 depth_stencil_ = depth_stencil;
28 [encoder_ setDepthStencilState:depth_stencil_];
29 }
30
31 bool PassBindingsCacheMTL::SetBuffer(ShaderStage stage,
32 uint64_t index,
33 uint64_t offset,
34 id<MTLBuffer> buffer) {
35 auto& buffers_map = buffers_[stage];
36 auto found = buffers_map.find(index);
37 if (found != buffers_map.end() && found->second.buffer == buffer) {
38 // The right buffer is bound. Check if its offset needs to be updated.
39 if (found->second.offset == offset) {
40 // Buffer and its offset is identical. Nothing to do.
41 return true;
42 }
43
44 // Only the offset needs to be updated.
45 found->second.offset = offset;
46
47 switch (stage) {
48 case ShaderStage::kVertex:
49 [encoder_ setVertexBufferOffset:offset atIndex:index];
50 return true;
51 case ShaderStage::kFragment:
52 [encoder_ setFragmentBufferOffset:offset atIndex:index];
53 return true;
54 default:
55 VALIDATION_LOG << "Cannot update buffer offset of an unknown stage.";
56 return false;
57 }
58 return true;
59 }
60 buffers_map[index] = {buffer, static_cast<size_t>(offset)};
61 switch (stage) {
62 case ShaderStage::kVertex:
63 [encoder_ setVertexBuffer:buffer offset:offset atIndex:index];
64 return true;
65 case ShaderStage::kFragment:
66 [encoder_ setFragmentBuffer:buffer offset:offset atIndex:index];
67 return true;
68 default:
69 VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
70 return false;
71 }
72 return false;
73 }
74
75 bool PassBindingsCacheMTL::SetTexture(ShaderStage stage,
76 uint64_t index,
77 id<MTLTexture> texture) {
78 auto& texture_map = textures_[stage];
79 auto found = texture_map.find(index);
80 if (found != texture_map.end() && found->second == texture) {
81 // Already bound.
82 return true;
83 }
84 texture_map[index] = texture;
85 switch (stage) {
86 case ShaderStage::kVertex:
87 [encoder_ setVertexTexture:texture atIndex:index];
88 return true;
89 case ShaderStage::kFragment:
90 [encoder_ setFragmentTexture:texture atIndex:index];
91 return true;
92 default:
93 VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
94 return false;
95 }
96 return false;
97 }
98
99 bool PassBindingsCacheMTL::SetSampler(ShaderStage stage,
100 uint64_t index,
101 id<MTLSamplerState> sampler) {
102 auto& sampler_map = samplers_[stage];
103 auto found = sampler_map.find(index);
104 if (found != sampler_map.end() && found->second == sampler) {
105 // Already bound.
106 return true;
107 }
108 sampler_map[index] = sampler;
109 switch (stage) {
110 case ShaderStage::kVertex:
111 [encoder_ setVertexSamplerState:sampler atIndex:index];
112 return true;
113 case ShaderStage::kFragment:
114 [encoder_ setFragmentSamplerState:sampler atIndex:index];
115 return true;
116 default:
117 VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
118 return false;
119 }
120 return false;
121 }
122
123 void PassBindingsCacheMTL::SetViewport(const Viewport& viewport) {
124 if (viewport_.has_value() && viewport_.value() == viewport) {
125 return;
126 }
127 [encoder_ setViewport:MTLViewport{
128 .originX = viewport.rect.GetX(),
129 .originY = viewport.rect.GetY(),
130 .width = viewport.rect.GetWidth(),
131 .height = viewport.rect.GetHeight(),
132 .znear = viewport.depth_range.z_near,
133 .zfar = viewport.depth_range.z_far,
134 }];
135 viewport_ = viewport;
136 }
137
138 void PassBindingsCacheMTL::SetScissor(const IRect32& scissor) {
139 if (scissor_.has_value() && scissor_.value() == scissor) {
140 return;
141 }
142 [encoder_
143 setScissorRect:MTLScissorRect{
144 .x = static_cast<NSUInteger>(scissor.GetX()),
145 .y = static_cast<NSUInteger>(scissor.GetY()),
146 .width = static_cast<NSUInteger>(scissor.GetWidth()),
147 .height = static_cast<NSUInteger>(scissor.GetHeight()),
148 }];
149 scissor_ = scissor;
150 }
151
152 void PassBindingsCacheMTL::SetStencilRef(uint32_t stencil_ref) {
153 if (stencil_ref_.has_value() && stencil_ref_.value() == stencil_ref) {
154 return;
155 }
156 [encoder_ setStencilReferenceValue:stencil_ref];
157 stencil_ref_ = stencil_ref;
158 }
159
160 } // namespace impeller
impeller
Definition: allocation.cc:12
impeller::ShaderStage
ShaderStage
Definition: shader_types.h:22
impeller::ShaderStage::kFragment
@ kFragment
impeller::ShaderStage::kVertex
@ kVertex
pass_bindings_cache_mtl.h
impeller::DepthRange::z_far
Scalar z_far
Definition: formats.h:396
impeller::DepthRange::z_near
Scalar z_near
Definition: formats.h:395
impeller::PassBindingsCacheMTL::SetStencilRef
void SetStencilRef(uint32_t stencil_ref)
Set the encoder's stencil reference if the value is different from the current encoder state.
Definition: pass_bindings_cache_mtl.mm:152
impeller::PassBindingsCacheMTL::SetRenderPipelineState
void SetRenderPipelineState(id< MTLRenderPipelineState > pipeline)
Set the render pipeline state for the current encoder.
Definition: pass_bindings_cache_mtl.mm:13
impeller::PassBindingsCacheMTL::SetSampler
bool SetSampler(ShaderStage stage, uint64_t index, id< MTLSamplerState > sampler)
Set the sampler for the given stage and binding.
Definition: pass_bindings_cache_mtl.mm:99
impeller::PassBindingsCacheMTL::SetBuffer
bool SetBuffer(ShaderStage stage, uint64_t index, uint64_t offset, id< MTLBuffer > buffer)
Set the buffer for the given shader stage, binding, and offset.
Definition: pass_bindings_cache_mtl.mm:31
impeller::PassBindingsCacheMTL::SetViewport
void SetViewport(const Viewport &viewport)
Set the viewport if the value is different from the current encoder state.
Definition: pass_bindings_cache_mtl.mm:123
impeller::PassBindingsCacheMTL::SetScissor
void SetScissor(const IRect32 &scissor)
Set the encoder scissor rect if the value is different from the current encoder state.
Definition: pass_bindings_cache_mtl.mm:138
impeller::PassBindingsCacheMTL::SetDepthStencilState
void SetDepthStencilState(id< MTLDepthStencilState > depth_stencil)
Set the depth and stencil state for the current encoder.
Definition: pass_bindings_cache_mtl.mm:22
impeller::PassBindingsCacheMTL::SetEncoder
void SetEncoder(id< MTLRenderCommandEncoder > encoder)
Set the command encoder for this pass bindings cache.
Definition: pass_bindings_cache_mtl.mm:9
impeller::PassBindingsCacheMTL::SetTexture
bool SetTexture(ShaderStage stage, uint64_t index, id< MTLTexture > texture)
Set the texture for the given stage and binding.
Definition: pass_bindings_cache_mtl.mm:75
impeller::TRect
Definition: rect.h:122
impeller::TRect::GetY
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:341
impeller::TRect::GetHeight
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:351
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:337
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:345
impeller::Viewport
Definition: formats.h:403
impeller::Viewport::rect
Rect rect
Definition: formats.h:404
impeller::Viewport::depth_range
DepthRange depth_range
Definition: formats.h:405
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91