Texture Pixel layout in Metal

I'm working on an app in MacOS in which I need to do mouse picking in a MTKView. To do this I render a Hit Triangle map of the mouse active areas into a MTLTexture. Since these areas do not change at run time the map only has to be rendered once. The metal debugger noticed this and suggested the texture resources be made purgeable. So I copied the pixel data out of the texture and marked the the texture as purgeable. I then read the pixel data from the C array and the mouse picking was screwed up. The Hit Triangles were not where they were supposed to be. I fussed around a bit and by trial and error I found out the pixels were copied out into the C array in column major order rather than row major order. I looked in the Metal documentation and couldn't find anywhere where this was pointed out. Is there anywhere in the Metal docs where it specifies how the pixels are laid out in a texture and how that relates to the viewable coordinates? This is not first time I've had problems related to this. Little details like this can really hang you up.


// Since the hit map only has to be made once the data is copied out
// and the texture is made purgeable.  This to stop the debugger
// from nagging about it.

[pickTexture getBytes: hitTriangleMap
          bytesPerRow: PICK_TEXTURE_SIZE * sizeof(uint8 [4])
           fromRegion: MTLRegionMake2D( 0  ,  0 , PICK_TEXTURE_SIZE, PICK_TEXTURE_SIZE)
          mipmapLevel: 0];

[pickTexture setPurgeableState: MTLPurgeableStateVolatile];
[pickDepth setPurgeableState: MTLPurgeableStateVolatile];
//
//     *
//     *
//     *
//
//  Previous inefficient version
//
//        [pickTexture getBytes: hit
//                  bytesPerRow: PICK_TEXTURE_SIZE * sizeof(uint8 [4])
//                   fromRegion: MTLRegionMake2D( hitPoint.x ,  hitPoint.y , 1, 1)
//                  mipmapLevel: 0];

// New Version   Column major arrays??  In any event it works this way.

x = hitPoint.x;
y =  hitPoint.y;
hit = hitTriangleMap[y][x];  //Inverted subscripts!!!

if( hit[0] <= Zs)
{
    cursorHit = hit[0];
    if( cursorOverHitArea == NO)
        [[NSCursor pointingHandCursor] set];
    cursorOverHitArea = YES;
}```

Replies

On reading my post I realized that the data in the C array is in row major order. The row index changes fastest and that is the right most index in a C array. I feel stupid.

Yes, you are correct that the C array is in row major order. It's important to note that not all languages address them equally. Some languages like Fortran, use column major order when storing the data, but use the same style (row, column) addressing. But in many shading languages, like Metal Shading Language, the first subscript is the column, and the second subscript is the row because for linear algebra reasons, vectors are treated like columns.