This happens for me too on a fresh-out-of-box M3 device. Don't know if this was an intentional change or not.
The shortcut is still documented here https://support.apple.com/en-us/HT201236#:~:text=Control%2DD%3A%20Delete%20the%20character,Or%20use%20Control%2DD
Control-D is also commonly bound for forward delete but given Fn-Delete = Forward Delete on non-mac devices I'd rather keep Fn-Delete, and not all programs respect Control-D.
Post
Replies
Boosts
Views
Activity
Thanks for the information! I was able to use an option in spirv_cross "--msl-force-active-argument-buffer-resources" to ensure the same type is emitted for the vertex and fragment files. This fixes the case mentioned above.
I think in my case, I'm better off using the second approach. I don't have nested structures in argument buffers because I need to stay compatible with vulkan and other graphics APIs. Additionally the first approach would still require me to pass the "correct" indices when setting the values in functions like MTLArgumentEncoder's setBuffer/setTexture so it still requires me to use reflection data (which I already generate offline).
I'm actually not sure if there is a way to force spirv_cross to omit the [[id(n)]] attributes. So it would be helpful to know if there are rules I need to follow. It seems like the most important thing is to include the same fields in the same order in all shader stages and in the host code. I noticed that even if I use different IDs in the vertex MSL, fragment MSL, and my host application code, as long as the fields are the same order and nothing is omitted, the triangle renders fine. (Not that I would intentionally "ship" like that :D)
Thanks again for answering, it's been very helpful!
Full shaders here, please see the comment in the second file. Thanks for looking at this! I can post the full single-file repro but it is in rust.)
triangle.vert.metal
#include metal_stdlib
#include simd/simd.h
using namespace metal;
struct ArgsTransform
{
float4x4 transform;
};
struct spvDescriptorSetBuffer0
{
constant ArgsTransform* uniform_buffer [[id(0)]];
};
struct main0_out
{
float4 position [[position]];
};
struct main0_in
{
float2 in_pos [[attribute(0)]];
float3 in_color [[attribute(1)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
out.position = (*spvDescriptorSet0.uniform_buffer).transform * float4(in.in_pos, 0.0, 1.0);
return out;
}
triangle.frag.metal
#include metal_stdlib
#include simd/simd.h
using namespace metal;
struct ArgsTransform
{
float4x4 transform;
};
struct Args
{
float4 color;
};
struct spvDescriptorSetBuffer0
{
/*
If the [[id(0)]] field is commented out, uniform_buffer returns the value
that was bound to [[id(0)]] instead of [[id(1)]] and the triangle does not
draw because the color is incorrect (0 alpha)/
/* constant ArgsTransform* transform [[id(0)]]; */
constant Args* uniform_buffer [[id(1)]];
};
struct main0_out
{
float4 out_color [[color(0)]];
};
struct main0_in
{
};
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
out.out_color = spvDescriptorSet0.uniform_buffer-color;
return out;
}
Excerpts from code
This is in rust, sorry :D.
//
// Setup argument buffer
//
let desc0 = ArgumentDescriptor::new();
desc0.set_data_type(MTLDataType::Pointer);
desc0.set_index(0);
let desc1 = ArgumentDescriptor::new();
desc1.set_data_type(MTLDataType::Pointer);
desc1.set_index(1);
println!("args: {:#?}", [&desc0, &desc1]);
let args = Array::from_slice(&[desc0, desc1]);
let encoder = device.new_argument_encoder(&args);
let argument_buffer = device.new_buffer(encoder.encoded_length(), MTLResourceOptions::empty());
encoder.set_argument_buffer(&argument_buffer, 0);
encoder.set_buffer(0, &transform_buffer, 0);
encoder.set_buffer(1, &color_buffer, 0);
// Bind argument buffer to vertex and fragment shaders
encoder.set_vertex_buffer(0, Some(&argument_buffer), 0);
encoder.set_fragment_buffer(0, Some(&argument_buffer), 0);
encoder.use_resource(&transform_buffer, MTLResourceUsage::Read);
encoder.use_resource(&color_buffer, MTLResourceUsage::Read);
encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 3);