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

基本概念

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 enabled
				if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
				{
					DynamicallyLoadedModuleNames.Add("D3D11RHI");

					//#todo-rco: D3D12 requires different SDK headers not compatible with WinXP
					DynamicallyLoadedModuleNames.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");

其中CoreTraceLog已经加入,而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 WinXP
	DynamicallyLoadedModuleNames.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 shading
		bForwardShading = TargetPlatform->UsesForwardShading();
	}
	else
	{
		// shader platform doesn't match a specific target platform, use cvar setting for forward shading
		static 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_METRICSDISCOVERY
	if (GDX11IntelMetricsDiscoveryEnabled)
	{
		return IntelMetricsDicoveryGetGPUTime();
	}
#endif // INTEL_METRICSDISCOVERY
	return 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的功能受到重要影响,其他地方的处理应该影响都不大。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值