18#if !__has_feature(objc_arc)
19#error This file must be compiled with Arc. Use -fobjc-arc flag
25 id<MTLCommandBuffer> mtlCommandBuffer;
26#if GR_METAL_SDK_VERSION >= 230
27 if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
28 MTLCommandBufferDescriptor*
desc = [[MTLCommandBufferDescriptor alloc]
init];
29 desc.errorOptions = MTLCommandBufferErrorOptionEncoderExecutionStatus;
30 mtlCommandBuffer = [
queue commandBufferWithDescriptor:
desc];
32 mtlCommandBuffer = [
queue commandBuffer];
35 mtlCommandBuffer = [
queue commandBuffer];
37 if (nil == mtlCommandBuffer) {
41#ifdef SK_ENABLE_MTL_DEBUG_INFO
42 mtlCommandBuffer.label =
@"GrMtlCommandBuffer::Make";
49 this->endAllEncoding();
59 fTrackedResources.
clear();
60 fTrackedGrBuffers.
clear();
61 fTrackedGrSurfaces.clear();
65 if (fActiveBlitCommandEncoder) {
66 return fActiveBlitCommandEncoder;
69 this->endAllEncoding();
70 if (fCmdBuffer.status != MTLCommandBufferStatusNotEnqueued) {
71 NSLog(
@"GrMtlCommandBuffer: tried to create MTLBlitCommandEncoder while in invalid state.");
74 fActiveBlitCommandEncoder = [fCmdBuffer blitCommandEncoder];
77 return fActiveBlitCommandEncoder;
80static bool compatible(
const MTLRenderPassAttachmentDescriptor* first,
81 const MTLRenderPassAttachmentDescriptor* second,
90 bool renderTargetsMatch = (first.texture == second.texture);
91 bool storeActionsValid = first.storeAction == MTLStoreActionStore ||
92 first.storeAction == MTLStoreActionDontCare;
93 bool loadActionsValid = second.loadAction == MTLLoadActionLoad ||
94 second.loadAction == MTLLoadActionDontCare;
95 bool secondDoesntSampleFirst = (!pipelineState ||
100 bool secondStoreValid =
true;
101 if (second.storeAction == MTLStoreActionDontCare) {
102 secondStoreValid = (first.storeAction == MTLStoreActionDontCare);
105 }
else if (second.storeAction == MTLStoreActionStore) {
106 if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
107 secondStoreValid = (first.storeAction == MTLStoreActionStore ||
108 first.storeAction == MTLStoreActionStoreAndMultisampleResolve);
110 secondStoreValid = (first.storeAction == MTLStoreActionStore);
114 }
else if (second.storeAction == MTLStoreActionMultisampleResolve) {
115 if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
116 secondStoreValid = (first.resolveTexture == second.resolveTexture) &&
117 (first.storeAction == MTLStoreActionMultisampleResolve ||
118 first.storeAction == MTLStoreActionStoreAndMultisampleResolve);
120 secondStoreValid = (first.resolveTexture == second.resolveTexture) &&
121 (first.storeAction == MTLStoreActionMultisampleResolve);
125 storeActionsValid = secondStoreValid;
127 if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
128 if (second.storeAction == MTLStoreActionStoreAndMultisampleResolve) {
129 secondStoreValid = (first.resolveTexture == second.resolveTexture) &&
130 (first.storeAction == MTLStoreActionStoreAndMultisampleResolve);
137 storeActionsValid = secondStoreValid;
142 return renderTargetsMatch &&
143 (nil == first.texture ||
144 (storeActionsValid && loadActionsValid && secondDoesntSampleFirst && secondStoreValid));
150 if (nil != fPreviousRenderPassDescriptor) {
151 if (
compatible(fPreviousRenderPassDescriptor.colorAttachments[0],
152 descriptor.colorAttachments[0], pipelineState) &&
153 compatible(fPreviousRenderPassDescriptor.stencilAttachment,
154 descriptor.stencilAttachment, pipelineState)) {
155 return fActiveRenderCommandEncoder.get();
163 MTLRenderPassDescriptor* descriptor,
165 this->endAllEncoding();
166 if (fCmdBuffer.status != MTLCommandBufferStatusNotEnqueued) {
167 NSLog(
@"GrMtlCommandBuffer: tried to create MTLRenderCommandEncoder while in bad state.");
171 [fCmdBuffer renderCommandEncoderWithDescriptor:descriptor]);
175 fPreviousRenderPassDescriptor = descriptor;
178 return fActiveRenderCommandEncoder.get();
182 this->endAllEncoding();
183 if ([fCmdBuffer status] != MTLCommandBufferStatusNotEnqueued) {
184 NSLog(
@"GrMtlCommandBuffer: Tried to commit command buffer while in invalid state.\n");
190#if defined(SK_BUILD_FOR_IOS) && defined(SK_METAL_WAIT_UNTIL_SCHEDULED)
194 [fCmdBuffer waitUntilScheduled];
198 if ([fCmdBuffer status] == MTLCommandBufferStatusError) {
199 SkDebugf(
"Error submitting command buffer.\n");
205 return ([fCmdBuffer status] != MTLCommandBufferStatusError);
208void GrMtlCommandBuffer::endAllEncoding() {
209 if (fActiveRenderCommandEncoder) {
210 fActiveRenderCommandEncoder->endEncoding();
211 fActiveRenderCommandEncoder.reset();
212 fPreviousRenderPassDescriptor = nil;
214 if (fActiveBlitCommandEncoder) {
215 [fActiveBlitCommandEncoder endEncoding];
216 fActiveBlitCommandEncoder = nil;
222 this->endAllEncoding();
223 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
232 this->endAllEncoding();
234 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
static bool compatible(const MTLRenderPassAttachmentDescriptor *first, const MTLRenderPassAttachmentDescriptor *second, const GrMtlPipelineState *pipelineState)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
GrMtlRenderCommandEncoder * getRenderCommandEncoder(MTLRenderPassDescriptor *, const GrMtlPipelineState *, GrMtlOpsRenderPass *opsRenderPass)
void addResource(const sk_sp< const GrManagedResource > &resource)
void waitUntilCompleted()
id< MTLBlitCommandEncoder > getBlitCommandEncoder()
~GrMtlCommandBuffer() override
void encodeWaitForEvent(sk_sp< GrMtlEvent >, uint64_t value)
static sk_sp< GrMtlCommandBuffer > Make(id< MTLCommandQueue > queue)
bool commit(bool waitUntilCompleted)
void encodeSignalEvent(sk_sp< GrMtlEvent >, uint64_t value)
void callFinishedCallbacks()
void initRenderState(GrMtlRenderCommandEncoder *)
bool doesntSampleAttachment(const MTLRenderPassAttachmentDescriptor *) const
static std::unique_ptr< GrMtlRenderCommandEncoder > Make(id< MTLRenderCommandEncoder > encoder)
const uint8_t uint32_t uint32_t GError ** error
#define TRACE_EVENT0(category_group, name)