-
Go bindless with Metal 3
Learn how you can unleash powerful rendering techniques like ray tracing when you go bindless with Metal 3. We'll show you how to make your app's bindless journey a joy by simplifying argument buffers, allocating acceleration structures from heaps, and benefitting from the improvements to the Metal's validation layer and Debugger Tools. We'll also explore how you can command more CPU and GPU performance with long-term resource structures.
Recursos
Vídeos relacionados
WWDC23
WWDC22
- Discover Metal 3
- Maximize your Metal ray tracing performance
- Profile and optimize your game's memory
WWDC21
-
Buscar neste vídeo...
-
-
5:38 - Write argument buffers in Metal 3
// Write argument buffers in Metal 3 struct Mesh { uint64_t normals; // 64-bit uint for constant packed_float3* }; NSUInteger meshArgumentSize = sizeof(struct Mesh); id<MTLBuffer> meshArgumentBuffer = [device newBufferWithLength:meshArgumentSize options:storageMode]; struct Mesh* meshes = (struct Mesh *)(meshArgumentBuffer.contents); meshes->normals = normalBuffer.gpuAddress + normalBufferOffset; -
6:31 - // Shader struct:
// Shader struct: struct Mesh { constant packed_float3* normals; }; // Host-side struct: struct Mesh { uint64_t normals; }; -
6:53 - Shared struct:
// Shared struct: #if __METAL_VERSION__ #define CONSTANT_PTR(x) constant x* #else #define CONSTANT_PTR(x) uint64_t #endif struct Mesh { CONSTANT_PTR(packed_float3) normals; }; -
7:53 - Write unbounded arrays of resources in Metal 3
// Write unbounded arrays of resources in Metal 3 struct Mesh { uint64_t normals; // 64-bit uint for constant packed_float3* }; NSUInteger meshArgumentSize = sizeof(struct Mesh) * meshes.count; id<MTLBuffer> meshArgumentBuffer = [device newBufferWithLength:meshArgumentSize options:storageMode]; struct Mesh* meshes = (struct Mesh *)(meshArgumentBuffer.contents); for ( NSUInteger i = 0; i < meshes.count; ++i ) { meshes[i].normals = normalBuffers[i].gpuAddress + normalBufferOffsets[i]; } -
9:03 - Metal shading language: unbounded arrays option 1
// Metal shading language: struct Mesh { constant packed_float3* normals; }; fragment half4 fragmentShader(ColorInOut v [[stage_in]], constant Mesh* meshes [[buffer(0)]] ) { /* determine mesh to read, e.g. geometry_id */ packed_float3 n0 = meshes[ geometry_id ].normals[0]; packed_float3 n1 = meshes[ geometry_id ].normals[1]; packed_float3 n2 = meshes[ geometry_id ].normals[2]; /* interpolate normals and calculate shading */ } -
9:25 - Metal shading language: unbounded arrays option 2
// Metal shading language: struct Mesh { constant packed_float3* normals; }; struct Scene { constant Mesh* meshes; // mesh array constant Material* materials; // material array }; fragment half4 fragmentShader(ColorInOut v [[stage_in]], constant Scene& scene [[buffer(0)]] ) { /* determine mesh to read, e.g. geometry_id */ packed_float3 n0 = scene.meshes[ geometry_id ].normals[0]; packed_float3 n1 = scene.meshes[ geometry_id ].normals[1]; packed_float3 n2 = scene.meshes[ geometry_id ].normals[2]; /* interpolate normals and calculate shading */ } -
11:00 - Size and alignment for MTLAccelerationStructure in a MTLHeap
heapAccelerationStructureSizeAndAlignWithDescriptor: -
13:49 - Store individual indirect resources in NSMutableSet
// Argument buffer loading for (NSUInteger i = 0; i < mesh.submeshes.count; ++i) { Submesh* submesh = mesh.submeshes[i]; id<MTLBuffer> indexBuffer = submesh.indexBuffer; NSArray* textures = submesh.textures; // Copy index buffer into argument buffer submeshAB[i].indices = indexBuffer.gpuAddress; // Copy material textures into argument buffer for (NSUInteger m = 0; m < textures.count; ++m) { submeshAB[i].textures[m] = textures[m].gpuResourceID; } // Remember indirect resources [sceneResources addObject:indexBuffer]; [sceneResources addObjectsFromArray:textures]; }
-