C++ DirectX11 Execution Warning #355 и #356 = неправильный размер шага

У меня возникли проблемы с поиском источника моей ошибки. Все работает нормально с приложением, но я получаю спам с этими 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, поскольку это размер в байтах XMFLOAT3 и DXGI_FORMAT_R32G32B32_FLOAT, которые входят во входной слот 1. Тем не менее, я думаю, что он ожидает общий размер моего буфера экземпляра, который я заполнил массивом из 4, содержащих данные XMFLOAT3 (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));

Неправильно ли заполнять массив данными и использовать его таким образом? программа по-прежнему работает нормально. Любая помощь будет принята с благодарностью.


person Eizo Zalman    schedule 21.10.2013    source источник


Ответы (1)


UINT stride[] = {sizeof(Vertex), 4 * sizeof(InstanceData)}; вместо UINT stride[] = {sizeof(Vertex), sizeof(InstanceData)};, если вы действительно используете четыре float3 для каждого экземпляра.

Если данные экземпляра действительно являются уникальными float3, то вместо этого три дополнительные семантики во входном макете неверны.

person galop1n    schedule 21.10.2013
comment
Конечно! Я совершенно забыл отредактировать лишнюю семантику World, чтобы она соответствовала моему собственному коду. Предупреждение теперь имеет гораздо больше смысла. Спасибо. - person Eizo Zalman; 21.10.2013