39#import <Metal/Metal.h>
46 size_t resourceBudget)
47 :
ResourceProvider(sharedContext, singleOwner, recorderID, resourceBudget) {}
55 uint64_t renderPassKey =
59 static const char* kLoadMSAAShaderText = R
"(
60 #include <metal_stdlib>
61 #include <simd/simd.h>
62 using namespace metal;
65 float4 position [[position]];
68 vertex VertexOutput vertexMain(uint vertexID [[vertex_id]]) {
70 float2 position = float2(float(vertexID >> 1), float(vertexID & 1));
71 out.position = float4(2.0 * position - 1.0, 0.0, 1.0);
75 fragment float4 fragmentMain(VertexOutput in [[stage_in]],
76 texture2d<half> colorMap [[texture(0)]]) {
77 uint2 coords = uint2(in.position.x, in.position.y);
78 half4 colorSample = colorMap.read(coords);
79 return float4(colorSample);
84 "LoadMSAAFromResolve",
88 sk_cfp<id<MTLDepthStencilState>> ignoreDS =
89 this->findOrCreateCompatibleDepthStencilState({});
91 std::string pipelineLabel =
"LoadMSAAFromResolve + ";
95 {mtlLibrary.get(),
"vertexMain"},
98 {mtlLibrary.get(),
"fragmentMain"},
105 fLoadMSAAPipelines.set(renderPassKey, pipeline);
116 std::string vsMSL, fsMSL;
120 settings.fForceNoRTFlip =
true;
137 std::string& fsSkSL = fsSkSLInfo.
fSkSL;
154 const std::string& vsSkSL = vsSkSLInfo.fSkSL;
166 this->mtlSharedContext(), vsSkSLInfo.fLabel, vsMSL, errorHandler);
168 this->mtlSharedContext(), fsSkSLInfo.
fLabel, fsMSL, errorHandler);
170 sk_cfp<id<MTLDepthStencilState>> dss =
171 this->findOrCreateCompatibleDepthStencilState(
step->depthStencilSettings());
173#if defined(GRAPHITE_TEST_UTILS)
174 GraphicsPipeline::PipelineInfo pipelineInfo = {pipelineDesc.
renderStepID(),
180 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = &pipelineInfo;
182 GraphicsPipeline::PipelineInfo* pipelineInfoPtr =
nullptr;
184 std::string pipelineLabel =
188 {vsLibrary.get(),
"vertexMain"},
189 step->vertexAttributes(),
190 step->instanceAttributes(),
191 {fsLibrary.get(),
"fragmentMain"},
193 step->depthStencilSettings().fStencilReferenceValue,
201 sk_cfp<id<MTLLibrary>> library;
202 std::string entryPointName;
209 nativeShader.fSource,
211 if (library == nil) {
214 entryPointName = std::move(nativeShader.fEntryPoint);
235 entryPointName =
"computeMain";
239 {library.get(), std::move(entryPointName)});
249 CFTypeRef mtlHandleTexture =
texture.getMtlTexture();
250 if (!mtlHandleTexture) {
253 sk_cfp<id<MTLTexture>> mtlTexture = sk_ret_cfp((id<MTLTexture>)mtlHandleTexture);
257 std::move(mtlTexture));
263 std::string_view label) {
264 return MtlBuffer::Make(this->mtlSharedContext(), size,
type, accessPattern, std::move(label));
275MTLCompareFunction compare_op_to_mtl(
CompareOp op) {
278 return MTLCompareFunctionAlways;
280 return MTLCompareFunctionNever;
282 return MTLCompareFunctionGreater;
284 return MTLCompareFunctionGreaterEqual;
286 return MTLCompareFunctionLess;
288 return MTLCompareFunctionLessEqual;
290 return MTLCompareFunctionEqual;
292 return MTLCompareFunctionNotEqual;
296MTLStencilOperation stencil_op_to_mtl(
StencilOp op) {
299 return MTLStencilOperationKeep;
301 return MTLStencilOperationZero;
303 return MTLStencilOperationReplace;
305 return MTLStencilOperationInvert;
307 return MTLStencilOperationIncrementWrap;
309 return MTLStencilOperationDecrementWrap;
311 return MTLStencilOperationIncrementClamp;
313 return MTLStencilOperationDecrementClamp;
317MTLStencilDescriptor* stencil_face_to_mtl(DepthStencilSettings::Face face) {
318 MTLStencilDescriptor*
result = [[MTLStencilDescriptor alloc]
init];
319 result.stencilCompareFunction = compare_op_to_mtl(face.fCompareOp);
320 result.readMask = face.fReadMask;
321 result.writeMask = face.fWriteMask;
322 result.depthStencilPassOperation = stencil_op_to_mtl(face.fDepthStencilPassOp);
323 result.stencilFailureOperation = stencil_op_to_mtl(face.fStencilFailOp);
328sk_cfp<id<MTLDepthStencilState>> MtlResourceProvider::findOrCreateCompatibleDepthStencilState(
329 const DepthStencilSettings& depthStencilSettings) {
330 sk_cfp<id<MTLDepthStencilState>>* depthStencilState;
331 depthStencilState = fDepthStencilStates.find(depthStencilSettings);
332 if (!depthStencilState) {
333 MTLDepthStencilDescriptor*
desc = [[MTLDepthStencilDescriptor alloc]
init];
334 SkASSERT(depthStencilSettings.fDepthTestEnabled ||
336 desc.depthCompareFunction = compare_op_to_mtl(depthStencilSettings.fDepthCompareOp);
337 if (depthStencilSettings.fDepthTestEnabled) {
338 desc.depthWriteEnabled = depthStencilSettings.fDepthWriteEnabled;
340 if (depthStencilSettings.fStencilTestEnabled) {
341 desc.frontFaceStencil = stencil_face_to_mtl(depthStencilSettings.fFrontStencil);
342 desc.backFaceStencil = stencil_face_to_mtl(depthStencilSettings.fBackStencil);
345 sk_cfp<id<MTLDepthStencilState>> dss(
346 [this->mtlSharedContext()->
device() newDepthStencilStateWithDescriptor:
desc]);
347 depthStencilState = fDepthStencilStates.set(depthStencilSettings, std::move(dss));
351 return *depthStencilState;
362 return BackendTexture(dimensions, (CFTypeRef)
texture.release());
367 CFTypeRef texHandle =
texture.getMtlTexture();
368 SkCFSafeRelease(texHandle);
static int step(int x, SkScalar min, SkScalar max)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
const char * c_str() const
skgpu::ShaderErrorHandler * shaderErrorHandler() const
const ResourceBindingRequirements & resourceBindingRequirements() const
bool storageBufferPreferred() const
const SkSL::ShaderCaps * shaderCaps() const
const ComputeStep * computeStep() const
bool supportsNativeShader() const
virtual NativeShaderSource nativeShaderSource(NativeShaderFormat) const
const char * name() const
UniquePaintParamsID paintParamsID() const
uint32_t renderStepID() const
static sk_sp< Buffer > Make(const MtlSharedContext *, size_t size, BufferType type, AccessPattern, std::string_view label)
uint64_t getRenderPassDescKey(const RenderPassDesc &) const
static sk_sp< MtlComputePipeline > Make(const MtlSharedContext *, const std::string &label, MSLFunction computeMain)
static sk_sp< MtlGraphicsPipeline > Make(const MtlSharedContext *, const std::string &label, MSLFunction vertexMain, SkSpan< const Attribute > vertexAttrs, SkSpan< const Attribute > instanceAttrs, MSLFunction fragmentMain, sk_cfp< id< MTLDepthStencilState > >, uint32_t stencilRefValue, const BlendInfo &blendInfo, const RenderPassDesc &, PipelineInfo *pipelineInfo)
sk_sp< GraphicsPipeline > createGraphicsPipeline(const RuntimeEffectDictionary *, const GraphicsPipelineDesc &, const RenderPassDesc &) override
sk_sp< Buffer > createBuffer(size_t size, BufferType type, AccessPattern, std::string_view label) override
sk_sp< Texture > createTexture(SkISize, const TextureInfo &, skgpu::Budgeted) override
sk_sp< Sampler > createSampler(const SamplerDesc &) override
void onDeleteBackendTexture(const BackendTexture &) override
sk_sp< MtlGraphicsPipeline > findOrCreateLoadMSAAPipeline(const RenderPassDesc &)
BackendTexture onCreateBackendTexture(SkISize dimensions, const TextureInfo &) override
sk_sp< Texture > createWrappedTexture(const BackendTexture &) override
MtlResourceProvider(SharedContext *sharedContext, SingleOwner *, uint32_t recorderID, size_t resourceBudget)
sk_sp< ComputePipeline > createComputePipeline(const ComputePipelineDesc &) override
static sk_sp< MtlSampler > Make(const MtlSharedContext *, const SkSamplingOptions &samplingOptions, SkTileMode xTileMode, SkTileMode yTileMode)
const MtlCaps & mtlCaps() const
static sk_sp< Texture > Make(const MtlSharedContext *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted)
static sk_cfp< id< MTLTexture > > MakeMtlTexture(const MtlSharedContext *, SkISize dimensions, const TextureInfo &)
static sk_sp< Texture > MakeWrapped(const MtlSharedContext *, SkISize dimensions, const TextureInfo &, sk_cfp< id< MTLTexture > >)
const RenderStep * lookup(uint32_t uniqueID) const
SharedContext * fSharedContext
const Caps * caps() const
ShaderCodeDictionary * shaderCodeDictionary()
const RendererProvider * rendererProvider() const
VertSkSLInfo BuildVertexSkSL(const ResourceBindingRequirements &bindingReqs, const RenderStep *step, bool useStorageBuffers, bool defineLocalCoordsVarying)
std::string BuildComputeSkSL(const Caps *caps, const ComputeStep *step)
FragSkSLInfo BuildFragmentSkSL(const Caps *caps, const ShaderCodeDictionary *dict, const RuntimeEffectDictionary *rteDict, const RenderStep *step, UniquePaintParamsID paintID, bool useStorageBuffers, skgpu::Swizzle writeSwizzle)
std::string GetPipelineLabel(const ShaderCodeDictionary *dict, const RenderPassDesc &renderPassDesc, const RenderStep *renderStep, UniquePaintParamsID paintID)
sk_cfp< id< MTLLibrary > > MtlCompileShaderLibrary(const MtlSharedContext *sharedContext, std::string_view label, std::string_view msl, ShaderErrorHandler *errorHandler)
bool SkSLToMSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *msl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
bool fRequiresLocalCoords
SkString toString() const
SkTileMode tileModeX() const
SkSamplingOptions samplingOptions() const
SkTileMode tileModeY() const