为什么我的常量缓冲区没有更新?
Why is my constant buffer not being updated?
波纹管是缓冲区的 cpu 边声明我遇到了问题:
struct PSMaterialTransform {
float Alpha;
bool WrapUV;
XMFLOAT2 padding;
} static m_PSMaterialTransformDesc;
下面是缓冲区的 gpu 端声明:
cbuffer MaterialTransform: register(b1) {
float Alpha;
bool WrapUV;
float2 padding;
};
这就是我创建所有常量缓冲区的方式:
template<typename T>
bool Seraph::ShaderManager<T>::Create(ID3D11Device* pDevice) {
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
bd.ByteWidth = sizeof(T);
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
hr = pDevice->CreateBuffer(&bd, nullptr, &m_pBuffer);
if (FAILED(hr))
return Log("Failed to create constant buffer.");
return true;
}
最后,这是我用来更新常量缓冲区的代码:
template<typename T>
bool Seraph::ShaderManager<T>::SetPS(ID3D11DeviceContext* pDeviceContext, T& Data, int ID) {
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE));
hr = pDeviceContext->Map(m_pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
if (FAILED(hr))
return Log("Failed to update constant buffer.");
*(T*)ms.pData = Data;
pDeviceContext->Unmap(m_pBuffer, 0);
pDeviceContext->PSSetConstantBuffers(ID, 1, &m_pBuffer);
return true;
}
变量ID
代表声明buffer的slot,我已经检查了3次ID
对于MaterialTransform
是1,但无所谓我发送到 gpu 的值,布尔值 WrapUV
总是 TRUE
,即使浮点数 Alpha
似乎正常更新。
HLSL 中 bool 的大小是 4 个字节,所以你的 CPU 结构应该是这样的
struct PSMaterialTransform
{
float Alpha;
int32_t WrapUV; //or uint32_t
XMFLOAT2 padding;
}
如果需要,您可以像这样使用 typedef/using 别名:
typedef int32_t bool32; //or
using bool32 = int32_t;
那你可以写成bool32 WrapUV;
。
波纹管是缓冲区的 cpu 边声明我遇到了问题:
struct PSMaterialTransform {
float Alpha;
bool WrapUV;
XMFLOAT2 padding;
} static m_PSMaterialTransformDesc;
下面是缓冲区的 gpu 端声明:
cbuffer MaterialTransform: register(b1) {
float Alpha;
bool WrapUV;
float2 padding;
};
这就是我创建所有常量缓冲区的方式:
template<typename T>
bool Seraph::ShaderManager<T>::Create(ID3D11Device* pDevice) {
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
bd.ByteWidth = sizeof(T);
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
hr = pDevice->CreateBuffer(&bd, nullptr, &m_pBuffer);
if (FAILED(hr))
return Log("Failed to create constant buffer.");
return true;
}
最后,这是我用来更新常量缓冲区的代码:
template<typename T>
bool Seraph::ShaderManager<T>::SetPS(ID3D11DeviceContext* pDeviceContext, T& Data, int ID) {
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE));
hr = pDeviceContext->Map(m_pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
if (FAILED(hr))
return Log("Failed to update constant buffer.");
*(T*)ms.pData = Data;
pDeviceContext->Unmap(m_pBuffer, 0);
pDeviceContext->PSSetConstantBuffers(ID, 1, &m_pBuffer);
return true;
}
变量ID
代表声明buffer的slot,我已经检查了3次ID
对于MaterialTransform
是1,但无所谓我发送到 gpu 的值,布尔值 WrapUV
总是 TRUE
,即使浮点数 Alpha
似乎正常更新。
HLSL 中 bool 的大小是 4 个字节,所以你的 CPU 结构应该是这样的
struct PSMaterialTransform
{
float Alpha;
int32_t WrapUV; //or uint32_t
XMFLOAT2 padding;
}
如果需要,您可以像这样使用 typedef/using 别名:
typedef int32_t bool32; //or
using bool32 = int32_t;
那你可以写成bool32 WrapUV;
。