[英]Marshalling C# Structs into DX11 cbuffers
I'm having some issues with (i think) the packing of my structure in C# and passing them through to cbuffers i have registered in HLSL. 我有一些问题(我认为)在C#中打包我的结构并将它们传递给我在HLSL中注册的cbuffers。 When i pack my struct in one manner the information seems to be able to pass to the shader:
当我以一种方式打包我的结构时,信息似乎能够传递到着色器:
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct TestStruct
{
[FieldOffset(0)]
public Vector3 mEyePosition;
[FieldOffset(12)]
public int type;
}
When i create this struct and set it as my constant buffer in C# it seems to work just fine. 当我创建这个结构并在C#中将其设置为我的常量缓冲区时,它似乎工作得很好。 I get what colours returned that i expect:
我得到了我期望的颜色:
cbuffer PerFrame : register(b0)
{
Vector3 eyePos;
int type;
}
float3 GetColour()
{
float3 returnColour = float(0.0f, 0.0f, 0.0f);
switch(type)
{
case 0:
returnColour = float3(1.0f, 0.0f, 0.0f);
break;
case 1:
returnColour = float3(0.0f, 1.0f, 0.0f);
break;
case 2:
returnColour = float3(0.0f, 0.0f, 1.0f);
break;
}
return returnColour;
}
But when i change the structure to be a struct using another struct it does seem to set properly. 但是当我使用另一个结构将结构更改为结构时,它似乎确实设置正确。 Note that internal struct is going to be containing extra information in it, but i was trying to simplify it as much as possible for now:
请注意,内部结构将包含其中的额外信息,但我现在试图尽可能地简化它:
[StructLayout(Layout.Explicit, Size = 16)] //Note this is 16 because HLSL packs in 4 float 'chunks'
internal struct InternalTestStruct
{
[FieldOffset(0)]
public int type;
}
[StructLayout(LayoutKind.Explicit, Size = 32)]
internal struct TestStruct
{
[FieldOffset(0)]
public Vector3 mEyePosition;
//Missing 4 bytes here for correct packing.
[FieldOffset(16)]
public InternalTestStruct internal;
}
And in HLSL 在HLSL中
struct InternalType
{
int type;
}
cbuffer PerFrame : register(b0)
{
Vector3 eyePos;
InternalType internalStruct;
}
float3 GetColour()
{
float3 returnColour = float(0.0f, 0.0f, 0.0f);
switch(internaltype.type)
{
case 0:
returnColour = float3(1.0f, 0.0f, 0.0f);
break;
case 1:
returnColour = float3(0.0f, 1.0f, 0.0f);
break;
case 2:
returnColour = float3(0.0f, 0.0f, 1.0f);
break;
}
return returnColour;
}
Do you think there is a problem in the way i am packing my structs? 你觉得我收拾结构的方式有问题吗? Or could the issue be elsewhere, i only think it is my packing because i can get the first example to work when i set the constant buffer with a TestStruct, but as soon as i expand it to include the InternalTestStruct it doesn't seem to work.
或者问题可能在其他地方,我只认为这是我的包装,因为我可以得到第一个例子,当我用TestStruct设置常量缓冲区时,但只要我扩展它以包含InternalTestStruct它似乎不工作。
Any help would be great. 任何帮助都会很棒。
Thanks in advance. 提前致谢。
When you use: 当你使用:
struct InternalType
{
int type;
}
cbuffer PerFrame : register(b0)
{
float3 eyePos;
InternalType internalStruct;
}
since InternalType is of size 4 it will pack into the layout of 16, so it's exactly the same as if you were just using an int. 因为InternalType的大小为4,所以它将打包成16的布局,所以它与你刚刚使用int的方式完全相同。
To match the second c# structure using InternalTestStruct, you'd need to do: 要使用InternalTestStruct匹配第二个c#结构,您需要执行以下操作:
cbuffer PerFrame : register(b0)
{
float3 eyePos;
int dummy; //Here you need to force the padding
InternalType internalStruct;
}
If you change internaltype to a size larger than one the padding will then become automatic (but it's always nice to keep it explicit). 如果将internaltype更改为大于1的大小,则填充将变为自动(但保持显式始终是好的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.