英文:
Using Metal API in background thread on macOS
问题
我的代码在CGContext中的并发线程上计算最终图像的部分(瓷砖)。我需要将每个计算的部分结果(顶点数据)在线程内传递到GPU,以便使用MPSImageGaussianBlur进行渲染。然后,我从生成的MTLTexture创建最终位图,并将其绘制回到CGContext和原始线程。每个线程上的所有渲染通道都利用一个共享的命令队列(在主线程上创建)。每个渲染通道在同一线程内启动和终止。其他线程不需要访问其他线程/渲染通道的资源,因为所有数据都在各自的线程中隔离。然而,在这种情况下,我不确定如何从主线程以外的线程调用Metal API(编码命令等)。尽管如此,我不能修改计算顶点数据的方式(在并发线程中)。您有关于如何安全地执行此任务的任何建议吗?谢谢。
英文:
my code calculates parts (tiles) of the final image on concurrent threads within CGContext. I need to pass the partial result of each calculation (vertex data) within a thread to the GPU for rendering by using MPSImageGaussianBlur. After that, I create the final bitmap from the resulting MTLTexture and draw it back to CGContext and the original thread. All render passes, on every thread, utilize a common commandQueue (created on the main thread). Each render pass initiates and terminates within the same thread. Other threads do not require access to resources from other threads/render passes as all data are isolated within their respective threads. However, I'm uncertain how to call Metal API ( encode commands, etc.) from threads other than the main thread in this circumstance. Despite this, I cannot modify the way I calculate vertex data (in concurrent threads). Do you have any advice on how to carry out this task securely? Thank you.
答案1
得分: 2
你可以在多个线程中使用 MTLCommandQueue
。无论命令队列在哪里创建都可以。命令队列的方法是线程安全的,这意味着你可以在后台线程上创建命令缓冲区并填充它,然后提交它。如果命令缓冲区需要按特定顺序执行,你可以在将它们交给后台线程之前使用 enqueue
来排队你的 MTLCommandBuffers
。或者你可以在它们准备好时只是 commit
它们。
请注意,尽管 MTLDevice、MTLCommandQueue 上的 API 是线程安全的,但MTLCommandBuffer 和其以下的所有 API,如任何命令编码器,都不是线程安全的。基本上,你可以给每个线程一个命令缓冲区,但不能将单个命令缓冲区交给多个线程。唯一的例外是并行渲染命令编码器,它们允许你创建“子编码器”,然后也可以在多个线程之间共享它们。
英文:
You can use the MTLCommandQueue
in multiple threads. It doesn't matter where the command queue is created. The methods of command queue are thread safe, which means you can create a command buffer and fill it out on a background thread and then commit it. You can either enqueue
your MTLCommandBuffers
before giving them away to a background thread, if the command buffers need to go in a specific order. Or you can just commit
them as they are ready.
Keep in mind, that the even though APIs on MTLDevice, MTLCommandQueue are safe, the APIs on MTLCommandBuffer and everything below, so any command encoder, are not thread safe. So basically, you can give each thread a command buffer, but you can't give a single command buffer to more than one thread. The only exception here is parallel render command encoders, which let you create "sub-encoders", that you can then also share between multiple threads.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论