Ios 用金属着色语言创建全局可访问的常量缓冲区
Ios 用金属着色语言创建全局可访问的常量缓冲区,ios,metal,Ios,Metal,我有一个关于金属中恒定缓冲区的问题。 让我们假设,我得到了如下内容: ...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
我有一个关于金属中恒定缓冲区的问题。 让我们假设,我得到了如下内容:
...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(),而不传递任何_值作为输入参数例如,在DX11或OpenGL中创建常量缓冲区,可以从着色器代码中的每个位置访问该缓冲区。
我考虑将“cb”的内容复制到临时全局对象,但我不知道如何做(因为地址空间是恒定的)。
另一个想法是以某种方式在全局范围内声明“cb”(但不幸的是[[buffer]]只设计用于参数)。有什么诀窍吗?这里有很多问题。我认为最好是你给我们提供一个问题来解决,而不是试图把其他平台的概念硬塞进金属中。现在,这里有一些想法 是否可以调用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而不是金属着色语言创建缓冲区。我的问题解决方案:
#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();
}
问题是,我的常量缓冲区中有一些变量(它们是4个不同的[[buffer()绑定]],我希望能够在代码中的任意位置读取它们,而无需将这些缓冲区作为参数传递给较低级别的函数(在我的示例中为CalcSomething())。您的第一个代码示例将仅适用于常量值(编译时知道)-没有选项使用[[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();
}
#define ANY_VALUE cb.ANY_VALUE.