• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrMtlRenderCommandEncoder_DEFINED
9 #define GrMtlRenderCommandEncoder_DEFINED
10 
11 #include <memory>
12 #include "src/gpu/GrSamplerState.h"
13 #include "src/gpu/mtl/GrMtlSampler.h"
14 #include "src/gpu/mtl/GrMtlUniformHandler.h"
15 #include "src/gpu/mtl/GrMtlUtil.h"
16 
17 class GrMtlSampler;
18 
19 #import <Metal/Metal.h>
20 
21 GR_NORETAIN_BEGIN
22 
23 /**
24  * Wraps a MTLRenderCommandEncoder object and associated tracked state
25  */
26 class GrMtlRenderCommandEncoder {
27 public:
Make(id<MTLRenderCommandEncoder> encoder)28     static std::unique_ptr<GrMtlRenderCommandEncoder> Make(id<MTLRenderCommandEncoder> encoder) {
29         return std::unique_ptr<GrMtlRenderCommandEncoder>(new GrMtlRenderCommandEncoder(encoder));
30     }
31 
setLabel(NSString * label)32     void setLabel(NSString* label) {
33         [fCommandEncoder setLabel:label];
34     }
35 
pushDebugGroup(NSString * string)36     void pushDebugGroup(NSString* string) {
37         [fCommandEncoder pushDebugGroup:string];
38     }
popDebugGroup()39     void popDebugGroup() {
40         [fCommandEncoder popDebugGroup];
41     }
insertDebugSignpost(NSString * string)42     void insertDebugSignpost(NSString* string) {
43         [fCommandEncoder insertDebugSignpost:string];
44     }
45 
setRenderPipelineState(id<MTLRenderPipelineState> pso)46     void setRenderPipelineState(id<MTLRenderPipelineState> pso) {
47         if (fCurrentRenderPipelineState != pso) {
48             [fCommandEncoder setRenderPipelineState:pso];
49             fCurrentRenderPipelineState = pso;
50         }
51     }
52 
setTriangleFillMode(MTLTriangleFillMode fillMode)53     void setTriangleFillMode(MTLTriangleFillMode fillMode) {
54         if (fCurrentTriangleFillMode != fillMode) {
55             [fCommandEncoder setTriangleFillMode:fillMode];
56             fCurrentTriangleFillMode = fillMode;
57         }
58     }
59 
setFrontFacingWinding(MTLWinding winding)60     void setFrontFacingWinding(MTLWinding winding) {
61         [fCommandEncoder setFrontFacingWinding:winding];
62     }
63 
setViewport(const MTLViewport & viewport)64     void setViewport(const MTLViewport& viewport) {
65         [fCommandEncoder setViewport:viewport];
66     }
67 
setVertexBuffer(id<MTLBuffer> buffer,NSUInteger offset,NSUInteger index)68     void setVertexBuffer(id<MTLBuffer> buffer, NSUInteger offset, NSUInteger index) {
69         if (@available(macOS 10.11, iOS 8.3, *)) {
70             if (fCurrentVertexBuffer[index] == buffer) {
71                 this->setVertexBufferOffset(offset, index);
72                 return;
73             }
74         }
75         if (fCurrentVertexBuffer[index] != buffer || fCurrentVertexOffset[index] != offset) {
76             [fCommandEncoder setVertexBuffer:buffer
77                                       offset:offset
78                                      atIndex:index];
79             fCurrentVertexBuffer[index] = buffer;
80             fCurrentVertexOffset[index] = offset;
81         }
82     }
setVertexBufferOffset(NSUInteger offset,NSUInteger index)83     void setVertexBufferOffset(NSUInteger offset, NSUInteger index)
84             SK_API_AVAILABLE(macos(10.11), ios(8.3)) {
85         if (fCurrentVertexOffset[index] != offset) {
86             [fCommandEncoder setVertexBufferOffset:offset
87                                            atIndex:index];
88             fCurrentVertexOffset[index] = offset;
89         }
90     }
91 
setFragmentBuffer(id<MTLBuffer> buffer,NSUInteger offset,NSUInteger index)92     void setFragmentBuffer(id<MTLBuffer> buffer, NSUInteger offset, NSUInteger index) {
93         if (@available(macOS 10.11, iOS 8.3, *)) {
94             if (fCurrentFragmentBuffer[index] == buffer) {
95                 this->setFragmentBufferOffset(offset, index);
96                 return;
97             }
98         }
99         if (fCurrentFragmentBuffer[index] != buffer || fCurrentFragmentOffset[index] != offset) {
100             [fCommandEncoder setFragmentBuffer:buffer
101                                         offset:offset
102                                        atIndex:index];
103             fCurrentFragmentBuffer[index] = buffer;
104             fCurrentFragmentOffset[index] = offset;
105         }
106     }
setFragmentBufferOffset(NSUInteger offset,NSUInteger index)107     void setFragmentBufferOffset(NSUInteger offset, NSUInteger index)
108             SK_API_AVAILABLE(macos(10.11), ios(8.3)) {
109         if (fCurrentFragmentOffset[index] != offset) {
110             [fCommandEncoder setFragmentBufferOffset:offset
111                                              atIndex:index];
112             fCurrentFragmentOffset[index] = offset;
113         }
114     }
115 
setVertexBytes(const void * bytes,NSUInteger length,NSUInteger index)116     void setVertexBytes(const void* bytes, NSUInteger length, NSUInteger index)
117             SK_API_AVAILABLE(macos(10.11), ios(8.3)) {
118         [fCommandEncoder setVertexBytes:bytes
119                                  length:length
120                                 atIndex:index];
121     }
setFragmentBytes(const void * bytes,NSUInteger length,NSUInteger index)122     void setFragmentBytes(const void* bytes, NSUInteger length, NSUInteger index)
123             SK_API_AVAILABLE(macos(10.11), ios(8.3)) {
124         [fCommandEncoder setFragmentBytes:bytes
125                                    length:length
126                                   atIndex:index];
127     }
128 
setFragmentTexture(id<MTLTexture> texture,NSUInteger index)129     void setFragmentTexture(id<MTLTexture> texture, NSUInteger index) {
130         SkASSERT(index < 16);
131         if (fCurrentTexture[index] != texture) {
132             [fCommandEncoder setFragmentTexture:texture
133                                          atIndex:index];
134             fCurrentTexture[index] = texture;
135         }
136     }
setFragmentSamplerState(GrMtlSampler * sampler,NSUInteger index)137     void setFragmentSamplerState(GrMtlSampler* sampler, NSUInteger index) {
138         if (fCurrentSampler[index] != sampler) {
139             [fCommandEncoder setFragmentSamplerState: sampler->mtlSampler()
140                                          atIndex: index];
141             fCurrentSampler[index] = sampler;
142         }
143     }
144 
setBlendColor(SkPMColor4f blendConst)145     void setBlendColor(SkPMColor4f blendConst) {
146         [fCommandEncoder setBlendColorRed: blendConst.fR
147                                     green: blendConst.fG
148                                      blue: blendConst.fB
149                                     alpha: blendConst.fA];
150     }
151 
setStencilFrontBackReferenceValues(uint32_t frontReferenceValue,uint32_t backReferenceValue)152     void setStencilFrontBackReferenceValues(uint32_t frontReferenceValue,
153                                             uint32_t backReferenceValue)
154             SK_API_AVAILABLE(macos(10.11), ios(9.0)) {
155         [fCommandEncoder
156                 setStencilFrontReferenceValue:frontReferenceValue
157                            backReferenceValue:backReferenceValue];
158     }
setStencilReferenceValue(uint32_t referenceValue)159     void setStencilReferenceValue(uint32_t referenceValue) {
160         [fCommandEncoder setStencilReferenceValue:referenceValue];
161     }
setDepthStencilState(id<MTLDepthStencilState> depthStencilState)162     void setDepthStencilState(id<MTLDepthStencilState> depthStencilState) {
163         if (depthStencilState != fCurrentDepthStencilState) {
164             [fCommandEncoder setDepthStencilState:depthStencilState];
165             fCurrentDepthStencilState = depthStencilState;
166         }
167     }
168 
setScissorRect(const MTLScissorRect & scissorRect)169     void setScissorRect(const MTLScissorRect& scissorRect) {
170         if (fCurrentScissorRect.x != scissorRect.x ||
171             fCurrentScissorRect.y != scissorRect.y ||
172             fCurrentScissorRect.width != scissorRect.width ||
173             fCurrentScissorRect.height != scissorRect.height) {
174             [fCommandEncoder setScissorRect:scissorRect];
175             fCurrentScissorRect = scissorRect;
176         }
177     }
178 
drawPrimitives(MTLPrimitiveType primitiveType,NSUInteger vertexStart,NSUInteger vertexCount)179     void drawPrimitives(MTLPrimitiveType primitiveType, NSUInteger vertexStart,
180                         NSUInteger vertexCount) {
181         [fCommandEncoder drawPrimitives:primitiveType
182                             vertexStart:vertexStart
183                             vertexCount:vertexCount];
184     }
drawPrimitives(MTLPrimitiveType primitiveType,NSUInteger vertexStart,NSUInteger vertexCount,NSUInteger instanceCount,NSUInteger baseInstance)185     void drawPrimitives(MTLPrimitiveType primitiveType, NSUInteger vertexStart,
186                         NSUInteger vertexCount, NSUInteger instanceCount,
187                         NSUInteger baseInstance) SK_API_AVAILABLE(macos(10.11), ios(9.0)) {
188         [fCommandEncoder drawPrimitives:primitiveType
189                             vertexStart:vertexStart
190                             vertexCount:vertexCount
191                           instanceCount:instanceCount
192                            baseInstance:baseInstance];
193     }
drawPrimitives(MTLPrimitiveType primitiveType,id<MTLBuffer> indirectBuffer,NSUInteger indirectBufferOffset)194     void drawPrimitives(MTLPrimitiveType primitiveType, id<MTLBuffer> indirectBuffer,
195                         NSUInteger indirectBufferOffset) SK_API_AVAILABLE(macos(10.11), ios(9.0)) {
196         [fCommandEncoder drawPrimitives:primitiveType
197                          indirectBuffer:indirectBuffer
198                    indirectBufferOffset:indirectBufferOffset];
199     }
200 
drawIndexedPrimitives(MTLPrimitiveType primitiveType,NSUInteger indexCount,MTLIndexType indexType,id<MTLBuffer> indexBuffer,NSUInteger indexBufferOffset)201     void drawIndexedPrimitives(MTLPrimitiveType primitiveType, NSUInteger indexCount,
202                                MTLIndexType indexType, id<MTLBuffer> indexBuffer,
203                                NSUInteger indexBufferOffset) {
204         [fCommandEncoder drawIndexedPrimitives:primitiveType
205                                     indexCount:indexCount
206                                      indexType:indexType
207                                    indexBuffer:indexBuffer
208                              indexBufferOffset:indexBufferOffset];
209     }
drawIndexedPrimitives(MTLPrimitiveType primitiveType,NSUInteger indexCount,MTLIndexType indexType,id<MTLBuffer> indexBuffer,NSUInteger indexBufferOffset,NSUInteger instanceCount,NSInteger baseVertex,NSUInteger baseInstance)210     void drawIndexedPrimitives(MTLPrimitiveType primitiveType, NSUInteger indexCount,
211                                MTLIndexType indexType, id<MTLBuffer> indexBuffer,
212                                NSUInteger indexBufferOffset,
213                                NSUInteger instanceCount,
214                                NSInteger baseVertex,
215                                NSUInteger baseInstance) SK_API_AVAILABLE(macos(10.11), ios(9.0)) {
216         [fCommandEncoder drawIndexedPrimitives:primitiveType
217                                     indexCount:indexCount
218                                      indexType:indexType
219                                    indexBuffer:indexBuffer
220                              indexBufferOffset:indexBufferOffset
221                                  instanceCount:instanceCount
222                                     baseVertex:baseVertex
223                                   baseInstance:baseInstance];
224     }
drawIndexedPrimitives(MTLPrimitiveType primitiveType,MTLIndexType indexType,id<MTLBuffer> indexBuffer,NSUInteger indexBufferOffset,id<MTLBuffer> indirectBuffer,NSUInteger indirectBufferOffset)225     void drawIndexedPrimitives(MTLPrimitiveType primitiveType,
226                                MTLIndexType indexType, id<MTLBuffer> indexBuffer,
227                                NSUInteger indexBufferOffset, id<MTLBuffer> indirectBuffer,
228                                NSUInteger indirectBufferOffset)
229             SK_API_AVAILABLE(macos(10.11), ios(9.0)) {
230         [fCommandEncoder drawIndexedPrimitives:primitiveType
231                                      indexType:indexType
232                                    indexBuffer:indexBuffer
233                              indexBufferOffset:indexBufferOffset
234                                 indirectBuffer:indirectBuffer
235                           indirectBufferOffset:indirectBufferOffset];
236     }
237 
endEncoding()238     void endEncoding() {
239         [fCommandEncoder endEncoding];
240     }
241 
242 private:
GrMtlRenderCommandEncoder(id<MTLRenderCommandEncoder> encoder)243     GrMtlRenderCommandEncoder(id<MTLRenderCommandEncoder> encoder)
244         : fCommandEncoder(encoder) {}
245 
246     id<MTLRenderCommandEncoder> fCommandEncoder = nil;
247 
248     __weak id<MTLRenderPipelineState> fCurrentRenderPipelineState = nil;
249     __weak id<MTLDepthStencilState> fCurrentDepthStencilState = nil;
250     __weak id<MTLBuffer> fCurrentVertexBuffer[2 + GrMtlUniformHandler::kUniformBindingCount];
251     NSUInteger fCurrentVertexOffset[2 + GrMtlUniformHandler::kUniformBindingCount];
252     __weak id<MTLBuffer> fCurrentFragmentBuffer[GrMtlUniformHandler::kUniformBindingCount];
253     NSUInteger fCurrentFragmentOffset[2 + GrMtlUniformHandler::kUniformBindingCount];
254     __weak id<MTLTexture> fCurrentTexture[GrSamplerState::kNumUniqueSamplers];
255     GrMtlSampler* fCurrentSampler[GrSamplerState::kNumUniqueSamplers] = { 0 };
256     MTLScissorRect fCurrentScissorRect = { 0, 0, 0, 0 };
257     MTLTriangleFillMode fCurrentTriangleFillMode = (MTLTriangleFillMode)-1;
258 };
259 
260 GR_NORETAIN_END
261 
262 #endif
263