D3D12GraphicsDevice.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #pragma once
  2. #include <comdef.h>
  3. #include <d3d11_4.h>
  4. #include <d3d12.h>
  5. #include <stdexcept>
  6. #include <wrl/client.h>
  7. #include <IUnityGraphicsD3D12.h>
  8. #include "D3D12Texture2D.h"
  9. #include "GraphicsDevice/Cuda/CudaContext.h"
  10. #include "GraphicsDevice/IGraphicsDevice.h"
  11. namespace unity
  12. {
  13. namespace webrtc
  14. {
  15. using namespace Microsoft::WRL;
  16. namespace webrtc = ::webrtc;
  17. #define DefPtr(_a) _COM_SMARTPTR_TYPEDEF(_a, __uuidof(_a))
  18. DefPtr(ID3D12CommandAllocator);
  19. DefPtr(ID3D12GraphicsCommandList4);
  20. inline std::string HrToString(HRESULT hr)
  21. {
  22. char s_str[64] = {};
  23. sprintf_s(s_str, "HRESULT of 0x%08X", static_cast<UINT>(hr));
  24. return std::string(s_str);
  25. }
  26. class HrException : public std::runtime_error
  27. {
  28. public:
  29. HrException(HRESULT hr)
  30. : std::runtime_error(HrToString(hr))
  31. , m_hr(hr)
  32. {
  33. }
  34. HRESULT Error() const { return m_hr; }
  35. private:
  36. const HRESULT m_hr;
  37. };
  38. inline void ThrowIfFailed(HRESULT hr)
  39. {
  40. if (FAILED(hr))
  41. {
  42. throw HrException(hr);
  43. }
  44. }
  45. class D3D12GraphicsDevice : public IGraphicsDevice
  46. {
  47. public:
  48. explicit D3D12GraphicsDevice(
  49. ID3D12Device* nativeDevice,
  50. IUnityGraphicsD3D12v5* unityInterface,
  51. UnityGfxRenderer renderer,
  52. ProfilerMarkerFactory* profiler);
  53. explicit D3D12GraphicsDevice(
  54. ID3D12Device* nativeDevice,
  55. ID3D12CommandQueue* commandQueue,
  56. UnityGfxRenderer renderer,
  57. ProfilerMarkerFactory* profiler);
  58. virtual ~D3D12GraphicsDevice();
  59. virtual bool InitV() override;
  60. virtual void ShutdownV() override;
  61. inline virtual void* GetEncodeDevicePtrV() override;
  62. virtual ITexture2D*
  63. CreateDefaultTextureV(uint32_t w, uint32_t h, UnityRenderingExtTextureFormat textureFormat) override;
  64. virtual bool CopyResourceV(ITexture2D* dest, ITexture2D* src) override;
  65. virtual bool CopyResourceFromNativeV(ITexture2D* dest, void* nativeTexturePtr) override;
  66. std::unique_ptr<GpuMemoryBufferHandle> Map(ITexture2D* texture) override;
  67. virtual ITexture2D*
  68. CreateCPUReadTextureV(uint32_t w, uint32_t h, UnityRenderingExtTextureFormat textureFormat) override;
  69. virtual rtc::scoped_refptr<webrtc::I420Buffer> ConvertRGBToI420(ITexture2D* tex) override;
  70. bool IsCudaSupport() override { return m_isCudaSupport; }
  71. CUcontext GetCUcontext() override { return m_cudaContext.GetContext(); }
  72. NV_ENC_BUFFER_FORMAT GetEncodeBufferFormat() override { return NV_ENC_BUFFER_FORMAT_ARGB; }
  73. private:
  74. D3D12Texture2D* CreateSharedD3D12Texture(uint32_t w, uint32_t h);
  75. void WaitForFence(ID3D12Fence* fence, HANDLE handle, uint64_t* fenceValue);
  76. void Barrier(
  77. ID3D12Resource* res,
  78. const D3D12_RESOURCE_STATES stateBefore,
  79. const D3D12_RESOURCE_STATES stateAfter,
  80. const UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
  81. ComPtr<ID3D12Device> m_d3d12Device;
  82. ComPtr<ID3D12CommandQueue> m_d3d12CommandQueue;
  83. //[Note-sin: 2019-10-30] sharing res from d3d12 to d3d11 require d3d11.1. Fence is supported in d3d11.4 or
  84. // newer.
  85. ComPtr<ID3D11Device5> m_d3d11Device;
  86. ComPtr<ID3D11DeviceContext4> m_d3d11Context;
  87. bool m_isCudaSupport;
  88. CudaContext m_cudaContext;
  89. //[TODO-sin: 2019-12-2] //This should be allocated for each frame.
  90. ID3D12CommandAllocatorPtr m_commandAllocator;
  91. ID3D12GraphicsCommandList4Ptr m_commandList;
  92. // Fence to copy resource on GPU (and CPU if the texture was created with CPU-access)
  93. ComPtr<ID3D12Fence> m_copyResourceFence;
  94. HANDLE m_copyResourceEventHandle;
  95. uint64_t m_copyResourceFenceValue = 1;
  96. CUcontext m_context;
  97. CUdevice m_device;
  98. };
  99. //---------------------------------------------------------------------------------------------------------------------
  100. // use D3D11. See notes below
  101. void* D3D12GraphicsDevice::GetEncodeDevicePtrV() { return reinterpret_cast<void*>(m_d3d11Device.Get()); }
  102. } // end namespace webrtc
  103. } // end namespace unity
  104. //---------------------------------------------------------------------------------------------------------------------
  105. //[Note-sin: 2019-10-30]
  106. // Since NVEncoder does not support DX12, we use a DX12 resource that can be shared with DX11, and then pass it
  107. // the DX11 resource to NVidia Encoder