SharpDX - 创建持续的缓冲区崩溃

SharpDX - Creating constant buffer crashes

我正在使用 SharpDX 在 C# 中创建一个基本的 DirectX 程序。我正在尝试使用常量缓冲区将一些数据向下传递给着色器,但是当我创建缓冲区时,DirectX 因参数不正确而崩溃。启用调试层不再给我任何信息。我的代码如下所示:

consts = new ConstantBufferData() { fTime = 0.0f };
constantBuffer = D3D11.Buffer.Create<ConstantBufferData>(device, D3D11.BindFlags.ConstantBuffer, ref consts);

其中 ConstantBufferData 是这样定义的结构:

[StructLayout(LayoutKind.Sequential)]
struct ConstantBufferData
{
    public float fTime;
};

奇怪的是,当我将缓冲区创建为顶点缓冲区时,整个程序编译和运行正常,但将其用作 context.PixelShader.SetConstantBuffer(0, constantBuffer); 的常量缓冲区。

我从未使用过 SharpDX,但这似乎是一个严重受限的类型参数。 检查 SharpDX's github 处的代码,我看到它使用互操作指针来传递指针。

所以我想这可能是可见性问题,因为 ConstantBufferData 未定义为 public。

或者形式参数问题,因为据我在 CreateBuffer's doc 中所见,数据参数必须符合 D3D11_SUBRESOURCE_DATA 结构

希望对您有所帮助。

常量缓冲区大小必须是 16 的倍数,而您的结构不是这种情况(只有 4),因此创建会失败。

另一方面,顶点缓冲区没有这个限制,所以在这种情况下资源会创建成功。

如果您打开调试设备,您应该会收到以下错误消息:

D3D11 ERROR: ID3D11Device::CreateBuffer: The Dimensions are invalid. For ConstantBuffers, marked with the D3D11_BIND_CONSTANT_BUFFER BindFlag, the ByteWidth (value = 4) must be a multiple of 16. [ STATE_CREATION ERROR #66: CREATEBUFFER_INVALIDDIMENSIONS]

解决此问题的两种方法。

1/向您的结构添加填充以适应 16 的倍数,例如:

[StructLayout(LayoutKind.Sequential)]
struct ConstantBufferData
{
    public float fTime;
    public int dum1,dum2,dum3;
};

或者在创建缓冲区时强制执行大小规则(确保描述中的大小是 16 的倍数,如果你的结构大小是 "size" 那么你有以下内容:

int paddedSize = ((size + 15) / 16) * 16;