2

我在查找错误的根源时遇到了一些麻烦。该应用程序一切正常,但我收到以下 2 个警告的垃圾邮件:

D3D11 WARNING: ID3D11DeviceContext::DrawIndexedInstanced: Input vertex slot 1 has stride 12 which is less than the minimum stride logically expected from the current Input Layout (48 bytes). This is OK, as hardware is perfectly capable of reading overlapping data. However the developer probably did not intend to make use of this behavior.  [ EXECUTION WARNING #355: DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL]
D3D11 WARNING: ID3D11DeviceContext::DrawIndexedInstanced: Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to traverse. This is OK, as reading off the end of the Buffer is defined to return 0. However the developer probably did not intend to make use of this behavior.  [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL]

似乎我的步幅值不正确,但我找不到哪里出错了。该应用程序仅使用实例化绘制多个纹理框。

输入布局:

D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
    { "WORLD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
    { "WORLD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 12, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
    { "WORLD", 2, DXGI_FORMAT_R32G32B32_FLOAT, 1, 24, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
    { "WORLD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 1, 36, D3D11_INPUT_PER_INSTANCE_DATA, 1 }

};

// Create the input layout
D3DX11_PASS_DESC passDesc;
mTech->GetPassByIndex(0)->GetDesc(&passDesc);

HR(md3dDevice->CreateInputLayout(vertexDesc, 6, passDesc.pIAInputSignature, 
    passDesc.IAInputSignatureSize, &mInputLayout));

绘制函数中的相关代码。

UINT stride[] = {sizeof(Vertex), sizeof(InstanceData)};
UINT offset[] = {0,0};
ID3D11Buffer* ivbs[2] = {mBoxVB, mInstancedBuffer};

md3dImmediateContext->IASetVertexBuffers(0, 2, ivbs, stride, offset);

md3dImmediateContext->DrawIndexedInstanced(24, 4, 0, 0, 0);

保存数据的结构:

struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT2 Tex;
};

struct InstanceData
{
XMFLOAT3 World; 
};

正确的步幅应该是 12,因为这是进入输入槽 1 的 XMFLOAT3 和 DXGI_FORMAT_R32G32B32_FLOAT 的字节大小。但我认为它期望我的实例缓冲区的总大小,我用一个包含 XMFLOAT3 数据的 4 个数组填充(4 * 12 = 48 符合警告)。

实例缓冲区:

InstanceData mInstanceData[4];

mInstanceData[0].World = XMFLOAT3(
                1.0f, 1.0f, 1.0f);

mInstanceData[1].World = XMFLOAT3(
                3.0f, 1.0f, 1.0f);

mInstanceData[2].World = XMFLOAT3(
                5.0f, 1.0f, 1.0f);

mInstanceData[3].World = XMFLOAT3(
                7.0f, 1.0f, 1.0f);

D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_DYNAMIC;
ibd.ByteWidth = sizeof(InstanceData) * 4;
ibd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA instanceData;
instanceData.pSysMem = mInstanceData;
instanceData.SysMemPitch = 0;
instanceData.SysMemSlicePitch = 0;


HR(md3dDevice->CreateBuffer(&ibd, &instanceData, &mInstancedBuffer));

用数据填充数组并像那样使用它是错误的吗?该程序仍然运行良好。任何帮助将不胜感激。

4

1 回答 1

3

UINT stride[] = {sizeof(Vertex), 4 * sizeof(InstanceData)};而不是UINT stride[] = {sizeof(Vertex), sizeof(InstanceData)};如果你真的每个实例使用四个 float3 。

如果实例数据真的是唯一的float3,那么输入布局中的三个额外语义反而是错误的。

于 2013-10-21T18:12:00.007 回答