DeviceResources.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // The MIT License(MIT)
  2. //
  3. // Copyright(c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. // this software and associated documentation files(the "Software"), to deal in
  7. // the Software without restriction, including without limitation the rights to
  8. // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
  9. // the Software, and to permit persons to whom the Software is furnished to do so,
  10. // subject to the following conditions :
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
  18. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #pragma once
  22. #include <d3d12.h>
  23. #include <dxgi1_4.h>
  24. #include <wrl.h>
  25. #include <iostream>
  26. #include <vector>
  27. #include "DXUtilities.h"
  28. using namespace Microsoft::WRL;
  29. constexpr uint32_t NUM_BACK_BUFFERS = 4;
  30. struct Adapter
  31. {
  32. std::string Description;
  33. uint32_t VendorId;
  34. uint32_t DeviceId;
  35. uint32_t SubSysId;
  36. uint32_t Revision;
  37. size_t DedicatedVideoMemory;
  38. size_t DedicatedSystemMemory;
  39. size_t SharedSystemMemory;
  40. };
  41. class DescriptorHeap
  42. {
  43. public:
  44. DescriptorHeap() {}
  45. void Create(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE Type, uint32_t numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAGS flags, LPCWSTR debugHeapName = L"") {
  46. m_HeapDesc.Type = Type;
  47. m_HeapDesc.NumDescriptors = numDescriptors;
  48. m_HeapDesc.Flags = flags;
  49. m_HeapDesc.NodeMask = 1;
  50. DX::ThrowIfFailed(device->CreateDescriptorHeap(&m_HeapDesc, __uuidof(ID3D12DescriptorHeap), &m_Heap));
  51. m_Heap->SetName(debugHeapName);
  52. m_DescriptorSize = device->GetDescriptorHandleIncrementSize(m_HeapDesc.Type);
  53. D3D12_CPU_DESCRIPTOR_HANDLE ret = m_Heap->GetCPUDescriptorHandleForHeapStart();
  54. }
  55. ID3D12DescriptorHeap* getDescriptorHeap() { return m_Heap.Get(); }
  56. D3D12_CPU_DESCRIPTOR_HANDLE getCPUDescriptorHandle(uint32_t idx) {
  57. D3D12_CPU_DESCRIPTOR_HANDLE ret = m_Heap->GetCPUDescriptorHandleForHeapStart();
  58. ret.ptr += m_DescriptorSize * idx;
  59. return ret;
  60. }
  61. D3D12_GPU_DESCRIPTOR_HANDLE getGPUDescriptorHandle(uint32_t idx) {
  62. D3D12_GPU_DESCRIPTOR_HANDLE ret = m_Heap->GetGPUDescriptorHandleForHeapStart();
  63. ret.ptr += m_DescriptorSize * idx;
  64. return ret;
  65. }
  66. private:
  67. ComPtr<ID3D12DescriptorHeap> m_Heap;
  68. D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc = {};
  69. uint64_t m_DescriptorSize = 0;
  70. };
  71. class DeviceResources;
  72. class GPUTimer
  73. {
  74. public:
  75. void Initialize(DeviceResources* deviceResources);
  76. void StartTimer(ID3D12GraphicsCommandList* commandList) {
  77. commandList->EndQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, 0);
  78. }
  79. void StopTimer(ID3D12GraphicsCommandList* commandList) {
  80. commandList->EndQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, 1);
  81. }
  82. void ResolveQuery(ID3D12GraphicsCommandList* commandList) {
  83. commandList->ResolveQueryData(m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, 0, 2, m_readBackBuffer.Get(), 0);
  84. }
  85. void ReadBack();
  86. double GetTime_us() {
  87. return static_cast<double>(m_gpuTickDelta * (m_timeEnd - m_timeStart)) * 1E6;
  88. }
  89. private:
  90. ComPtr<ID3D12Resource> m_readBackBuffer;
  91. ComPtr<ID3D12QueryHeap> m_queryHeap;
  92. uint64_t m_fenceValue = 0;
  93. uint64_t m_timeStart = 0;
  94. uint64_t m_timeEnd = 0;
  95. double m_gpuTickDelta = 0.0;
  96. };
  97. class DeviceResources
  98. {
  99. public:
  100. void create(HWND hWnd, uint32_t adapterIdx);
  101. bool isInitialized() { return m_initialized; }
  102. ID3D12Device* device() { return m_device.Get(); }
  103. ID3D12DescriptorHeap* SRVDescHeap() { return m_SRVDescHeap.getDescriptorHeap(); }
  104. ID3D12CommandQueue* commandQueue() { return m_commandQueue.Get(); }
  105. ID3D12GraphicsCommandList* commandList() { return m_commandList.Get(); }
  106. void WaitForGPU();
  107. void MoveToNextFrame();
  108. void PopulateCommandList();
  109. void Present(uint32_t SyncInterval, uint32_t Flags);
  110. void resizeRenderTarget(uint32_t width, uint32_t height);
  111. void CreateTexture2D(uint32_t width, uint32_t height, DXGI_FORMAT format, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource);
  112. void CreateTexture1D(uint32_t width, DXGI_FORMAT format, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource);
  113. void CreateBuffer(uint32_t size, D3D12_HEAP_TYPE heapType, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource);
  114. void UploadTextureData(void* data, uint32_t size, uint32_t rowPitch, ID3D12Resource* pResource, ID3D12Resource* pStagingResource);
  115. void UploadBufferData(void* data, uint32_t size, ID3D12Resource* pResource, ID3D12Resource* pStagingResource);
  116. void CopyToRenderTarget(ID3D12Resource* pSrc);
  117. ID3D12Resource* getRenderTarget();
  118. Adapter adapter() { return m_adapter; }
  119. ID3D12GraphicsCommandList* computeCommandList() { return m_computeCommandList.Get(); }
  120. void StartComputeTimer() { m_timer.StartTimer(m_computeCommandList.Get()); }
  121. void StopComputeTimer() { m_timer.StopTimer(m_computeCommandList.Get()); }
  122. void ResolveComputeTimerQuery() { m_timer.ResolveQuery(m_computeCommandList.Get()); }
  123. double GetTime_us() { return m_timer.GetTime_us(); }
  124. ID3D12Resource* m_output;
  125. protected:
  126. void CreateRenderTarget();
  127. void ReleaseRenderTarget();
  128. private:
  129. struct FrameContext
  130. {
  131. ComPtr<ID3D12CommandAllocator> m_allocator;
  132. ComPtr<ID3D12CommandAllocator> m_computeAllocator;
  133. ComPtr<ID3D12Fence> m_fence;
  134. uint64_t m_fenceValue = 0;
  135. };
  136. ComPtr<ID3D12Device> m_device;
  137. ComPtr<ID3D12CommandQueue> m_commandQueue;
  138. ComPtr<ID3D12GraphicsCommandList> m_commandList;
  139. ComPtr<ID3D12GraphicsCommandList> m_computeCommandList;
  140. ComPtr<ID3D12PipelineState> m_pipelineState;
  141. FrameContext m_frameContext[NUM_BACK_BUFFERS] = {};
  142. uint32_t m_frameIndex = 0;
  143. Wrappers::Event m_fenceEvent;
  144. ComPtr<IDXGISwapChain3> m_swapChain;
  145. HANDLE m_swapChainWaitableObject = nullptr;
  146. ComPtr<ID3D12Resource> m_RTResource[NUM_BACK_BUFFERS] = {};
  147. DescriptorHeap m_RTVDescHeap;
  148. DescriptorHeap m_SRVDescHeap;
  149. GPUTimer m_timer;
  150. bool m_initialized = false;
  151. bool m_windowResized = false;
  152. Adapter m_adapter;
  153. };