【问题标题】:Constant buffer is empty when passed HLSL C++通过 HLSL C++ 时常量缓冲区为空
【发布时间】:2015-06-12 09:48:05
【问题描述】:

所以我从这个问题:Previous problem 转移到这个问题:)。

我在 C++ 中创建了 2 个常量缓冲区,我将它们传递给我的 HLSL 着色器,但是当我调试并查看缓冲区时,除了最后 3 个数字(它们是 -572662307)之外,它们只填充了零。 我在关注这个例子https://msdn.microsoft.com/en-us/library/windows/desktop/ff476896(v=vs.85).aspx

这是我用来创建缓冲区的代码。

    // Define the constant data used to communicate with shaders.
__declspec(align(4)) struct GS_CONSTANT_BUFFER_EDGETABLE
{
    int edgeTable[256];
};
__declspec(align(4)) struct GS_CONSTANT_BUFFER_TRITABLE
{
    int triTable[256][16];
};

// Supply the gs constant data.
GS_CONSTANT_BUFFER_EDGETABLE GsConstDataEdge;
GS_CONSTANT_BUFFER_TRITABLE GsConstDataTri;
for (int i = 0; i < 256; ++i)
{
    GsConstDataEdge.edgeTable[i] = edgeTable[i];
    for (int j = 0; j < 16; ++j)        
        GsConstDataTri.triTable[i][j] = triTable[i][j];     
}

//EDGE
// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc1;
cbDesc1.ByteWidth = sizeof(GsConstDataEdge);
cbDesc1.Usage = D3D11_USAGE_DYNAMIC;
cbDesc1.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc1.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc1.MiscFlags = 0;
cbDesc1.StructureByteStride = 0;

// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData1;
InitData1.pSysMem = &GsConstDataEdge;
InitData1.SysMemPitch = 0;
InitData1.SysMemSlicePitch = 0;

// Create the buffer. 
auto hr = gameContext.pDevice->CreateBuffer(&cbDesc1, &InitData1, &g_pConstantBuffer1);

if (FAILED(hr)) 
    std::cout << "Error buffer creation1" << endl;  

// Set the buffer.
gameContext.pDeviceContext->GSSetConstantBuffers(0, 1, &g_pConstantBuffer1);
//

// TRI
// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc2;
cbDesc2.ByteWidth = sizeof(GsConstDataTri);
cbDesc2.Usage = D3D11_USAGE_DYNAMIC;
cbDesc2.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc2.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc2.MiscFlags = 0;
cbDesc2.StructureByteStride = 0;

// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData2;
InitData2.pSysMem = &GsConstDataTri;
InitData2.SysMemPitch = 0;
InitData2.SysMemSlicePitch = 0;

// Create the buffer. 
hr = gameContext.pDevice->CreateBuffer(&cbDesc2, &InitData2, &g_pConstantBuffer2);

if (FAILED(hr)) 
    std::cout << "Error buffer creation2" << endl;  

// Set the buffer.
gameContext.pDeviceContext->GSSetConstantBuffers(1, 1, &g_pConstantBuffer2);

这是我的 HLSL 着色器中的结构。

cbuffer GS_CONSTANT_BUFFER_EDGETABLE : register(b0)
{
    int edgeTable[256];
}

cbuffer GS_CONSTANT_BUFFER_TRITABLE : register(b1)
{
    int triTable[256][16];
}

编辑: http://imgur.com/Xv7B1SO 现在我确实有我创建的 2 个缓冲区,但它们似乎没有分配给 HLSL 代码中的 cbuffers。

【问题讨论】:

  • sizeof(GsConstDataTri) 是否给您合适的尺寸?在我的脑海中,我不确定它会给你数组的完整大小,它可能只会给你指针的大小。
  • 它确实给出了正确的大小 (16384),但是当我检查使用的缓冲区时,它显示大小为 65536。我认为这不正确吗? (对于 c 的其他缓冲区相同)
  • 我认为你在设置pSysMem时不需要传递指针的地址,所以去掉&。该指针是指向内存的指针。这使它成为一个 void*,这意味着所有类型的安全性都被抛到了窗外。
  • 我在关注这个 MS msdn.microsoft.com/en-us/library/windows/desktop/… 的例子。当我删除 & 时,我收到一条错误消息,因为 pSysMem 需要一个 void 指针。
  • 没关系,你是对的,我认为它是动态分配的。由于非常奇怪的字节对齐内容,可能存在偏移。尝试给出实际数组的地址,所以 GsConstDataTri.triTable

标签: c++ directx shader hlsl


【解决方案1】:

已修复,我只是将其添加到管道中即可。 我必须在调用 draw 之前但在 get 技术之后分配它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    相关资源
    最近更新 更多