ShaderD3DBase::ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs)
{
    std::string strShaderProfile;
    switch(CreationAttribs.Desc.ShaderType)
    {
        case SHADER_TYPE_VERTEX:  strShaderProfile="vs"; break;
        case SHADER_TYPE_PIXEL:   strShaderProfile="ps"; break;
        case SHADER_TYPE_GEOMETRY:strShaderProfile="gs"; break;
        case SHADER_TYPE_HULL:    strShaderProfile="hs"; break;
        case SHADER_TYPE_DOMAIN:  strShaderProfile="ds"; break;
        case SHADER_TYPE_COMPUTE: strShaderProfile="cs"; break;

        default: UNEXPECTED( "Unknown shader type" );
    }
    strShaderProfile += "_";
    auto *pProfileSuffix = DXShaderProfileToString(CreationAttribs.Desc.TargetProfile);
    strShaderProfile += pProfileSuffix;

    String ShaderSource(g_HLSLDefinitions);
    if( CreationAttribs.Source )
        ShaderSource.append( CreationAttribs.Source );
    else
    {
        VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null");
        VERIFY(CreationAttribs.FilePath, "File path is null. Either shader source or source file path must be specified.");
        RefCntAutoPtr<IFileStream> pSourceStream;
        CreationAttribs.pShaderSourceStreamFactory->CreateInputStream( CreationAttribs.FilePath, &pSourceStream );
        RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl );
        pSourceStream->Read( pFileData );
        // Null terminator is not read from the stream!
        auto* FileDataPtr = reinterpret_cast<Char*>( pFileData->GetDataPtr() );
        auto Size = pFileData->GetSize();
        ShaderSource.append( FileDataPtr, FileDataPtr + Size/sizeof(*FileDataPtr) );
    }

    const D3D_SHADER_MACRO *pDefines = nullptr;
    std::vector<D3D_SHADER_MACRO> D3DMacros;
    if( CreationAttribs.Macros )
    {
        for( auto* pCurrMacro = CreationAttribs.Macros; pCurrMacro->Name && pCurrMacro->Definition; ++pCurrMacro )
        {
            D3DMacros.push_back( {pCurrMacro->Name, pCurrMacro->Definition} );
        }
        D3DMacros.push_back( {nullptr, nullptr} );
        pDefines = D3DMacros.data();
    }

    CHECK_D3D_RESULT_THROW( CompileShader( ShaderSource.c_str(), CreationAttribs.EntryPoint, pDefines, CreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode ),
                            "Failed to compile the shader");
}
    STDMETHOD( Open )(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes)
    {
        RefCntAutoPtr<IFileStream> pSourceStream;
        m_pStreamFactory->CreateInputStream( pFileName, &pSourceStream );
        if( pSourceStream == nullptr )
        {
            LOG_ERROR( "Failed to open shader include file ", pFileName, ". Check that the file exists" );
            return E_FAIL;
        }

        RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl );
        pSourceStream->Read( pFileData );
        *ppData = pFileData->GetDataPtr();
        *pBytes = static_cast<UINT>( pFileData->GetSize() );

        m_DataBlobs.insert( std::make_pair(*ppData, pFileData) );

        return S_OK;
    }