Magenta screen and crash when sampling a texture through argument buffer.

Whenever my fragment shader tries to sample my texture, it causes the window to go magenta, and crash after a few seconds. I think I got all the parts right... does anyone see what I missed?

Shader:

struct TexStruct
{
  texture2d<float> tex [[id(0)]];
  sampler sam [[id(1)]];
};

fragment float4 frag(constant TexStruct& texStruct [[buffer(0)]])
{
    return texStruct.tex.sample(texStruct.sam, float2(.5, .5));
}```

Relavent Code: 
```objc++
int tex_width, tex_height, tex_channels;
stbi_uc* pixels = stbi_load("/Users/fancyfurret/Downloads/texture.jpg", &tex_width, &tex_height, &tex_channels, STBI_rgb_alpha);
MTLTextureDescriptor* textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
                                                               width:tex_width
                                                              height:tex_height
                                                           mipmapped:NO];
id<MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
MTLRegion region = MTLRegionMake2D(0, 0, tex_width, tex_height);
[texture replaceRegion:region mipmapLevel:0 withBytes:pixels bytesPerRow:4 * tex_width]

MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init];
id<MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:samplerDescriptor];

id<MTLArgumentEncoder> argEncoder = [fragmentFunction newArgumentEncoderWithBufferIndex:0];
id<MTLBuffer> argBuffer = [device newBufferWithLength:argEncoder.encodedLength options:MTLResourceStorageModeShared];
[argEncoder setArgumentBuffer:argBuffer offset:0];
[argEncoder setTexture:texture atIndex:0];
[argEncoder setSamplerState:sampler atIndex:1];
[argBuffer didModifyRange:NSMakeRange(0, argBuffer.length)];

// At draw time
[renderEncoder setFragmentBuffer:argBuffer offset:0 atIndex:0];
[renderEncoder useResource:texture usage:MTLResourceUsageRead];```



Accepted Answer

Hi FancyFurret,

There is a small gotcha when using MTLSamplerStates through argument buffers. In Metal, when you intend to store a MTLSamplerState in an argument buffer, you must first request support for this at sampler creation time.

Set the supportArgumentBuffers property of your MTLSamplerDescriptor to YES before you create the Sampler State so you can then correctly use it in from your fragment shader through your argument buffer - https://developer.apple.com/documentation/metal/mtlsamplerdescriptor/2915782-supportargumentbuffers?language=objc

This is necessary because samplers are a bit different from other Metal resource types you typically store in argument buffers.

Magenta screen and crash when sampling a texture through argument buffer.
 
 
Q