Path: blob/master/src/util/d3d12_descriptor_heap_manager.cpp
4214 views
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>1// SPDX-License-Identifier: CC-BY-NC-ND-4.023#include "d3d12_descriptor_heap_manager.h"45#include "common/assert.h"6#include "common/error.h"78D3D12DescriptorHeapManager::D3D12DescriptorHeapManager() = default;9D3D12DescriptorHeapManager::~D3D12DescriptorHeapManager() = default;1011bool D3D12DescriptorHeapManager::Create(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE type, u32 num_descriptors,12bool shader_visible, Error* error)13{14D3D12_DESCRIPTOR_HEAP_DESC desc = {15type, static_cast<UINT>(num_descriptors),16shader_visible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE, 0u};1718HRESULT hr = device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(m_descriptor_heap.ReleaseAndGetAddressOf()));19if (FAILED(hr)) [[unlikely]]20{21Error::SetHResult(error, "CreateDescriptorHeap() failed: ", hr);22return false;23}2425m_heap_base_cpu = m_descriptor_heap->GetCPUDescriptorHandleForHeapStart();26if (shader_visible)27m_heap_base_gpu = m_descriptor_heap->GetGPUDescriptorHandleForHeapStart();2829m_num_descriptors = num_descriptors;30m_descriptor_increment_size = device->GetDescriptorHandleIncrementSize(type);31m_shader_visible = shader_visible;3233// Set all slots to unallocated (1)34const u32 bitset_count = num_descriptors / BITSET_SIZE + (((num_descriptors % BITSET_SIZE) != 0) ? 1 : 0);35m_free_slots.resize(bitset_count);36for (BitSetType& bs : m_free_slots)37bs.flip();3839return true;40}4142void D3D12DescriptorHeapManager::Destroy()43{44#if defined(_DEBUG) || defined(_DEVEL)45for (BitSetType& bs : m_free_slots)46{47DebugAssert(bs.all());48}49#endif5051m_shader_visible = false;52m_num_descriptors = 0;53m_descriptor_increment_size = 0;54m_heap_base_cpu = {};55m_heap_base_gpu = {};56m_descriptor_heap.Reset();57m_free_slots.clear();58}5960bool D3D12DescriptorHeapManager::Allocate(D3D12DescriptorHandle* handle)61{62// Start past the temporary slots, no point in searching those.63for (u32 group = 0; group < m_free_slots.size(); group++)64{65BitSetType& bs = m_free_slots[group];66if (bs.none())67continue;6869u32 bit = 0;70for (; bit < BITSET_SIZE; bit++)71{72if (bs[bit])73break;74}7576u32 index = group * BITSET_SIZE + bit;77bs[bit] = false;7879handle->index = index;80handle->cpu_handle.ptr = m_heap_base_cpu.ptr + index * m_descriptor_increment_size;81handle->gpu_handle.ptr = m_shader_visible ? (m_heap_base_gpu.ptr + index * m_descriptor_increment_size) : 0;82return true;83}8485return false;86}8788void D3D12DescriptorHeapManager::Free(u32 index)89{90DebugAssert(index < m_num_descriptors);9192u32 group = index / BITSET_SIZE;93u32 bit = index % BITSET_SIZE;94m_free_slots[group][bit] = true;95}9697void D3D12DescriptorHeapManager::Free(D3D12DescriptorHandle* handle)98{99if (handle->index == D3D12DescriptorHandle::INVALID_INDEX)100return;101102Free(handle->index);103handle->Clear();104}105106D3D12DescriptorAllocator::D3D12DescriptorAllocator() = default;107D3D12DescriptorAllocator::~D3D12DescriptorAllocator() = default;108109bool D3D12DescriptorAllocator::Create(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE type, u32 num_descriptors, Error* error)110{111const D3D12_DESCRIPTOR_HEAP_DESC desc = {type, static_cast<UINT>(num_descriptors),112D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, 0u};113const HRESULT hr = device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(m_descriptor_heap.ReleaseAndGetAddressOf()));114if (FAILED(hr))115{116Error::SetHResult(error, "CreateDescriptorHeap() failed: ", hr);117return false;118}119120m_num_descriptors = num_descriptors;121m_descriptor_increment_size = device->GetDescriptorHandleIncrementSize(type);122m_heap_base_cpu = m_descriptor_heap->GetCPUDescriptorHandleForHeapStart();123m_heap_base_gpu = m_descriptor_heap->GetGPUDescriptorHandleForHeapStart();124return true;125}126127void D3D12DescriptorAllocator::Destroy()128{129m_descriptor_heap.Reset();130m_descriptor_increment_size = 0;131m_num_descriptors = 0;132m_current_offset = 0;133m_heap_base_cpu = {};134m_heap_base_gpu = {};135}136137bool D3D12DescriptorAllocator::Allocate(u32 num_handles, D3D12DescriptorHandle* out_base_handle)138{139if ((m_current_offset + num_handles) > m_num_descriptors)140return false;141142out_base_handle->index = m_current_offset;143out_base_handle->cpu_handle.ptr = m_heap_base_cpu.ptr + m_current_offset * m_descriptor_increment_size;144out_base_handle->gpu_handle.ptr = m_heap_base_gpu.ptr + m_current_offset * m_descriptor_increment_size;145m_current_offset += num_handles;146return true;147}148149void D3D12DescriptorAllocator::Reset()150{151m_current_offset = 0;152}153154155