Metal 中存在矛盾的 textureUsage 的持续错误?

Persistent error with contradictory textureUsage in Metal?

这发生在我尝试使用 CAMetalLayer 渲染金属时,以及我下载的许多 'Metal By Example' 示例代码中。问题出在 'texture' 我想,这是一些代码,我无法提供所有代码,但我会尝试提供最相关的部分。它不接受纹理描述符,将其打印到控制台。

failed assertion `MTLTextureDescriptor: Depth, Stencil, DepthStencil, and Multisample textures must be allocated with the MTLStorageModePrivate or MTLStorageModeMemoryless storage mode.'

- (void)buildDepthTexture
{
    CGSize drawableSize = self.layer.drawableSize;
    MTLTextureDescriptor *descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float
                                                                                          width:drawableSize.width
                                                                                         height:drawableSize.height
                                                                                      mipmapped:NO];
    self.depthTexture = [self.device newTextureWithDescriptor:descriptor]; // Thread 1: signal SIGABRT
    [self.depthTexture setLabel:@"Depth Texture"];
}

同样,这是可能有效但不再有效的示例代码。所以我想好吧,让我们用私有存储模式或一些垃圾来分配它。 descriptor.storageMode = MTLStorageModePrivate;

但是当我这样做时,无法在 draw 中创建渲染过程描述符。

failed assertion `Texture at depthAttachment has usage (0x01) which doesn't specify MTLTextureUsageRenderTarget (0x04)'

MTLRenderPassDescriptor *renderPass = [self newRenderPassWithColorAttachmentTexture:[drawable texture]];

id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];

id<MTLRenderCommandEncoder> commandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPass]; //Thread 1: signal SIGABRT

这是 newRenderPassWithColorAttachmentTexture 的代码。

- (MTLRenderPassDescriptor *)newRenderPassWithColorAttachmentTexture:(id<MTLTexture>)texture
{
    MTLRenderPassDescriptor *renderPass = [MTLRenderPassDescriptor new];

    renderPass.colorAttachments[0].texture = texture;
    renderPass.colorAttachments[0].loadAction = MTLLoadActionClear;
    renderPass.colorAttachments[0].storeAction = MTLStoreActionStore;
    renderPass.colorAttachments[0].clearColor = MBEClearColor;

    renderPass.depthAttachment.texture = self.depthTexture;
    renderPass.depthAttachment.loadAction = MTLLoadActionClear;
    renderPass.depthAttachment.storeAction = MTLStoreActionStore;
    renderPass.depthAttachment.clearDepth = 1.0;

    return renderPass;
}

所以基本上,两个不同的渲染阶段似乎需要两个不同的互斥条件。如果一个有效,则另一个无效,反之亦然。似乎不可能,说真的,我该怎么办?给出了什么?

你应该提供纹理使用说明:

    - (void)buildDepthTexture
    {
        CGSize drawableSize = self.layer.drawableSize;
        MTLTextureDescriptor *descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float
                                                                                              width:drawableSize.width
                                                                                             height:drawableSize.height
                                                                                          mipmapped:NO];
    
        descriptor.storageMode = MTLStorageModePrivate;
        descriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;

        self.depthTexture = [self.device newTextureWithDescriptor:descriptor]; // Thread 1: signal SIGABRT
        [self.depthTexture setLabel:@"Depth Texture"];
    }