7#include "flutter/fml/closure.h"
8#include "flutter/fml/logging.h"
9#include "flutter/fml/make_copyable.h"
29 MTLRenderPassAttachmentDescriptor* attachment) {
34 if (needs_resolve && !desc.resolve_texture) {
35 VALIDATION_LOG <<
"Resolve store action specified on attachment but no "
36 "resolve texture was specified.";
40 if (desc.resolve_texture && !needs_resolve) {
41 VALIDATION_LOG <<
"A resolve texture was specified even though the store "
42 "action doesn't require it.";
46 if (!desc.resolve_texture) {
50 attachment.resolveTexture =
57 MTLRenderPassAttachmentDescriptor* attachment) {
75 MTLRenderPassColorAttachmentDescriptor* attachment) {
85 MTLRenderPassDepthAttachmentDescriptor* attachment) {
89 attachment.clearDepth = desc.clear_depth;
95 MTLRenderPassStencilAttachmentDescriptor* attachment) {
99 attachment.clearStencil = desc.clear_stencil;
106 auto result = [MTLRenderPassDescriptor renderPassDescriptor];
108 const auto& colors = desc.GetColorAttachments();
110 for (
const auto&
color : colors) {
113 VALIDATION_LOG <<
"Could not configure color attachment at index "
119 const auto& depth = desc.GetDepthAttachment();
121 if (depth.has_value() &&
127 const auto& stencil = desc.GetStencilAttachment();
129 if (stencil.has_value() &&
138RenderPassMTL::RenderPassMTL(std::shared_ptr<const Context> context,
139 const RenderTarget&
target,
140 id<MTLCommandBuffer>
buffer)
141 : RenderPass(
std::move(context),
target),
144 if (!buffer_ || !desc_ || !render_target_.IsValid()) {
147 encoder_ = [buffer_ renderCommandEncoderWithDescriptor:desc_];
153 is_metal_trace_active_ =
154 [[MTLCaptureManager sharedCaptureManager] isCapturing];
156 pass_bindings_.SetEncoder(encoder_);
157 pass_bindings_.SetViewport(
163RenderPassMTL::~RenderPassMTL() {
164 if (!did_finish_encoding_) {
165 [encoder_ endEncoding];
166 did_finish_encoding_ =
true;
170bool RenderPassMTL::IsValid()
const {
174void RenderPassMTL::OnSetLabel(std::string label) {
179 encoder_.label = @(std::string(label).c_str());
183bool RenderPassMTL::OnEncodeCommands(
const Context& context)
const {
184 did_finish_encoding_ =
true;
185 [encoder_ endEncoding];
197 auto device_buffer = view.
buffer;
198 if (!device_buffer) {
202 auto buffer = DeviceBufferMTL::Cast(*device_buffer).GetMTLBuffer();
214 const std::unique_ptr<const Sampler>& sampler,
216 if (!sampler || !
texture.IsValid()) {
220 if (
texture.NeedsMipmapGeneration()) {
224 <<
"Texture at binding index " << bind_index
225 <<
" has a mip count > 1, but the mipmap has not been generated.";
231 TextureMTL::Cast(
texture).GetMTLTexture()) &&
233 SamplerMTL::Cast(*sampler).GetMTLSamplerState());
237void RenderPassMTL::SetPipeline(
241 pass_bindings_.SetRenderPipelineState(
242 PipelineMTL::Cast(*pipeline).GetMTLRenderPipelineState());
243 pass_bindings_.SetDepthStencilState(
244 PipelineMTL::Cast(*pipeline).GetMTLDepthStencilState());
247 WindingOrder::kClockwise
248 ? MTLWindingClockwise
249 : MTLWindingCounterClockwise];
253 has_valid_pipeline_ =
true;
257void RenderPassMTL::SetCommandLabel(std::string_view label) {
259 if (is_metal_trace_active_) {
261 std::string label_copy(label);
262 [encoder_ pushDebugGroup:@(label_copy.c_str())];
268void RenderPassMTL::SetStencilReference(uint32_t value) {
269 [encoder_ setStencilReferenceValue:
value];
273void RenderPassMTL::SetBaseVertex(uint64_t value) {
274 base_vertex_ =
value;
278void RenderPassMTL::SetViewport(
Viewport viewport) {
279 pass_bindings_.SetViewport(viewport);
283void RenderPassMTL::SetScissor(
IRect scissor) {
284 pass_bindings_.SetScissor(scissor);
288void RenderPassMTL::SetInstanceCount(
size_t count) {
289 instance_count_ =
count;
294 if (
buffer.index_type == IndexType::kUnknown) {
298 if (!
Bind(pass_bindings_, ShaderStage::kVertex,
299 VertexDescriptor::kReservedVertexBufferIndex,
304 vertex_count_ =
buffer.vertex_count;
305 if (
buffer.index_type != IndexType::kNone) {
307 index_buffer_ = std::move(
buffer.index_buffer);
314 if (!has_valid_pipeline_) {
318 if (!index_buffer_) {
319 if (instance_count_ != 1u) {
321 vertexStart:base_vertex_
322 vertexCount:vertex_count_
323 instanceCount:instance_count_
327 vertexStart:base_vertex_
328 vertexCount:vertex_count_];
331 id<MTLBuffer> mtl_index_buffer =
332 DeviceBufferMTL::Cast(*index_buffer_.buffer).GetMTLBuffer();
333 if (instance_count_ != 1u) {
335 indexCount:vertex_count_
336 indexType:index_type_
337 indexBuffer:mtl_index_buffer
338 indexBufferOffset:index_buffer_.range.offset
339 instanceCount:instance_count_
340 baseVertex:base_vertex_
344 indexCount:vertex_count_
345 indexType:index_type_
346 indexBuffer:mtl_index_buffer
347 indexBufferOffset:index_buffer_.range.offset];
353 [encoder_ popDebugGroup];
359 instance_count_ = 1u;
361 has_valid_pipeline_ =
false;
377bool RenderPassMTL::BindResource(
381 const std::shared_ptr<const ShaderMetadata>& metadata,
387bool RenderPassMTL::BindResource(
392 std::shared_ptr<const Texture>
texture,
393 const std::unique_ptr<const Sampler>& sampler) {
static TextureMTL & Cast(Texture &base)
To do anything rendering related with Impeller, you need a context.
CullMode GetCullMode() const
PrimitiveType GetPrimitiveType() const
PolygonMode GetPolygonMode() const
WindingOrder GetWindingOrder() const
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
id< MTLTexture > GetMTLTexture() const
static const uint8_t buffer[]
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)
constexpr MTLTriangleFillMode ToMTLTriangleFillMode(PolygonMode mode)
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)
constexpr MTLCullMode ToMTLCullMode(CullMode mode)
std::shared_ptr< const DeviceBuffer > buffer
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)
bool SetBuffer(ShaderStage stage, uint64_t index, uint64_t offset, id< MTLBuffer > buffer)
bool SetTexture(ShaderStage stage, uint64_t index, id< MTLTexture > texture)
Metadata required to bind a combined texture and sampler.
size_t texture_index
ext_res_0 is the Metal binding value.
static constexpr TRect MakeSize(const TSize< U > &size)