511 lines
20 KiB
C++
511 lines
20 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
VulkanContext.h: Class to generate Vulkan command buffers from RHI CommandLists
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#include "VulkanResources.h"
|
|
#include "VulkanRHIPrivate.h"
|
|
#include "VulkanGPUProfiler.h"
|
|
#include "VulkanSubmission.h"
|
|
|
|
class FVulkanDevice;
|
|
class FVulkanDynamicRHI;
|
|
class FVulkanPendingGfxState;
|
|
class FVulkanPendingComputeState;
|
|
class FVulkanQueue;
|
|
class FVulkanSwapChain;
|
|
|
|
|
|
enum class EVulkanFlushFlags
|
|
{
|
|
None = 0,
|
|
|
|
// Block the calling thread until the submission thread has dispatched all work.
|
|
WaitForSubmission = 1,
|
|
|
|
// Both the calling thread until the GPU has signaled completion of all dispatched work.
|
|
WaitForCompletion = 2
|
|
};
|
|
ENUM_CLASS_FLAGS(EVulkanFlushFlags)
|
|
|
|
|
|
struct FVulkanParallelRenderPassInfo
|
|
{
|
|
VkRenderPass RenderPassHandle = VK_NULL_HANDLE;
|
|
TArray<FVulkanPayload*> SecondaryPayloads;
|
|
};
|
|
|
|
|
|
class FVulkanContextCommon
|
|
{
|
|
protected:
|
|
// Phases are used to track where we are at in filling the current payload.
|
|
// Phases always move forward in the order declared here, never backwards.
|
|
// Always use GetPayload(EPhase) to fetch the payload for the phase you want,
|
|
// it will take care of creating a new payload when necessary.
|
|
enum class EPhase
|
|
{
|
|
Wait,
|
|
Execute,
|
|
Signal
|
|
};
|
|
|
|
public:
|
|
FVulkanContextCommon(FVulkanDevice& InDevice, FVulkanQueue& InQueue, EVulkanCommandBufferType InCommandBufferType);
|
|
virtual ~FVulkanContextCommon();
|
|
|
|
FVulkanPayload& GetPayload(EPhase Phase)
|
|
{
|
|
if (Payloads.Num() == 0 || Phase < CurrentPhase)
|
|
{
|
|
NewPayload();
|
|
}
|
|
|
|
CurrentPhase = Phase;
|
|
return *Payloads.Last();
|
|
}
|
|
|
|
// NOTE: This call is getting phased out, use GetCommandBuffer()
|
|
FVulkanCommandBuffer* GetActiveCmdBuffer()
|
|
{
|
|
return &GetCommandBuffer();
|
|
}
|
|
|
|
FVulkanCommandBuffer& GetCommandBuffer()
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(EPhase::Execute);
|
|
checkSlow(Payload.SignalSemaphores.Num() == 0);
|
|
|
|
if (Payload.CommandBuffers.Num() == 0)
|
|
{
|
|
PrepareNewCommandBuffer(Payload);
|
|
}
|
|
|
|
return *Payload.CommandBuffers.Last();
|
|
}
|
|
|
|
void AddWaitSemaphore(VkPipelineStageFlags InWaitFlags, VulkanRHI::FSemaphore* InWaitSemaphore)
|
|
{
|
|
AddWaitSemaphores(InWaitFlags, MakeArrayView<VulkanRHI::FSemaphore*>(&InWaitSemaphore, 1));
|
|
}
|
|
void AddWaitSemaphores(VkPipelineStageFlags InWaitFlags, TArrayView<VulkanRHI::FSemaphore*> InWaitSemaphores)
|
|
{
|
|
if (InWaitSemaphores.Num())
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(EPhase::Wait);
|
|
checkSlow((Payload.CommandBuffers.Num() == 0) && (Payload.SignalSemaphores.Num() == 0));
|
|
|
|
Payload.WaitFlags.Reserve(Payload.WaitFlags.Num() + InWaitSemaphores.Num());
|
|
for (int32 Index = 0; Index < InWaitSemaphores.Num(); ++Index)
|
|
{
|
|
InWaitSemaphores[Index]->AddRef();
|
|
Payload.WaitFlags.Add(InWaitFlags);
|
|
}
|
|
Payload.WaitSemaphores.Append(InWaitSemaphores);
|
|
}
|
|
}
|
|
|
|
void AddSignalSemaphore(VulkanRHI::FSemaphore* InSignalSemaphore)
|
|
{
|
|
AddSignalSemaphores(MakeArrayView<VulkanRHI::FSemaphore*>(&InSignalSemaphore, 1));
|
|
}
|
|
void AddSignalSemaphores(TArrayView<VulkanRHI::FSemaphore*> InSignalSemaphores)
|
|
{
|
|
if (InSignalSemaphores.Num())
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(EPhase::Signal);
|
|
Payload.SignalSemaphores.Append(InSignalSemaphores);
|
|
}
|
|
}
|
|
|
|
// Complete recording of the current command list set, and appends the resulting
|
|
// payloads to the given array. Resets the context so new commands can be recorded.
|
|
virtual void Finalize(TArray<FVulkanPayload*>& OutPayloads);
|
|
|
|
VkCommandPool GetHandle() const
|
|
{
|
|
return Pool.GetHandle();
|
|
}
|
|
|
|
void FreeUnusedCmdBuffers(bool bTrimMemory);
|
|
|
|
// Should only ne used when we are certain there are no other pending contexts (like UploadContext)
|
|
void FlushCommands(EVulkanFlushFlags FlushFlags = EVulkanFlushFlags::None);
|
|
|
|
// Public immutable references, access them directly
|
|
FVulkanDevice& Device;
|
|
FVulkanQueue& Queue;
|
|
|
|
// Add a provided sync point that will be signaled at the end of the current payload's accumulated work
|
|
void SignalSyncPoint(const FVulkanSyncPointRef& InSync)
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(EPhase::Signal);
|
|
Payload.SyncPoints.Add(InSync);
|
|
}
|
|
|
|
// Add provided sync points that will be appended next time a payload reaches the Signal phase
|
|
void AddPendingSyncPoint(const FVulkanSyncPointRef& InSyncs)
|
|
{
|
|
PendingSyncPoints.Add(InSyncs);
|
|
}
|
|
|
|
// Add an event to be signaled with the current payload is submitted (does not alter phase)
|
|
void AddSubmissionEvent(FGraphEventRef& InEvent)
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(CurrentPhase);
|
|
Payload.SubmissionEvents.Add(InEvent);
|
|
}
|
|
|
|
// Force pending syncs to be sent to a payload
|
|
void FlushPendingSyncPoints()
|
|
{
|
|
if (PendingSyncPoints.Num())
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(EPhase::Signal);
|
|
Payload.SyncPoints.Append(PendingSyncPoints);
|
|
PendingSyncPoints.Empty();
|
|
}
|
|
}
|
|
|
|
// Returns a single sync point for the context that will be inserted when it is finalized
|
|
FVulkanSyncPoint* GetContextSyncPoint()
|
|
{
|
|
if (!ContextSyncPoint)
|
|
{
|
|
ContextSyncPoint = CreateVulkanSyncPoint();
|
|
}
|
|
return ContextSyncPoint;
|
|
}
|
|
|
|
TArray<FVulkanQueryPool*>& GetQueryPoolArray(EVulkanQueryPoolType Type)
|
|
{
|
|
FVulkanPayload& Payload = GetPayload(EPhase::Execute);
|
|
return Payload.QueryPools[(int32)Type];
|
|
}
|
|
|
|
FVulkanQueryPool* GetCurrentTimestampQueryPool()
|
|
{
|
|
return GetCurrentTimestampQueryPool(GetPayload(EPhase::Execute));
|
|
}
|
|
|
|
virtual FVulkanParallelRenderPassInfo* GetParallelRenderPassInfo()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
private:
|
|
|
|
FVulkanQueryPool* GetCurrentTimestampQueryPool(FVulkanPayload& Payload);
|
|
void PrepareNewCommandBuffer(FVulkanPayload& Payload);
|
|
void NewPayload();
|
|
void EndPayload();
|
|
|
|
FVulkanCommandBufferPool& Pool;
|
|
|
|
TArray<FVulkanPayload*> Payloads;
|
|
EPhase CurrentPhase = EPhase::Wait;
|
|
|
|
// Sync points signaled at the next Signal phase (will not force a phase change) or when context is finalized
|
|
TArray<FVulkanSyncPointRef> PendingSyncPoints;
|
|
|
|
// Sync point signaled when the current context is finalized
|
|
FVulkanSyncPointRef ContextSyncPoint;
|
|
};
|
|
|
|
|
|
|
|
class FVulkanCommandListContext : public FVulkanContextCommon, public IRHICommandContext
|
|
{
|
|
public:
|
|
FVulkanCommandListContext(FVulkanDevice& InDevice, ERHIPipeline InPipeline, FVulkanCommandListContext* InImmediate);
|
|
virtual ~FVulkanCommandListContext();
|
|
|
|
// Constructor for parallel render contexts that use secondary command buffers
|
|
FVulkanCommandListContext(FVulkanDevice& InDevice, FVulkanCommandListContext* InImmediate, FVulkanParallelRenderPassInfo* InParallelRenderPassInfo);
|
|
|
|
static inline FVulkanCommandListContext& Get(FRHICommandListBase& RHICmdList)
|
|
{
|
|
return static_cast<FVulkanCommandListContext&>(RHICmdList.GetContext().GetLowestLevelContext());
|
|
}
|
|
|
|
inline bool IsImmediate() const
|
|
{
|
|
return Immediate == nullptr;
|
|
}
|
|
|
|
virtual ERHIPipeline GetPipeline() const override
|
|
{
|
|
return RHIPipeline;
|
|
}
|
|
|
|
template <class ShaderType> void SetResourcesFromTables(const ShaderType* RESTRICT);
|
|
void CommitGraphicsResourceTables();
|
|
void CommitComputeResourceTables();
|
|
|
|
virtual void RHISetStreamSource(uint32 StreamIndex, FRHIBuffer* VertexBuffer, uint32 Offset) final override;
|
|
virtual void RHISetViewport(float MinX, float MinY, float MinZ, float MaxX, float MaxY, float MaxZ) final override;
|
|
virtual void RHISetStereoViewport(float LeftMinX, float RightMinX, float LeftMinY, float RightMinY, float MinZ, float LeftMaxX, float RightMaxX, float LeftMaxY, float RightMaxY, float MaxZ) override;
|
|
virtual void RHISetScissorRect(bool bEnable, uint32 MinX, uint32 MinY, uint32 MaxX, uint32 MaxY) final override;
|
|
virtual void RHISetGraphicsPipelineState(FRHIGraphicsPipelineState* GraphicsState, uint32 StencilRef, bool bApplyAdditionalState) final override;
|
|
void RHISetShaderTexture(FRHIGraphicsShader* Shader, uint32 TextureIndex, FRHITexture* NewTexture);
|
|
void RHISetShaderTexture(FRHIComputeShader* PixelShader, uint32 TextureIndex, FRHITexture* NewTexture);
|
|
void RHISetShaderSampler(FRHIComputeShader* ComputeShader, uint32 SamplerIndex, FRHISamplerState* NewState);
|
|
void RHISetShaderSampler(FRHIGraphicsShader* Shader, uint32 SamplerIndex, FRHISamplerState* NewState);
|
|
void RHISetUAVParameter(FRHIPixelShader* PixelShader, uint32 UAVIndex, FRHIUnorderedAccessView* UAV);
|
|
void RHISetUAVParameter(FRHIComputeShader* ComputeShader, uint32 UAVIndex, FRHIUnorderedAccessView* UAV);
|
|
void RHISetUAVParameter(FRHIComputeShader* ComputeShader, uint32 UAVIndex, FRHIUnorderedAccessView* UAV, uint32 InitialCount);
|
|
void RHISetShaderResourceViewParameter(FRHIGraphicsShader* Shader, uint32 SamplerIndex, FRHIShaderResourceView* SRV);
|
|
void RHISetShaderResourceViewParameter(FRHIComputeShader* ComputeShader, uint32 SamplerIndex, FRHIShaderResourceView* SRV);
|
|
virtual void RHISetStaticUniformBuffers(const FUniformBufferStaticBindings& InUniformBuffers) final override;
|
|
virtual void RHISetStaticUniformBuffer(FUniformBufferStaticSlot Slot, FRHIUniformBuffer* Buffer) final override;
|
|
virtual void RHISetUniformBufferDynamicOffset(FUniformBufferStaticSlot Slot, uint32 InOffset) final override;
|
|
void RHISetShaderUniformBuffer(FRHIGraphicsShader* Shader, uint32 BufferIndex, FRHIUniformBuffer* Buffer);
|
|
void RHISetShaderUniformBuffer(FRHIComputeShader* ComputeShader, uint32 BufferIndex, FRHIUniformBuffer* Buffer);
|
|
void RHISetShaderParameter(FRHIGraphicsShader* Shader, uint32 BufferIndex, uint32 BaseIndex, uint32 NumBytes, const void* NewValue);
|
|
void RHISetShaderParameter(FRHIComputeShader* ComputeShader, uint32 BufferIndex, uint32 BaseIndex, uint32 NumBytes, const void* NewValue);
|
|
virtual void RHISetShaderParameters(FRHIGraphicsShader* Shader, TConstArrayView<uint8> InParametersData, TConstArrayView<FRHIShaderParameter> InParameters, TConstArrayView<FRHIShaderParameterResource> InResourceParameters, TConstArrayView<FRHIShaderParameterResource> InBindlessParameters) final override;
|
|
virtual void RHISetShaderParameters(FRHIComputeShader* Shader, TConstArrayView<uint8> InParametersData, TConstArrayView<FRHIShaderParameter> InParameters, TConstArrayView<FRHIShaderParameterResource> InResourceParameters, TConstArrayView<FRHIShaderParameterResource> InBindlessParameters) final override;
|
|
virtual void RHISetStencilRef(uint32 StencilRef) final override;
|
|
virtual void RHIDrawPrimitive(uint32 BaseVertexIndex, uint32 NumPrimitives, uint32 NumInstances) final override;
|
|
virtual void RHIDrawPrimitiveIndirect(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
virtual void RHIDrawIndexedIndirect(FRHIBuffer* IndexBufferRHI, FRHIBuffer* ArgumentsBufferRHI, int32 DrawArgumentsIndex, uint32 NumInstances) final override;
|
|
virtual void RHIDrawIndexedPrimitive(FRHIBuffer* IndexBuffer, int32 BaseVertexIndex, uint32 FirstInstance, uint32 NumVertices, uint32 StartIndex, uint32 NumPrimitives, uint32 NumInstances) final override;
|
|
virtual void RHIDrawIndexedPrimitiveIndirect(FRHIBuffer* IndexBuffer, FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
#if PLATFORM_SUPPORTS_MESH_SHADERS
|
|
virtual void RHIDispatchMeshShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ) final override;
|
|
virtual void RHIDispatchIndirectMeshShader(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
#endif
|
|
virtual void RHISetDepthBounds(float MinDepth, float MaxDepth) final override;
|
|
#if WITH_RHI_BREADCRUMBS
|
|
virtual void RHIBeginBreadcrumbGPU(FRHIBreadcrumbNode* Breadcrumb) final override;
|
|
virtual void RHIEndBreadcrumbGPU (FRHIBreadcrumbNode* Breadcrumb) final override;
|
|
#endif
|
|
|
|
virtual void RHISetComputePipelineState(FRHIComputePipelineState* ComputePipelineState) final override;
|
|
virtual void RHIDispatchComputeShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ) final override;
|
|
virtual void RHIDispatchIndirectComputeShader(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
|
|
virtual void RHISetMultipleViewports(uint32 Count, const FViewportBounds* Data) final override;
|
|
virtual void RHIClearUAVFloat(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FVector4f& Values) final override;
|
|
virtual void RHIClearUAVUint(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FUintVector4& Values) final override;
|
|
virtual void RHICopyTexture(FRHITexture* SourceTexture, FRHITexture* DestTexture, const FRHICopyTextureInfo& CopyInfo) final override;
|
|
virtual void RHICopyBufferRegion(FRHIBuffer* DstBuffer, uint64 DstOffset, FRHIBuffer* SrcBuffer, uint64 SrcOffset, uint64 NumBytes) final override;
|
|
virtual void RHIBeginTransitions(TArrayView<const FRHITransition*> Transitions) override final;
|
|
virtual void RHIEndTransitions(TArrayView<const FRHITransition*> Transitions) override final;
|
|
virtual void RHICopyToStagingBuffer(FRHIBuffer* SourceBuffer, FRHIStagingBuffer* DestinationStagingBuffer, uint32 Offset, uint32 NumBytes) final override;
|
|
virtual void RHIWriteGPUFence(FRHIGPUFence* Fence) final override;
|
|
|
|
// Render time measurement
|
|
virtual void RHIBeginRenderQuery(FRHIRenderQuery* RenderQuery) final override;
|
|
virtual void RHIEndRenderQuery(FRHIRenderQuery* RenderQuery) final override;
|
|
|
|
#if RHI_NEW_GPU_PROFILER
|
|
void FlushProfilerStats()
|
|
{
|
|
// Flush accumulated draw stats (if breadcrumbs are available to attach them to)
|
|
if (StatEvent && bSupportsBreadcrumbs)
|
|
{
|
|
GetCommandBuffer().EmplaceProfilerEvent<UE::RHI::GPUProfiler::FEvent::FStats>() = StatEvent;
|
|
StatEvent = {};
|
|
}
|
|
}
|
|
#else
|
|
virtual void RHICalibrateTimers(FRHITimestampCalibrationQuery* CalibrationQuery) final override;
|
|
#endif
|
|
|
|
virtual void Finalize(TArray<FVulkanPayload*>& OutPayloads) override;
|
|
|
|
virtual void RHIBeginDrawingViewport(FRHIViewport* Viewport, FRHITexture* RenderTargetRHI) final override;
|
|
virtual void RHIEndDrawingViewport(FRHIViewport* Viewport, bool bPresent, bool bLockToVsync) final override;
|
|
|
|
virtual void RHIBeginRenderPass(const FRHIRenderPassInfo& InInfo, const TCHAR* InName) final override;
|
|
virtual void RHIEndRenderPass() final override;
|
|
virtual void RHINextSubpass() final override;
|
|
|
|
virtual void RHIBeginParallelRenderPass(TSharedPtr<FRHIParallelRenderPassInfo> InInfo, const TCHAR* InName) final override;
|
|
virtual void RHIEndParallelRenderPass() final override;
|
|
|
|
virtual void RHIClearShaderBindingTable(FRHIShaderBindingTable* SBT) final override;
|
|
virtual void RHICommitShaderBindingTable(FRHIShaderBindingTable* SBT, FRHIBuffer* InlineBindingDataBuffer) final override;
|
|
virtual void RHIBindAccelerationStructureMemory(FRHIRayTracingScene* Scene, FRHIBuffer* Buffer, uint32 BufferOffset) final override;
|
|
virtual void RHIBuildAccelerationStructures(TConstArrayView<FRayTracingGeometryBuildParams> Params, const FRHIBufferRange& ScratchBufferRange) final override;
|
|
virtual void RHIBuildAccelerationStructures(TConstArrayView<FRayTracingSceneBuildParams> Params) final override;
|
|
|
|
virtual void RHIRayTraceDispatch(FRHIRayTracingPipelineState* RayTracingPipelineState, FRHIRayTracingShader* RayGenShader,
|
|
FRHIShaderBindingTable* SBT, const FRayTracingShaderBindings& GlobalResourceBindings,
|
|
uint32 Width, uint32 Height) final override;
|
|
virtual void RHIRayTraceDispatchIndirect(FRHIRayTracingPipelineState* RayTracingPipelineState, FRHIRayTracingShader* RayGenShader,
|
|
FRHIShaderBindingTable* SBT, const FRayTracingShaderBindings& GlobalResourceBindings,
|
|
FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
|
|
virtual void RHISetBindingsOnShaderBindingTable(FRHIShaderBindingTable* SBT,
|
|
FRHIRayTracingPipelineState* Pipeline,
|
|
uint32 NumBindings, const FRayTracingLocalShaderBindings* Bindings,
|
|
ERayTracingBindingType BindingType) final override;
|
|
|
|
inline FVulkanPendingGfxState* GetPendingGfxState()
|
|
{
|
|
return PendingGfxState;
|
|
}
|
|
|
|
inline FVulkanPendingComputeState* GetPendingComputeState()
|
|
{
|
|
return PendingComputeState;
|
|
}
|
|
|
|
inline void NotifyDeletedRenderTarget(VkImage Image)
|
|
{
|
|
if (CurrentFramebuffer && CurrentFramebuffer->ContainsRenderTarget(Image))
|
|
{
|
|
CurrentFramebuffer = nullptr;
|
|
}
|
|
}
|
|
|
|
inline FVulkanRenderPass* GetCurrentRenderPass()
|
|
{
|
|
return CurrentRenderPass;
|
|
}
|
|
|
|
inline FVulkanFramebuffer* GetCurrentFramebuffer()
|
|
{
|
|
return CurrentFramebuffer;
|
|
}
|
|
|
|
#if (RHI_NEW_GPU_PROFILER == 0)
|
|
inline FVulkanGPUProfiler& GetGPUProfiler()
|
|
{
|
|
return GpuProfiler;
|
|
}
|
|
#endif
|
|
|
|
void BeginRecursiveCommand()
|
|
{
|
|
// Nothing to do
|
|
}
|
|
|
|
void ReleasePendingState();
|
|
|
|
FVulkanQueryPool* GetCurrentOcclusionQueryPool();
|
|
|
|
virtual FVulkanParallelRenderPassInfo* GetParallelRenderPassInfo()
|
|
{
|
|
return CurrentParallelRenderPassInfo;
|
|
}
|
|
|
|
void SetParallelRenderPassInfo(FVulkanParallelRenderPassInfo* ParallelRenderPassInfo)
|
|
{
|
|
CurrentParallelRenderPassInfo = ParallelRenderPassInfo;
|
|
}
|
|
|
|
bool AcquirePoolSetAndDescriptorsIfNeeded(const class FVulkanDescriptorSetsLayout& Layout, bool bNeedDescriptors, VkDescriptorSet* OutDescriptors);
|
|
|
|
protected:
|
|
FVulkanCommandListContext* Immediate;
|
|
const ERHIPipeline RHIPipeline;
|
|
const bool bSupportsBreadcrumbs;
|
|
|
|
void BeginOcclusionQueryBatch(uint32 NumQueriesInBatch);
|
|
|
|
TArray<FString> EventStack;
|
|
|
|
FVulkanRenderPass* CurrentRenderPass = nullptr;
|
|
FVulkanFramebuffer* CurrentFramebuffer = nullptr;
|
|
|
|
FVulkanParallelRenderPassInfo* CurrentParallelRenderPassInfo = nullptr;
|
|
|
|
FVulkanPendingGfxState* PendingGfxState = nullptr;
|
|
FVulkanPendingComputeState* PendingComputeState = nullptr;
|
|
|
|
// Match the D3D12 maximum of 16 constant buffers per shader stage.
|
|
enum { MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE = 16 };
|
|
|
|
// Track the currently bound uniform buffers.
|
|
FVulkanUniformBuffer* BoundUniformBuffers[SF_NumStandardFrequencies][MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE] = {};
|
|
|
|
// Bit array to track which uniform buffers have changed since the last draw call.
|
|
uint16 DirtyUniformBuffers[SF_NumStandardFrequencies] = {};
|
|
|
|
void InternalClearMRT(FVulkanCommandBuffer& CommandBuffer, bool bClearColor, int32 NumClearColors, const FLinearColor* ColorArray, bool bClearDepth, float Depth, bool bClearStencil, uint32 Stencil);
|
|
|
|
FVulkanDescriptorPoolSetContainer* CurrentDescriptorPoolSetContainer = nullptr;
|
|
TMap<uint32, class FVulkanTypedDescriptorPoolSet*> TypedDescriptorPoolSets;
|
|
void AcquirePoolSetContainer();
|
|
|
|
public:
|
|
bool IsSwapchainImage(FRHITexture* InTexture) const;
|
|
VkFormat GetSwapchainImageFormat() const;
|
|
FVulkanSwapChain* GetSwapChain() const;
|
|
|
|
FVulkanRenderPass* PrepareRenderPassForPSOCreation(const FGraphicsPipelineStateInitializer& Initializer);
|
|
FVulkanRenderPass* PrepareRenderPassForPSOCreation(const FVulkanRenderTargetLayout& Initializer);
|
|
|
|
private:
|
|
void RHIClearMRT(bool bClearColor, int32 NumClearColors, const FLinearColor* ColorArray, bool bClearDepth, float Depth, bool bClearStencil, uint32 Stencil);
|
|
|
|
friend class FVulkanDevice;
|
|
friend class FVulkanDynamicRHI;
|
|
|
|
#if (RHI_NEW_GPU_PROFILER == 0)
|
|
void RegisterGPUWork(uint32 NumPrimitives = 0, uint32 NumVertices = 0) { GpuProfiler.RegisterGPUWork(NumPrimitives, NumVertices); }
|
|
void RegisterGPUDispatch(FIntVector GroupCount) { GpuProfiler.RegisterGPUDispatch(GroupCount); }
|
|
|
|
FVulkanGPUProfiler GpuProfiler;
|
|
FVulkanGPUTiming* FrameTiming = nullptr;
|
|
#endif
|
|
|
|
template <typename TRHIShader>
|
|
void ApplyStaticUniformBuffers(TRHIShader* Shader);
|
|
|
|
TArray<FRHIUniformBuffer*> GlobalUniformBuffers;
|
|
};
|
|
|
|
class FVulkanCommandListContextImmediate : public FVulkanCommandListContext
|
|
{
|
|
public:
|
|
static inline FVulkanCommandListContextImmediate& Get(FRHICommandListBase& RHICmdList)
|
|
{
|
|
return static_cast<FVulkanCommandListContextImmediate&>(RHICmdList.GetContext().GetLowestLevelContext());
|
|
}
|
|
|
|
FVulkanCommandListContextImmediate(FVulkanDevice& InDevice);
|
|
};
|
|
|
|
class FVulkanUploadContext : public FVulkanContextCommon, public IRHIUploadContext
|
|
{
|
|
public:
|
|
|
|
static inline FVulkanUploadContext& Get(FRHICommandListBase& RHICmdList)
|
|
{
|
|
return static_cast<FVulkanUploadContext&>(RHICmdList.GetUploadContext());
|
|
}
|
|
|
|
FVulkanUploadContext(FVulkanDevice& Device, FVulkanQueue& InQueue);
|
|
virtual ~FVulkanUploadContext();
|
|
|
|
static TLockFreePointerListUnordered<FVulkanUploadContext, PLATFORM_CACHE_LINE_SIZE> Pool;
|
|
static void DestroyPool();
|
|
};
|
|
|
|
template<>
|
|
struct TVulkanResourceTraits<IRHIUploadContext>
|
|
{
|
|
typedef FVulkanUploadContext TConcreteType;
|
|
};
|
|
|
|
|
|
struct FVulkanContextArray : public TRHIPipelineArray<FVulkanCommandListContext*>
|
|
{
|
|
FVulkanContextArray(FRHIContextArray const& Contexts)
|
|
: TRHIPipelineArray(InPlace, nullptr)
|
|
{
|
|
for (ERHIPipeline Pipeline : MakeFlagsRange(ERHIPipeline::All))
|
|
{
|
|
IRHIComputeContext* Context = Contexts[Pipeline];
|
|
(*this)[Pipeline] = Context ? static_cast<FVulkanCommandListContext*>(&Context->GetLowestLevelContext()) : nullptr;
|
|
}
|
|
}
|
|
};
|