DescriptorHeap.h 2.4 KB

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