DescriptorHeap.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. if (inFlags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE)
  25. mGPUOffset = mHeap->GetGPUDescriptorHandleForHeapStart().ptr - mHeap->GetCPUDescriptorHandleForHeapStart().ptr;
  26. // Populate the freelist
  27. mFreeList.reserve(inNumber);
  28. for (uint i = 0; i < inNumber; ++i)
  29. mFreeList.push_back(i);
  30. }
  31. /// Allocate and return a new handle
  32. D3D12_CPU_DESCRIPTOR_HANDLE Allocate()
  33. {
  34. JPH_ASSERT(!mFreeList.empty());
  35. D3D12_CPU_DESCRIPTOR_HANDLE handle = mHeap->GetCPUDescriptorHandleForHeapStart();
  36. uint index = mFreeList.back();
  37. mFreeList.pop_back();
  38. handle.ptr += index * mDescriptorSize;
  39. return handle;
  40. }
  41. /// Free a handle and return it to the freelist
  42. void Free(D3D12_CPU_DESCRIPTOR_HANDLE inHandle)
  43. {
  44. uint index = uint((inHandle.ptr - mHeap->GetCPUDescriptorHandleForHeapStart().ptr) / mDescriptorSize);
  45. mFreeList.push_back(index);
  46. }
  47. /// Convert from a CPU to a GPU handle
  48. D3D12_GPU_DESCRIPTOR_HANDLE ConvertToGPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE inHandle)
  49. {
  50. JPH_ASSERT(mGPUOffset != -1);
  51. return { UINT64(inHandle.ptr) + mGPUOffset };
  52. }
  53. /// Access to the underlying DirectX structure
  54. ID3D12DescriptorHeap * Get()
  55. {
  56. return mHeap.Get();
  57. }
  58. private:
  59. ComPtr<ID3D12DescriptorHeap> mHeap;
  60. uint mDescriptorSize; ///< The size (in bytes) of a single heap descriptor
  61. Array<uint> mFreeList; ///< List of indices in the heap that are still free
  62. INT64 mGPUOffset = -1; ///< Offset between CPU and GPU handles
  63. };