From 3da1c138cb23837ed65791803bf7a05f6d30b5b5 Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Sun, 4 Feb 2024 19:41:22 +0800 Subject: [PATCH] vault backup: 2024-02-04 19:41:22 --- .../plugins/various-complements/data.json | 64 +----- .../剖析虚幻渲染体系(10)- RHI.md | 188 +++++++++++++++++- 2 files changed, 195 insertions(+), 57 deletions(-) diff --git a/.obsidian/plugins/various-complements/data.json b/.obsidian/plugins/various-complements/data.json index 09512a3..64d0ff8 100644 --- a/.obsidian/plugins/various-complements/data.json +++ b/.obsidian/plugins/various-complements/data.json @@ -47,62 +47,6 @@ }, "showLogAboutPerformanceInConsole": false, "selectionHistoryTree": { - "Shader。以及rayOrigin、MVP、alpha_limit、stage变量;创建idTexture、colorTexture贴图变量以及过滤器;创建fbo以及depthBuffer。": { - "Shader。以及rayOrigin、MVP、alpha_limit、stage变量;创建idTexture、colorTexture贴图变量以及过滤器;创建fbo以及depthBuffer。": { - "currentFile": { - "count": 1, - "lastUpdated": 1704113005339 - } - } - }, - "Shader。以及rayOrigin、MVP、alpha_limit、stage变量;创建idTexture、colorTexture贴图变量以及过滤器;创建fbo对象以及depthBuffer之后调用makeFBO": { - "Shader。以及rayOrigin、MVP、alpha_limit、stage变量;创建idTexture、colorTexture贴图变量以及过滤器;创建fbo对象以及depthBuffer之后调用makeFBO": { - "currentFile": { - "count": 1, - "lastUpdated": 1704113520683 - } - } - }, - "rayOrigin、MVP、alpha_limit、stage变量;创建idTexture、colorTexture贴图变量以及过滤器;创建fbo对象以及depthBuffer之后调用makeFBO": { - "rayOrigin、MVP、alpha_limit、stage变量;创建idTexture、colorTexture贴图变量以及过滤器;创建fbo对象以及depthBuffer之后调用makeFBO": { - "currentFile": { - "count": 1, - "lastUpdated": 1704113533106 - } - } - }, - "sibr_gaussian": { - "sibr_gaussian": { - "currentFile": { - "count": 1, - "lastUpdated": 1704117184719 - } - } - }, - "c++17带来的代码变化": { - "c++17带来的代码变化": { - "internalLink": { - "count": 1, - "lastUpdated": 1704171666800 - } - } - }, - "闲时模式的相关资产": { - "闲时模式的相关资产": { - "currentFile": { - "count": 1, - "lastUpdated": 1704193924669 - } - } - }, - "唱歌(N套预先录制)": { - "唱歌(N套预先录制)": { - "currentFile": { - "count": 1, - "lastUpdated": 1704193979940 - } - } - }, "UE5中,这些名称有了一定的变化": { "UE5中,这些名称有了一定的变化": { "currentFile": { @@ -126,6 +70,14 @@ "lastUpdated": 1706177275907 } } + }, + "结构体。具有void": { + "结构体。具有void": { + "currentFile": { + "count": 1, + "lastUpdated": 1707040198653 + } + } } } } \ No newline at end of file diff --git a/03-UnrealEngine/Rendering/RenderingPipeline/向往渲染系列文章阅读笔记/剖析虚幻渲染体系(10)- RHI.md b/03-UnrealEngine/Rendering/RenderingPipeline/向往渲染系列文章阅读笔记/剖析虚幻渲染体系(10)- RHI.md index 6b36d8a..bc5bd99 100644 --- a/03-UnrealEngine/Rendering/RenderingPipeline/向往渲染系列文章阅读笔记/剖析虚幻渲染体系(10)- RHI.md +++ b/03-UnrealEngine/Rendering/RenderingPipeline/向往渲染系列文章阅读笔记/剖析虚幻渲染体系(10)- RHI.md @@ -13,4 +13,190 @@ rating: ⭐ - 比如输入的顶点数据、顶点Index数据、贴图数据等。 - FRHIResource:抽象了GPU侧的资源,也是众多RHI资源类型的父类。可以认为是承载**显卡API相关资源的载体**。 - 比如TextureSampler、TextureObject等。 -- FRHICommand: \ No newline at end of file +- FRHICommand:其父类为**FRHICommandBase**结构体。其含有**FRHICommandBase* Next**用来保存下一个Command的指针,所以存储他的结构为**链表**。 + - 含有接口:void void ExecuteAndDestruct(FRHICommandListBase& CmdList, FRHICommandListDebugContext& DebugContext)。执行完就销毁。 + - UE使用**FRHICOMMAND_MACRO**宏来快速定义各种RHICommand。主要功能包含: + - 数据和资源的设置、更新、清理、转换、拷贝、回读。 + - 图元绘制。 + - Pass、SubPass、场景、ViewPort等的开始和结束事件。 + - 栅栏、等待、广播接口。 + - 光线追踪。 + - Slate、调试相关的命令。 +- FRHICommandList:是**RHI的指令队列**,用来管理、执行一组FRHICommand的对象。 + - 其子类有**FRHICommandListImmediate**(立即执行队列)、FRHIComputeCommandList_RecursiveHazardous与TRHIComputeCommandList_RecursiveHazardous(命令列表的递归使用) +- IRHICommandContext:是RHI的命令上下文接口类,定义了一组图形API相关的操作。在可以并行处理命令列表的平台上,它是一个单独的对象类。 + - 主要的接口函数有: + - 派发ComputeShader + - 渲染查询(可见性?) + - 相关开始/结束函数。 + - 设置数据(Viewport、GraphicsPipelineState等) + - 设置ShadserParameter + - 绘制图元 + - 纹理拷贝/更新 + - Raytracing + - IRHICommandContext的接口和FRHICommandList的接口高度相似且重叠。IRHICommandContext还有许多子类: + - IRHICommandContextPSOFallback:不支持真正的图形管道的RHI命令上下文。 + - FNullDynamicRHI:空实现的动态绑定RHI。 + - FOpenGLDynamicRHI:OpenGL的动态RHI。 + - FD3D11DynamicRHI:D3D11的动态RHI。 + - FMetalRHICommandContext:Metal平台的命令上下文。 + - FD3D12CommandContextBase:D3D12的命令上下文。 + - FVulkanCommandListContext:Vulkan平台的命令队列上下文。 + - FEmptyDynamicRHI:动态绑定的RHI实现的接口。 + - FValidationContext:校验上下文。 +- IRHICommandContextContainer:IRHICommandContextContainer就是包含了IRHICommandContext对象的类型。相当于存储了一个或一组命令上下文的容器,以支持并行化地提交命令队列,只在D3D12、Metal、Vulkan等现代图形API中有实现。 + - D3D12存储了FD3D12Adapter* Adapter、FD3D12CommandContext* CmdContext、 FD3D12CommandContextRedirector* CmdContextRedirector。 +- FDynamicRHI:FDynamicRHI是由动态绑定的RHI实现的接口,它定义的接口和CommandList、CommandContext比较相似。 + - 代码详见[[#FDynamicRHI]] +- FRHICommandListExecutor + +## FDynamicRHI +```c++ +class RHI_API FDynamicRHI +{ +public: + virtual ~FDynamicRHI() {} + + virtual void Init() = 0; + virtual void PostInit() {} + virtual void Shutdown() = 0; + + void InitPixelFormatInfo(const TArray& PixelFormatBlockBytesIn); + + // ---- RHI接口 ---- + + // 下列接口要求FlushType: Thread safe + virtual FSamplerStateRHIRef RHICreateSamplerState(const FSamplerStateInitializerRHI& Initializer) = 0; + virtual FRasterizerStateRHIRef RHICreateRasterizerState(const FRasterizerStateInitializerRHI& Initializer) = 0; + virtual FDepthStencilStateRHIRef RHICreateDepthStencilState(const FDepthStencilStateInitializerRHI& Initializer) = 0; + virtual FBlendStateRHIRef RHICreateBlendState(const FBlendStateInitializerRHI& Initializer) = 0; + + // 下列接口要求FlushType: Wait RHI Thread + virtual FVertexDeclarationRHIRef RHICreateVertexDeclaration(const FVertexDeclarationElementList& Elements) = 0; + virtual FPixelShaderRHIRef RHICreatePixelShader(TArrayView Code, const FSHAHash& Hash) = 0; + virtual FVertexShaderRHIRef RHICreateVertexShader(TArrayView Code, const FSHAHash& Hash) = 0; + virtual FHullShaderRHIRef RHICreateHullShader(TArrayView Code, const FSHAHash& Hash) = 0; + virtual FDomainShaderRHIRef RHICreateDomainShader(TArrayView Code, const FSHAHash& Hash) = 0; + virtual FGeometryShaderRHIRef RHICreateGeometryShader(TArrayView Code, const FSHAHash& Hash) = 0; + virtual FComputeShaderRHIRef RHICreateComputeShader(TArrayView Code, const FSHAHash& Hash) = 0; + + // FlushType: Must be Thread-Safe. + virtual FRenderQueryPoolRHIRef RHICreateRenderQueryPool(ERenderQueryType QueryType, uint32 NumQueries = UINT32_MAX); + inline FComputeFenceRHIRef RHICreateComputeFence(const FName& Name); + + virtual FGPUFenceRHIRef RHICreateGPUFence(const FName &Name); + virtual void RHICreateTransition(FRHITransition* Transition, ERHIPipeline SrcPipelines, ERHIPipeline DstPipelines, ERHICreateTransitionFlags CreateFlags, TArrayView Infos); + virtual void RHIReleaseTransition(FRHITransition* Transition); + + // FlushType: Thread safe. + virtual FStagingBufferRHIRef RHICreateStagingBuffer(); + virtual void* RHILockStagingBuffer(FRHIStagingBuffer* StagingBuffer, FRHIGPUFence* Fence, uint32 Offset, uint32 SizeRHI); + virtual void RHIUnlockStagingBuffer(FRHIStagingBuffer* StagingBuffer); + + // FlushType: Thread safe, but varies depending on the RHI + virtual FBoundShaderStateRHIRef RHICreateBoundShaderState(FRHIVertexDeclaration* VertexDeclaration, FRHIVertexShader* VertexShader, FRHIHullShader* HullShader, FRHIDomainShader* DomainShader, FRHIPixelShader* PixelShader, FRHIGeometryShader* GeometryShader) = 0; + // FlushType: Thread safe + virtual FGraphicsPipelineStateRHIRef RHICreateGraphicsPipelineState(const FGraphicsPipelineStateInitializer& Initializer); + + // FlushType: Thread safe, but varies depending on the RHI + virtual FUniformBufferRHIRef RHICreateUniformBuffer(const void* Contents, const FRHIUniformBufferLayout& Layout, EUniformBufferUsage Usage, EUniformBufferValidation Validation) = 0; + virtual void RHIUpdateUniformBuffer(FRHIUniformBuffer* UniformBufferRHI, const void* Contents) = 0; + + // FlushType: Wait RHI Thread + virtual FIndexBufferRHIRef RHICreateIndexBuffer(uint32 Stride, uint32 Size, uint32 InUsage, ERHIAccess InResourceState, FRHIResourceCreateInfo& CreateInfo) = 0; + virtual void* RHILockIndexBuffer(FRHICommandListImmediate& RHICmdList, FRHIIndexBuffer* IndexBuffer, uint32 Offset, uint32 Size, EResourceLockMode LockMode); + virtual void RHIUnlockIndexBuffer(FRHICommandListImmediate& RHICmdList, FRHIIndexBuffer* IndexBuffer); + virtual void RHITransferIndexBufferUnderlyingResource(FRHIIndexBuffer* DestIndexBuffer, FRHIIndexBuffer* SrcIndexBuffer); + + // FlushType: Wait RHI Thread + virtual FVertexBufferRHIRef RHICreateVertexBuffer(uint32 Size, uint32 InUsage, ERHIAccess InResourceState, FRHIResourceCreateInfo& CreateInfo) = 0; + // FlushType: Flush RHI Thread + virtual void* RHILockVertexBuffer(FRHICommandListImmediate& RHICmdList, FRHIVertexBuffer* VertexBuffer, uint32 Offset, uint32 SizeRHI, EResourceLockMode LockMode); + virtual void RHIUnlockVertexBuffer(FRHICommandListImmediate& RHICmdList, FRHIVertexBuffer* VertexBuffer); + // FlushType: Flush Immediate (seems dangerous) + virtual void RHICopyVertexBuffer(FRHIVertexBuffer* SourceBuffer, FRHIVertexBuffer* DestBuffer) = 0; + virtual void RHITransferVertexBufferUnderlyingResource(FRHIVertexBuffer* DestVertexBuffer, FRHIVertexBuffer* SrcVertexBuffer); + + // FlushType: Wait RHI Thread + virtual FStructuredBufferRHIRef RHICreateStructuredBuffer(uint32 Stride, uint32 Size, uint32 InUsage, ERHIAccess InResourceState, FRHIResourceCreateInfo& CreateInfo) = 0; + // FlushType: Flush RHI Thread + virtual void* RHILockStructuredBuffer(FRHICommandListImmediate& RHICmdList, FRHIStructuredBuffer* StructuredBuffer, uint32 Offset, uint32 SizeRHI, EResourceLockMode LockMode); + virtual void RHIUnlockStructuredBuffer(FRHICommandListImmediate& RHICmdList, FRHIStructuredBuffer* StructuredBuffer); + + // FlushType: Wait RHI Thread + virtual FUnorderedAccessViewRHIRef RHICreateUnorderedAccessView(FRHIStructuredBuffer* StructuredBuffer, bool bUseUAVCounter, bool bAppendBuffer) = 0; + // FlushType: Wait RHI Thread + virtual FUnorderedAccessViewRHIRef RHICreateUnorderedAccessView(FRHITexture* Texture, uint32 MipLevel) = 0; + // FlushType: Wait RHI Thread + virtual FUnorderedAccessViewRHIRef RHICreateUnorderedAccessView(FRHITexture* Texture, uint32 MipLevel, uint8 Format); + + (......) + + // RHI帧更新,须从主线程调用,FlushType: Thread safe + virtual void RHITick(float DeltaTime) = 0; + // 阻塞CPU直到GPU执行完成变成空闲. FlushType: Flush Immediate (seems wrong) + virtual void RHIBlockUntilGPUIdle() = 0; + // 开始当前帧,并确保GPU正在积极地工作 FlushType: Flush Immediate (copied from RHIBlockUntilGPUIdle) + virtual void RHISubmitCommandsAndFlushGPU() {}; + + // 通知RHI准备暂停它. + virtual void RHIBeginSuspendRendering() {}; + // 暂停RHI渲染并将控制权交给系统的操作, FlushType: Thread safe + virtual void RHISuspendRendering() {}; + // 继续RHI渲染, FlushType: Thread safe + virtual void RHIResumeRendering() {}; + // FlushType: Flush Immediate + virtual bool RHIIsRenderingSuspended() { return false; }; + + // FlushType: called from render thread when RHI thread is flushed + // 仅在FRHIResource::FlushPendingDeletes内的延迟删除之前每帧调用. + virtual void RHIPerFrameRHIFlushComplete(); + + // 执行命令队列, FlushType: Wait RHI Thread + virtual void RHIExecuteCommandList(FRHICommandList* CmdList) = 0; + + // FlushType: Flush RHI Thread + virtual void* RHIGetNativeDevice() = 0; + // FlushType: Flush RHI Thread + virtual void* RHIGetNativeInstance() = 0; + + // 获取命令上下文. FlushType: Thread safe + virtual IRHICommandContext* RHIGetDefaultContext() = 0; + // 获取计算上下文. FlushType: Thread safe + virtual IRHIComputeContext* RHIGetDefaultAsyncComputeContext(); + + // FlushType: Thread safe + virtual class IRHICommandContextContainer* RHIGetCommandContextContainer(int32 Index, int32 Num) = 0; + + // 直接由渲染线程调用的接口, 以优化RHI调用. + virtual FVertexBufferRHIRef CreateAndLockVertexBuffer_RenderThread(class FRHICommandListImmediate& RHICmdList, uint32 Size, uint32 InUsage, ERHIAccess InResourceState, FRHIResourceCreateInfo& CreateInfo, void*& OutDataBuffer); + virtual FIndexBufferRHIRef CreateAndLockIndexBuffer_RenderThread(class FRHICommandListImmediate& RHICmdList, uint32 Stride, uint32 Size, uint32 InUsage, ERHIAccess InResourceState, FRHIResourceCreateInfo& CreateInfo, void*& OutDataBuffer); + + (......) + + // Buffer Lock/Unlock + virtual void* LockVertexBuffer_BottomOfPipe(class FRHICommandListImmediate& RHICmdList, ...); + virtual void* LockIndexBuffer_BottomOfPipe(class FRHICommandListImmediate& RHICmdList, ...); + + (......) +}; +``` + +以上只显示了部分接口,其中部分接口要求从渲染线程调用,部分须从游戏线程调用。大多数接口在被调用前需刷新指定类型的命令,比如: +```c++ +class RHI_API FDynamicRHI +{ + // FlushType: Wait RHI Thread + void RHIExecuteCommandList(FRHICommandList* CmdList); + + // FlushType: Flush Immediate + void RHIBlockUntilGPUIdle(); + + // FlushType: Thread safe + void RHITick(float DeltaTime); +}; +``` +可以在**FRHICommandListImmediate**的**ExecuteCommandList()**、**BlockUntilGPUIdle()**、**Tick()** 看到调用。 + +>需要注意的是,传统图形API(D3D11、OpenGL)除了继承FDynamicRHI,还需要继承**IRHICommandContextPSOFallback**,因为需要借助后者的接口处理PSO的数据和行为,以保证传统和现代API对PSO的一致处理行为。也正因为此,现代图形API(D3D12、Vulkan、Metal)不需要继承**IRHICommandContext**的任何继承体系的类型,单单直接继承**FDynamicRHI**就可以处理RHI层的所有数据和操作。 +既然现代图形API(D3D12、Vulkan、Metal)的**DynamicRHI**没有继承**IRHICommandContext**的任何继承体系的类型,那么它们是如何实现FDynamicRHI::RHIGetDefaultContext的接口?下面以FD3D12DynamicRHI为例: \ No newline at end of file