金属纹理不可过滤



我正在尝试对MTLTexture对象中包含的纹理进行微调映射。这种纹理是从OpenCV Mat加载的。我可以在这个纹理上正确运行内核,所以我知道我的导入过程是正确的。

不幸的是,生成mipmaps函数给出了这个相当不透明的错误。即使我temp更改为 BGRA,我也会收到类似的错误。

-[MTLDebugBlitCommandEncoder generateMipmapsForTexture:]:1074: 
failed assertion `tex(MTLPixelFormatR8Uint) is not filterable.'
// create an MTL Texture
{
MTLTextureDescriptor * textureDescriptor = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Uint
width:cols
height:rows
mipmapped:NO];
textureDescriptor.usage = MTLTextureUsageShaderRead;
_mImgTex = [_mDevice newTextureWithDescriptor:textureDescriptor];
}
{
MTLTextureDescriptor * textureDescriptor = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Uint
width:cols
height:rows
mipmapped:YES];
textureDescriptor.mipmapLevelCount = 5;
textureDescriptor.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
_mPyrTex = [_mDevice newTextureWithDescriptor:textureDescriptor];
}

// copy data to GPU
cv::Mat temp;
cv::cvtColor(image, temp, cv::COLOR_BGRA2GRAY);
MTLRegion region = MTLRegionMake2D(0, 0, cols, rows);
const int bytesPerPixel = 1 * 1; // 1 uint * 1 channels
const int bytesPerRow = bytesPerPixel * cols;
[_mImgTex replaceRegion:region mipmapLevel:0 withBytes:temp.data bytesPerRow:bytesPerRow];
// try to mipmap
id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
MTLOrigin origin = MTLOriginMake(0, 0, 0);
MTLSize size = MTLSizeMake(cols, rows, 1);
[blitEncoder copyFromTexture:_mImgTex sourceSlice:0 sourceLevel:0 sourceOrigin:origin sourceSize:size toTexture:_mPyrTex destinationSlice:0 destinationLevel:0 destinationOrigin:origin];
[blitEncoder generateMipmapsForTexture:_mPyrTex];
[blitEncoder endEncoding];

generateMipmapsForTextures的文档说:

Mipmap 生成仅适用于具有可渲染和可滤色像素格式的纹理。

如果您查看此处的"像素格式功能"表,您会发现R8Uint不支持Filter,也无法呈现颜色(Color(。

也许R8Unorm(MTLPixelFormatR8Unorm(可以很好地满足您的需求。否则,您可能需要使用计算编写自己的 mip 生成代码(尽管我不确定是否有具有不可过滤纹理的 mipmap 用例(。

最新更新