void BufferGLImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, class IBufferView **ppView, bool bIsDefaultView )
{
    VERIFY( ppView != nullptr, "Buffer view pointer address is null" );
    if( !ppView )return;
    VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" );
    
    *ppView = nullptr;

    try
    {
        auto ViewDesc = OrigViewDesc;
        CorrectBufferViewDesc( ViewDesc );

        auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice());
        auto &BuffViewAllocator = pDeviceGLImpl->GetBuffViewObjAllocator();
        VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" );

        auto pContext = pDeviceGLImpl->GetImmediateContext();
        VERIFY( pContext, "Immediate context has been released" );
        
        *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewGLImpl instance", BufferViewGLImpl, bIsDefaultView ? this : nullptr)(pDeviceGLImpl, pContext, ViewDesc, this, bIsDefaultView);
        
        if( !bIsDefaultView )
            (*ppView)->AddRef();
    }
    catch( const std::runtime_error & )
    {
        const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType);
        LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name ? m_Desc.Name : "", "\"");
    }
}
void BufferD3D12Impl::CreateSRV( struct BufferViewDesc &SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVDescriptor )
{
    CorrectBufferViewDesc( SRVDesc );

    D3D12_SHADER_RESOURCE_VIEW_DESC D3D12_SRVDesc;
    BufferViewDesc_to_D3D12_SRV_DESC(m_Desc, SRVDesc, D3D12_SRVDesc);

    auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device();
    pDeviceD3D12->CreateShaderResourceView( m_pd3d12Resource, &D3D12_SRVDesc, SRVDescriptor );
}
void BufferD3D12Impl::CreateUAV( BufferViewDesc &UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVDescriptor )
{
    CorrectBufferViewDesc( UAVDesc );

    D3D12_UNORDERED_ACCESS_VIEW_DESC D3D12_UAVDesc;
    BufferViewDesc_to_D3D12_UAV_DESC(m_Desc, UAVDesc, D3D12_UAVDesc);

    auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device();
    pDeviceD3D12->CreateUnorderedAccessView( m_pd3d12Resource, nullptr, &D3D12_UAVDesc, UAVDescriptor );
}
void BufferD3D11Impl::CreateSRV( struct BufferViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV )
{
    CorrectBufferViewDesc( SRVDesc );

    D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc;
    BufferViewDesc_to_D3D11_SRV_DESC(m_Desc, SRVDesc, D3D11_SRVDesc);

    auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device();
    CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Buffer, &D3D11_SRVDesc, ppD3D11SRV ),
                            "Failed to create D3D11 shader resource view" );
}
void BufferD3D11Impl::CreateUAV( BufferViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV )
{
    CorrectBufferViewDesc( UAVDesc );

    D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc;
    BufferViewDesc_to_D3D11_UAV_DESC(m_Desc, UAVDesc, D3D11_UAVDesc);

    auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device();
    CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Buffer, &D3D11_UAVDesc, ppD3D11UAV ),
                            "Failed to create D3D11 unordered access view" );
}