johnbakers
johnbakers

Reputation: 24770

How to create a 1D Metal Texture?

I want an array of 1-dimensional data (essentially an array of arrays) that is created at run time, so the size of this array is not known at compile time. I want to easily send the array of that data to a kernel shader using setTextures so my kernel can just accept a single argument like texture1d_array which will bind each element texture to a different kernel index automatically, regardless of how many there are.

The question is how to actually create a 1D MTLTexture ? All the MTLTextureDescriptor options seem to focus on 2D or 3D. Is it as simple as creating a 2D texture with the height of 1? Would that then be a 1D texture that the kernel would accept?

I.e.

 let textureDescriptor = MTLTextureDescriptor
        .texture2DDescriptor(pixelFormat: .r16Uint,
                             width: length,
                             height: 1,
                             mipmapped: false)

If my data is actually just one dimensional (not actually pixel data), is there is an equally convenient way to use an ordinary buffer instead of MTLTexture, with the same flexibility of sending an arbitrarily-sized array of these buffers to the kernel as a single kernel argument?

Upvotes: 2

Views: 437

Answers (1)

user652038
user652038

Reputation:

You can recreate all of those factory methods yourself. I would just use an initializer though unless you run into collisions.

public extension MTLTextureDescriptor {
  /// A 1D texture descriptor.
  convenience init(
    pixelFormat: MTLPixelFormat = .r16Uint,
    width: Int
  ) {
    self.init()
    textureType = .type1D
    self.pixelFormat = pixelFormat
    self.width = width
  }
}
MTLTextureDescriptor(width: 512)

This is no different than texture2DDescriptor with a height of 1, but it's not as much of a lie. (I.e. yes, a texture can be thought of as infinite-dimensional, with a magnitude of 1 in everything but the few that matter. But we throw out all the dimensions with 1s when saying "how dimensional" something is.)

var descriptor = MTLTextureDescriptor.texture2DDescriptor(
  pixelFormat: .r16Uint,
  width: 512,
  height: 1,
  mipmapped: false
)
descriptor.textureType = .type1D
descriptor == MTLTextureDescriptor(width: 512) // true

——

textureType = .typeTextureBuffer takes care of your second question, but why not use textureBufferDescriptor then?

Upvotes: 2

Related Questions