public int CreatePool([NativeTypeName("const POOL_DESC*")] D3D12MA_POOL_DESC *pPoolDesc, D3D12MA_Pool **ppPool)
        {
            if ((pPoolDesc == null) || (ppPool == null) || !IsHeapTypeValid(pPoolDesc->HeapType) || ((pPoolDesc->MaxBlockCount > 0) && (pPoolDesc->MaxBlockCount < pPoolDesc->MinBlockCount)))
            {
                D3D12MA_ASSERT(false); // "Invalid arguments passed to Allocator::CreatePool."
                return(E_INVALIDARG);
            }

            if (!m_Pimpl->HeapFlagsFulfillResourceHeapTier(pPoolDesc->HeapFlags))
            {
                D3D12MA_ASSERT(false); // "Invalid pPoolDesc->HeapFlags passed to Allocator::CreatePool. Did you forget to handle ResourceHeapTier=1?"
                return(E_INVALIDARG);
            }

            using var debugGlobalMutexLock = D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK();

            *ppPool = D3D12MA_NEW <D3D12MA_Pool>(m_Pimpl->GetAllocs());
            D3D12MA_Pool._ctor(ref **ppPool, ref this, pPoolDesc);

            HRESULT hr = (*ppPool)->m_Pimpl->Init();

            if (SUCCEEDED(hr))
            {
                m_Pimpl->RegisterPool(*ppPool, pPoolDesc->HeapType);
            }
            else
            {
                D3D12MA_DELETE(m_Pimpl->GetAllocs(), *ppPool);
                *ppPool = null;
            }

            return(hr);
        }
 internal static void _ctor(ref D3D12MA_Pool pThis, ref D3D12MA_Allocator allocator, [NativeTypeName("const POOL_DESC&")] D3D12MA_POOL_DESC *desc)
 {
     pThis.m_Pimpl = D3D12MA_NEW <D3D12MA_PoolPimpl>(allocator.m_Pimpl->GetAllocs());
     D3D12MA_PoolPimpl._ctor(ref *pThis.m_Pimpl, allocator.m_Pimpl, desc);
 }