Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 Graphics & Games

WWDC21 · 30 min · Graphics & Games

Create image processing apps powered by Apple silicon

Discover how to optimize your image processing app for Apple silicon. Explore how to take advantage of Metal render command encoders, tile shading, unified memory architecture, and memoryless attachments. We’ll show you how to use Apple’s unique tile based deferred renderer architecture to create power efficient apps with low memory footprint, and take you through best practices when migrating your compute-based apps from discrete GPUs to Apple silicon.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 4 snippets

Memoryless attachments swift · at 10:53 ↗
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor()
let outputTexture = device.makeTexture(descriptor: textureDescriptor)

textureDescriptor.storageMode = .memoryless
let tempTexture = device.makeTexture(descriptor: textureDescriptor) 

let renderPassDesc = MTLRenderPassDescriptor()
renderPassDesc.colorAttachments[0].texture      = outputTexture
renderPassDesc.colorAttachments[0].loadAction   = .dontCare
renderPassDesc.colorAttachments[0].storeAction  = .store
renderPassDesc.colorAttachments[1].texture      = tempTexture
renderPassDesc.colorAttachments[1].loadAction   = .clear
renderPassDesc.colorAttachments[1].storeAction  = .dontCare

let renderPass = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDesc)
Uber-shaders impact on registers objectivec · at 12:25 ↗
fragment float4 processPixel(const constant ParamsStr* cs [[ buffer(0) ]])
{
  if (cs->inputIsHDR) {
    // do HDR stuff
  } else {
    // do non-HDR stuff
  }
  if (cs->tonemapEnabled) {
    // tone map
  }
}
Function constants for Uber-shaders objectivec · at 13:32 ↗
constant bool featureAEnabled[[function_constant(0)]];
constant bool featureBEnabled[[function_constant(1)]];

fragment float4 processPixel(...)
{
  if (featureAEnabled) {
    // do A stuff
  } else {
    // do not-A stuff
  }
  if (featureBEnabled) {
    // do B stuff
  }
}
Image processing filter graph objectivec · at 23:02 ↗
typedef struct
{
    float4 OPTexture        [[ color(0) ]];
    float4 IntermediateTex  [[ color(1) ]];
} FragmentIO;

fragment FragmentIO Unpack(RasterizerData in [[ stage_in ]],
                           texture2d<float, access::sample> srcImageTexture [[texture(0)]])
{
    FragmentIO out;
    
    //...
                         
    // Run necessary per-pixel operations
    out.OPTexture       = // assign computed value;
    out.IntermediateTex = // assign computed value;
    return out;
}

fragment FragmentIO CSC(RasterizerData in [[ stage_in ]], FragmentIO Input)
{
    FragmentIO out;

    //...    
    
    out.IntermediateTex = // assign computed value;
    return out;
}

Resources