【问题标题】:How to set texture storage mode to `private` to texture created from `CVMetalTextureCacheCreateTextureFromImage`?如何将纹理存储模式设置为“私有”以从“CVMetalTextureCacheCreateTextureFromImage”创建纹理?
【发布时间】:2020-11-06 20:18:44
【问题描述】:

Xcode 的GPU frame capture 将多个表达式突出显示为紫色,并说我应该将纹理存储模式设置为private,因为只有 GPU 可以访问它。我正在尝试修复紫色建议。

Memory Usage'Texture:0x10499ae00 "CoreVideo 0x6000017f2bc0"' 具有存储模式 'Managed' 但仅由 GPU 访问

当使用device.makeBuffer(bytes:length:options:)创建MTLTexture时,我可以在参数options中将storageMode设置为private

但是当从CVPixelBufferCVMetalTextureCacheCreateTextureFromImage()创建MTLTexture时,我不知道如何为创建的纹理配置存储模式。

我尝试过的方法:

  • 将纹理属性字典传递给CVMetalTextureCacheCreateTextureFromImage(..., _ textureAttributes: CFDictionary?, ...) 中的textureAttributes 参数
var textureAttrs: [String: Any] = [:]
if #available(macOS 10.15, *) {
    textureAttrs[kCVMetalTextureStorageMode as String] = MTLStorageMode.private
}
CVMetalTextureCacheCreateTextureFromImage(,,,textureAttrs as CFDictionary,..., &texture)

if let texture = texture,
    let metalTexture = CVMetalTextureGetTexture(texture) {
        print(metalTexture.storageMode.rawValue)
    }
}

我的操作系统已经是 10.15.4,但创建的 MTLTexture 仍然有 storageMode 作为 managed/rawValue: 1

  • 将相同的属性传递给CVMetalTextureCacheCreate(),这会在cacheAttributestextureAttributes 中为CVMetalTextureCacheCreateTextureFromImage 创建缓存。

结果是一样的。

问题:

  • 是我的属性字典设置了错误的键值对吗?苹果文档没有描述需要设置哪些键和值。
  • 或者有正确的配置方式
  • 还是目前还不支持?

参考资料:

【问题讨论】:

  • 我也遇到了同样的问题...你找到什么了吗?
  • @vtruant 还没有。还在等待答案。

标签: swift macos metal core-video


【解决方案1】:

我有使用 Metal 的经验并且遇到过同样的问题。没有办法改变纹理storageMode 一个苍蝇。您必须使用所需的storageMode 创建另一个MTLTexture 并使用MTLBlitCommandEncoder 将数据复制到其中。

这是我项目中的一段代码:

    MTLTextureDescriptor* descriptor = [[MTLTextureDescriptor alloc] init];
    descriptor.storageMode = MTLStorageModePrivate;
    descriptor.pixelFormat = MTLPixelFormatRGBA8Unorm;
    descriptor.width = width;
    descriptor.height = height;

    id<MTLTexture> texture = [__metal_device newTextureWithDescriptor: descriptor];

    if ((data != NULL) && (size > 0)) {
        id<MTLCommandQueue> command_queue = [__metal_device newCommandQueue];
        id<MTLCommandBuffer> command_buffer = [command_queue commandBuffer];
        id<MTLBlitCommandEncoder> command_encoder = [command_buffer blitCommandEncoder];
        id<MTLBuffer> buffer = [__metal_device newBufferWithBytes: data
                                                           length: size
                                                          options: MTLResourceStorageModeShared];
        [command_encoder copyFromBuffer: buffer
                           sourceOffset: 0
                      sourceBytesPerRow: (width * 4)
                    sourceBytesPerImage: (width * height * 4)
                             sourceSize: (MTLSize){ width, height, 1 }
                              toTexture: texture
                       destinationSlice: 0
                       destinationLevel: 0
                      destinationOrigin: (MTLOrigin){ 0, 0, 0 }];

        [command_encoder endEncoding];
        [command_buffer commit];
        [command_buffer waitUntilCompleted];
    }

【讨论】:

    【解决方案2】:

    要设置纹理属性 - 您可以使用 rawValueMTLStorageMode。例如:

        var textureAttrs: [String: Any] = [:]
        
        if #available(macOS 10.15, *) {
            result[kCVMetalTextureStorageMode as String] = MTLStorageMode.managed.rawValue
        }
    
        var textureCache: CVMetalTextureCache!
        let textureCache = CVMetalTextureCacheCreate(
                nil, nil, device, textureAttrs as CFDictionary, &self.textureCache)
    

    使用这些纹理属性创建缓存后,您可以在创建每个纹理时将 nil 作为纹理属性传递给 CVMetalTextureCacheCreateTextureFromImage,因为它将使用创建缓存时使用的任何存储模式。例如:

          var cvTexture: CVMetalTexture?
          CVMetalTextureCacheCreateTextureFromImage(nil, textureCache, pixelBuffer, nil, .bgra8Unorm, width, height, 0, &cvTexture)
    

    注意事项 - 我在 Xcode 中收到金属警告,提示我的纹理应该设为私有而不是托管,但是在将缓存设置为私有存储模式时,出现以下错误:

    failed assertion 'Texture Descriptor Validation IOSurface textures must use MTLStorageModeManaged'

    这是因为这些纹理是 IOSurface 支持的。所以现在我一直在管理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2018-03-31
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 2013-01-01
      相关资源
      最近更新 更多