DescriptorHeap.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. /// DirectX descriptor heap, used to allocate handles for resources to bind them to shaders
  5. class DescriptorHeap
  6. {
  7. public:
  8. /// Initialize the heap
  9. /// @param inDevice The DirectX device
  10. /// @param inType Type of heap
  11. /// @param inFlags Flags for the heap
  12. /// @param inNumber Number of handles to reserve
  13. void Init(ID3D12Device *inDevice, D3D12_DESCRIPTOR_HEAP_TYPE inType, D3D12_DESCRIPTOR_HEAP_FLAGS inFlags, uint inNumber)
  14. {
  15. // Create the heap
  16. D3D12_DESCRIPTOR_HEAP_DESC heap_desc = {};
  17. heap_desc.NumDescriptors = inNumber;
  18. heap_desc.Type = inType;
  19. heap_desc.Flags = inFlags;
  20. FatalErrorIfFailed(inDevice->CreateDescriptorHeap(&heap_desc, IID_PPV_ARGS(&mHeap)));
  21. // Delta between descriptor elements
  22. mDescriptorSize = inDevice->GetDescriptorHandleIncrementSize(heap_desc.Type);
  23. // Delta between the CPU and GPU heap
  24. mGPUOffset = mHeap->GetGPUDescriptorHandleForHeapStart().ptr - mHeap->GetCPUDescriptorHandleForHeapStart().ptr;
  25. // Populate the freelist
  26. mFreeList.reserve(inNumber);
  27. for (uint i = 0; i < inNumber; ++i)
  28. mFreeList.push_back(i);
  29. }
  30. /// Allocate and return a new handle
  31. D3D12_CPU_DESCRIPTOR_HANDLE Allocate()
  32. {
  33. JPH_ASSERT(!mFreeList.empty());
  34. D3D12_CPU_DESCRIPTOR_HANDLE handle = mHeap->GetCPUDescriptorHandleForHeapStart();
  35. uint index = mFreeList.back();
  36. mFreeList.pop_back();
  37. handle.ptr += index * mDescriptorSize;
  38. return handle;
  39. }
  40. /// Free a handle and return it to the freelist
  41. void Free(D3D12_CPU_DESCRIPTOR_HANDLE inHandle)
  42. {
  43. uint index = uint((inHandle.ptr - mHeap->GetCPUDescriptorHandleForHeapStart().ptr) / mDescriptorSize);
  44. mFreeList.push_back(index);
  45. }
  46. /// Convert from a CPU to a GPU handle
  47. D3D12_GPU_DESCRIPTOR_HANDLE ConvertToGPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE inHandle)
  48. {
  49. return { inHandle.ptr + mGPUOffset };
  50. }
  51. /// Access to the underlying DirectX structure
  52. ID3D12DescriptorHeap * Get()
  53. {
  54. return mHeap.Get();
  55. }
  56. private:
  57. ComPtr<ID3D12DescriptorHeap> mHeap;
  58. uint mDescriptorSize; ///< The size (in bytes) of a single heap descriptor
  59. vector<uint> mFreeList; ///< List of indices in the heap that are still free
  60. INT64 mGPUOffset; ///< Offset between CPU and GPU handles
  61. };