I'm trying to use an Argument Buffer with a Buffer pointer and noticed crashes XCode 13.2 (19585) while debugging (Frame Capture) on a MBP M1 Max (macOS 12.2.1):
Crashed Thread: 24 Dispatch queue: gputools.GPUMTLVariablesViewContentProvider.0x2d0638a40
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000a10
Exception Codes: 0x0000000000000001, 0x0000000000000a10
Exception Note: EXC_CORPSE_NOTIFY
I've created a small reproduction project (with screen recordings): https://github.com/peterwmwong/ArgumentBufferXCodeCrashRepro
It's essentially a stripped down version of Apple Developer sample code: https://developer.apple.com/documentation/metal/buffers/managing_groups_of_resources_with_argument_buffers?language=objc
Basically, this is the setup of the Argument Buffer (SceneArgumentBuffer) and Buffer pointer (Rectangle *) it references:
typedef struct Rectangle
{
vector_float4 color;
vector_float2 size;
} Rectangle;
struct SceneArgumentBuffer {
device Rectangle *rects [[ id(SceneArgumentBufferIDRectangles) ]];
};
vertex VertexOut
vertexShader(
uint instanceID [[ instance_id ]],
uint vertexID [[ vertex_id ]],
constant SceneArgumentBuffer &args [[ buffer(VertexBufferIndexArgumentBuffer) ]])
{
const Rectangle rect = args.rects[instanceID];
// ...
}
uint16_t numRects = 2;
_rectanglesBuffer = [_device newBufferWithLength:sizeof(Rectangle) * numRects
options:MTLResourceStorageModeShared];
_rectanglesBuffer.label = @"Rects Buffer";
Rectangle * const rects = _rectanglesBuffer.contents;
rects[0].color = simd_make_float4(0.0, 1.0, 0.0, 1.0);
rects[0].size = simd_make_float2(0.75, 0.75);
rects[1].color = simd_make_float4(0.0, 0.0, 1.0, 1.0);
rects[1].size = simd_make_float2(0.5, 0.25);
// Argument buffer creation and encoding
id<MTLArgumentEncoder> argumentEncoder =
[vertexFunction newArgumentEncoderWithBufferIndex:VertexBufferIndexArgumentBuffer];
_argumentBuffer = [_device newBufferWithLength:argumentEncoder.encodedLength options:0];
_argumentBuffer.label = @"Argument Buffer";
[argumentEncoder setArgumentBuffer:_argumentBuffer
offset:0];
[argumentEncoder setBuffer:_rectanglesBuffer
offset:0
atIndex:SceneArgumentBufferIDRectangles];
// Encoding into a Render Command
id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
[renderEncoder useResource:_rectanglesBuffer
usage:MTLResourceUsageRead
stages:MTLRenderStageVertex];
[renderEncoder setVertexBuffer:_argumentBuffer
offset:0
atIndex:VertexBufferIndexArgumentBuffer];
My application "works". Runs as expected, access to argument buffer and referenced buffer yields correct information to draw the screen correctly... it's just stinks (maintenance/development nightmare) that debugging is hosed. I can't debug shaders or look at pipeline statistics.
Is this suppose to work? Are there any weird XCode/Metal environment variables or settings that I should be using to get this to work?
Any help/suggestions would be appreciated, thanks!