Search code examples
c++directxhlsl

DirectX11 - Geometry Shader Stream Output Stream Undefined


I'm trying to create a geometry shader which uses the stream output stage following the outline provided on MSDN: Link

However when trying to do this I get the following error:

ID3D11Device::CreateGeometryShaderWithStreamOutput: Stream (=3435973836) must be less than or equal to 3.

As far as I'm aware, the only point at which I can define the stream is in the stream output declaration entry, but I've already done this (code below).

// Reads compiled shader into a buffer
HRESULT result = D3DReadFileToBlob(filename, &geometryShaderBuffer);

D3D11_SO_DECLARATION_ENTRY SODeclarationEntry[3] =
{

    { 0, "POSITION", 0, 0, 3, 0 },
    { 0, "NORMAL", 0, 0, 3, 0 },
    { 0, "TEXCOORD", 0, 0, 3, 0 }

};

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

Is there somewhere else where I'm supposed to be defining an output stream?


Solution

  • The problem here is that you have provided far too large a number for NumEntries so it's reading a bunch of junk entries after the 3 you have defined for pSODeclaration. That's why the validation error debug output is reporting nonsense values like "Stream (=3435973836)".

    result = renderer->CreateGeometryShaderWithStreamOutput(
        geometryShaderBuffer->GetBufferPointer(), geometryShaderBuffer->GetBufferSize(),
        SODeclarationEntry, sizeof(SODeclarationEntry),
        nullptr, 0, 0, nullptr, &streamOutputGeometryShader);
    

    should be:

    result = renderer->CreateGeometryShaderWithStreamOutput(
        geometryShaderBuffer->GetBufferPointer(), geometryShaderBuffer->GetBufferSize(),
        SODeclarationEntry, _countof(SODeclarationEntry),
        nullptr, 0, 0, nullptr, &streamOutputGeometryShader);
    

    Note that if you are working with a different compiler than Microsoft Visual C++, _countof is:

    #define _countof(array) (sizeof(array) / sizeof(array[0]))
    

    BTW, this is the kind of bug that static code analysis (/analyze) and the SAL annotations that are used for the Windows system headers can find for you:

    warning C6385: Reading invalid data from 'SODeclarationEntry':  the readable
    size is '48' bytes, but '768' bytes may be read.
    

    See Microsoft Docs for more information.