文档列表见:Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)
【持续更新】
已知问题:
-
iOS 12新增接口
renderTargetArrayLength
。此接口默认值应该为0,表示禁用层渲染。若不小心设置为1,则出现Metal参数验证断言失败,信息如下:-[MTLRenderPassDescriptorInternal validate:width:height:]:1972: failed assertion `renderTargetArrayLength > 0 specified, but Layered Rendering is not supported on this device.'
The default value is 0, indicating layered rendering is not enabled.
-
Capture GPU Frame在iMac AMD显卡和MacBook Intel显卡的不同表现。 相同Metal代码在:
- iMac 5k Later 2015、macOS 10.14、Xcode 9.4.1,没法Capture GPU Frame,推测是AMD显卡驱动写的不够好,2017年同一台iMac用macOS 10.13也遇到此问题。
- MacBook Mid 2015、macOS 10.13.5、Xcode 9.4.1,可以Capture GPU Frame。不过,如果只通过MTLHeap创建Texture并上传纹理数据,由于不是完整绘制流程,没有Scope停止信号导致Capture GPU Frame确实捕获到Command Buffer,也就无法进入在线调试界面。
-
非Draw Call调用无法进入在线调试界面,非Draw Call是指MTLCommandBuffer的
commit()
和waitUntilCompleted()
。 由前面实践得出此结论。二次验证是RenderPass只配置ClearColor,渲染到纹理。let submit = { let mut cmd_buffer = command_pool.acquire_command_buffer(false); cmd_buffer.set_viewports(0, &[viewport.clone()]); { let mut encoder = cmd_buffer.begin_render_pass_inline( &render_pass, &framebuffer, viewport.rect, &[command::ClearValue::Color(command::ClearColor::Float([0.0, 1.0, 0.5, 1.0]))], ); }; cmd_buffer.finish() }; let submission = Submission::new() .wait_on(&[(&frame_semaphore, PipelineStage::BOTTOM_OF_PIPE)]) .submit(Some(submit)); queue_group.queues[0].submit(submission, Some(&mut frame_fence)); queue_group.queues[0].wait_idle(); // 等待队列任务执行完成 复制代码
-
验证Capture GPU Frame的Scope信号,即是Capture GPU Frame的结束信号,否则Xcode会一直收集MTLCommandBuffer却不进入Replay Frame界面,即前面说的调试界面。根据我的开发经验,结束信号可在代码中主动调用
MTLCaptureScope
实现,也会由MTLCommandBuffer::presentDrawable:
或MTLCommandBuffer::waitUntilCompleted
+MTLRenderCommandEncoder::drawPrimitives
系列函数触发,但是,由于TBDR机制与Metal驱动的性能调优原因,原则上只有发出MTLCommandBuffer::presentDrawable:
指令后,MTLCommandQueue才会执行已入队的MTLCommandBuffer,这是TBDR中的DR工作机制。