在金属着色语言中创build全局可访问的常量缓冲区

我有一个关于金属常量缓冲区的问题。 我们假设,我有这样的东西:

...list of includes goes here... using namespace metal; struct ConstantBuffer { float ANY_VALUE; }; struct VS_INPUTS { float4 i_pos_ms [ [ attribute ( 0 ) ] ] ; } ; struct V2P_STRUCT { float4 v_pos_out [ [ position ] ] ; } ; float3 CalcSomething() { return float3(ANY_VALUE, ANY_VALUE, ANY_VALUE); // !!!!!!!! } vertex V2P_STRUCT VertexFunc(VS_INPUTS vs_inputs [ [ stage_in ] ] , constant ConstantBuffer& cb [ [ buffer (1) ] ] ) { V2P_STRUCT vs_outputs; vs_outputs.v_pos_out.xyz = CalcSomething(); vs_outputs.v_pos_out.w = cb.ANY_VALUE; // that's OK return vs_outputs; } 

是否可以调用CalcSomething()而不传递ANY_VALUE作为input参数?
例如,在DX11或OpenGL中,您可以创build常量缓冲区,可以从着色器代码中的每个位置访问该缓冲区。

我想将“cb”的内容复制到临时的全局对象,但我不知道该怎么做(因为地址空间不变)。

另一个想法是以某种方式在全局范围内声明“cb”(但是不幸的是[[buffer]]只能用于参数)。 这有什么窍门吗?

解决我的问题:

 #include <metal_stdlib> #include <metal_graphics> #include <metal_texture> #include <metal_matrix> #include <metal_math> #include <metal_geometric> #include <metal_common> using namespace metal; constant float MyVariable = 4; struct ConstantBuffer { float ANY_VALUE; }; struct VS_INPUTS { float4 i_pos_ms [ [ attribute ( 0 ) ] ] ; }; struct V2P_STRUCT { float4 v_pos_out [ [ position ] ] ; }; struct VertexShader { thread VS_INPUTS& vs_inputs; thread texture2d<float> img; constant ConstantBuffer& cb; VertexShader(thread VS_INPUTS& inputs, constant ConstantBuffer& b, thread texture2d<float>& texture) : cb(b) , vs_inputs(inputs) , img(texture) {} float3 CalcSomething() { return float3(cb.ANY_VALUE, cb.ANY_VALUE, cb.ANY_VALUE); // !!!!!!!! } V2P_STRUCT majn() { V2P_STRUCT vs_outputs; vs_outputs.v_pos_out.xyz = CalcSomething(); vs_outputs.v_pos_out.w = cb.ANY_VALUE * vs_inputs.i_pos_ms.x * MyVariable; // that's OK return vs_outputs; } }; vertex V2P_STRUCT VertexFunc(VS_INPUTS vs_inputs [ [ stage_in ] ] , constant ConstantBuffer& cb [ [ buffer (1) ] ] , texture2d<float> img [[ texture(0) ]] ) { VertexShader vs(vs_inputs, cb, img); return vs.majn(); } 

我创build了一个包含我的整个原始着色器的结构。 参数作为引用传递给构造函数。 任何函数都可以从常量缓冲区读取而不需要接收大量的参数 要解决现在是cb的一部分的ANY_VALUE问题,我使用macros:

 #define ANY_VALUE cb.ANY_VALUE. 

这里有很多问题。 我认为如果你给我们提供了一个解决问题的办法,那么最好不要试图把其他平台的概念变成金属。 现在,这里有一些想法。

是否可以调用CalcSomething()而不传递ANY_VALUE作为input参数?

 struct ConstantBuffer { const float ANY_VALUE; }; constant const ConstantBuffer constantBuffer = {1}; static float3 CalcSomething() { return float3(constantBuffer.ANY_VALUE); } 

你确定CalcSomething不应该是一个方法吗?

 struct ConstantBuffer { ConstantBuffer(const float value): value(value) {} float3 calculateSomething() const { return float3(value); } const float value; }; vertex V2P_STRUCT VertexFunc( constant const ConstantBuffer& _constantBuffer [[buffer(1)]] ) { // Metal can't currently deal with methods without this. const auto constantBuffer = _constantBuffer; 

另一个想法是以某种方式在全局范围内声明“cb”(但是不幸的是[[buffer]]只能用于参数)。 这有什么窍门吗?

在我看来,“诀窍”是在Swift中创build缓冲区,而不是金属阴影语言。