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