boost::intrusive_ptr<ID3D11InputLayout> VertexBufferGroup::CreateInputLayout(Device& device, const VertexShader& validationShader, const VertexBufferVec& buffers)
{
    if(buffers.size() >= D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT)
        e_throw(VertexBufferGroupException() << error_description_info("Maximum VertexBufferGroup size is " + D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT));

    std::vector<D3D11_INPUT_ELEMENT_DESC> bufferDesc;

    for(unsigned int i = 0; i < buffers.size(); ++i)
    {
        for(const auto& layout : buffers[i]->GetBufferLayout())
        {
            D3D11_INPUT_ELEMENT_DESC desc =
            {
                layout.semanticName.c_str(),
                layout.semanticIndex,
                layout.format,
                i,
                layout.alignedByteOffset,
                D3D11_INPUT_PER_VERTEX_DATA,
                0
            };

            bufferDesc.push_back(desc);
        }
    }

    boost::intrusive_ptr<ID3D11InputLayout> inputLayout;
    e_throw_com_ret_error(device.GetD3DDevice()
        .CreateInputLayout(&bufferDesc[0],
                           static_cast<UINT>(bufferDesc.size()),
                           &validationShader.GetShaderData()[0],
                           validationShader.GetShaderData().size(),
                           ReceiveCOM(inputLayout)), "ID3D11Device::CreateInputLayout");

    return inputLayout;
}