From what I understood by reading the docs, a 3D texture only has 1 slice. When I try to load data into it though, it fails with error:
MTLTexture.m:504: failed assertion `imageBytes(0) must be >= (2048).'
The code used to load is (texture is type MTLPixelFormatRG16Uint and size elementsInRow * elementsInRow * elementsInRow):
[texture replaceRegion:region mipmapLevel:0 withBytes:data bytesPerRow:sizeof(uint16_t) * 2 * elementsInRow];
where elementsInRow is 128, region is MTLRegion region = MTLRegionMake3D(50, 50, 50, 4, 4, 4); and data is uint16_t data[region.size.depth][region.size.height][region.size.width][2].
I also tried with:
[texture replaceRegion:region mipmapLevel:0 slice:0 data bytesPerRow:sizeof(uint16_t) * 2 * elementsInRow bytesPerImage:sizeof(uint16_t) * 2 * elementsInRow * elementsInRow];
but it results in a memory error.
See also here: https://forums.developer.apple.com/message/43332#43332
How can I correctly load data in a 3D region of a 3D texture?
UPDATE 1:
The second example works when the region has depth 1 and even bigger width and height (but with 32x32x1 it will crash).
UPDATE 2:
If I use 16x16x1 and write the same value for every pixel in the region, it seems to work, but when I export the data as an image, it looks like random data is being written instead, see this zoomed section of the image:

If I run the test again, the image will have the same top section in uniform color, but the rest of the points will change intensity. Notice that I am writing the same value to every pixel, so the region should just be of uniform color.
That was it. I was trying to read from outside of boundaries memory, as the bytesPerRow and bytesPerImage parameters were not correct.
The documentation says:
bytesPerRow
For an ordinary or packed pixel format, the stride, in bytes, between rows of source data.bytesPerImage
The stride, in bytes, between images in the source data.
I was passing the values thinking that they were referred to the texture, not the region.
So the code should be:
[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];
You can never read the documentation carefully enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With