MTLTextureLoader creates Texture on iPad but not on iPhone

I'm using MTKTextureLoader to try and load a texture it works on iPads, but not on iPhone where I get the error : Error Domain=MTKTextureLoaderErrorDomain Code=0 "Image decoding failed" UserInfo={NSLocalizedDescription=Image decoding failed, MTKTextureLoaderErrorKey=Image decoding failed


I'd like to know why, how to detect it, and how to work around it.


im working with devices using iOS 11 and 12, but the version doesn't seem to make a difference, just iPad/iPhone


Setup to hand right now:

iPhone X: iOS 12.1.3 , A11 GPU

iPad : iOS 11.4.1, A9 GPU


The texture is JPG format, size 8192 x 8192, and when it loads, it has the pixelformat MTLPixelFormatBGRA8Unorm_sRGB


The code to load it is:

    NSError *textureError;
    //self.texture =[textureLoader newTextureWithCGImage:image.CGImage options:textureLoadingOptions error:&textureError];
    self.texture = [textureLoader newTextureWithContentsOfURL:textureURL
                                                      options:textureLoadingOptions
                                                        error:&textureError];
    if (textureError) {
   
        NSLog(@"Texture failed to load  %@ with error : %@", image, textureError);
        return NO;
    }


The commented out code was checking loading the texture from an UIImage, the result is the same.


Thinking it was the feature set, I checked the devices supported all the iOS 11 feature sets, the iPhone support all of them, the iPad supports all but MTLFeatureSet_iOS_GPUFamily4_v1 . I was expecting the iPhone to not support one.


I saw this question which has the same error: https://forums.developer.apple.com/thread/97218


I haven't tried the solution yet but it's my next step, but it won't be a very useful solution if I can't detect when I have to use it.

Accepted Reply

I managed to solve this by loading the texture manually using CGImage abd CGDataProvider, drawing the image into a CGContext, then copying and swapping the bytes from RGB to BGRA and using that to create the texture. Similar to the technique used in Apple's Basic Texturing example.


As it's possible to do manually, I beleive this is a bug in the MTKTextureLoader

Replies

I managed to solve this by loading the texture manually using CGImage abd CGDataProvider, drawing the image into a CGContext, then copying and swapping the bytes from RGB to BGRA and using that to create the texture. Similar to the technique used in Apple's Basic Texturing example.


As it's possible to do manually, I beleive this is a bug in the MTKTextureLoader

This happens on macOS 12 with an image created using -[NSImage lockFocus], depending on what the main display is.

This makes me wonder why MTKTextureLoader exists. It would be a nice convenience if it worked reliably.