基本概念

RHI(Render Hardware Interface)的职责是对OpenGL、DirectX3D、Vulkan这些图形接口API进行封装,来统一上层的调用。D3D11RHI就是 RHI 的 D3D11 的实现,模块中的很多类继承了 RHI 模块中的很多类,所以很显然D3D11RHI一定是依赖于RHI的。而RenderCore听名字就能知道,它包含了UE4渲染系统的很多核心内容,其中直接调用了RHI的接口,所以RenderCore也是依赖于RHI的。因此,他们三个的 基本 依赖关系如下:

实现
调用
D3D11RHI
RHI
RenderCore

当然,他们都依赖于Core模块。

我想具体观察一下这三个模块的依赖关系,因为他们各自的.Build.cs文件指出,他们还依赖于其他的模块。我想观察是什么内容导致他们还需要依赖于其他模块。如果依赖关系的分析正确的话,我想在我自己的空白工程中(在《【UE4源代码观察】尝试生成启动画面》完成时Core模块已经加入),能将这三个模块加入并保证正常编译。(工程代码见GIT仓库)

RHI模块

1.分析.Build.cs文件

RHI.Build.cs的内容如下:

public class RHI : ModuleRules
{public RHI(ReadOnlyTargetRules Target) : base(Target){PrivateDependencyModuleNames.Add("Core");PrivateDependencyModuleNames.Add("ApplicationCore");PrivateDependencyModuleNames.Add("TraceLog");if (Target.bCompileAgainstEngine){DynamicallyLoadedModuleNames.Add("NullDrv");if (Target.Type != TargetRules.TargetType.Server)   // Dedicated servers should skip loading everything but NullDrv{// UEBuildAndroid.cs adds VulkanRHI for Android builds if it is enabledif ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64)){DynamicallyLoadedModuleNames.Add("D3D11RHI");//#todo-rco: D3D12 requires different SDK headers not compatible with WinXPDynamicallyLoadedModuleNames.Add("D3D12RHI");}if ((Target.Platform == UnrealTargetPlatform.HoloLens)){DynamicallyLoadedModuleNames.Add("D3D11RHI");}if ((Target.Platform == UnrealTargetPlatform.Win64) ||(Target.Platform == UnrealTargetPlatform.Win32) ||(Target.IsInPlatformGroup(UnrealPlatformGroup.Unix) && (Target.Architecture.StartsWith("x86_64") || Target.Architecture.StartsWith("aarch64")))) // temporary, not all archs can support Vulkan atm{DynamicallyLoadedModuleNames.Add("VulkanRHI");}if ((Target.Platform == UnrealTargetPlatform.Win32) ||(Target.Platform == UnrealTargetPlatform.Win64) ||(Target.IsInPlatformGroup(UnrealPlatformGroup.Linux) && Target.Type != TargetRules.TargetType.Server))  // @todo should servers on all platforms skip this?{DynamicallyLoadedModuleNames.Add("OpenGLDrv");}}}if (Target.Configuration != UnrealTargetConfiguration.Shipping){PrivateIncludePathModuleNames.AddRange(new string[] { "TaskGraph" });}PrivateIncludePaths.Add("Runtime/RHI/Private");}
}

首先,它指出依赖了三个模块

PrivateDependencyModuleNames.Add("Core");
PrivateDependencyModuleNames.Add("ApplicationCore");
PrivateDependencyModuleNames.Add("TraceLog");

其中Core和TraceLog已经加入,而ApplicationCore在工程中并不完整,之后可以观察是否缺损的内容导致无法编译。

随后,他根据不同的平台来动态读取一些模块,例如在Win32Win64平台,读取了D3D11RHID3D12RHI模块:

if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
{DynamicallyLoadedModuleNames.Add("D3D11RHI");//#todo-rco: D3D12 requires different SDK headers not compatible with WinXPDynamicallyLoadedModuleNames.Add("D3D12RHI");
}

不过,动态读取模块不会影响编译。所以他提及的模块不用全部考虑,我只需要保证之后D3D11模块可用就行了。
最后,在不是Shipping(发行版本)时需要include TaskGraph中的文件:

if (Target.Configuration != UnrealTargetConfiguration.Shipping)
{PrivateIncludePathModuleNames.AddRange(new string[] { "TaskGraph" });
}

TaskGraph看名字不像是RHI需要依赖的一个核心功能,而且只是include并不是依赖,所以我决定先将它注释掉,希望之后要做的补救不会太多。

2.尝试编译

先将RHI这个模块的文件夹拷贝到空白工程中,然后在启动模块Launch.Build.cs中指明要依赖于这个模块,这样它就会触发编译:

PrivateDependencyModuleNames.AddRange(new string[] {"Core","ApplicationCore","RHI",
});

随后,得到了错误:

1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/RHI/Private/GPUProfiler.cpp(11): fatal error C1083: 无法打开包括文件: “VisualizerEvents.h”: No such file or directory

VisualizerEvents.h这个文件是TaskGraph模块中的文件,这是我先前注释的行为所致。看名字应该是和GPU性能观察相关的内容。不过看了VisualizerEvents.h以后,发现它其实只#include "CoreMinimal.h",因此我可以单独将这个文件拷贝过来,然后include它:

#include "../../../Developer/TaskGraph/Public/VisualizerEvents.h"

之后也对STaskGraph.h这个文件做相同的处理
随后,编译成功。

RenderCore模块

1.分析.Build.cs文件

public class RenderCore : ModuleRules
{public RenderCore(ReadOnlyTargetRules Target) : base(Target){PublicDependencyModuleNames.AddRange(new string[] { "RHI" });if (Target.bBuildEditor == true){PrivateDependencyModuleNames.Add("TargetPlatform");}else{PrivateIncludePathModuleNames.AddRange(new string[] { "TargetPlatform" });}PrivateDependencyModuleNames.AddRange(new string[] { "Core", "Projects", "RHI", "ApplicationCore" });PrivateIncludePathModuleNames.AddRange(new string[] { "DerivedDataCache" });// Added in Dev-VT, still needed?PrivateIncludePathModuleNames.AddRange(new string[] { "TargetPlatform" });}
}

可以看到:
对于TargetPlatform这个模组,视(Target.bBuildEditor == true)的情况:
如果是的话则依赖这个模块:

PrivateDependencyModuleNames.Add("TargetPlatform");

否则的话只是include它的头文件:

PrivateIncludePathModuleNames.AddRange(new string[] { "TargetPlatform" });

而下面四个模块是它依赖的:

PrivateDependencyModuleNames.AddRange(new string[] { "Core", "Projects", "RHI", "ApplicationCore" });

其中可以放心CoreRHI,但是Projects当前还没有加入,而ApplicationCore也并不完整,这在之后需要注意。
最后,他还需要include DerivedDataCache中的头文件:

PrivateIncludePathModuleNames.AddRange(new string[] { "DerivedDataCache" });

2.尝试编译

TargetPlatform DerivedDataCache Projects临时注释掉,观察随后的错误来了解RenderCore为何依赖它们,随后视情况来处理问题。

2.1 与 ApplicationCore模块 的联系
1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp(11): fatal error C1083: 无法打开包括文件: “HAL/PlatformApplicationMisc.h”: No such file or directory

缺失的文件是ApplicationCore模块中的,但是从Build.cs来看,ApplicationCore模块牵连了不少内容,因此将它拷贝过来似乎要耗费很多精力。
RenderingThread.cpp中只是用到了PlatformApplicationMisc的一个功能——在CheckRenderingThreadHealth()函数中调用了:

FPlatformApplicationMisc::PumpMessages(false);

看起来和消息显示有关,这不是个核心的内容,因此我选择暂时将它注释掉。

2.2 与 TargetPlatform模块 的联系
1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/RenderCore/Private/Shader.cpp(13): fatal error C1083: 无法打开包括文件: “Interfaces/ITargetPlatform.h”: No such file or directory

查看后,发现Shader.cpp中include了TargetPlatform的一些头文件:

#include "Interfaces/ITargetPlatform.h"
#include "Interfaces/ITargetPlatformManagerModule.h"
#include "Interfaces/IShaderFormat.h"

而在ShaderMapAppendKeyString函数中有TargetPlatform模块重要的应用:

ITargetPlatform* TargetPlatform = GetTargetPlatformManager()->FindTargetPlatformWithSupport(TEXT("ShaderFormat"), LegacyShaderPlatformToShaderFormat(Platform));
{bool bForwardShading = false;if (TargetPlatform){// if there is a specific target platform that matches our shader platform, use that to drive forward shadingbForwardShading = TargetPlatform->UsesForwardShading();}else{// shader platform doesn't match a specific target platform, use cvar setting for forward shadingstatic IConsoleVariable* CVarForwardShadingLocal = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ForwardShading"));bForwardShading = CVarForwardShadingLocal ? (CVarForwardShadingLocal->GetInt() != 0) : false;}if (bForwardShading){KeyString += TEXT("_FS");}
}{if (UseVirtualTexturing(GetMaxSupportedFeatureLevel(Platform), TargetPlatform)){KeyString += TEXT("_VT");}
}
//。。。

看起来它根据当前的平台来对KeyString做处理,比如根据是否支持VirtualTexturing来向KeyString中加入后缀"_VT":

if (UseVirtualTexturing(GetMaxSupportedFeatureLevel(Platform), TargetPlatform))
{KeyString += TEXT("_VT");
}

这个函数在引擎初始化阶段被调用过:

看起来它和 Shader Map有很大的关系,是个核心的功能。但是TargetPlatform模块牵扯太多内容,我应该无法在短时间内搞懂了。所以这里我选择将用到的地方注释掉。但我明白代价是这么做暂时无法使用shader相关功能

2.3 与 Projects模块 的联系
1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/RenderCore/Private/ShaderCodeLibrary.cpp(19): fatal error C1083: 无法打开包括文件: “Interfaces/IPluginManager.h”: No such file or directory

IPluginManager.hProjects模块的文件。看起来在ShaderCodeLibrary.cpp中需要处理一些和插件相关的内容,具体我没有研究。
我想直接把Projects模块拷贝过来,因为我觉得它是一个比较基础的模块,而且依赖关系比较简单:
Projects只依赖于CoreJson。而后者只依赖于Core

随后,编译成功

D3D11RHI模块

1.分析.Build.cs文件

public class D3D11RHI : ModuleRules
{public D3D11RHI(ReadOnlyTargetRules Target) : base(Target){if (Target.Platform == UnrealTargetPlatform.HoloLens){PrivateIncludePaths.Add("Runtime/Windows/D3D11RHI/Private/HoloLens");}PrivateIncludePaths.Add("Runtime/Windows/D3D11RHI/Private");PrivateIncludePaths.Add("../Shaders/Shared");PrivateDependencyModuleNames.AddRange(new string[] {"Core","Engine","RHI","RenderCore"});AddEngineThirdPartyPrivateStaticDependencies(Target, "DX11");if (Target.Platform != UnrealTargetPlatform.HoloLens){ AddEngineThirdPartyPrivateStaticDependencies(Target, "NVAPI");AddEngineThirdPartyPrivateStaticDependencies(Target, "AMD_AGS");AddEngineThirdPartyPrivateStaticDependencies(Target, "NVAftermath");AddEngineThirdPartyPrivateStaticDependencies(Target, "IntelMetricsDiscovery");}if (Target.Configuration != UnrealTargetConfiguration.Shipping){PrivateIncludePathModuleNames.AddRange(new string[] { "TaskGraph" });}}
}

首先,它依赖于Core Engine RHI RenderCore模块,除了Engine模块外我都已经加入到项目中了,但Engine这个模块实在是有非常多的内容(基本上是目前我看到的最多内容的模块了),其实从名字也能看出它是整个引擎的躯体,依赖于很多更底层的模块。按照现在空白工程中的内容,是不可能让Engine模块正常运行的。然而,D3D11RHI是个较为底层的模块,理论上讲他不应该依赖Engine这个模块,现在既然依赖,那也应该是在不太核心的地方上有所牵连,所以我选择暂时注释掉Engine模块,之后再想办法弥补。
另外,他也 include TaskGraph,暂时注释掉,后续处理方法同上。

2.尝试编译

2.1 拷贝 Shaders/Shared 目录
1>D:\0_WorkSpace\UEYaksueTest\Engine\Source\Runtime\Windows\D3D11RHI\D3D11RHI.Build.cs : warning : Referenced directory 'D:\0_WorkSpace\UEYaksueTest\Engine\Shaders\Shared' does not exist.

看来是PrivateIncludePaths.Add("../Shaders/Shared");语句没能成功。
\Engine\Shaders\Shared拷贝过来,消除错误。

2.2 拷贝静态库
1>UnrealBuildTool : error : Could not find definition for module 'DX11', (referenced via Target -> Launch.Build.cs -> D3D11RHI.Build.cs)

它所需要的一些第三方的静态库并没有拷贝过来:

AddEngineThirdPartyPrivateStaticDependencies(Target, "DX11");
if (Target.Platform != UnrealTargetPlatform.HoloLens)
{ AddEngineThirdPartyPrivateStaticDependencies(Target, "NVAPI");AddEngineThirdPartyPrivateStaticDependencies(Target, "AMD_AGS");AddEngineThirdPartyPrivateStaticDependencies(Target, "NVAftermath");AddEngineThirdPartyPrivateStaticDependencies(Target, "IntelMetricsDiscovery");
}

\Engine\Source\ThirdParty\Windows\DirectX\Engine\Source\ThirdParty\Windows\DX11拷贝过来,来完成对DX11静态库的依赖。
\Engine\Source\ThirdParty\NVIDIA拷贝过来,来完成对NVAPINVAftermath静态库的依赖。
\Engine\Source\ThirdParty\AMD\AMD_AGS拷贝过来,来完成对AMD_AGS静态库的依赖。
\Engine\Source\ThirdParty\IntelMetricsDiscovery拷贝过来,来完成对IntelMetricsDiscovery静态库的依赖。

2.3
1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/Windows/D3D11RHI/Private/Windows/WindowsD3D11Device.cpp(20): fatal error C1083: 无法打开包括文件: “Runtime/HeadMountedDisplay/Public/IHeadMountedDisplayModule.h”: No such file or directory

缺失的文件是HeadMountedDisplay模块的,奇怪的是在D3D11RHI.Build.cs中没有提及这个模块。这里我简单将这个文件单独拷贝,通过编译。

2.4 Engine模块相关
2.4.1 D3D11Commands.cpp相关的Engine模块内容

在编译D3D11Commands.cpp时有如下eroor:

D3D11RHIPrivate.h(16): fatal error C1083: 无法打开包括文件: “EngineGlobals.h”: No such file or directory
D3D11RHIPrivate.h(17): fatal error C1083: 无法打开包括文件: “Engine/Engine.h”: No such file or directory
D3D11Commands.cpp(15): fatal error C1083: 无法打开包括文件: “SceneUtils.h”: No such file or directory

缺失的文件都是Engine中的,只能将他们注释掉,然后报错如下:

D3D11Commands.cpp(1788): error C2065: “GGPUFrameTime”: 未声明的标识符

发现在下面函数中有这个变量的使用:

/*** Returns the total GPU time taken to render the last frame. Same metric as FPlatformTime::Cycles().*/
uint32 FD3D11DynamicRHI::RHIGetGPUFrameCycles()
{#if INTEL_METRICSDISCOVERYif (GDX11IntelMetricsDiscoveryEnabled){return IntelMetricsDicoveryGetGPUTime();}
#endif // INTEL_METRICSDISCOVERYreturn GGPUFrameTime;
}

但需要注意的是,INTEL_METRICSDISCOVERY这个宏应该是已有的,因为在之前添加的第三方库——IntelMetricsDiscovery模块的IntelMetricsDiscovery.Build.cs文件中有:

if ( (Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32) )
{PublicDefinitions.Add("INTEL_METRICSDISCOVERY=1");
}

所以程序不会走到最后的return,因此我将这里改为:

uint32 FD3D11DynamicRHI::RHIGetGPUFrameCycles()
{return IntelMetricsDicoveryGetGPUTime();
}

效果应该没有改变。
下一个错误:

D3D11Commands.cpp(1880): error C3867: “FD3D11DynamicRHI::RHITransitionResources”: 非标准语法;请使用 "&" 来创建指向成员的指针
D3D11Commands.cpp(1880): error C3861: “SCOPED_RHI_CONDITIONAL_DRAW_EVENTF”: 找不到标识符
D3D11Commands.cpp(1886): error C2065: “RHITransitionResourcesLoop”: 未声明的标识符
D3D11Commands.cpp(1886): error C3861: “SCOPED_RHI_CONDITIONAL_DRAW_EVENTF”: 找不到标识符

这是SCOPED_RHI_CONDITIONAL_DRAW_EVENTF宏没有找到所致。然而这个宏实际是在\Engine\Source\Runtime\RenderCore\Public\ProfilingDebugging\RealtimeGPUProfiler.h中定义的,并不在Engine模块中,所以我想这里实际是我注释掉的include头文件间接引用了它所致。因此我直接加上了include:

#include"ProfilingDebugging/RealtimeGPUProfiler.h"
2.4.2 D3D11RenderTarget.cpp 相关的Engine模块内容
D3D11RenderTarget.cpp(8): fatal error C1083: 无法打开包括文件: “BatchedElements.h”: No such file or directory
D3D11RenderTarget.cpp(9): fatal error C1083: 无法打开包括文件: “ScreenRendering.h”: No such file or directory

直接注释掉之后,发现并没有报错?
这比较奇怪,难道是历史上曾经include过,后来修改后已经不用include了,但是忘记删除了?

2.4.3 D3D11RHI.cpp 相关的Engine模块内容
D3D11RHI.cpp(10): fatal error C1083: 无法打开包括文件: “Engine/GameViewportClient.h”: No such file or directory

注释掉之后的错误:

D3D11RHI.cpp(439): error C2065: “GGPUFrameTime”: 未声明的标识符
D3D11RHI.cpp(443): error C2065: “GGPUFrameTime”: 未声明的标识符
D3D11RHI.cpp(466): error C2065: “GEngine”: 未声明的标识符
D3D11RHI.cpp(468): error C2065: “GEngine”: 未声明的标识符
D3D11RHI.cpp(506): error C2065: “GEngine”: 未声明的标识符
D3D11RHI.cpp(508): error C2065: “GEngine”: 未声明的标识符

我看到他们都在FD3DGPUProfiler::EndFrame()这个函数中使用。从名字就可以看出这个函数是GPU性能剖析相关的,所以暂时我选择注释掉这个函数所有的内容。

2.4.4 D3D11Util.cpp 相关的Engine模块内容
D3D11Util.cpp(8): fatal error C1083: 无法打开包括文件: “EngineModule.h”: No such file or directory

注释掉之后也没有错误

2.4.4 D3D11Viewport.cpp 相关的Engine模块内容
D3D11Viewport.cpp(9): fatal error C1083: 无法打开包括文件: “Engine/RendererSettings.h”: No such file or directory

注释掉之后的错误:

D3D11Viewport.cpp(598): error C2653: “EDefaultBackBufferPixelFormat”: 不是类或命名空间名称
D3D11Viewport.cpp(598): error C3861: “FromInt”: 找不到标识符
D3D11Viewport.cpp(598): error C3861: “Convert2PixelFormat”: 找不到标识符
D3D11Viewport.cpp(620): error C2653: “EDefaultBackBufferPixelFormat”: 不是类或命名空间名称
D3D11Viewport.cpp(620): error C3861: “FromInt”: 找不到标识符
D3D11Viewport.cpp(620): error C3861: “Convert2PixelFormat”: 找不到标识符

注意到它应用的场合:

FViewportRHIRef FD3D11DynamicRHI::RHICreateViewport(void* WindowHandle,uint32 SizeX,uint32 SizeY,bool bIsFullscreen,EPixelFormat PreferredPixelFormat)
{check( IsInGameThread() );// Use a default pixel format if none was specified  if (PreferredPixelFormat == EPixelFormat::PF_Unknown){static const auto CVarDefaultBackBufferPixelFormat = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.DefaultBackBufferPixelFormat"));PreferredPixelFormat = EDefaultBackBufferPixelFormat::Convert2PixelFormat(EDefaultBackBufferPixelFormat::FromInt(CVarDefaultBackBufferPixelFormat->GetValueOnGameThread()));}return new FD3D11Viewport(this,(HWND)WindowHandle,SizeX,SizeY,bIsFullscreen,PreferredPixelFormat);
}

这是个很核心的函数,会在引擎初始化时调用:

因此EDefaultBackBufferPixelFormat的声明与实现都是不可或缺的。
我决定建立一个空的Engine模块,将包含EDefaultBackBufferPixelFormat的最小内容拷贝过来,下面是我的步骤:
一,建立Engine.Build.cs,不过它除了Core模块以外都不依赖:

public class Engine : ModuleRules
{public Engine(ReadOnlyTargetRules Target) : base(Target){PrivateDependencyModuleNames.AddRange(new string[] {"Core",})bRequiresImplementModule = false;}
}

二,拷贝RendererSettings.h。不过删掉了EDefaultBackBufferPixelFormat之外的所有内容。而且,因为反射机制还没有建立,所以UENUM()UMETA这类的宏都不能用,只能注释掉。
最终文件的内容如下:

#pragma once#include "../../../Core/Public/CoreMinimal.h"
#include"../../../Core/Public/PixelFormat.h"/** used by GetDefaultBackBufferPixelFormat*/
//UENUM()
namespace EDefaultBackBufferPixelFormat
{enum Type{DBBPF_B8G8R8A8 = 0              ,//UMETA(DisplayName = "8bit RGBA"),DBBPF_A16B16G16R16_DEPRECATED    ,//UMETA(DisplayName = "DEPRECATED - 16bit RGBA", Hidden),DBBPF_FloatRGB_DEPRECATED      ,//UMETA(DisplayName = "DEPRECATED - Float RGB", Hidden),DBBPF_FloatRGBA                 ,//UMETA(DisplayName = "Float RGBA"),DBBPF_A2B10G10R10               ,//UMETA(DisplayName = "10bit RGB, 2bit Alpha"),DBBPF_MAX,};
}namespace EDefaultBackBufferPixelFormat
{ENGINE_API EPixelFormat Convert2PixelFormat(EDefaultBackBufferPixelFormat::Type InDefaultBackBufferPixelFormat);ENGINE_API int32 NumberOfBitForAlpha(EDefaultBackBufferPixelFormat::Type InDefaultBackBufferPixelFormat);ENGINE_API EDefaultBackBufferPixelFormat::Type FromInt(int32 InDefaultBackBufferPixelFormat);
}

二,拷贝RendererSettings.cpp。同样删掉了EDefaultBackBufferPixelFormat之外的所有内容。
最终文件内容如下:

#include "Engine/RendererSettings.h"namespace EDefaultBackBufferPixelFormat
{EPixelFormat Convert2PixelFormat(EDefaultBackBufferPixelFormat::Type InDefaultBackBufferPixelFormat){const int32 ValidIndex = FMath::Clamp((int32)InDefaultBackBufferPixelFormat, 0, (int32)DBBPF_MAX - 1);static EPixelFormat SPixelFormat[] = { PF_B8G8R8A8, PF_B8G8R8A8, PF_FloatRGBA, PF_FloatRGBA, PF_A2B10G10R10 };return SPixelFormat[ValidIndex];}int32 NumberOfBitForAlpha(EDefaultBackBufferPixelFormat::Type InDefaultBackBufferPixelFormat){switch (InDefaultBackBufferPixelFormat){case DBBPF_A16B16G16R16_DEPRECATED:case DBBPF_B8G8R8A8:case DBBPF_FloatRGB_DEPRECATED:case DBBPF_FloatRGBA:return 8;case DBBPF_A2B10G10R10:return 2;default:return 0;}return 0;}EDefaultBackBufferPixelFormat::Type FromInt(int32 InDefaultBackBufferPixelFormat){const int32 ValidIndex = FMath::Clamp(InDefaultBackBufferPixelFormat, 0, (int32)DBBPF_MAX - 1);static EDefaultBackBufferPixelFormat::Type SPixelFormat[] = { DBBPF_B8G8R8A8, DBBPF_B8G8R8A8, DBBPF_FloatRGBA, DBBPF_FloatRGBA, DBBPF_A2B10G10R10 };return SPixelFormat[ValidIndex];}
}

之后,恢复D3D11Viewport.cppRendererSettings.h的注释,就OK了。

2.4.5 WindowsD3D11Device.cpp 相关的Engine模块内容
WindowsD3D11Device.cpp(19): fatal error C1083: 无法打开包括文件: “HardwareInfo.h”: No such file or directory

注释掉后的错误如下:

WindowsD3D11Device.cpp(1749): error C2653: “FHardwareInfo”: 不是类或命名空间名称
WindowsD3D11Device.cpp(1749): error C2065: “NAME_RHI”: 未声明的标识符
WindowsD3D11Device.cpp(1749): error C3861: “RegisterHardwareInfo”: 找不到标识符

实际都在一行代码中:

FHardwareInfo::RegisterHardwareInfo( NAME_RHI, TEXT( "D3D11" ) );

虽然他在初始化阶段FD3D11DynamicRHI::InitD3DDevice()函数中调用,但是看名字应该是和信息注册相关的,不是核心的功能,因此我选择将这行注释掉。

最后编译成功

总结

最后,总结下这三个模块完整的依赖情况:

实现
调用
想调用输出信息相关的函数
动态读取
核心功能Shader需要平台相关的内容
D3D11RHI
RHI
RenderCore
Core
ApplicationCore
Projects
Json
TargetPlatform
Engine
一些第三方库模块

其中虚线是当前做了一些处理的。其中RenderCore依赖TargetPlatform的处理其实让Shader的功能受到重要影响,其他地方的处理应该影响都不大。

【UE4源代码观察】观察 RHI、D3D11RHI、RenderCore 这三个模块的依赖关系相关推荐

  1. 【UE4源代码观察】手动建立一个使用UBT进行编译的空白工程

    我想观察UE4是怎么编译的,于是查阅官方文档,了解到UE4有一套自己的编译工具:UnrealBuildTool,简称UBT.关于UBT的官方文档参阅:虚幻编译工具.我想尝试自己手动建立一个使用UBT进 ...

  2. 【UE4源代码观察】尝试调试UBT

    前言 在之前的博客<[UE4源代码观察]手动建立一个使用UBT进行编译的空白工程>中我尝试动手搭建了一个用UBT进行编译的空白的工程.但是对UBT其中的逻辑并不理解. 后来在学习UE4源代 ...

  3. UE4 自定义Shader 和 RHI

    UE4 自定义Shader 和 RHI 使用UE4自定义Shader和RHI绘制简单三角形,参考上一节创建RenderTarget来显示三角形. 创建shader 使用UE4创建自定义shader需要 ...

  4. 从UE4源代码启动、创建UE4新项目

    (该方法在windows 10 x64专业版和UE4 4.25.1版本上得到验证) 运行环境: .net framework 4.6.2 VSC 2019 方法如下: 得到UE4源代码(下载方法见官方 ...

  5. STM32F0系列FOC 源代码, 有单电阻采样和三电阻采样两种代码

    STM32F0系列FOC 源代码, 有单电阻采样和三电阻采样两种代码. 都是ST很经典算法,代码学习,无感算法开源,代码不是库. 学习代码规范和无感FOC算法. ID:7410063429430296 ...

  6. octave源代码安装之——依赖关系解析(致数学爱好者)

    octave源代码安装之--依赖关系解析(致数学爱好者) 我的系统是gentoo 3. 0 .6, gnome-3 ,gcc-4.5.3, 安装好系统,和一些必要的autotool, 就可以下载oct ...

  7. 【UE4源代码观察】观察D3D11是如何被RHI封装的

    我想了解D3D11是如何被UE4的RHI封装的.我知道这牵扯到很多复杂的内容,但通过观察一些最基础的API被谁在哪调用,可以对RHI是如何封装的有一个大致了解.在之前的博客<创建一个最小的D3D ...

  8. 【UE4源代码观察】学习队列模板TQueue

    队列 "队列"是一个基础的数据结构,UE4对其有模板实现:TQueue,它在\Engine\Source\Runtime\Core\Public\Containers\Queue. ...

  9. 根据你对优秀软件开发者(优秀软件工程师)的观察和认识,说出三个共同的个人特质(优秀品质),试举例。

    1. 具有很强的分析思维 作为一名优秀的开发者,你需要思考,观察数据,记忆并且分析这些现象和内容,并解决问题.虽然这一点有些抽象,但很不幸的是这是非常重要的一点.为什么很不幸呢?因为这一点意味着不是每 ...

最新文章

  1. 世界最大的多语言语音数据集现已开源!超40万小时,共23种语言
  2. 第十六届全国大学生智能车各分赛区所需要的比赛系统器材
  3. 开课吧python小课值得么-好消息!今天,审计、会计、税务、财务主管彻底沸腾了……...
  4. httpservletrequest_了解HttpServletRequest 对象 基本应用
  5. matlab中的square函数
  6. javascript原生事件句柄、BOM、DOM对象属性方法总结
  7. OpenOffice java api UNO 设置属性总结
  8. 为什么不敢和别人竞争_内心很脆弱,不敢和人竞争。该怎么办?
  9. 永恒之蓝(MS17-010)补丁KB号
  10. python画二维图_使用python绘制二维图形示例
  11. java重载静态方法_java – 使用静态和非静态方法重载的方法
  12. linux谷歌浏览器无法登陆,使用chrome/chrominum浏览器无法正常登陆deepin论坛的解决...
  13. oracle 客户端配置
  14. 巧用批处理cmd快速切换IP地址
  15. SQL Server 2008 R2安装功能选择
  16. 【数据结构】串(定长顺序串、堆串、块链串)的存储结构及基本运算(C语言)
  17. 《趣味知识博文》小W与小L带你聊天式备考CDA Level Ⅰ(三)
  18. windows install clean up
  19. FPGA第三节:IP调用实现HDMI输出
  20. 通过设置路由器屏避小米电视盒子广告

热门文章

  1. 数据结构与算法--基本介绍
  2. 做一名服装设计师要学什么
  3. 游戏策划设计中关于游戏节奏的控制
  4. android socket gprs 与 wifi 网络切换,Android应用开发Android 获取手机Wifi地址和Gprs地址,反射修改Wifi地址...
  5. IDEA导入maven聚合项目
  6. s8韩版 android8,真凉了!三星S8安卓8.0稳定版系统推送时间曝光:2月底
  7. 转一封菜鸟来信及关于如何提问,还有其他
  8. 元宵特辑 |不猜灯谜,来一场特别的坦白局如何?
  9. win10关闭快速启动_win10系统关闭快速启动功能教程
  10. Flowable教程