Search code examples
iosswiftmetal

How to bind Array Texture 2D in Metal


I am trying to use an array texture 2D in metal by following what I could dig about them from the internet. I was successfully able to initialise my texture array but now I am stuck with an error that shows up after binding the texture with myEncoder.setFragmentTexture(myTextureArray, index: myIndex):

Failed assertion `Fragment Function(basicFragment): incorrect type of
texture (MTLTextureType2DArray) bound at texture binding at index 0
(expect MTLTextureType2D) for texture[0].

No idea what I am doing wrong here and unfortunately neither does Google. I guess I need to call a specific function to bind an array texture instead of the one used to bind ordinary textures (setFragmentTexture), or maybe I am mysteriously setting my texture type to be single 2D texture somewhere else and not allowing a texture array to be set? So my question is:

How to appropriately bind my texture array in Metal?

EDIT:

My fragment shader:

fragment float4 basicFragment(VertexOut vertexOut [[ stage_in ]],
                              texture2d<float> texture [[ texture(0) ]],
                              sampler sampler2D [[ sampler(0) ]])
{
    return texture.sample(sampler2D, vertexOut.texCoord, vertexOut.slice);
}

Solution

  • According to the Metal Shading Language Specification, on page 26:

    The following example uses access qualifiers with texture object arguments.

    void foo (texture2d<float> imgA [[texture(0)]],
             texture2d<float, access::read> imgB [[texture(1)]],
             texture2d<float, access::write> imgC [[texture(2)]])
    

    On the previous page, they show that instead of using texture2d<type, access>, you'd use texture2d_array<type, access> for a 2D texture array. So I think it would be something like:

    void basicFragment(texture2d_array<float> imgA [[texture(0)]],...
    

    for example.