在Metal中将数据加载到3D纹理中

4

从我阅读文档所了解到的是,3D纹理只有一个切片。但是当我尝试加载数据时,会出现错误:

MTLTexture.m:504: failed assertion `imageBytes(0) must be >= (2048).'

用于加载的代码如下(纹理类型为 MTLPixelFormatRG16Uint,大小为 elementsInRow * elementsInRow * elementsInRow):

[texture replaceRegion:region mipmapLevel:0 withBytes:data bytesPerRow:sizeof(uint16_t) * 2 * elementsInRow];

其中elementsInRow128,区域为MTLRegion region = MTLRegionMake3D(50, 50, 50, 4, 4, 4);,数据为uint16_t data[region.size.depth][region.size.height][region.size.width][2]

我同样尝试了以下内容:

[texture replaceRegion:region mipmapLevel:0 slice:0 data bytesPerRow:sizeof(uint16_t) * 2 * elementsInRow bytesPerImage:sizeof(uint16_t) * 2 * elementsInRow * elementsInRow];

但是这会导致内存错误。

还可以在此处查看:https://forums.developer.apple.com/message/43332#43332

如何正确地在3D纹理的3D区域中加载数据?

更新1:

第二个示例适用于区域深度为1,甚至更大的widthheight(但使用32x32x1时会崩溃)。

更新2:

如果我使用16x16x1并且在区域中的每个像素写入相同的值,则似乎可以工作,但是当我将数据导出为图像时,它看起来像是随机数据而不是统一的颜色。请参见图像的缩放部分:

enter image description here

如果我再次运行测试,图像将具有相同的顶部部分,呈均匀颜色,但其余点的强度将发生变化。请注意,我正在向每个像素写入相同的值,因此该区域应具有均匀的颜色。

1个回答

4

这就是问题所在。由于bytesPerRowbytesPerImage参数不正确,我试图从超出边界的内存中读取数据。

文档中解释如下:

bytesPerRow
对于普通或打包像素格式,源数据行之间的跨度(以字节为单位)。

bytesPerImage
源数据中图像之间的跨度(以字节为单位)。

我传递了这些值,认为它们是针对纹理而非区域

因此,代码应该是:

[texture replaceRegion:region mipmapLevel:0 slice:0 data bytesPerRow:sizeof(uint16_t) * 2 * region.size.width bytesPerImage:sizeof(uint16_t) * 2 * region.size.width * region.size.height];

你永远不可能对文档读得太仔细。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接