Files
FlaxEngine/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h
2024-04-02 14:56:26 +02:00

210 lines
8.1 KiB
C++

// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/GPUContext.h"
#include "IShaderResourceDX12.h"
#include "DescriptorHeapDX12.h"
#include "../IncludeDirectXHeaders.h"
#if GRAPHICS_API_DIRECTX12
class GPUDeviceDX12;
class GPUPipelineStateDX12;
class GPUBufferDX12;
class GPUSamplerDX12;
class GPUConstantBufferDX12;
class GPUTextureViewDX12;
/// <summary>
/// Size of the resource barriers buffer size (will be flushed on overflow)
/// </summary>
#define DX12_RB_BUFFER_SIZE 16
/// <summary>
/// GPU Commands Context implementation for DirectX 12
/// </summary>
class GPUContextDX12 : public GPUContext
{
friend GPUDeviceDX12;
public:
typedef DescriptorHeapRingBufferDX12::Allocation Descriptor;
private:
GPUDeviceDX12* _device;
ID3D12GraphicsCommandList* _commandList;
ID3D12CommandAllocator* _currentAllocator;
GPUPipelineStateDX12* _currentState;
GPUShaderProgramCS* _currentCompute;
int32 _swapChainsUsed;
int32 _vbCount;
int32 _rtCount;
int32 _rbBufferSize;
uint32 _srMaskDirtyGraphics;
uint32 _srMaskDirtyCompute;
uint32 _stencilRef;
D3D_PRIMITIVE_TOPOLOGY _primitiveTopology;
int32 _isCompute : 1;
int32 _rtDirtyFlag : 1;
int32 _psDirtyFlag : 1;
int32 _cbGraphicsDirtyFlag : 1;
int32 _cbComputeDirtyFlag : 1;
int32 _samplersDirtyFlag : 1;
GPUTextureViewDX12* _rtDepth;
GPUTextureViewDX12* _rtHandles[GPU_MAX_RT_BINDED];
IShaderResourceDX12* _srHandles[GPU_MAX_SR_BINDED];
IShaderResourceDX12* _uaHandles[GPU_MAX_UA_BINDED];
GPUBufferDX12* _ibHandle;
GPUBufferDX12* _vbHandles[GPU_MAX_VB_BINDED];
D3D12_INDEX_BUFFER_VIEW _ibView;
D3D12_VERTEX_BUFFER_VIEW _vbViews[GPU_MAX_VB_BINDED];
D3D12_RESOURCE_BARRIER _rbBuffer[DX12_RB_BUFFER_SIZE];
GPUConstantBufferDX12* _cbHandles[GPU_MAX_CB_BINDED];
GPUSamplerDX12* _samplers[GPU_MAX_SAMPLER_BINDED - GPU_STATIC_SAMPLERS_COUNT];
public:
GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
~GPUContextDX12();
public:
FORCE_INLINE ID3D12GraphicsCommandList* GetCommandList() const
{
return _commandList;
}
uint64 FrameFenceValues[2];
public:
/// <summary>
/// Adds the transition barrier for the given resource (or subresource). Supports batching barriers.
/// </summary>
/// <param name="resource">The resource.</param>
/// <param name="before">The 'before' state.</param>
/// <param name="after">The 'after' state.</param>
/// <param name="subresourceIndex">The index of the subresource.</param>
void AddTransitionBarrier(ResourceOwnerDX12* resource, const D3D12_RESOURCE_STATES before, const D3D12_RESOURCE_STATES after, const int32 subresourceIndex);
/// <summary>
/// Adds the UAV barrier. Supports batching barriers.
/// </summary>
void AddUAVBarrier();
/// <summary>
/// Set DirectX 12 resource state using resource barrier
/// </summary>
/// <param name="resource">Resource to use</param>
/// <param name="after">The target state to resource have.</param>
/// <param name="subresourceIndex">The subresource index. Use -1 to apply for the whole resource.</param>
void SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURCE_STATES after, int32 subresourceIndex = -1);
/// <summary>
/// Reset commands list and request new allocator for commands
/// </summary>
void Reset();
/// <summary>
/// Flush existing commands to the GPU
/// </summary>
/// <param name="waitForCompletion">True if CPU should wait for GPU to wait job</param>
/// <returns>Next fence value used for CPU/GPU work synchronization</returns>
uint64 Execute(bool waitForCompletion = false);
/// <summary>
/// External event called by swap chain after using context end
/// </summary>
void OnSwapChainFlush();
/// <summary>
/// Flush pending resource barriers
/// </summary>
FORCE_INLINE void FlushResourceBarriers()
{
flushRBs();
}
protected:
void GetActiveHeapDescriptor(const D3D12_CPU_DESCRIPTOR_HANDLE& cpuHandle, Descriptor& descriptor);
private:
void flushSRVs();
void flushRTVs();
void flushUAVs();
void flushCBs();
void flushSamplers();
void flushRBs();
void flushPS();
void OnDrawCall();
public:
// [GPUContext]
void FrameBegin() override;
void FrameEnd() override;
#if GPU_ALLOW_PROFILE_EVENTS
void EventBegin(const Char* name) override;
void EventEnd() override;
#endif
void* GetNativePtr() const override;
bool IsDepthBufferBinded() override;
void Clear(GPUTextureView* rt, const Color& color) override;
void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
void ClearUA(GPUBuffer* buf, const Float4& value) override;
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
void ClearUA(GPUTexture* texture, const uint32 value[4]) override;
void ClearUA(GPUTexture* texture, const Float4& value) override;
void ResetRenderTarget() override;
void SetRenderTarget(GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts) override;
void SetBlendFactor(const Float4& value) override;
void SetStencilRef(uint32 value) override;
void ResetSR() override;
void ResetUA() override;
void ResetCB() override;
void BindCB(int32 slot, GPUConstantBuffer* cb) override;
void BindSR(int32 slot, GPUResourceView* view) override;
void BindUA(int32 slot, GPUResourceView* view) override;
void BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets = nullptr) override;
void BindIB(GPUBuffer* indexBuffer) override;
void BindSampler(int32 slot, GPUSampler* sampler) override;
void UpdateCB(GPUConstantBuffer* cb, const void* data) override;
void Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCountX, uint32 threadGroupCountY, uint32 threadGroupCountZ) override;
void DispatchIndirect(GPUShaderProgramCS* shader, GPUBuffer* bufferForArgs, uint32 offsetForArgs) override;
void ResolveMultisample(GPUTexture* sourceMultisampleTexture, GPUTexture* destTexture, int32 sourceSubResource, int32 destSubResource, PixelFormat format) override;
void DrawInstanced(uint32 verticesCount, uint32 instanceCount, int32 startInstance, int32 startVertex) override;
void DrawIndexedInstanced(uint32 indicesCount, uint32 instanceCount, int32 startInstance, int32 startVertex, int32 startIndex) override;
void DrawInstancedIndirect(GPUBuffer* bufferForArgs, uint32 offsetForArgs) override;
void DrawIndexedInstancedIndirect(GPUBuffer* bufferForArgs, uint32 offsetForArgs) override;
void SetViewport(const Viewport& viewport) override;
void SetScissor(const Rectangle& scissorRect) override;
GPUPipelineState* GetState() const override;
void SetState(GPUPipelineState* state) override;
void ClearState() override;
void FlushState() override;
void Flush() override;
void UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 size, uint32 offset) override;
void CopyBuffer(GPUBuffer* dstBuffer, GPUBuffer* srcBuffer, uint32 size, uint32 dstOffset, uint32 srcOffset) override;
void UpdateTexture(GPUTexture* texture, int32 arrayIndex, int32 mipIndex, const void* data, uint32 rowPitch, uint32 slicePitch) override;
void CopyTexture(GPUTexture* dstResource, uint32 dstSubresource, uint32 dstX, uint32 dstY, uint32 dstZ, GPUTexture* srcResource, uint32 srcSubresource) override;
void ResetCounter(GPUBuffer* buffer) override;
void CopyCounter(GPUBuffer* dstBuffer, uint32 dstOffset, GPUBuffer* srcBuffer) override;
void CopyResource(GPUResource* dstResource, GPUResource* srcResource) override;
void CopySubresource(GPUResource* dstResource, uint32 dstSubresource, GPUResource* srcResource, uint32 srcSubresource) override;
void SetResourceState(GPUResource* resource, uint64 state, int32 subresource) override;
void ForceRebindDescriptors() override;
};
#endif