Search code examples
objective-cmetal

Loading data into a texture defined as a MTLTextureType1DArray


I'm trying to set up some compute kernels that require interpolating some radial profiles of Fourier coefficients. Essentially I need to be discreet in one index but interpolating in the other. I figured that implementing these a 1D texture array would allow me to use the built in interpolation functions of my GPU. Looking through the Metal docs, it seems like a MTLTextureType1DArray with a MTLPixelFormatR32Float would be the right setup for this.

I'm setting up my texture description as

MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
textureDescriptor.pixelFormat = MTLPixelFormatR32Float;
textureDescriptor.textureType = MTLTextureType1DArray;

textureDescriptor.width = numRadialPoints;
textureDescriptor.height = 1;
textureDescriptor.depth = 1;

textureDescriptor.arrayLength = numArrays;

textureDescriptor.mipmapLevelCount = 1;
textureDescriptor.sampleCount = 1;

textureDescriptor.resourceOptions = MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeManaged;
textureDescriptor.cpuCacheMode = MTLCPUCacheModeWriteCombined;
textureDescriptor.storageMode = MTLStorageModeManaged;
textureDescriptor.usage = MTLTextureUsageShaderRead;

What I can't figure out is how to now load the texture data. My first attempt was to

_texture = [device newTextureWithDescriptor:textureDescriptor];
[_texture replaceRegion:MTLRegionMake2D(0, 0, numRadialPoints, numArrays) mipmapLevel:0 withBytes:floatbuffer bytesPerRow:4*numRadialPoints];

But this results in an error since heights don't match.

_validateReplaceRegion:144: failed assertion `(origin.y + size.height)(163) must be <= height(1).'

How do I load data into a MTLTextureType1DArray?


Solution

  • You need to use multiple calls to -replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:, once for each element of the array. You specify the array index with the slice parameter.

    The region parameter needs to be 1-dimensional.