E_INVALIDARG when calling CreateGraphicsPipelineState

0

I've been getting a weird error when calling CreateGraphicsPipelineState(). The function returns E_INVALIDARG even though the description is all set up.

The description worked before and the I tried to add indexbuffers to my pipeline, I didn't even touch any of the code for PSO or Shaders and now the PSO creation is all messed up.

The issue is that I don't get any DX-error messages from the driver when enabling the debug-layer. I only get this

"Microsoft C++ exception: _com_error at memory location

when I step through the function.

It feels like it is some pointer error or similar, but I can't figure out what the error is. Perhaps anyone of you can see an obvious mistake that I made?

Here's my code:

CGraphicsPSO* pso = new CGraphicsPSO();

    D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};


    // Input Layout
    std::vector<D3D12_INPUT_ELEMENT_DESC> elements;
    if (aPSODesc.inputLayout != nullptr)
    {
        auto& ilData = aPSODesc.inputLayout->desc;
        for (auto& element : ilData)
        {
            // All Data here is correct when breaking
            D3D12_INPUT_ELEMENT_DESC elementDesc;
            elementDesc.SemanticName = element.mySemanticName;
            elementDesc.SemanticIndex = element.mySemanticIndex;
            elementDesc.InputSlot = element.myInputSlot;
            elementDesc.AlignedByteOffset = element.myAlignedByteOffset;
            elementDesc.InputSlotClass = _ConvertInputClassificationDX12(element.myInputSlotClass);
            elementDesc.Format = _ConvertFormatDX12(element.myFormat);
            elementDesc.InstanceDataStepRate = element.myInstanceDataStepRate;

            elements.push_back(elementDesc);
        }
        D3D12_INPUT_LAYOUT_DESC inputLayout = {};
        inputLayout.NumElements = (UINT)elements.size();
        inputLayout.pInputElementDescs = elements.data();
        psoDesc.InputLayout = inputLayout;
    }   
    // TOPOLOGY
    switch (aPSODesc.topology)
    {
    default:
    case EPrimitiveTopology::TriangleList:
        psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; // <--- Always this option
        break;
    case EPrimitiveTopology::PointList:
        psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
        break;
    case EPrimitiveTopology::LineList:
        psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
        break;
        //case EPrimitiveTopology::Patch:
        //  psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
        //  break;
    }

    // Shaders
    if (aPSODesc.vs != nullptr)
    {
        D3D12_SHADER_BYTECODE vertexShaderBytecode = {};
        vertexShaderBytecode.BytecodeLength = aPSODesc.vs->myByteCodeSize;
        vertexShaderBytecode.pShaderBytecode = aPSODesc.vs->myByteCode;
        psoDesc.VS = vertexShaderBytecode;
    }
    if (aPSODesc.ps != nullptr)
    {
        D3D12_SHADER_BYTECODE pixelShaderBytecode = {};
        pixelShaderBytecode.BytecodeLength = aPSODesc.ps->myByteCodeSize;
        pixelShaderBytecode.pShaderBytecode = aPSODesc.ps->myByteCode;
        psoDesc.PS = pixelShaderBytecode;
    }

    psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; // format of the render target

    DXGI_SAMPLE_DESC sampleDesc = {};
    sampleDesc.Count = 1;
    sampleDesc.Quality = 0;

    psoDesc.DepthStencilState.DepthEnable = FALSE;
    psoDesc.DepthStencilState.StencilEnable = FALSE;

    psoDesc.SampleDesc = sampleDesc; // must be the same sample description as the swapchain and depth/stencil buffer
    psoDesc.SampleMask = UINT_MAX; // sample mask has to do with multi-sampling. 0xffffffff means point sampling is done
    psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); // a default rasterizer state.
    psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); // a default blent state.
    psoDesc.NumRenderTargets = 1; // we are only binding one render target
    psoDesc.pRootSignature = myGraphicsRootSignature;
    psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;

    ID3D12PipelineState* pipelineState;
    HRESULT hr = myDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState));
    pso->myPipelineState = pipelineState;
    if (FAILED(hr))
    {
        delete pso;
        return nullptr;
    }

    return pso;
c++
c++17
directx-12
asked on Stack Overflow Jul 27, 2018 by Hampus Siversson • edited Jul 30, 2018 by StaceyGirl

2 Answers

1

So I just found the error. It seems like the way I parsed my semantics for my input-layout gave me an invalid pointer. Thus the memory at the adress was invalid and giving the DX12-device incorrect decriptions.

So what I did was to locally store the semantic-names within my CreatePSO function until the PSO was created, and now it all works.

answered on Stack Overflow Jul 30, 2018 by Hampus Siversson
0

Looks to me like the pointers to storage you promised are going out of scope.

..
  D3D12_INPUT_LAYOUT_DESC inputLayout = {};
..
  psoDesc.InputLayout = inputLayout;
}
answered on Stack Overflow Jul 30, 2018 by holtavolt

User contributions licensed under CC BY-SA 3.0