605 working with metal advanced
TRANSCRIPT
-
8/10/2019 605 Working With Metal Advanced
1/161
2014 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
#WWD
Working With MetalAdvanced
Graphics and Games
Session 605
Gokhan Avkarogullari
GPU Software
Aaftab Munshi
GPU Software
Serhat Tekin
GPU Software
-
8/10/2019 605 Working With Metal Advanced
2/161
Agenda
Introduction to Metal
Fundamentals of Metal
Building a Metal application
Metal shading language
Advanced Metal Deep dive into creating a graphics application with Metal
Data-Parallel Computing with Metal
Developer Tools Review
-
8/10/2019 605 Working With Metal Advanced
3/161
Creating Multi-Pass Graphics
Applications with Metal
-
8/10/2019 605 Working With Metal Advanced
4/161
Graphics Application with Multiple Passe
Multiple framebuffer configurations
Render to off-screen and on-screen textures
Meshes that are used with multiple shaders
Multiple encoders
-
8/10/2019 605 Working With Metal Advanced
5/161
Deferred Lighting with Shadow Maps
Shadow Map
Depth-only render from the perspective of the directional light
Deferred Lighting
Multiple render targets
Framebuffer fetch for in-place light accumulation Stencil buffer for light culling
-
8/10/2019 605 Working With Metal Advanced
6/161
Deferred Lighting with Shadow Maps
Shadow Map
Depth-only render from the perspective of the directional light
Deferred Lighting
Multiple render targets
Framebuffer fetch for in-place light accumulation Stencil buffer for light culling
Dont worry about the algorithm
Focus on the details of how the API is used
-
8/10/2019 605 Working With Metal Advanced
7/161
Deferred Lighting with Shadow Maps
Command Queue
Render Command Encoderfor Deferred Lighting Pass
Command Buffer #1
Render Command Encoderfor Shadow Pass
Pipeline State
Shaders Blend, etc.
Depth State
Buffers
Textures
Pipeline State
Shaders Blend, etc.
Depth State
Buffers
Textures
-
8/10/2019 605 Working With Metal Advanced
8/161
Demo
Deferred Lighting
-
8/10/2019 605 Working With Metal Advanced
9/161
Render Setup
Actions to take once at application start time
Actions that are taken as needed
Level load time
Texture streaming
Mesh streamingActions to take every frame
Actions to take every render-to-texture pass
-
8/10/2019 605 Working With Metal Advanced
10/161
Render SetupDo once
Create device
Create command queue
-
8/10/2019 605 Working With Metal Advanced
11/161
Render SetupDo as needed
Create framebuffer textures
Create render pass descriptors
Create buffers for meshes
Create render pipeline objects
Create texturesCreate state objects
Create uniform buffers
-
8/10/2019 605 Working With Metal Advanced
12/161
Render SetupDo every frame
Create command buffer
Update frame-based uniform buffers
Submit command buffer
-
8/10/2019 605 Working With Metal Advanced
13/161
Render SetupDo every render to texture pass
Create command encoder
Draw many times
Update uniform buffers
Set states
Make draw calls
-
8/10/2019 605 Working With Metal Advanced
14/161
Render SetupDo as needed
Create framebuffer textures
Create render pass descriptors
Create buffers for meshes
Create render pipeline objects
Create texturesCreate state objects
Create uniform buffers
-
8/10/2019 605 Working With Metal Advanced
15/161
Render SetupA word on descriptors
Descriptors are like blueprints
Once the object is created the connection to the descriptor is gone
Changing descriptors will not change the object
Same descriptor can be reused to create another object
Descriptor can be modified and then reused to create a new object
-
8/10/2019 605 Working With Metal Advanced
16/161
Render SetupCreating render pass descriptors
MTLRenderPassDescriptor
Color Color
Color Color
Depth Stencil
-
8/10/2019 605 Working With Metal Advanced
17/161
Render SetupCreating render pass descriptors
MTLRenderPassDes
Color Co
Color Co
Depth Ste
-
8/10/2019 605 Working With Metal Advanced
18/161
Render SetupCreating render pass descriptors
MTLRenderPassAttachmentDescriptor
MTLTexture
MTLResolveTexture
loadActionstoreAction
-
MTLRenderPassDes
Color Co
Color Co
Depth Ste
-
8/10/2019 605 Working With Metal Advanced
19/161
Render SetupCreating render pass descriptors
Texture
MTLRenderPassAttachmentDescriptor
MTLTexture
MTLResolveTexture
loadActionstoreAction
-
MTLRenderPassDes
Color Co
Color Co
Depth Ste
-
8/10/2019 605 Working With Metal Advanced
20/161
Render SetupRender pass descriptor for shadowMap pass
shadowRenderPassDescriptor
Depth
-
8/10/2019 605 Working With Metal Advanced
21/161
Render SetupRender pass descriptor for shadowMap pass
// Create texture
id shadow_texture;
MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float
width: 1024
height: 1024
mipmapped: NO];shadow_texture = [device newTextureWithDescriptor: shadowTextureDesc];
-
8/10/2019 605 Working With Metal Advanced
22/161
Render SetupRender pass descriptor for shadowMap pass
// Create texture
id shadow_texture;
MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float
width: 1024
height: 1024
mipmapped: NO];shadow_texture = [device newTextureWithDescriptor: shadowTextureDesc];
-
8/10/2019 605 Working With Metal Advanced
23/161
Render SetupRender pass descriptor for shadowMap pass
// Create texture
id shadow_texture;
MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float
width: 1024
height: 1024
mipmapped: NO];shadow_texture = [devicenewTextureWithDescriptor: shadowTextureDesc];
-
8/10/2019 605 Working With Metal Advanced
24/161
Render SetupRender pass descriptor for shadowMap pass
// Create render pass descriptor
MTLRenderPassDescriptor *shadowMapPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
-
8/10/2019 605 Working With Metal Advanced
25/161
Render SetupRender pass descriptor for shadowMap pass
// Create render pass descriptor
MTLRenderPassDescriptor *shadowMapPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
// Set the texture on the render pass descriptor
shadowMapPassDesc.depthAttachment.texture = shadow_texture;
d
-
8/10/2019 605 Working With Metal Advanced
26/161
Render SetupRender pass descriptor for shadowMap pass
// Create render pass descriptor
MTLRenderPassDescriptor *shadowMapPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
// Set the texture on the render pass descriptor
shadowMapPassDesc.depthAttachment.texture = shadow_texture;
R d S
-
8/10/2019 605 Working With Metal Advanced
27/161
Render SetupRender pass descriptor for shadowMap pass
// Create render pass descriptor
MTLRenderPassDescriptor *shadowMapPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
// Set the texture on the render pass descriptor
shadowMapPassDesc.depthAttachment.texture = shadow_texture;
// Set other properties on the render pass descriptor
shadowMapPassDesc.depthAttachment.clearValue = MTLClearValueMakeDepth(1.0
shadowMapPassDesc.depthAttachment.loadAction = MTLLoadActionClear;
shadowMapPassDesc.depthAttachment.setStoreAction = MTLStoreActionStore;
R d S
-
8/10/2019 605 Working With Metal Advanced
28/161
Render SetupRender pass descriptor for shadowMap pass
// Create render pass descriptor
MTLRenderPassDescriptor *shadowMapPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
// Set the texture on the render pass descriptor
shadowMapPassDesc.depthAttachment.texture = shadow_texture;
// Set other properties on the render pass descriptor
shadowMapPassDesc.depthAttachment.clearValue = MTLClearValueMakeDepth(1.0
shadowMapPassDesc.depthAttachment.loadAction = MTLLoadActionClear;
shadowMapPassDesc.depthAttachment.setStoreAction = MTLStoreActionStore;
R d S t
-
8/10/2019 605 Working With Metal Advanced
29/161
Render SetupRender pass descriptor for shadowMap pass
// Create render pass descriptor
MTLRenderPassDescriptor *shadowMapPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
// Set the texture on the render pass descriptor
shadowMapPassDesc.depthAttachment.texture = shadow_texture;
// Set other properties on the render pass descriptor
shadowMapPassDesc.depthAttachment.clearValue = MTLClearValueMakeDepth(1.0
shadowMapPassDesc.depthAttachment.loadAction= MTLLoadActionClear;
shadowMapPassDesc.depthAttachment.setStoreAction= MTLStoreActionStore;
R d S t
-
8/10/2019 605 Working With Metal Advanced
30/161
Render SetupRender pass descriptor for the Deferred Lighting pass
deferredPassDesc
Color Color
Color Color
Depth Stencil
R d S t
-
8/10/2019 605 Working With Metal Advanced
31/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm
width: desc.width
height: desc.height
mipmapped: NO];
R d S t
-
8/10/2019 605 Working With Metal Advanced
32/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm
width: desc.width
height: desc.height
mipmapped: NO];
// Create textures based on the descriptors
gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc
Render Setup
-
8/10/2019 605 Working With Metal Advanced
33/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm
width: desc.width
height: desc.height
mipmapped: NO];
// Create textures based on the descriptors
gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc
Render Setup
-
8/10/2019 605 Working With Metal Advanced
34/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm
width: desc.width
height: desc.height
mipmapped: NO];
// Create textures based on the descriptors
gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc
// Modify descriptor and create new texture
[attachmentX_texture_desc setPixelFormat: ];
gbuffer_texture2 = [device newTextureWithDescriptor: attachmentX_tex_desc
Render Setup
-
8/10/2019 605 Working With Metal Advanced
35/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm
width: desc.width
height: desc.height
mipmapped: NO];
// Create textures based on the descriptors
gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc
// Modify descriptor and create new texture
[attachmentX_texture_desc setPixelFormat: ];
gbuffer_texture2 = [device newTextureWithDescriptor: attachmentX_tex_desc
Render Setup
-
8/10/2019 605 Working With Metal Advanced
36/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm
width: desc.width
height: desc.height
mipmapped: NO];
// Create textures based on the descriptors
gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc
// Modify descriptor and create new texture
[attachmentX_texture_desc setPixelFormat: ];
gbuffer_texture2 = [device newTextureWithDescriptor: attachmentX_tex_desc
Render Setup
-
8/10/2019 605 Working With Metal Advanced
37/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Create render pass descriptorMTLRenderPassDescriptor *deferredPassDesc =
[MTLRenderPassDescriptor renderPassDescriptor];
Render Setup
-
8/10/2019 605 Working With Metal Advanced
38/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil; //will come from draw
Render Setup
-
8/10/2019 605 Working With Metal Advanced
39/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil; //will come from draw
Render Setup
-
8/10/2019 605 Working With Metal Advanced
40/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
Render Setup
-
8/10/2019 605 Working With Metal Advanced
41/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
Render Setup
-
8/10/2019 605 Working With Metal Advanced
42/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
// Describe color attachment 1
deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;
Render Setup
-
8/10/2019 605 Working With Metal Advanced
43/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
// Describe color attachment 1
deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;
Render Setup
-
8/10/2019 605 Working With Metal Advanced
44/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
// Describe color attachment 1
deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;
Render Setup
-
8/10/2019 605 Working With Metal Advanced
45/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
// Describe color attachment 1
deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;
deferredPassDesc.colorAttachments[1].clearValue = clearColor1;
deferredPassDesc.colorAttachments[1].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[1].storeAction = MTLStoreActionDontCare
Render Setup
-
8/10/2019 605 Working With Metal Advanced
46/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
// Describe color attachment 1
deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;
deferredPassDesc.colorAttachments[1].clearValue = clearColor1;
deferredPassDesc.colorAttachments[1].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[1].storeAction = MTLStoreActionDontCare
Render Setup
-
8/10/2019 605 Working With Metal Advanced
47/161
Render SetupRender pass descriptor for the Deferred Lighting pass
// Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;
deferredPassDesc.colorAttachments[0].clearValue = clearColor1;
deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
// Describe color attachment 1
deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;
deferredPassDesc.colorAttachments[1].clearValue = clearColor1;
deferredPassDesc.colorAttachments[1].loadAction = MTLLoadActionClear;
deferredPassDesc.colorAttachments[1].storeAction = MTLStoreActionDontCare
Render Setup
-
8/10/2019 605 Working With Metal Advanced
48/161
pDo as needed
Create framebuffer textures
Create render pass descriptors
Create textures
Create buffers for meshes
Create state objects
Create pipeline objects
Create uniform buffers
Creating Textures
-
8/10/2019 605 Working With Metal Advanced
49/161
g
// Copy texture data to bitmapDataunsigned Npixels = tex_info.width * tex_info.height;
id texture = [device newTextureWithDescriptor: ];
Creating Textures
-
8/10/2019 605 Working With Metal Advanced
50/161
// Copy texture data to bitmapDataunsigned Npixels = tex_info.width * tex_info.height;
id texture = [device newTextureWithDescriptor: ];
[texture replaceRegion: bitmapData
g
Creating Textures
-
8/10/2019 605 Working With Metal Advanced
51/161
// Copy texture data to bitmapDataunsigned Npixels = tex_info.width * tex_info.height;
id texture = [device newTextureWithDescriptor: ];
[texture replaceRegion: bitmapData
g
Creating Buffers for Meshes
-
8/10/2019 605 Working With Metal Advanced
52/161
g
float4 temple[100];
spriteBuffer = [device newBufferWithBytes: &temple
length: sizeof(temple)
options: 0];
Creating Buffers for Meshes
-
8/10/2019 605 Working With Metal Advanced
53/161
g
float4 temple[100];
spriteBuffer = [device newBufferWithBytes: &temple
length: sizeof(temple)
options: 0];
Creating State Objects
-
8/10/2019 605 Working With Metal Advanced
54/161
g j
MTLDepthStencilDescriptor*desc = [[MTLDepthStencilDescriptor alloc] initdesc.depthCompareFunction = MTLCompareFunctionLessEqual;
desc.depthWriteEnabled = YES;
MTLStencilDescriptor *stencilStateDesc = [[MTLStencilDescriptor alloc] in
stencilState.stencilCompareFunction = MTLCompareFunctionAlways;
stencilState.stencilFailureOperation = MTLStencilOperationKeep;
desc.frontFaceStencilDescriptor = stencilStateDesc;
desc.backFaceStencilDescriptor = stencilStateDesc;
id shadowDepthStencilState= [devicenewDepthStencilStateWithDescriptor: desc];
Creating State Objects
-
8/10/2019 605 Working With Metal Advanced
55/161
MTLDepthStencilDescriptor*desc = [[MTLDepthStencilDescriptor alloc] initdesc.depthCompareFunction = MTLCompareFunctionLessEqual;
desc.depthWriteEnabled = YES;
MTLStencilDescriptor*stencilStateDesc = [[MTLStencilDescriptor alloc] in
stencilState.stencilCompareFunction = MTLCompareFunctionAlways;
stencilState.stencilFailureOperation = MTLStencilOperationKeep;
desc.frontFaceStencilDescriptor = stencilStateDesc;
desc.backFaceStencilDescriptor= stencilStateDesc;
id shadowDepthStencilState = [devicenewDepthStencilStateWithDescriptor: desc];
GPU Render Pipeline
-
8/10/2019 605 Working With Metal Advanced
56/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
BuffersTextures
Samplers
Buffers
Render Pipeline State Object
-
8/10/2019 605 Working With Metal Advanced
57/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Render Pipeline State Object
-
8/10/2019 605 Working With Metal Advanced
58/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Shaders
Render Pipeline State Object
-
8/10/2019 605 Working With Metal Advanced
59/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Framebuffer configuration
Number of render targets, pixel format, sample co
Render Pipeline State Object
-
8/10/2019 605 Working With Metal Advanced
60/161
Buffers
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Depth and stencil state
Render Pipeline State Object
-
8/10/2019 605 Working With Metal Advanced
61/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Render Pipeline State ObjectNot Includ
-
8/10/2019 605 Working With Metal Advanced
62/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Inputs
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Render Pipeline State ObjectNot Includ
-
8/10/2019 605 Working With Metal Advanced
63/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Outputs
Render Pipeline State ObjectNot Includ
-
8/10/2019 605 Working With Metal Advanced
64/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Primitive setup
Cull mode, facing orientation
depth clipping, polygon mode
Render Pipeline State ObjectNot Includ
-
8/10/2019 605 Working With Metal Advanced
65/161
Vertex Fetch
Vertex Shader
Rasterizer
FragmentShader
Framebuffer
Primitive Setup
Buffers
Buffers
Textures
Samplers
Buffers
Textures
Samplers
Buffers
Viewport and scissorDepth bias/slope/clamp
Occlusion queries
Creating Render Pipeline State Object
-
8/10/2019 605 Working With Metal Advanced
66/161
Every draw call requires a render pipeline state object to be setSame mesh usually has multiple pipeline state objects
The temple object in our demo is rendered twice
- The shadow passDepth only render with simple vertex shader
- The deferred passRendered to generate g-buffer attributes
- Each one requires a different render pipeline state object to be created
Creating Render Pipeline State Objecth d M
-
8/10/2019 605 Working With Metal Advanced
67/161
shadowMap pass
// Create the descriptorMTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
Creating Render Pipeline State Objecth d M
-
8/10/2019 605 Working With Metal Advanced
68/161
shadowMap pass
// Create the descriptor
MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
// Get the shaders from the library
id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];
Creating Render Pipeline State ObjectshadowMap pass
-
8/10/2019 605 Working With Metal Advanced
69/161
shadowMap pass
// Create the descriptor
MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
// Get the shaders from the library
id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];
Creating Render Pipeline State ObjectshadowMap pass
-
8/10/2019 605 Working With Metal Advanced
70/161
shadowMap pass
// Create the descriptor
MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
// Get the shaders from the library
id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];
// Set the states
desc.label = @"Shadow Render";desc.vertexFunction = zOnlyVert;
desc.stencilWriteEnabled = false;
desc.depthWriteEnabled = true;
desc.fragmentFunction = nil; //depth write only
desc.depthAttachmentPixelFormat = pixelFormat;
Creating Render Pipeline State ObjectshadowMap pass
-
8/10/2019 605 Working With Metal Advanced
71/161
shadowMap pass
// Create the descriptor
MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
// Get the shaders from the library
id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];
// Set the states
desc.label = @"Shadow Render";desc.vertexFunction = zOnlyVert;
desc.stencilWriteEnabled = false;
desc.depthWriteEnabled = true;
desc.fragmentFunction = nil; //depth write only
desc.depthAttachmentPixelFormat = pixelFormat;
Creating Render Pipeline State ObjectshadowMap pass
-
8/10/2019 605 Working With Metal Advanced
72/161
shadowMap pass
MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];
desc.label = @"Shadow Render";
desc.vertexFunction = zOnlyVert;
desc.stencilWriteEnabled = false;
desc.depthWriteEnabled = true;desc.fragmentFunction = nil; //depth write only
desc.depthAttachmentPixelFormat = pixelFormat;
// Create the render pipeline state object
id pipeline = [device
newRenderPipelineStateWithDescriptor: desc error: &err];
Creating Render Pipeline State ObjectshadowMap pass
-
8/10/2019 605 Working With Metal Advanced
73/161
shadowMap pass
MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];
desc.label = @"Shadow Render";
desc.vertexFunction = zOnlyVert;
desc.stencilWriteEnabled = false;
desc.depthWriteEnabled = true;desc.fragmentFunction = nil; //depth write only
desc.depthAttachmentPixelFormat = pixelFormat;
// Create the render pipeline state object
id pipeline = [device
newRenderPipelineStateWithDescriptor: desc error: &err];
Creating Render Pipeline State ObjectDeferred Lighting pass
-
8/10/2019 605 Working With Metal Advanced
74/161
Deferred Lighting pass
desc.vertexFunction = gBufferVert;
desc.fragmentFunction = gBufferFrag;
desc.colorAttachments[0].pixelFormat = gbuffer_texture0.pixelFormat;
desc.colorAttachments[1].pixelFormat = gbuffer_texture1.pixelFormat;
desc.depthAttachmentPixelFormat = depth_texture.pixelFormat;
desc.stencilAttachmentPixelFormat = stencil_texture.pixelFormat;
Creating Render Pipeline State ObjectDeferred Lighting pass
-
8/10/2019 605 Working With Metal Advanced
75/161
Deferred Lighting pass
desc.vertexFunction = gBufferVert;
desc.fragmentFunction = gBufferFrag;
desc.colorAttachments[0].pixelFormat = gbuffer_texture0.pixelFormat;
desc.colorAttachments[1].pixelFormat = gbuffer_texture1.pixelFormat;
desc.depthAttachmentPixelFormat = depth_texture.pixelFormat;
desc.stencilAttachmentPixelFormat = stencil_texture.pixelFormat;
Creating Render Pipeline State ObjectDeferred Lighting pass
-
8/10/2019 605 Working With Metal Advanced
76/161
Deferred Lighting pass
desc.vertexFunction = gBufferVert;
desc.fragmentFunction = gBufferFrag;
desc.colorAttachments[0].pixelFormat = gbuffer_texture0.pixelFormat;
desc.colorAttachments[1].pixelFormat = gbuffer_texture1.pixelFormat;
desc.depthAttachmentPixelFormat = depth_texture.pixelFormat;
desc.stencilAttachmentPixelFormat = stencil_texture.pixelFormat;
Render SetupDo every frame
-
8/10/2019 605 Working With Metal Advanced
77/161
Do every frame
Create command bufferUpdate frame-based uniform buffers
Submit command buffer
Render SetupCreate and submit command buffer
-
8/10/2019 605 Working With Metal Advanced
78/161
Create and submit command buffer
// BeginFrame
commandBuffer = [commandQueue commandBuffer];
// EndFrame
[commandBuffer addPresent: drawable];
[commandBuffer commit];
commandBuffer = nil;
Render SetupCreate and submit command buffer
-
8/10/2019 605 Working With Metal Advanced
79/161
Create and submit command buffer
// BeginFrame
commandBuffer = [commandQueue commandBuffer];
// EndFrame
[commandBuffer addPresent: drawable];
[commandBuffer commit];
commandBuffer = nil;
Render SetupCreate and submit command buffer
-
8/10/2019 605 Working With Metal Advanced
80/161
Create and submit command buffer
// BeginFrame
commandBuffer = [commandQueue commandBuffer];
// EndFrame
[commandBuffer addPresent: drawable];
[commandBuffer commit];
commandBuffer = nil;
Render SetupDo every render to texture pass
-
8/10/2019 605 Working With Metal Advanced
81/161
y p
Create command encoder
Draw many times
Update uniform buffers
Set states
Make draw calls
Render SetupshadowMap pass render encoding
-
8/10/2019 605 Working With Metal Advanced
82/161
p p g
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: shadowMapPassDesc];
Render SetupshadowMap pass render encoding
-
8/10/2019 605 Working With Metal Advanced
83/161
p p g
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: shadowMapPassDesc];
// Set states and draw
[encoder setRenderPipelineState: shadow_render_pipeline];
[encoder setDepthStencilState: shadowDepthStencilState];
[encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0
[encoder drawIndexedPrimitives:
Render SetupshadowMap pass render encoding
-
8/10/2019 605 Working With Metal Advanced
84/161
p p g
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: shadowMapPassDesc];
// Set states and draw
[encoder setRenderPipelineState: shadow_render_pipeline];
[encoder setDepthStencilState: shadowDepthStencilState];
[encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0
[encoder drawIndexedPrimitives:
Render SetupshadowMap pass render encoding
-
8/10/2019 605 Working With Metal Advanced
85/161
g
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: shadowMapPassDesc];
// Set states and draw
[encoder setRenderPipelineState: shadow_render_pipeline];
[encoder setDepthStencilState: shadowDepthStencilState];
[encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0
[encoder drawIndexedPrimitives:
// end encoding
[encoder endEncoding];
Render SetupshadowMap pass render encoding
-
8/10/2019 605 Working With Metal Advanced
86/161
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: shadowMapPassDesc];
// Set states and draw
[encoder setRenderPipelineState: shadow_render_pipeline];
[encoder setDepthStencilState: shadowDepthStencilState];
[encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0
[encoder drawIndexedPrimitives:
// end encoding
[encoder endEncoding];
Render SetupDeferred Lighting pass render encoding
-
8/10/2019 605 Working With Metal Advanced
87/161
deferredPassDesc.colorAttachments[0].texture = texture_from_drawable;
Render SetupDeferred Lighting pass render encoding
-
8/10/2019 605 Working With Metal Advanced
88/161
deferredPassDesc.colorAttachments[0].texture = texture_from_drawable;
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: deferredPassDesc];
Render SetupDeferred Lighting pass render encoding
-
8/10/2019 605 Working With Metal Advanced
89/161
deferredPassDesc.colorAttachments[0].texture = texture_from_drawable;
// Create encoder
id encoder = [commandBuffer
renderCommandEncoderWithDescriptor: deferredPassDesc];
// End encoding
[encoder endEncoding];
Agenda
-
8/10/2019 605 Working With Metal Advanced
90/161
Introduction to Metal
Fundamentals of Metal
Building a Metal application
Metal shading language
Advanced Metal
Data-Parallel Computing with Metal
Developer Tools Review
-
8/10/2019 605 Working With Metal Advanced
91/161
Data-Parallel Computing with Metal
Aaftab MunshiGPU Software
Data-Parallel Computing with MetalWhat youll learn
-
8/10/2019 605 Working With Metal Advanced
92/161
Data-Parallel Computing with MetalWhat youll learn
-
8/10/2019 605 Working With Metal Advanced
93/161
What is data-parallel computing?
Data-Parallel Computing with MetalWhat youll learn
-
8/10/2019 605 Working With Metal Advanced
94/161
What is data-parallel computing?
Data-parallel computing in Metal
Data-Parallel Computing with MetalWhat youll learn
-
8/10/2019 605 Working With Metal Advanced
95/161
What is data-parallel computing?
Data-parallel computing in Metal
Writing data-parallel kernels in Metal
Data-Parallel Computing with MetalWhat youll learn
-
8/10/2019 605 Working With Metal Advanced
96/161
What is data-parallel computing?
Data-parallel computing in Metal
Writing data-parallel kernels in Metal
Executing kernels in Metal
Data-Parallel ComputingA brief introduction
-
8/10/2019 605 Working With Metal Advanced
97/161
Data-Parallel ComputingA brief introduction
-
8/10/2019 605 Working With Metal Advanced
98/161
Similar and independent computations on multiple data elements
Data-Parallel ComputingA brief introduction
-
8/10/2019 605 Working With Metal Advanced
99/161
Similar and independent computations on multiple data elements
ExampleBlurring an image
Same computation for each input
All results are independent
Data-Parallelism in Metal
-
8/10/2019 605 Working With Metal Advanced
100/161
Data-Parallelism in Metal
-
8/10/2019 605 Working With Metal Advanced
101/161
Code that describes computation is called a kernel
Data-Parallelism in Metal
-
8/10/2019 605 Working With Metal Advanced
102/161
Code that describes computation is called a kernel
Independent computation instance
Work-item
Data-Parallelism in Metal
-
8/10/2019 605 Working With Metal Advanced
103/161
Code that describes computation is called a kernel
Independent computation instance
Work-item
Work-items that execute together
Work-group
Cooperate by sharing data Can synchronize execution
Data-Parallelism in MetalComputation domain
-
8/10/2019 605 Working With Metal Advanced
104/161
Data-Parallelism in MetalComputation domain
-
8/10/2019 605 Working With Metal Advanced
105/161
Number of dimensions
1D, 2D, or 3D
Data-Parallelism in MetalComputation domain
-
8/10/2019 605 Working With Metal Advanced
106/161
Number of dimensions
1D, 2D, or 3D
For each dimension specify
Number of work-items in work-group also known as work-group size
Number of work-groups
Data-Parallelism in MetalComputation domain
-
8/10/2019 605 Working With Metal Advanced
107/161
Number of dimensions
1D, 2D, or 3D
For each dimension specify
Number of work-items in work-group also known as work-group size
Number of work-groups
Choose the dimensions that are best for your algorithm
Pseudo Code for a Data-Parallel Kernel
-
8/10/2019 605 Working With Metal Advanced
108/161
voidsquare(const float* input,
float* output,uint id
{output[id] = input[id] * input[id];
}
Pseudo Code for a Data-Parallel Kernel
-
8/10/2019 605 Working With Metal Advanced
109/161
#include
using namespace metal;voidsquare(const float* input,
float* output,uint id
{output[id] = input[id] * input[id];
}
Pseudo Code for a Data-Parallel Kernel
-
8/10/2019 605 Working With Metal Advanced
110/161
#include
using namespace metal;kernel voidsquare(const float* input,
float* output,uint id
{output[id] = input[id] * input[id];
}
Pseudo Code for a Data-Parallel Kernel
-
8/10/2019 605 Working With Metal Advanced
111/161
#include
using namespace metal;kernelvoidsquare(const global float* input [[ buffer(0)]],
global float* output [[ buffer(1)]],uint id
{output[id] = input[id] * input[id];
}
Metal Kernel
-
8/10/2019 605 Working With Metal Advanced
112/161
#include
using namespace metal;kernelvoidsquare(const global float* input [[ buffer(0)]],
global float* output [[ buffer(1)]],uint id [[ global_id]])
{output[id] = input[id] * input[id];
}
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
113/161
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
114/161
kernel void
horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
115/161
kernel void
horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
116/161
kernel void
horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
117/161
kernel void
horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
118/161
kernel void
horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}
Another Kernel Example in MetalUsing images in a kernel
-
8/10/2019 605 Working With Metal Advanced
119/161
kernel void
horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}
Built-in Kernel VariablesAttributes for kernel arguments
-
8/10/2019 605 Working With Metal Advanced
120/161
kernel void
my_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
Built-in Kernel VariablesAttributes for kernel arguments
k l id
-
8/10/2019 605 Working With Metal Advanced
121/161
kernel void
my_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
Built-in Kernel VariablesAttributes for kernel arguments
k l id
-
8/10/2019 605 Working With Metal Advanced
122/161
kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],
uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
Built-in Kernel VariablesAttributes for kernel arguments
kernel void
-
8/10/2019 605 Working With Metal Advanced
123/161
kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],
uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
Built-in Kernel VariablesAttributes for kernel arguments
kernel void
-
8/10/2019 605 Working With Metal Advanced
124/161
kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],
uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
Built-in Kernel VariablesAttributes for kernel arguments
kernel void
-
8/10/2019 605 Working With Metal Advanced
125/161
kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],
uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
Built-in Kernel VariablesAttributes for kernel arguments
kernel void
-
8/10/2019 605 Working With Metal Advanced
126/161
kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],
uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)
{
}
-
8/10/2019 605 Working With Metal Advanced
127/161
Executing Kernels in MetalPost-processing example
Post-Processing KernelKernel source
-
8/10/2019 605 Working With Metal Advanced
128/161
Post-Processing KernelKernel source
kernel void
-
8/10/2019 605 Working With Metal Advanced
129/161
kernel voidpostprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix
float4 color = inImage.sample(s, transformedCoord);
// Apply post-processing effect
outImage.write(color, gid);}
Post-Processing KernelKernel source
kernel void
-
8/10/2019 605 Working With Metal Advanced
130/161
postprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix
float4 color = inImage.sample(s, transformedCoord);
// Apply post-processing effect
outImage.write(color, gid);}
Post-Processing KernelKernel source
kernel void
-
8/10/2019 605 Working With Metal Advanced
131/161
postprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix
float4 color = inImage.sample(s, transformedCoord);
// Apply post-processing effect
outImage.write(color, gid);}
Post-Processing KernelKernel source
kernel void
-
8/10/2019 605 Working With Metal Advanced
132/161
postprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix
float4 color = inImage.sample(s, transformedCoord);
// Apply post-processing effect
outImage.write(color, gid);}
Post-Processing KernelProcessing multiple pixels/work-item
constexpr constant int num_pixels_work_item = 4;
-
8/10/2019 605 Working With Metal Advanced
133/161
kernel voidpostprocess_filter(, uint2 gid [[global_id]],
uint2 lsize [[local_size]]){ for (int i=0; i
-
8/10/2019 605 Working With Metal Advanced
134/161
kernel voidpostprocess_filter(, uint2 gid [[global_id]],
uint2 lsize [[local_size]]){ for (int i=0; i
-
8/10/2019 605 Working With Metal Advanced
135/161
kernel voidpostprocess_filter(, uint2 gid [[global_id]],
uint2 lsize [[local_size]]){ for (int i=0; i
-
8/10/2019 605 Working With Metal Advanced
136/161
Executing a KernelCompute command encoder
//Load library and kernel function
-
8/10/2019 605 Working With Metal Advanced
137/161
id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library
newFunctionWithName:@postprocess_filter]
Executing a KernelCompute command encoder
//Load library and kernel function
-
8/10/2019 605 Working With Metal Advanced
138/161
id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library
newFunctionWithName:@postprocess_filter]
// Create compute state
id filterKernel=[device newComputePipelineStateWithFunction:filterFuncerror:&err];
Executing a KernelCompute command encoder
//Load library and kernel function
-
8/10/2019 605 Working With Metal Advanced
139/161
id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library
newFunctionWithName:@postprocess_filter]
// Create compute state
id filterKernel=[device newComputePipelineStateWithFunction:filterFuncerror:&err];
// Create compute command encoder
Executing a KernelCompute command encoder
//Load library and kernel function
-
8/10/2019 605 Working With Metal Advanced
140/161
id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library
newFunctionWithName:@postprocess_filter]
// Create compute state
id filterKernel=[device newComputePipelineStateWithFunction:filterFuncerror:&err];
// Create compute command encoder
id computeEncoder=[commandBuffer computeCommandEncoder];
Executing a KernelEncode compute commands
-
8/10/2019 605 Working With Metal Advanced
141/161
Executing a KernelEncode compute commands
// Set compute state
[ t E d tC t Pi li St t filt K l]
-
8/10/2019 605 Working With Metal Advanced
142/161
[computeEncoder setComputePipelineState:filterKernel];
Executing a KernelEncode compute commands
// Set compute state
[comp teEncoder setComp tePipelineState filterKernel]
-
8/10/2019 605 Working With Metal Advanced
143/161
[computeEncoder setComputePipelineState:filterKernel];
// Set Resources used by kernel
[computeEncoder setTexture:inputImage atIndex:0];[computeEncoder setTexture:outputImage atIndex:1];[computeEncoder setTexture:curveImage atIndex:2];[computeEncoder setBuffer:params offset:0 atIndex:0];
Executing a KernelEncode compute commands
-
8/10/2019 605 Working With Metal Advanced
144/161
Executing a KernelEncode compute commands
// Calculate the work-group size and number of work-groups
MTLSize wgSize = { 16 16 1 };
-
8/10/2019 605 Working With Metal Advanced
145/161
MTLSize wgSize = { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };
Executing a KernelEncode compute commands
// Calculate the work-group size and number of work-groups
MTLSize wgSize = { 16 16 1 };
-
8/10/2019 605 Working With Metal Advanced
146/161
MTLSize wgSize = { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };
Executing a KernelEncode compute commands
// Calculate the work-group size and number of work-groups
MTLSize wgSize = { 16 16 1 };
-
8/10/2019 605 Working With Metal Advanced
147/161
MTLSize wgSize = { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };
// Execute Kernel
[computeEncoder executeKernelWithWorkGroupSize:wgSizeworkGroupCount:numWorkGroups];
Executing a KernelEncode compute commands
// Calculate the work-group size and number of work-groups
MTLSize wgSize = { 16, 16, 1 };
-
8/10/2019 605 Working With Metal Advanced
148/161
MTLSize wgSize { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };
// Execute Kernel
[computeEncoder executeKernelWithWorkGroupSize:wgSizeworkGroupCount:numWorkGroups];
Executing a KernelEncode compute commands
// Calculate the work-group size and number of work-groups
MTLSize wgSize = { 16, 16, 1 };
-
8/10/2019 605 Working With Metal Advanced
149/161
MTLSize wgSize { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };
// Execute Kernel
[computeEncoder executeKernelWithWorkGroupSize:wgSizeworkGroupCount:numWorkGroups];
// Finish encoding
[computeEncoder endEncoding];
Executing a KernelSubmit commands to the GPU
// Commit the command buffer
[commandBuffer commit];
-
8/10/2019 605 Working With Metal Advanced
150/161
[ ];
-
8/10/2019 605 Working With Metal Advanced
151/161
Demo
Post-processing kernels
Agenda
Introduction to Metal
-
8/10/2019 605 Working With Metal Advanced
152/161
Fundamentals of Metal Building a Metal application
Metal shading language
Advanced Metal
Developer Tools Review
-
8/10/2019 605 Working With Metal Advanced
153/161
ToolsDebugging and profiling Metal applications in Xcode
Summary
-
8/10/2019 605 Working With Metal Advanced
154/161
Summary
A deeper dive into Metal
-
8/10/2019 605 Working With Metal Advanced
155/161
Structuring your application for Metal Using descriptors and state objects for rendering
Multi-pass encoding in Metal
Summary
A deeper dive into Metal
-
8/10/2019 605 Working With Metal Advanced
156/161
Structuring your application for Metal Using descriptors and state objects for rendering
Multi-pass encoding in Metal
Data-parallel computing in Metal
How data-parallelism works in Metal
Write and execute kernels in Metal
Summary
A deeper dive into Metal
S i li i f l
-
8/10/2019 605 Working With Metal Advanced
157/161
Structuring your application for Metal Using descriptors and state objects for rendering
Multi-pass encoding in Metal
Data-parallel computing in Metal
How data-parallelism works in Metal
Write and execute kernels in Metal
Tools
How to create and compile Metal Shaders in Xcode
Debug and profile a Metal application
More Information
Filip IliescuGraphics and Games Technologies Evangelist
fili @ l
-
8/10/2019 605 Working With Metal Advanced
158/161
Allan SchafferGraphics and Games Technologies Evangelist
Documentation
http://developer.apple.com
Apple Developer Forumshttp://devforums.apple.com
Related Sessions
http://devforums.apple.com/http://devforums.apple.com/ -
8/10/2019 605 Working With Metal Advanced
159/161
Labs
-
8/10/2019 605 Working With Metal Advanced
160/161
-
8/10/2019 605 Working With Metal Advanced
161/161