DirectX11 - геометрический шейдер с потоковым выводом - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь вывести данные из геометрического шейдера в качестве буфера вершин для ввода в другой шейдер.Однако, похоже, это не работает, и уровень отладки ничего не говорит мне.Что-то не так с описаниями буферов?

Вот как я создаю выходной буфер:

D3D11_BUFFER_DESC outputBufferDesc;
ZeroMemory(&outputBufferDesc, sizeof(outputBufferDesc));
outputBufferDesc.ByteWidth = sizeof(XMFLOAT4) + 2 * sizeof(XMFLOAT3);
outputBufferDesc.Usage = D3D11_USAGE_DEFAULT;
outputBufferDesc.BindFlags = D3D11_BIND_STREAM_OUTPUT;
outputBufferDesc.CPUAccessFlags = 0;
outputBufferDesc.MiscFlags = 0;
outputBufferDesc.StructureByteStride = 0;

result = renderer->CreateBuffer(&outputBufferDesc, NULL, &outputBuffer);
if (result != S_OK)
{
    MessageBox(NULL, filename, L"Failed to create stream output buffer", MB_OK);
    exit(0);
}

UINT offset[1] = { 0 };
deviceContext->SOSetTargets(1, &outputBuffer, offset);

И вызов draw для первого шейдера:

deviceContext->VSSetShader(vertexShader, NULL, 0);
deviceContext->PSSetShader(pixelShader, NULL, 0);
deviceContext->GSSetShader(streamOutputGeometryShader, NULL, 0);

// Render the triangle.
deviceContext->DrawIndexed(indexCount, 0, 0);

UINT offset[1] = { 0 };
ID3D11Buffer* pNullBuffer = 0;
deviceContext->SOSetTargets(1, &pNullBuffer, offset);

И куда я копирую информацию из этого буфера во второй буфер:

D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.ByteWidth = sizeof(XMFLOAT4) + 2 * sizeof(XMFLOAT3);
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;

result = renderer->CreateBuffer(&vertexBufferDesc, NULL, &vertexBuffer);
if (result != S_OK)
{

    MessageBox(NULL, L"Failed to create output mesh vertex buffer", L"Failed", MB_OK);
    exit(0);

}

deviceContext->CopyResource(vertexBuffer, buffer);

И где я устанавливаю топологию ввода для меша, используя буфер вершин:

unsigned int stride;
unsigned int offset;

// Set vertex buffer stride and offset.
stride = sizeof(XMFLOAT4) + 2 * sizeof(XMFLOAT3);
offset = 0;

deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

И, наконец, вызов отрисовки для второго шейдера прост:

deviceContext->DrawAuto();

РЕДАКТИРОВАТЬ: геометрия вычисляется в геометрическом шейдере правильно, но она не выводится.Я включил код создания геометрического шейдера ниже:

D3D11_SO_DECLARATION_ENTRY SODeclarationEntry[3] =
{

    { 0, "SV_POSITION", 0, 0, 4, 0 },
    { 0, "NORMAL", 0, 0, 3, 0 },
    { 0, "TEXCOORD", 0, 0, 3, 0 }

};

// Create the geometry shader from the buffer.
result = renderer->CreateGeometryShaderWithStreamOutput(geometryShaderBuffer->GetBufferPointer(), geometryShaderBuffer->GetBufferSize(), SODeclarationEntry, _countof(SODeclarationEntry),
    NULL, 0, D3D11_SO_NO_RASTERIZED_STREAM, NULL, &streamOutputGeometryShader);

1 Ответ

0 голосов
/ 22 ноября 2018

В дополнение к только фактическим данным вершин, буферы, используемые в качестве целей для Стадии вывода потока, поддерживают некоторое внутреннее состояние, чтобы отслеживать, сколько геометрии было записано.DrawAuto() полагается на эту информацию, чтобы знать, сколько геометрии нарисовать.Когда вы копируете только данные вершин из буфера вывода потока в обычный D3D11_BIND_VERTEX_BUFFER, эта информация будет потеряна.

Соответствующая цитата из документации :

DrawAuto работает только при рисовании с одним входным буфером, привязанным в качестве входа к этапу IA в слоте 0. Приложения должны создать ресурс буфера SO с обоими флагами привязки, D3D11_BIND_VERTEX_BUFFER и D3D11_BIND_STREAM_OUTPUT.

IЯ не уверен, если это возможно, чтобы скопировать данные из одного буфера вывода потока в другой и DrawAuto() оттуда.Я думаю, это может сработать.Однако то, что вы делаете в данный момент, определенно не должно работать в соответствии с документацией.В идеале вы бы просто не копировали данные.Если вам действительно нужно скопировать данные (по какой-либо причине), я советую вам все же сначала попробовать рисовать непосредственно из буфера, в который вы перенаправили поток, чтобы убедиться, что все остальное настроено правильно, и только после того, как это сработает, попробуйте скопировать в другой буфер, который имеетустановлены флаги привязки выходных данных вершин и потоков…

...