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);
Topic:
Graphics & Games
SubTopic:
General
Tags: