31 MTLRenderPassAttachmentDescriptor* attachment) {
37 VALIDATION_LOG <<
"Resolve store action specified on attachment but no "
38 "resolve texture was specified.";
43 VALIDATION_LOG <<
"A resolve texture was specified even though the store "
44 "action doesn't require it.";
52 attachment.resolveTexture =
59 MTLRenderPassAttachmentDescriptor* attachment) {
70 attachment.slice = desc.
slice;
81 MTLRenderPassColorAttachmentDescriptor* attachment) {
91 MTLRenderPassDepthAttachmentDescriptor* attachment) {
101 MTLRenderPassStencilAttachmentDescriptor* attachment) {
111 auto result = [MTLRenderPassDescriptor renderPassDescriptor];
116 result.colorAttachments[index]);
119 if (!configured_attachment) {
126 if (depth.has_value() &&
134 if (stencil.has_value() &&
143RenderPassMTL::RenderPassMTL(std::shared_ptr<const Context>
context,
144 const RenderTarget&
target,
145 id<MTLCommandBuffer> buffer)
149 if (!buffer_ || !
desc_ || !render_target_.IsValid()) {
152 encoder_ = [buffer_ renderCommandEncoderWithDescriptor:
desc_];
158 is_metal_trace_active_ =
159 [[MTLCaptureManager sharedCaptureManager] isCapturing];
161 pass_bindings_.SetEncoder(encoder_);
162 pass_bindings_.SetViewport(
168RenderPassMTL::~RenderPassMTL() {
169 if (!did_finish_encoding_) {
170 [encoder_ endEncoding];
171 did_finish_encoding_ =
true;
175bool RenderPassMTL::IsValid()
const {
179void RenderPassMTL::OnSetLabel(std::string_view label) {
184 encoder_.label = @(std::string(label).c_str());
188bool RenderPassMTL::OnEncodeCommands(
const Context&
context)
const {
189 did_finish_encoding_ =
true;
190 [encoder_ endEncoding];
198 if (!
view.GetBuffer()) {
203 if (!device_buffer) {
207 auto buffer = DeviceBufferMTL::Cast(*device_buffer).GetMTLBuffer();
213 return pass.
SetBuffer(stage, bind_index,
view.GetRange().offset, buffer);
221 if (!sampler || !
texture.IsValid()) {
226 TextureMTL::Cast(
texture).GetMTLTexture()) &&
228 SamplerMTL::Cast(*sampler).GetMTLSamplerState());
232void RenderPassMTL::SetPipeline(PipelineRef
pipeline) {
233 const PipelineDescriptor& pipeline_desc =
pipeline->GetDescriptor();
234 context_->GetPipelineLibrary()->LogPipelineUsage(pipeline_desc);
235 primitive_type_ = pipeline_desc.GetPrimitiveType();
236 pass_bindings_.SetRenderPipelineState(
237 PipelineMTL::Cast(*pipeline).GetMTLRenderPipelineState());
238 pass_bindings_.SetDepthStencilState(
239 PipelineMTL::Cast(*pipeline).GetMTLDepthStencilState());
241 [encoder_ setFrontFacingWinding:pipeline_desc.GetWindingOrder() ==
242 WindingOrder::kClockwise
243 ? MTLWindingClockwise
244 : MTLWindingCounterClockwise];
245 [encoder_ setCullMode:ToMTLCullMode(pipeline_desc.GetCullMode())];
246 [encoder_ setTriangleFillMode:ToMTLTriangleFillMode(
247 pipeline_desc.GetPolygonMode())];
248 has_valid_pipeline_ =
true;
252void RenderPassMTL::SetCommandLabel(std::string_view label) {
254 if (is_metal_trace_active_) {
256 std::string label_copy(label);
257 [encoder_ pushDebugGroup:@(label_copy.c_str())];
263void RenderPassMTL::SetStencilReference(uint32_t value) {
264 pass_bindings_.SetStencilRef(value);
268void RenderPassMTL::SetBaseVertex(uint64_t value) {
269 base_vertex_ =
value;
273void RenderPassMTL::SetViewport(Viewport viewport) {
274 pass_bindings_.SetViewport(viewport);
278void RenderPassMTL::SetScissor(IRect32 scissor) {
279 pass_bindings_.SetScissor(scissor);
283void RenderPassMTL::SetElementCount(
size_t count) {
284 vertex_count_ = count;
288void RenderPassMTL::SetInstanceCount(
size_t count) {
289 instance_count_ = count;
293bool RenderPassMTL::SetVertexBuffer(BufferView vertex_buffers[],
294 size_t vertex_buffer_count) {
295 if (!ValidateVertexBuffers(vertex_buffers, vertex_buffer_count)) {
299 for (
size_t i = 0;
i < vertex_buffer_count;
i++) {
300 if (!
Bind(pass_bindings_, ShaderStage::kVertex,
301 VertexDescriptor::kReservedVertexBufferIndex -
i,
302 vertex_buffers[
i])) {
311bool RenderPassMTL::SetIndexBuffer(BufferView index_buffer,
312 IndexType index_type) {
313 if (!ValidateIndexBuffer(index_buffer, index_type)) {
317 if (index_type != IndexType::kNone) {
319 index_buffer_ = std::move(index_buffer);
327 if (!has_valid_pipeline_) {
331 if (!index_buffer_) {
332 if (instance_count_ != 1u) {
334 vertexStart:base_vertex_
335 vertexCount:vertex_count_
336 instanceCount:instance_count_
340 vertexStart:base_vertex_
341 vertexCount:vertex_count_];
344 id<MTLBuffer> mtl_index_buffer =
345 DeviceBufferMTL::Cast(*index_buffer_.GetBuffer()).GetMTLBuffer();
346 if (instance_count_ != 1u) {
348 indexCount:vertex_count_
349 indexType:index_type_
350 indexBuffer:mtl_index_buffer
351 indexBufferOffset:index_buffer_.GetRange().offset
352 instanceCount:instance_count_
353 baseVertex:base_vertex_
357 indexCount:vertex_count_
358 indexType:index_type_
359 indexBuffer:mtl_index_buffer
360 indexBufferOffset:index_buffer_.GetRange().offset];
366 [encoder_ popDebugGroup];
372 instance_count_ = 1u;
374 has_valid_pipeline_ =
false;
381bool RenderPassMTL::BindResource(ShaderStage stage,
383 const ShaderUniformSlot& slot,
384 const ShaderMetadata* metadata,
386 return Bind(pass_bindings_, stage, slot.ext_res_0, view);
390bool RenderPassMTL::BindDynamicResource(
393 const ShaderUniformSlot& slot,
394 std::unique_ptr<ShaderMetadata> metadata,
396 return Bind(pass_bindings_, stage, slot.ext_res_0, view);
400bool RenderPassMTL::BindResource(ShaderStage stage,
402 const SampledImageSlot& slot,
403 const ShaderMetadata* metadata,
404 std::shared_ptr<const Texture>
texture,
405 raw_ptr<const Sampler> sampler) {
409 return Bind(pass_bindings_, stage, slot.texture_index, sampler, *
texture);
412bool RenderPassMTL::BindDynamicResource(
415 const SampledImageSlot& slot,
416 std::unique_ptr<ShaderMetadata> metadata,
417 std::shared_ptr<const Texture>
texture,
418 raw_ptr<const Sampler> sampler) {
422 return Bind(pass_bindings_, stage, slot.texture_index, sampler, *
texture);
static TextureMTL & Cast(Texture &base)
bool IterateAllColorAttachments(const std::function< bool(size_t index, const ColorAttachment &attachment)> &iterator) const
const std::optional< DepthAttachment > & GetDepthAttachment() const
const std::optional< StencilAttachment > & GetStencilAttachment() const
id< MTLTexture > GetMTLTexture() const
A wrapper around a raw ptr that adds additional unopt mode only checks.
std::optional< PipelineDescriptor > desc_
static bool ConfigureColorAttachment(const ColorAttachment &desc, MTLRenderPassColorAttachmentDescriptor *attachment)
static bool ConfigureDepthAttachment(const DepthAttachment &desc, MTLRenderPassDepthAttachmentDescriptor *attachment)
constexpr MTLLoadAction ToMTLLoadAction(LoadAction action)
@ kStoreAndMultisampleResolve
static MTLRenderPassDescriptor * ToMTLRenderPassDescriptor(const RenderTarget &desc)
static bool ConfigureResolveTextureAttachment(const Attachment &desc, MTLRenderPassAttachmentDescriptor *attachment)
constexpr MTLPrimitiveType ToMTLPrimitiveType(PrimitiveType type)
static bool ConfigureStencilAttachment(const StencilAttachment &desc, MTLRenderPassStencilAttachmentDescriptor *attachment)
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
constexpr MTLIndexType ToMTLIndexType(IndexType type)
constexpr MTLStoreAction ToMTLStoreAction(StoreAction action)
MTLClearColor ToMTLClearColor(const Color &color)
static bool ConfigureAttachment(const Attachment &desc, MTLRenderPassAttachmentDescriptor *attachment)
std::shared_ptr< ContextGLES > context
std::shared_ptr< PipelineGLES > pipeline
impeller::ShaderType type
std::shared_ptr< Texture > resolve_texture
std::shared_ptr< Texture > texture
Ensures that bindings on the pass are not redundantly set or updated. Avoids making the driver do add...
bool SetSampler(ShaderStage stage, uint64_t index, id< MTLSamplerState > sampler)
Set the sampler for the given stage and binding.
bool SetBuffer(ShaderStage stage, uint64_t index, uint64_t offset, id< MTLBuffer > buffer)
Set the buffer for the given shader stage, binding, and offset.
bool SetTexture(ShaderStage stage, uint64_t index, id< MTLTexture > texture)
Set the texture for the given stage and binding.
static constexpr TRect MakeSize(const TSize< U > &size)