Пример #1
0
        public void CalculateStats([NativeTypeName("StatInfo&")] ref D3D12MA_StatInfo outStats)
        {
            ZeroMemory(Unsafe.AsPointer(ref outStats), (nuint)sizeof(D3D12MA_StatInfo));
            outStats.AllocationSizeMin  = UINT64_MAX;
            outStats.UnusedRangeSizeMin = UINT64_MAX;

            using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0);

            for (D3D12MA_Allocation *alloc = m_AllocationList.Front();
                 alloc != null; alloc = D3D12MA_IntrusiveLinkedList <D3D12MA_Allocation> .GetNext(alloc))
            {
                ulong size = alloc->GetSize();
                ++outStats.BlockCount;
                ++outStats.AllocationCount;
                outStats.UsedBytes += size;

                if (size > outStats.AllocationSizeMax)
                {
                    outStats.AllocationSizeMax = size;
                }

                if (size < outStats.AllocationSizeMin)
                {
                    outStats.AllocationSizeMin = size;
                }
            }
        }
        public int CreateAliasingResource(D3D12MA_Allocation *pAllocation, [NativeTypeName("UINT64")] ulong AllocationLocalOffset, [NativeTypeName("const D3D12_RESOURCE_DESC*")] D3D12_RESOURCE_DESC *pResourceDesc, D3D12_RESOURCE_STATES InitialResourceState, [NativeTypeName("const D3D12_CLEAR_VALUE*")] D3D12_CLEAR_VALUE *pOptimizedClearValue, [NativeTypeName("REFIID")] Guid *riidResource, void **ppvResource)
        {
            if ((pAllocation == null) || (pResourceDesc == null) || (ppvResource == null))
            {
                D3D12MA_ASSERT(false); // "Invalid arguments passed to Allocator::CreateAliasingResource."
                return(E_INVALIDARG);
            }

            using var debugGlobalMutexLock = D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK();

            return(m_Pimpl->CreateAliasingResource(pAllocation, AllocationLocalOffset, pResourceDesc, InitialResourceState, pOptimizedClearValue, riidResource, ppvResource));
        }
Пример #3
0
        /// <summary>Writes JSON array with the list of allocations.</summary>
        public void BuildStatsString([NativeTypeName("JsonWriter&")] ref D3D12MA_JsonWriter json)
        {
            using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0);

            json.BeginArray();
            for (D3D12MA_Allocation *alloc = m_AllocationList.Front();
                 alloc != null; alloc = D3D12MA_IntrusiveLinkedList <D3D12MA_Allocation> .GetNext(alloc))
            {
                json.BeginObject(true);
                json.AddAllocationToObject(alloc);
                json.EndObject();
            }
            json.EndArray();
        }
Пример #4
0
        public void Register(D3D12MA_Allocation *alloc)
        {
            using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0);

            m_AllocationList.PushBack(alloc);
        }
Пример #5
0
        public void Unregister(D3D12MA_Allocation *alloc)
        {
            using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0);

            m_AllocationList.Remove(alloc);
        }
        public void AddAllocationToObject(D3D12MA_Allocation *alloc)
        {
            WriteString("Type");

            switch (alloc->m_PackedData.GetResourceDimension())
            {
            case D3D12_RESOURCE_DIMENSION_UNKNOWN:
            {
                WriteString("UNKNOWN");
                break;
            }

            case D3D12_RESOURCE_DIMENSION_BUFFER:
            {
                WriteString("BUFFER");
                break;
            }

            case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
            {
                WriteString("TEXTURE1D");
                break;
            }

            case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
            {
                WriteString("TEXTURE2D");
                break;
            }

            case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
            {
                WriteString("TEXTURE3D");
                break;
            }

            default:
            {
                D3D12MA_ASSERT(false);
                break;
            }
            }

            WriteString("Size");
            WriteNumber(alloc->GetSize());

            ushort *name = alloc->GetName();

            if (name != null)
            {
                WriteString("Name");
                WriteString(name);
            }

            if (alloc->m_PackedData.GetResourceFlags() != 0)
            {
                WriteString("Flags");
                WriteNumber((uint)alloc->m_PackedData.GetResourceFlags());
            }

            if (alloc->m_PackedData.GetTextureLayout() != 0)
            {
                WriteString("Layout");
                WriteNumber((uint)alloc->m_PackedData.GetTextureLayout());
            }

            if (alloc->m_CreationFrameIndex != 0)
            {
                WriteString("CreationFrameIndex");
                WriteNumber(alloc->m_CreationFrameIndex);
            }
        }
Пример #7
0
 public void Free(D3D12MA_Allocation *alloc)
 {
     using var mutexLock = new D3D12MA_MutexLock(ref m_Mutex);
     m_Allocator.Free(alloc);
 }
Пример #8
0
        public void Free(D3D12MA_Allocation *hAllocation)
        {
            D3D12MA_NormalBlock *pBlockToDelete = null;

            bool budgetExceeded = false;

            {
                D3D12MA_Budget budget = default;
                m_hAllocator->GetBudgetForHeapType(&budget, m_HeapType);
                budgetExceeded = budget.UsageBytes >= budget.BudgetBytes;
            }

            using (var @lock = new D3D12MA_MutexLockWrite(ref m_Mutex, m_hAllocator->UseMutex()))
            {
                D3D12MA_NormalBlock *pBlock = hAllocation->m_Placed.block;

                pBlock->m_pMetadata->FreeAtOffset(hAllocation->GetOffset());
                D3D12MA_HEAVY_ASSERT((D3D12MA_DEBUG_LEVEL > 1) && pBlock->Validate());

                nuint blockCount   = m_Blocks.size();
                ulong sumBlockSize = CalcSumBlockSize();

                // pBlock became empty after this deallocation.
                if (pBlock->m_pMetadata->IsEmpty())
                {
                    // Already has empty Allocation. We don't want to have two, so delete this one.
                    if ((m_HasEmptyBlock || budgetExceeded) && (blockCount > m_MinBlockCount) && ((sumBlockSize - pBlock->m_pMetadata->GetSize()) >= m_MinBytes))
                    {
                        pBlockToDelete = pBlock;
                        Remove(pBlock);
                    }
                    else
                    {
                        // We now have first empty block.
                        m_HasEmptyBlock = true;
                    }
                }
                else if (m_HasEmptyBlock && blockCount > m_MinBlockCount)
                {
                    // pBlock didn't become empty, but we have another empty block - find and free that one.
                    // (This is optional, heuristics.)

                    D3D12MA_NormalBlock *pLastBlock = m_Blocks.back()->Value;

                    if (pLastBlock->m_pMetadata->IsEmpty() && ((sumBlockSize - pLastBlock->m_pMetadata->GetSize()) >= m_MinBytes))
                    {
                        pBlockToDelete = pLastBlock;
                        m_Blocks.pop_back();
                        m_HasEmptyBlock = false;
                    }
                }

                IncrementallySortBlocks();
            }

            // Destruction of a free Allocation. Deferred until this point, outside of mutex
            // lock, for performance reason.
            if (pBlockToDelete != null)
            {
                D3D12MA_DELETE(m_hAllocator->GetAllocs(), pBlockToDelete);
            }
        }