-
Explore jogos feitos com o Metal 4
Saiba como otimizar o mecanismo do seu jogo com os últimos avanços do Metal 4. Abordaremos como unificar a codificação de comandos para minimizar a sobrecarga na CPU, aumentar o gerenciamento de recursos gráficos para compatibilidade com cenas grandes e maximizar seu orçamento para memória e carregar rapidamente bibliotecas grandes de configurações do pipeline.
Para aproveitar ao máximo esta sessão, primeiro assista ao vídeo “Conheça o Metal 4”.Capítulos
- 0:00 - Introdução
- 1:33 - Codificar com mais eficiência
- 8:42 - Aumentar o gerenciamento de recursos
- 17:24 - Carregar pipelines rapidamente
- 31:25 - Próximas etapas
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
Vídeos relacionados
WWDC25
- Aprimore jogos com o Metal 4
- Combine o aprendizado de máquina e os gráficos do Metal 4
- Conheça o Metal 4
- Melhore ainda mais seus jogos
- Novidades na renderização no Metal para apps imersivos
Tech Talks
-
Buscar neste vídeo...
-
-
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 - Introdução
Esta é a segunda de uma série de quatro partes no Metal 4, a nova API gráfica da Apple criada para mecanismos de jogos modernos. O Metal 4 aprimora a codificação de comandos, o gerenciamento de recursos e o carregamento de pipeline. Ele atende às demandas de jogos atuais e futuros, que transmitem gigabytes de geometria detalhada e texturas, renderizadas com milhares de sombreadores, para aproveitar todo o poder da computação que o Apple Silicon oferece. Assista também às outras partes da série para saber mais sobre MetalFX, traçado de raios e integração de aprendizado de máquina.
- 1:33 - Codificar com mais eficiência
O Metal 4 foi projetado para aumentar a eficiência da GPU otimizando a codificação de comandos. Ele apresenta duas classes principais de codificadores, renderização e computação, que agora podem processar as operações de jogos mais comuns. Use o Metal 4 para melhorar a eficiência da codificação reduzindo o número de codificadores, reutilizando a memória de comando e codificando em várias threads.
- 8:42 - Aumentar o gerenciamento de recursos
O Metal 4 tem alguns recursos interessantes para ajudar a gerenciar as funcionalidades. As tabelas de argumentos e os conjuntos residentes permitem dimensionar a associação de milhares de recursos. O Metal 4 permite gerenciar os recursos de desenho e dá controle sobre dependências. As barreiras de filas permitem expressar as dependências de recursos. Os pools de visualização de textura e os heaps esparsos de posicionamento ajudam a gerenciar a memória de recursos grandes.
- 17:24 - Carregar pipelines rapidamente
Os jogos modernos precisam criar milhares de pipelines para criar visuais complexos e dinâmicos. Carregar muitos pipelines com rapidez é crucial para eliminar travamentos na compilação dos sombreadores e reduzir o tempo de carregamento do jogo. Para fazer isso no Metal 4, reutilize suas compilações de pipeline de renderização, compile os pipelines no dispositivo com um novo nível de paralelismo e com antecedência para que o tempo de carregamento seja reduzido para quase 0.
- 31:25 - Próximas etapas
As APIs do Metal 4 foram projetadas para você criar a próxima geração de jogos de alto desempenho. Você pode conferir a documentação no site do desenvolvedor, testar os projetos de exemplo e baixar o novo Xcode para começar.