Is it possible to use textures with GPU-driven indirect command buffers on Metal running on the A11 hardware?
First, the Metal indirect command buffer API does not have a `set_texture` method, just `set_vertex_buffer` and `set_fragment_buffer`. However, with argument buffers, a texture can be placed inside a buffer, so in theory it should be possible to use textures in indirect command buffers. Whenever I try this though, the MTLCompiler crashes.
Is this a bug, or is it an intended feature that textures can't be used in indirect command buffers? If so, that's a major limitation, and I'm a little surprised that it isn't called out anywhere that I can find in the documentation. On the other hand, Apple's only code sample of indirect command buffers doesn't use any textures, so I have my suspicions.
Here's some sample code to demonstrate the MTLCompiler crash. If you uncomment the `set_fragment_buffer` line that sets the argument buffer containing textures, MTLCompiler crashes with "MTLCompiler: Compilation failed with XPC_ERROR_CONNECTION_INTERRUPTED"
```
struct ICBContainer {
command_buffer commandBuffer [[ id(0) ]];
};
typedef struct TextureData {
texture2d<half> albedo [[ id(1) ]];
} TextureData;
kernel void encodeDraw(uint nodeId [[ thread_position_in_grid ]],
device VertexIn *vertices [[ buffer(BufferIndexVertices) ]],
device uint *indices [[ buffer(BufferIndexIndices) ]],
device ICBContainer *container [[ buffer( BufferIndexICBContainer ) ]],
device TextureData *textureData [[ buffer(BufferIndexTextureData) ]],
device InstanceData* instances [[ buffer( BufferIndexInstances ) ]],
constant VoxelUniforms *uniforms [[ buffer(BufferIndexVoxelUniforms)]], //nb has to be passed by pointer in order to be encoded
device ObjectParameters *parameters [[ buffer(BufferIndexObjectParameters) ]]
) {
InstanceData instance = instances[nodeId];
float4x4 modelMatrix = instance.modelMatrix;
// TODO frustum culling
instances[nodeId].normalViewMatrix = rotationMatrix(uniforms->viewMatrix) * rotationMatrix(modelMatrix);
instances[nodeId].shadowMVPTransformMatrix = clipToTexture * uniforms->shadowViewProjectionMatrix * modelMatrix;
render_command cmd(container->commandBuffer, nodeId);
cmd.set_vertex_buffer(instances, BufferIndexInstances);
cmd.set_vertex_buffer(vertices, BufferIndexVertices);
cmd.set_vertex_buffer(uniforms, BufferIndexVoxelUniforms);
cmd.set_fragment_buffer(uniforms, BufferIndexVoxelUniforms);
// cmd.set_fragment_buffer(textureData, BufferIndexTextureData); // uncomment this and compilation crashes
cmd.draw_indexed_primitives(primitive_type::triangle,
parameters[instance.meshId].indexCount,
indices, 1, parameters[instance.meshId].baseVertex,
nodeId);
};
```