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

本文关键字:缓冲区 崩溃 创建 SharpDX | 更新日期: 2023-09-27 18:32:01

我正在使用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 - 创建持续的缓冲区崩溃

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

另一方面,顶点缓冲区没有此限制,因此在这种情况下,资源将成功创建。

如果打开调试设备,则应显示以下错误消息:

D3D11 错误: ID3D11设备::创建缓冲区: 维度无效。对于标有 D3D11_BIND_CONSTANT_BUFFER BindFlag 的 ConstantBuffers,ByteWidth(值 = 4)必须是 16 的倍数。[ STATE_CREATION错误 #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;

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

所以我想这可能是一个可见性问题,因为ConstantBufferData没有被定义为公共的。

或者是一个正式的参数问题,因为据我在 CreateBuffer 的文档中看到,数据参数必须符合D3D11_SUBRESOURCE_DATA结构

希望这有帮助。