-
Explorar juegos de Metal 4
Aprende a optimizar tu motor de juegos con los últimos avances de Metal 4. Hablaremos de cómo unificar la codificación de comandos para minimizar la sobrecarga de la CPU, ampliar la gestión de recursos gráficos para admitir escenas masivas y maximizar el presupuesto de memoria, y cargar rápidamente grandes bibliotecas de estados de canales.
Para aprovechar al máximo esta sesión, primero mira “Descubrir Metal 4”.Capítulos
- 0:00 - Introducción
- 1:33 - Codificar de forma más eficiente
- 8:42 - Escalar la gestión de recursos
- 17:24 - Cargar canales rápidamente
- 31:25 - Resumen
Recursos
- Metal binary archives
- Reading and writing to sparse textures
- Synchronizing passes with producer barriers
- Synchronizing passes with consumer barriers
- Synchronizing passes with a fence
- Synchronizing stages within a pass
- Resource synchronization
- Drawing a triangle with Metal 4
- Using the Metal 4 compilation API
- Understanding the Metal 4 core API
- Human Interface Guidelines: Designing for games
Videos relacionados
WWDC25
- Combina el aprendizaje automático y los gráficos de Metal 4
- Descubrir Metal 4
- Novedades del renderizado de Metal para apps inmersivas
- Sube de nivel tus juegos
- Ve más allá con los juegos de Metal 4
Tech Talks
-
Buscar este video…
-
-
0:01 - Synchronize access to a buffer within an encoder
// Synchronize access to a buffer within an encoder id<MTL4ComputeCommandEncoder> encoder = [commandBuffer computeCommandEncoder]; [encoder copyFromBuffer:src sourceOffset:0 toBuffer:buffer1 destinationOffset:0 size:64]; [encoder barrierAfterEncoderStages:MTLStageBlit beforeEncoderStages:MTLStageDispatch visibilityOptions:MTL4VisibilityOptionDevice]; [encoder setComputePipelineState:pso]; [argTable setAddress:buffer1.gpuAddress atIndex:0]; [encoder setArgumentTable:argTable]; [encoder dispatchThreads:threadsPerGrid threadsPerThreadgroup:threadsPerThreadgroup]; [encoder endEncoding];code snippet. -
4:29 - Configure superset of color attachments
// Configure superset of color attachments MTL4RenderPassDescriptor *desc = [MTLRenderPassDescriptor renderPassDescriptor]; desc.supportColorAttachmentMapping = YES; desc.colorAttachments[0].texture = colortex0; desc.colorAttachments[1].texture = colortex1; desc.colorAttachments[2].texture = colortex2; desc.colorAttachments[3].texture = colortex3; desc.colorAttachments[4].texture = colortex4; -
4:38 - Set color attachment map entries
// Set color attachment map entries MTLLogicalToPhysicalColorAttachmentMap* myAttachmentRemap = [MTLLogicalToPhysicalColorAttachmentMap new]; [myAttachmentRemap setPhysicalIndex:0 forLogicalIndex:0]; [myAttachmentRemap setPhysicalIndex:3 forLogicalIndex:1]; [myAttachmentRemap setPhysicalIndex:4 forLogicalIndex:2]; -
4:57 - Set a color attachment map per pipeline
// Set a color attachment map per pipeline [renderEncoder setRenderPipelineState:myPipeline]; [renderEncoder setColorAttachmentMap:myAttachmentRemap]; // Draw with myPipeline [renderEncoder setRenderPipelineState:myPipeline2]; [renderEncoder setColorAttachmentMap:myAttachmentRemap2]; // Draw with myPipeline2 -
8:03 - Encode a single render pass with 3 render encoders
// Encode a single render pass with 3 render encoders with suspend/resume options id<MTL4RenderCommandEncoder> enc0 = [cmdbuf0 renderCommandEncoderWithDescriptor:desc options:MTL4RenderEncoderOptionSuspending]; id<MTL4RenderCommandEncoder> enc1 = [cmdbuf1 renderCommandEncoderWithDescriptor:desc options:MTL4RenderEncoderOptionResuming | MTL4RenderEncoderOptionSuspending]; id<MTL4RenderCommandEncoder> enc2 = [cmdbuf2 renderCommandEncoderWithDescriptor:desc options:MTL4RenderEncoderOptionResuming]; id<MTL4CommandBuffer> cmdbufs[] = { cmdbuf0, cmdbuf1, cmdbuf2 }; [commandQueue commit:cmdbufs count:3] -
11:48 - Synchronize drawable contents
// Synchronize drawable contents id<MTLDrawable> drawable = [metalLayer nextDrawable]; [queue waitForDrawable:drawable]; // ... encode render commands to commandBuffer ... [queue commit:&commandBuffer count:1]; [queue signalDrawable:drawable]; [drawable present]; -
13:25 - Encode a queue barrier to synchronize data
// Encode a queue barrier to synchronize data id<MTL4ComputeCommandEncoder> compute = [commandBuffer computeCommandEncoder]; [compute dispatchThreadgroups:threadGrid threadsPerThreadgroup:threadsPerThreadgroup]; [compute endEncoding]; id<MTL4RenderCommandEncoder> render = [commandBuffer renderCommandEncoderWithDescriptor:des]; [render barrierAfterQueueStages:MTLStageDispatch beforeStages:MTLStageFragment visibilityOptions:MTL4VisibilityOptionDevice]; [renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:vertexStart vertexCount:vertexCount]; [render endEncoding]; -
14:57 - Create a texture view pool
// Create a texture view pool MTLResourceViewPoolDescriptor *desc = [[MTLResourceViewPoolDescriptor alloc] init]; desc.resourceCount = 500; id <MTLTextureViewPool> myTextureViewPool = [myDevice newTextureViewPoolWithDescriptor:myTextureViewPoolDescriptor error:nullptr]; -
15:07 - Set a texture view
// Set a texture view MTLResourceID myTextureView = [myTextureViewPool setTextureView:myTexture descriptor:myTextureViewDescriptor atIndex:5]; [myArgumentTable setTexture:myTextureView atIndex:0]; -
16:01 - Choose appropriate sparse page size
MTLHeapDescriptor *desc = [MTLHeapDescriptor new]; desc.type = MTLHeapTypePlacement; desc.storageMode = MTLStorageModePrivate; desc.maxCompatiblePlacementSparsePageSize = MTLSparsePageSize64; desc.size = alignedHeapSize; id<MTLHeap> heap = [device newHeapWithDescriptor:desc]; -
17:05 - Update buffer mappings
// Update buffer mappings MTL4UpdateSparseBufferMappingOperation bufferOperation; bufferOperation.mode = MTLSparseTextureMappingModeMap; bufferOperation.bufferRange.location = bufferOffsetInTiles; bufferOperation.bufferRange.length = length; bufferOperation.heapOffset = heapOffsetInTiles; [cmdQueue updateBufferMappings:myBuf heap:myHeap operations:&bufferOperation count:1]; -
20:41 - Set unspecialized configuration
// In MTL4RenderPipelineColorAttachmentDescriptor // Set unspecialized configuration pipelineDescriptor.colorAttachments[i].pixelFormat = MTLPixelFormatUnspecialized; pipelineDescriptor.colorAttachments[i].writeMask = MTLColorWriteMaskUnspecialized; pipelineDescriptor.colorAttachments[i].blendingState = MTL4BlendStateUnspecialized; -
21:40 - Create a specialized transparent pipeline
// Create a specialized transparent pipeline // Set the previously unspecialized properties pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; pipelineDescriptor.colorAttachments[0].writeMask = MTLColorWriteMaskRed | MTLColorWriteMaskGreen | MTLColorWriteMaskBlue; pipelineDescriptor.colorAttachments[0].blendingState = MTL4BlendStateEnabled; pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; id<MTLRenderPipelineState> transparentPipeline = [compiler newRenderPipelineStateBySpecializationWithDescriptor:pipelineDescriptor pipeline:unspecializedPipeline error:&error]; // Similarly, create the specialized opaque and hologram pipelines -
26:22 - Determine thread count
// Determine thread count NSInteger numThreads = 2; if (@available(macOS 13.3, iOS 19, visionOS 3, tvOS 19, *)) { numThreads = [device maximumConcurrentCompilationTaskCount]; } -
26:30 - Set a proper QoS class for your compilation threads
// Create thread pool for (NSInteger i = 0; i < numThreads; ++i) { // Creating a thread with a QoS class DEFAULT pthread_attr_set_qos_class_np(&attr, QOS_CLASS_DEFAULT, 0) ; pthread_create(&threadIds[i], &attr, entryPoint, NULL); pthread_attr_destroy(&attr); } -
28:24 - Harvest pipeline configuration scripts
// Harvest pipeline configuration scripts with the pipeline data set serializer // Create a pipeline data set serializer that only captures descriptors MTL4PipelineDataSetSerializerDescriptor *desc = [MTL4PipelineDataSetSerializerDescriptor new]; desc.configuration = MTL4PipelineDataSetSerializerConfigurationCaptureDescriptors; id<MTL4PipelineDataSetSerializer> serializer = [device newPipelineDataSetSerializerWithDescriptor:desc]; // Set the pipeline data set serializer when creating the compiler MTL4CompilerDescriptor *compilerDesc = [MTL4CompilerDescriptor new]; [compilerDesc setPipelineDataSetSerializer:serializer]; id<MTL4Compiler> compiler = [device newCompilerWithDescriptor:compilerDesc error:nil]; // Create pipelines using the compiler as usual // Serialize the descriptors as a pipeline script NSData *data = [serializer serializeAsPipelinesScriptWithError:&err]; // Write the pipeline script data to disk NSString *path = [NSString pathWithComponents:@[folder, @"pipelines.mtl4-json"]]; BOOL success = [data writeToFile:path options:NSDataWritingAtomic error:&err]; -
30:28 - Query pipeline state from MTLArchive
// Query pipeline state from MTLArchive id<MTL4Archive> archive = [device newArchiveWithURL:archiveURL error:&error]; id<MTLRenderPipelineState> pipeline = [archive newRenderPipelineStateWithDescriptor:descriptor error:&error]; if (pipeline == nil) { // handle lookup miss pipeline = [compiler newRenderPipelineStateWithDescriptor:descriptor compilerTaskOptions:nil }
-
-
- 0:00 - Introducción
Esta es la segunda de una serie de cuatro partes sobre Metal 4, la nueva API de gráficos de Apple diseñada para motores de juegos modernos. Metal 4 mejora la codificación de comandos, la administración de recursos y la carga de procesos. Metal 4 satisface las demandas de los juegos actuales y futuros que transmiten gigabytes de geometría y texturas detalladas, renderizadas con miles de sombreadores, para que puedan aprovechar toda la potencia informática disponible con el Apple Chip. Consulta también las otras partes de la serie para conocer más detalles sobre MetalFX, el trazado de rayos y la integración del aprendizaje automático.
- 1:33 - Codificar de forma más eficiente
Metal 4 está diseñado para mejorar la eficiencia del GPU mediante la optimización de la codificación de comandos. Presenta dos clases de codificador principales, render y compute, que ahora pueden procesar las operaciones de juego más comunes. Puedes usar Metal 4 para mejorar la eficiencia de la codificación mediante la reducción de codificadores, la reutilización de la memoria de comandos y la codificación en varios subprocesos.
- 8:42 - Escalar la gestión de recursos
Metal 4 tiene funcionalidades nuevas e interesantes para administrar recursos a escala. Las tablas de argumentos y los conjuntos de residencia permiten escalar la vinculación a miles de recursos. Metal 4 ayuda a administrar los recursos dibujables y ofrece control sobre las dependencias. Las barreras de fila ofrecen una forma de expresar las dependencias de recursos a escala. Los grupos de vistas de texturas y las pilas dispersas de ubicación ayudan a administrar la memoria que requieren recursos grandes.
- 17:24 - Cargar canales rápidamente
Los juegos modernos necesitan crear miles de procesos para crear imágenes complejas y dinámicas. Cargar rápido varios procesos es crucial para eliminar las intermitencias en la compilación de los sombreadores y reducir el tiempo de carga del juego. Para cargar procesos rápidamente en Metal 4, reúsa tus compilaciones de procesos de renderizado, compila procesos en el dispositivo con un nuevo nivel de paralelismo y hazlo con anticipación para que el tiempo de carga se reduzca casi a 0.
- 31:25 - Resumen
Las API de Metal 4 están diseñadas para crear la próxima generación de juegos de alto rendimiento. Puedes consultar la documentación en el sitio web para desarrolladores, probar los proyectos de muestra y descargar el nuevo Xcode para comenzar.