RendererDX12.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/UnorderedMap.h>
  6. #include <Renderer/Renderer.h>
  7. #include <Renderer/DX12/CommandQueueDX12.h>
  8. #include <Renderer/DX12/DescriptorHeapDX12.h>
  9. #include <Renderer/DX12/ConstantBufferDX12.h>
  10. #include <Renderer/DX12/TextureDX12.h>
  11. /// DirectX 12 renderer
  12. class RendererDX12 : public Renderer
  13. {
  14. public:
  15. /// Destructor
  16. virtual ~RendererDX12() override;
  17. // See: Renderer
  18. virtual void Initialize(ApplicationWindow *inWindow) override;
  19. virtual void BeginFrame(const CameraState &inCamera, float inWorldScale) override;
  20. virtual void EndShadowPass() override;
  21. virtual void EndFrame() override;
  22. virtual void SetProjectionMode() override;
  23. virtual void SetOrthoMode() override;
  24. virtual Ref<Texture> CreateTexture(const Surface *inSurface) override;
  25. virtual Ref<VertexShader> CreateVertexShader(const char *inName) override;
  26. virtual Ref<PixelShader> CreatePixelShader(const char *inName) override;
  27. virtual unique_ptr<PipelineState> CreatePipelineState(const VertexShader *inVertexShader, const PipelineState::EInputDescription *inInputDescription, uint inInputDescriptionCount, const PixelShader *inPixelShader, PipelineState::EDrawPass inDrawPass, PipelineState::EFillMode inFillMode, PipelineState::ETopology inTopology, PipelineState::EDepthTest inDepthTest, PipelineState::EBlendMode inBlendMode, PipelineState::ECullMode inCullMode) override;
  28. virtual RenderPrimitive * CreateRenderPrimitive(PipelineState::ETopology inType) override;
  29. virtual RenderInstances * CreateRenderInstances() override;
  30. virtual Texture * GetShadowMap() const override { return mShadowMap.GetPtr(); }
  31. virtual void OnWindowResize() override;
  32. /// Create a constant buffer
  33. unique_ptr<ConstantBufferDX12> CreateConstantBuffer(uint inBufferSize);
  34. /// Create a buffer on the default heap (usable for permanent buffers)
  35. ComPtr<ID3D12Resource> CreateD3DResourceOnDefaultHeap(const void *inData, uint64 inSize);
  36. /// Create buffer on the upload heap (usable for temporary buffers).
  37. ComPtr<ID3D12Resource> CreateD3DResourceOnUploadHeap(uint64 inSize);
  38. /// Recycle a buffer on the upload heap. This puts it back in a cache and will reuse it when it is certain the GPU is no longer referencing it.
  39. void RecycleD3DResourceOnUploadHeap(ID3D12Resource *inResource, uint64 inSize);
  40. /// Keeps a reference to the resource until the current frame has finished
  41. void RecycleD3DObject(ID3D12Object *inResource);
  42. /// Access to the most important DirectX structures
  43. ID3D12Device * GetDevice() { return mDevice.Get(); }
  44. ID3D12RootSignature * GetRootSignature() { return mRootSignature.Get(); }
  45. ID3D12GraphicsCommandList * GetCommandList() { JPH_ASSERT(mInFrame); return mCommandList.Get(); }
  46. CommandQueueDX12 & GetUploadQueue() { return mUploadQueue; }
  47. DescriptorHeapDX12 & GetDSVHeap() { return mDSVHeap; }
  48. DescriptorHeapDX12 & GetSRVHeap() { return mSRVHeap; }
  49. private:
  50. // Wait for pending GPU work to complete
  51. void WaitForGpu();
  52. // Create render targets and their views
  53. void CreateRenderTargets();
  54. // Create a depth buffer for the back buffer
  55. void CreateDepthBuffer();
  56. // Function to create a ID3D12Resource on specified heap with specified state
  57. ComPtr<ID3D12Resource> CreateD3DResource(D3D12_HEAP_TYPE inHeapType, D3D12_RESOURCE_STATES inResourceState, uint64 inSize);
  58. // Copy CPU memory into a ID3D12Resource
  59. void CopyD3DResource(ID3D12Resource *inDest, const void *inSrc, uint64 inSize);
  60. // Copy a CPU resource to a GPU resource
  61. void CopyD3DResource(ID3D12Resource *inDest, ID3D12Resource *inSrc, uint64 inSize);
  62. // DirectX interfaces
  63. ComPtr<IDXGIFactory4> mDXGIFactory;
  64. ComPtr<ID3D12Device> mDevice;
  65. DescriptorHeapDX12 mRTVHeap; ///< Render target view heap
  66. DescriptorHeapDX12 mDSVHeap; ///< Depth stencil view heap
  67. DescriptorHeapDX12 mSRVHeap; ///< Shader resource view heap
  68. ComPtr<IDXGISwapChain3> mSwapChain;
  69. ComPtr<ID3D12Resource> mRenderTargets[cFrameCount]; ///< Two render targets (we're double buffering in order for the CPU to continue while the GPU is rendering)
  70. D3D12_CPU_DESCRIPTOR_HANDLE mRenderTargetViews[cFrameCount]; ///< The two render views corresponding to the render targets
  71. ComPtr<ID3D12Resource> mDepthStencilBuffer; ///< The main depth buffer
  72. D3D12_CPU_DESCRIPTOR_HANDLE mDepthStencilView { 0 }; ///< A view for binding the depth buffer
  73. ComPtr<ID3D12CommandAllocator> mCommandAllocators[cFrameCount]; ///< Two command allocator lists (one per frame)
  74. ComPtr<ID3D12CommandQueue> mCommandQueue; ///< The command queue that will execute commands (there's only 1 since we want to finish rendering 1 frame before moving onto the next)
  75. ComPtr<ID3D12GraphicsCommandList> mCommandList; ///< The command list
  76. ComPtr<ID3D12RootSignature> mRootSignature; ///< The root signature, we have a simple application so we only need 1, which is suitable for all our shaders
  77. Ref<TextureDX12> mShadowMap; ///< Used to render shadow maps
  78. CommandQueueDX12 mUploadQueue; ///< Queue used to upload resources to GPU memory
  79. unique_ptr<ConstantBufferDX12> mVertexShaderConstantBufferProjection[cFrameCount];
  80. unique_ptr<ConstantBufferDX12> mVertexShaderConstantBufferOrtho[cFrameCount];
  81. unique_ptr<ConstantBufferDX12> mPixelShaderConstantBuffer[cFrameCount];
  82. // Synchronization objects used to finish rendering and swapping before reusing a command queue
  83. HANDLE mFenceEvent; ///< Fence event to wait for the previous frame rendering to complete (in order to free 1 of the buffers)
  84. ComPtr<ID3D12Fence> mFence; ///< Fence object, used to signal the end of a frame
  85. UINT64 mFenceValues[cFrameCount] = {}; ///< Values that were used to signal completion of one of the two frames
  86. using ResourceCache = UnorderedMap<uint64, Array<ComPtr<ID3D12Resource>>>;
  87. ResourceCache mResourceCache; ///< Cache items ready to be reused
  88. ResourceCache mDelayCached[cFrameCount]; ///< List of reusable ID3D12Resources that are potentially referenced by the GPU so can be used only when the GPU finishes
  89. Array<ComPtr<ID3D12Object>> mDelayReleased[cFrameCount]; ///< Objects that are potentially referenced by the GPU so can only be freed when the GPU finishes
  90. bool mIsExiting = false; ///< When exiting we don't want to add references too buffers
  91. };