Optimizing Metal: Stitch several Metal functions into a single shader using MTLFunctionStitchingGraph

Stitching Graph

In this post I’ll show how to use Metal’s new feature MTLFunctionStitchingGraph to create an image processing pipeline in a single shader instead of chain of several GPU kernels. In terms of common GPU practices it is a new option for creating uber-shaders in runtime using precompiled Metal functions. And for large pipelines it can be much more efficient than compiling the whole shader from source in runtime and less error prone.

With this post I start a new series of articles about Metal optimizations. I’ll cover several topics which I found interesting and useful for Metal pipeline creation and encoding which can help you to process your pipelines faster. And I’ll try to explain them in details so that you can use them in your projects.

This technology is used inside Apple’s MPSGraph but MPSGraph doesn’t allow to inject custom shaders in it and works only with multidimensional arrays. I’ll show how to create MPSGraph like processing but with plain old Metal textures and of course your own shaders.

read more

Code Signing Hell with XCFramework

XCFramework Code Signing

If you’ve ever dealt with code signing issues in iOS or macOS apps, you know how challenging it can be. Code signing is typically something that just works, but when you encounter errors, it can be difficult to determine what went wrong. Seems that code signing problems are so unique that it can be hard to find solutions in Google, and you have to figure out the problem on your own.

This post is about one such unique issue that I encountered. I don’t know if anyone else has faced the same problem, as I couldn’t find any information about it. The issue involved signing an internal XCFramework with a C++ library that was distributed as a Swift Package, added as a dependency to another package, and only appeared on macOS.

read more

Shaders Explained: Dithering


Three months ago I launched a small app on the App Store which allows users to edit photos in a stylish old-school way. The processing technology is called dithering. It is a very old technic from the days when computers were capable to show very limited amount of colors. But developers and artists always wanted to go further existing software and hardware limits so they invented such algorithms. Dithering makes images look like they use much extended color palette than they actually has and missing shades are emulated through placing pixels with allowed colors in proper way. Look at the image in the header. Central part of it uses only black and white pixels and not a single grey one but because the amount of black and white pixels is different in different areas the whole image looks like it uses much extended grayscale color palette. In this post I’ll explain how it works and how to implement it in Metal.

read more

SwiftUI Gradient Builder

Gradient Builder

In the last post about gradient shader I covered GPU part of gradient rendering in Metal but if you’ll use it in your apps it won’t make enough sense without giving user the ability to build a gradient in UI. I’m a big fan of SwiftUI and in my opinion current state of this new UI framework including iOS16 API gives all the necessary tools to build apps of any kinds and complexity. Today I’ll show you how to create this fancy control to construct gradients purely on SwiftUI.

read more

Shaders Explained: Gradients


Write functional and performant shaders is the basic skill for GPU developer no matter what framework or engine he or she uses. But there are not much information about it on the web especially if we talk about Metal. Though shading languages are pretty similar and hours spent on ShaderToy can give you some inspiration and knowledge about OpenGL shaders and you can easily convert them to Metal I personally feel a huge lack of structured information about shader writing. So in this article and others under the title Shaders Explained I’ll go through different shaders in detail, teach you some shader technics and explain my motivation under each line of code. Hope that it will make you and me better shader programmers.

For the first article I chose a pretty basic gradient shader which I implemented for one of my personal projects. Gradients are at the very heart of GPU programming and every shader tutorial starts with the triangle colored with gradient from red, green and blue. But we won’t build yet another Hello Triangle tutorial. Instead I’ll show you how to make gradient shader to fill texture with arbitrary gradient stops with different locations and colors for three basic gradient types. Additionally we’ll add support for rotation. Actually we will implement the most part of CAGradientLayer or SwiftUI Gradient from scratch with broad focus on its GPU side.

read more

Build Swift Executable with Metal Library

Metal Library

When you build a Swift Package Xcode will compile all your .swift files to single executable file and process all other resources which includes Assets catalogue, Core Data files, Storyboards and many more including all .metal files. All these resources will be put in package Bundle and you have access to them through Bundle.module if you add them to resources array in package’s target.

But it will work only for library product type. If you want to build a Swift executable product resources won’t be processed or copied to Bundle because there is no actual Bundle there. So Swift executable is limited to only .swift files so you can’t build executable which will run you Metal shaders. Let’s try to fix it!

read more