// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #if GRAPHICS_API_DIRECTX12 #include "../GPUDeviceDX.h" #include "Engine/Graphics/GPUResource.h" #include "../IncludeDirectXHeaders.h" #include "ResourceOwnerDX12.h" #include "UploadBufferDX12.h" #include "QueryHeapDX12.h" #include "DescriptorHeapDX12.h" #if PLATFORM_WINDOWS #define DX12_BACK_BUFFER_COUNT 3 #else #define DX12_BACK_BUFFER_COUNT 2 #endif class Engine; class WindowsWindow; class GPUContextDX12; class GPUSwapChainDX12; class CommandQueueDX12; class CommandSignatureDX12; /// /// Implementation of Graphics Device for DirectX 12 rendering system /// class GPUDeviceDX12 : public GPUDeviceDX { friend GPUContextDX12; friend GPUSwapChainDX12; private: struct DisposeResourceEntry { IGraphicsUnknown* Resource; uint64 TargetFrame; }; private: // Private Stuff ID3D12Device* _device; IDXGIFactory4* _factoryDXGI; CriticalSection _res2DisposeLock; Array _res2Dispose; // Pipeline ID3D12RootSignature* _rootSignature; CommandQueueDX12* _commandQueue; GPUContextDX12* _mainContext; // Heaps DescriptorHeapWithSlotsDX12::Slot _nullSrv[D3D12_SRV_DIMENSION_TEXTURECUBEARRAY + 1]; DescriptorHeapWithSlotsDX12::Slot _nullUav; public: static GPUDevice* Create(); GPUDeviceDX12(IDXGIFactory4* dxgiFactory, GPUAdapterDX* adapter); ~GPUDeviceDX12(); public: /// /// Data uploading utility via pages. /// UploadBufferDX12 UploadBuffer; /// /// The timestamp queries heap. /// QueryHeapDX12 TimestampQueryHeap; bool AllowTearing = false; CommandSignatureDX12* DispatchIndirectCommandSignature = nullptr; CommandSignatureDX12* DrawIndexedIndirectCommandSignature = nullptr; CommandSignatureDX12* DrawIndirectCommandSignature = nullptr; GPUBuffer* DummyVB = nullptr; D3D12_CPU_DESCRIPTOR_HANDLE NullSRV(D3D12_SRV_DIMENSION dimension) const; D3D12_CPU_DESCRIPTOR_HANDLE NullUAV() const; public: /// /// Gets DX12 device. /// FORCE_INLINE ID3D12Device* GetDevice() const { return _device; } /// /// Gets DXGI factory. /// FORCE_INLINE IDXGIFactory4* GetDXGIFactory() const { return _factoryDXGI; } /// /// Gets DirectX 12 command list object /// ID3D12GraphicsCommandList* GetCommandList() const; /// /// Gets command queue. /// FORCE_INLINE CommandQueueDX12* GetCommandQueue() const { return _commandQueue; } /// /// Gets DirectX 12 command queue object. /// ID3D12CommandQueue* GetCommandQueueDX12() const; /// /// Gets root signature of the graphics pipeline. /// FORCE_INLINE ID3D12RootSignature* GetRootSignature() const { return _rootSignature; } /// /// Gets main commands context (for DirectX 12) /// FORCE_INLINE GPUContextDX12* GetMainContextDX12() const { return _mainContext; } public: DescriptorHeapPoolDX12 Heap_CBV_SRV_UAV; DescriptorHeapPoolDX12 Heap_RTV; DescriptorHeapPoolDX12 Heap_DSV; DescriptorHeapPoolDX12 Heap_Sampler; DescriptorHeapRingBufferDX12 RingHeap_CBV_SRV_UAV; DescriptorHeapRingBufferDX12 RingHeap_Sampler; public: // Add resource to late release service (will be released after 'safeFrameCount' frames) void AddResourceToLateRelease(IGraphicsUnknown* resource, uint32 safeFrameCount = DX12_RESOURCE_DELETE_SAFE_FRAMES_COUNT); static FORCE_INLINE uint32 GetMaxMSAAQuality(uint32 sampleCount) { if (sampleCount <= 8) return 0; return 0xffffffff; } #if PLATFORM_XBOX_SCARLETT ||PLATFORM_XBOX_ONE void OnSuspended(); void OnResumed(); #endif private: #if PLATFORM_XBOX_SCARLETT ||PLATFORM_XBOX_ONE void updateFrameEvents(); #endif void updateRes2Dispose(); public: // [GPUDeviceDX] GPUContext* GetMainContext() override { return reinterpret_cast(_mainContext); } void* GetNativePtr() const override { return _device; } bool Init() override; void DrawBegin() override; void RenderEnd() override; void Dispose() final override; void WaitForGPU() override; GPUTexture* CreateTexture(const StringView& name) override; GPUShader* CreateShader(const StringView& name) override; GPUPipelineState* CreatePipelineState() override; GPUTimerQuery* CreateTimerQuery() override; GPUBuffer* CreateBuffer(const StringView& name) override; GPUSampler* CreateSampler() override; GPUVertexLayout* CreateVertexLayout(const VertexElements& elements, bool explicitOffsets) override; GPUSwapChain* CreateSwapChain(Window* window) override; GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override; }; /// /// GPU resource implementation for DirectX 12 backend. /// template class GPUResourceDX12 : public GPUResourceBase { public: /// /// Initializes a new instance of the class. /// /// The graphics device. /// The resource name. GPUResourceDX12(GPUDeviceDX12* device, const StringView& name) : GPUResourceBase(device, name) { } }; extern GPUDevice* CreateGPUDeviceDX12(); #endif