相当于内核程序的 Metal 中的 glColorMask?

Equivalent of glColorMask in Metal for a kernel program?

我正在尝试将我的 iOS 应用程序从 OpenGL 迁移到 Metal。在我的 OpenGL 代码中,我在很多地方使用 glColorMask(如果我只想写入选定的通道,例如只写入纹理的 alpha 通道)。

在 Metal 中,对于渲染管线(虽然顶点和片段着色器)似乎 MTLColorWriteMask 等同于 glColorMask。我可以在通过 MTLRenderPipelineDescriptor 创建 MTLRenderPipelineState 时设置它。

但我找不到类似的计算管道选项(通过内核函数)。每次写入输出纹理时,我总是需要写入所有通道(红色、绿色、蓝色和 alpha)。如果我想保留 alpha(或任何其他通道)并且只想修改颜色通道怎么办?我可以创建输出纹理的副本并将其用作输入之一并从中读取 alpha 以保留值,但这很昂贵。

计算机内存架构不喜欢只写入一些字节的数据。写入 4 个字节中的 1 个通常涉及将这四个字节读入缓存,修改缓存中的其中一个,然后将这四个字节写回到内存中。好吧,大多数计算机 read/write 一次 很多 超过 4 个字节,但你明白了。

帧缓冲区也会发生这种情况。如果您执行部分写入掩码,硬件仍将在该纹理上执行相当于 read/modify/write 的操作。它只是没有改变它读取的所有字节。

因此您可以从计算着色器中执行相同的操作。读取 4 向量值,修改所需的通道,然后将其写回。只要读取和写入来自同一个着色器调用,就不会有同步问题(假设没有其他调用试图 read/write 到同一位置,但如果是这样的话,你会无论如何都有问题)。