gpt4 book ai didi

c++ - HLSL:包装错误?

转载 作者:行者123 更新时间:2023-11-30 04:21:18 25 4
gpt4 key购买 nike

我正在传递具有以下布局的常量缓冲区:

struct 
{
float spread;
D2D1_POINT_2F dimension;
D2D1_POINT_2F dimension2;
} m_constants;

为了调试,dimension 和 dimension2 具有相同的值。

在着色器中我有:

cbuffer constants
{
float spread;
float2 dimension;
float2 dimension2;
};

float4 main(
float4 pos : SV_POSITION,
float4 posScene : SCENE_POSITION,
float4 uv0 : TEXCOORD0
) : SV_Target
{
float width = dimension.x;
float height = dimension.y;
float2 uv2 = float2(posScene.x / width, posScene.y / height);
color.rgb = float3(uv2.xy, 0);
return color;
}

从理论上讲,这应该输出左下角为绿色、右上角为红色的渐变。确实如此。但是,如果在着色器中我有宽度和高度来代替使用 dimension2。我得到一个水平渐变,从左边的绿色到右边的黄色。

这是为什么呢?当我将 m_constants 传递给着色器时,两个维度具有相同的值

最佳答案

常量缓冲区数据默认按 16 字节对齐,因此这意味着:

cbuffer constants
{
float spread;
float2 dimension;
float2 dimension2;
};

会是

cbuffer constants
{
float spread; // 4 bytes
float2 dimension; // 4 + 8 = 12 bytes
float dummy; //12+8 = 20, which means we cross 16 for dimension 2, hence a dummy 4 bytes element is added
float2 dimension2;
};

这是一个link描述了这一点。

因此,安排结构的更好方法是:

struct 
{
D2D1_POINT_2F dimension;
D2D1_POINT_2F dimension2;
float spread;
} m_constants;

并相应地修改 hlsl 拷贝:

cbuffer constants
{
float2 dimension;
float2 dimension2;
float spread; // No more 16 bytes crossing problem
};

另一种方式,在不修改初始布局的情况下,在 C++ 端,要么像这样声明您的结构:

#pragma pack(push)
#pragma pack(16)
struct
{
float spread;
D2D1_POINT_2F dimension;
D2D1_POINT_2F dimension2;
} m_constants;
#pragma pack(pop)

这将强制结构为 16 字节对齐。

你也可以使用/Zp16 compiler flag ,但这将适用于你程序中的每个结构(这并不总是可取的)。在 visual studio 中,转到项目属性 -> c/c++ -> 代码生成,然后你可以选择“结构成员对齐”,你可以从中进行设置。

你也可以在 hlsl 端使用 packoffset,但这意味着 c++ 布局需要匹配打包的 hlsl 布局(这意味着你在 hlsl 常量缓冲区中保持相同的顺序,但仍然必须修改 c++ 版本)。

关于c++ - HLSL:包装错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14574061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com