【问题标题】:HLSL float array packing in constant buffer?HLSL浮点数组打包在常量缓冲区中?
【发布时间】:2013-01-20 15:06:39
【问题描述】:

人。

我在通过 常量缓冲区浮点数组 传递到顶点着色器 (HLSL) 时遇到问题。我知道由于 HLSL 打包规则,下面数组中的每个“float”都会单独获得一个 16 字节的插槽(空间相当于 float4):

// C++ struct
struct ForegroundConstants
{
    DirectX::XMMATRIX transform;
    float bounceCpp[64];
};


// Vertex shader constant buffer
cbuffer ForegroundConstantBuffer : register(b0)
{
    matrix transform;
    float bounceHlsl[64];
};

(不幸的是,简单的解决方案here 不起作用,在我进行更改后没有绘制任何内容)

当 C++ 数据被传递时,由于打包规则,它们被隔开,使得 bounceCpp C++ 数组中的每个“浮点数”都在 中单独进入一个 16 字节的空间>bounceHlsl 数组。这导致了类似于以下内容的警告:

ID3D11DeviceContext::DrawIndexed:顶点着色器单元插槽 0 的常量缓冲区的大小太小(提供 320 字节,预计至少 1088 字节)。这没关系,因为越界读取被定义为返回 0。开发人员也可能知道无论如何都不会使用丢失的数据。仅当开发人员实际上打算为着色器所期望的绑定足够大的常量缓冲区时,这才是一个问题。

正如herehere 所指出的,建议是以这种方式重写 HLSL 常量缓冲区:

cbuffer ForegroundConstantBuffer : register(b0)
{
    matrix transform;
    float4 bounceHlsl[16]; // equivalent to 64 floats.
};

static float temp[64] = (float[64]) bounceHlsl;

main(pos : POSITION) : SV_POSITION
{
    int index = someValueRangeFrom0to63;
    float y = temp[index];

    // Bla bla bla...
}

但这不起作用(即 ID3D11Device1::CreateVertexShader 永远不会返回)。我正在针对 Shader Model 4 Level 9_1 进行编译,你能发现我在这里做错了什么吗?

提前致谢! :)

问候, 本

【问题讨论】:

    标签: directx hlsl directx-11 vertex-shader


    【解决方案1】:

    一种解决方案,尽管不是最优的,就是将你的浮点数组声明为

    float4 bounceHlsl[16];
    

    然后像处理索引一样

    float x = ((float[4])(bounceHlsl[i/4]))[i%4];
    

    其中 i 是您需要的索引。

    【讨论】:

    • 感谢 Alanw,我想这可行(正如我在其他网站上看到的那样),但在我的情况下它不起作用。不过,我将继续将您的答案标记为答案,并进一步调试以找出对我来说失败的原因:)
    • 但要小心,它可能效率低下:geidav.wordpress.com/2013/03/05/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多