- 图形学
- 游戏开发
【免费下载链接】dlssg-to-fsr3
Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).
本篇技术指南围绕 dlssg-to-fsr3 仓库所依赖的 FidelityFX-SDK 中内嵌的DirectX Shader Compiler(DXC)组件展开,深入讲解其在 SDK 中承担的角色、当前版本(1.8.2403.2)、标准更新维护流程,并结合源码解析FidelityFX_SC.exe通过dxcompiler.dll完成 HLSL 着色器编译的底层调用链与全部命令行参数。读完本文,你将掌握如何安全升级 FidelityFX-SDK 附带的 DXC、理解 shader permutation 的生成机制,并能在自己的构建流程中正确驱动 FidelityFX Shader Compiler。
dxc 在 FidelityFX-SDK 中的角色
FidelityFX-SDK 采用“预编译 + 运行时加载”的策略:SDK 在构建阶段通过一个名为FidelityFX Shader Compiler(FidelityFX_SC.exe)的命令行工具,把所有 HLSL 着色器按“permutation(置换/变体)”预先编译成二进制与对应头文件,运行时再直接加载这些预生成结果,从而避免运行时 JIT 编译带来的卡顿与复杂性。
在这一链路中,dxc(DirectX Shader Compiler)是面向 DirectX 12 后端的关键编译器内核:FidelityFX_SC通过dxcompiler.dll调用 DXC 的公开 COM 接口(DxcCreateInstance),将 HLSL 源码编译为可在 D3D12 上执行的 DXIL 二进制,同时产出 shader hash、PDB 调试信息与反射(reflection)数据。也就是说,dxc 是 FidelityFX-SDK DX12 后端所有预编译着色器的实际“翻译官”,其版本与正确性直接决定 SDK 内 FSR 2/FSR 3、光学流、模糊、LPM 等全部 DX12 效果的编译结果。
当前版本与目录布局
FidelityFX-SDK 的 dxc 组件由 FFX_SDK_README.md 这一内嵌说明文档管理,文档明确记录:
- 当前版本:
1.8.2403.2,并特别标注其为DirectX12 Agility SDK 兼容编译器。
这一“Agility SDK 兼容”特性并非营销话术,在源码中有直接证据:SDK 的 HLSL 编译器在 hlsl_compiler.cpp 中导出了与 Microsoft DirectX12 Agility SDK 版本号严格对齐的符号:
extern "C" { __declspec(dllexport) extern const UINT D3D12SDKVersion = 614; } extern "C" { __declspec(dllexport) extern const char* D3D12SDKPath = u8".\\D3D12\\"; }其中D3D12SDKVersion = 614对应的正是 SDK 内嵌 Agility SDK 版本1.614.1(见 agilitysdk/FFX_SDK_README.md),保证编译器加载的 D3D12 运行时与 SDK 期望的 Agility SDK 版本保持一致。
在仓库中,dxc 组件实际位于dependencies/FidelityFX-SDK/sdk/tools/ffx_shader_compiler/libs/dxc/,其目录结构为:
| 路径 | 内容说明 |
|---|---|
inc/ | 头文件:dxcapi.h(DXC 公共 API)、d3d12shader.h、dxcerrors.h、dxcisense.h |
lib/x64/ | 导入库:dxcompiler.lib(链接期使用,运行时仍需dxcompiler.dll) |
CMakeLists.txt | 以 INTERFACE 库形式接入构建系统,并负责拷贝运行期 DLL |
FFX_SDK_README.md | 版本记录与更新说明(即本文关联文档) |
LICENSE-LLVM.txt/LICENSE-MIT.txt/LICENSE-MS.txt | DXC 的三份许可证文本(LLVM、MIT、Microsoft 条款) |
注意:仓库内嵌的 dxc 目录仅包含编译期头文件与导入库,运行期所需的dxcompiler.dll、dxil.dll位于 sdk/tools/binary_store/,与FidelityFX_SC.exe、D3D12Core.dll、d3d12SDKLayers.dll、d3dconfig.exe、glslangValidator.exe一同分发,供构建与运行直接使用。
如何更新 dxc 版本
FFX_SDK_README.md给出了标准的 4 步更新流程,这是维护者升级编译器内核时必须遵循的规范操作:
- 从微软 DirectXShaderCompiler 项目的官方发布渠道下载最新版本压缩包(注意:不要下载任意来源的第三方构建,必须使用官方发布的 zip)。
- 解压该压缩包。
- 将解压出的全部内容拷贝到本目录(
libs/dxc/),覆盖原有头文件与导入库。 - 同步更新本
FFX_SDK_README.md中的版本号,使其与实际下载的版本一致。
结合仓库实际情况,完整落地一次更新还需要注意以下配套动作,否则新编译器可能无法正确工作:
- 同步检查 Agility SDK 版本:dxc 需要与 hlsl_compiler.cpp 中导出的
D3D12SDKVersion对齐。若 dxc 大版本更新对 Agility SDK 提出了新要求,需要一并更新libs/agilitysdk/中的运行时,并把hlsl_compiler.cpp顶部的版本常量改为新子版本号(agilitysdk 的FFX_SDK_README.md也明确要求“Update D3D12SDKVersion … with the subversion number”)。 - 同步替换运行期 DLL:
binary_store目录中的dxcompiler.dll与dxil.dll必须与新的编译器版本配套。因为 SDK 在构建阶段实际执行的是binary_store/FidelityFX_SC.exe,而该 exe 在运行时通过LoadLibrary("dxcompiler.dll")动态加载(详见下文“运行时加载”一节)。 - 全量重建:由于 shader 二进制以哈希命名,编译器更新后生成结果可能变化,建议强制重建整个 SDK 解决方案,保证所有 permutation 头文件与二进制都基于新编译器重新生成。
CMake 构建集成:dxc 如何被链接与分发
dxc 在 FidelityFX-SDK 构建系统中以INTERFACE 库形式接入。查看 libs/dxc/CMakeLists.txt 可以看到核心逻辑:
add_library(dxc INTERFACE) target_include_directories(dxc INTERFACE BEFORE "inc/") set(dxc_binaries ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_GENERATOR_PLATFORM}/dxcompiler.dll ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_GENERATOR_PLATFORM}/dxil.dll) copyTargetCommand("${dxc_binaries}" ${CMAKE_HOME_DIRECTORY}/bin/Debug copied_dxc_bin_debug) copyTargetCommand("${dxc_binaries}" ${CMAKE_HOME_DIRECTORY}/bin/Release copied_dxc_bin_release) add_dependencies(dxc copied_dxc_bin_debug copied_dxc_bin_release)它做了三件事:
- 把
inc/暴露为包含目录(BEFORE确保优先于其他同名头文件); - 声明两个运行期 DLL(
dxcompiler.dll、dxil.dll); - 通过
copyTargetCommand自定义目标,在构建时把 DLL 拷贝到输出目录bin/Debug与bin/Release,确保FidelityFX_SC.exe运行时有依赖 DLL 可用。
而在上层 ffx_shader_compiler/CMakeLists.txt 中,dxc 与 agilitysdk、glslangValidator、tiny-process-library 一起被add_subdirectory引入,并通过target_link_libraries(... dxc ...)完成链接。该项目还要求MSVC toolset 142 或更高(Visual Studio 2019+),并输出二进制到bin/目录,这是构建 shader compiler 自身的前提条件。
运行时加载与编译链路(源码级)
FidelityFX_SC.exe的 DX12 后端编译由 hlsl_compiler.cpp 中的HLSLCompiler类承担,其构造器按后端类型走不同的加载路径,DXC分支的核心逻辑如下:
1. 动态加载 dxcompiler.dll
m_DllHandle = LoadLibrary(dll.empty() ? "dxcompiler.dll" : dll.c_str()); m_DxcCreateInstanceFunc = (DxcCreateInstanceProc)GetProcAddress(m_DllHandle, "DxcCreateInstance");DXC 不是静态链接进 exe,而是运行时通过LoadLibrary+GetProcAddress("DxcCreateInstance")动态加载。因此-dxcdll=<DXC DLL Path>命令行参数可以指定替代 DLL;加载失败时(例如 DLL 缺失),工具会抛出“Failed to load DXC library!”并附上GetLastError的错误码,这解释了为什么binary_store中必须随 exe 携带配套的dxcompiler.dll。
2. 创建编译器与 utils 实例
加载成功后通过DxcCreateInstance创建三类 COM 对象:
CLSID_DxcUtils→m_DxcUtils(工具集:参数构建、反射、默认 include handler);CLSID_DxcCompiler→m_DxcCompiler(编译器主体);m_DxcUtils->CreateDefaultIncludeHandler(&m_DxcDefaultIncludeHandler)(默认 include 处理器,作为自定义处理器的兜底)。
3. 自定义 include handler
DXC 路径使用 DxcCustomIncludeHandler:先尝试在着色器源码所在目录查找#include文件,失败后再按-I传入的 include 搜索路径逐一尝试;若仍找不到,会逐级剥离路径前缀再做一次重试(这是为了绕过多级嵌套 include 时pFilename可能带多余相对路径的缺陷)。所有成功解析的依赖文件会被记录到dependencies集合中,最终用于生成-deps=gcc/msvc格式的 depfile,供增量构建判断依赖变更。
4. 参数解析与宏定义
CompileDXC会逐项解析传入参数:-E(入口点)、-T(profile/目标)、-I(include 路径)、-D(宏定义)被提取后单独处理,其余参数原样透传给 DXC。调试模式(-debugcompile)会自动追加-Zss(源码名进 PDB)、-Zi(调试信息)与跳过优化参数;Xbox GDK 后端(Scarlett/Xbox One)则会追加-Qstrip_debug。最终通过m_DxcUtils->BuildArguments(...)组装完整参数数组,交由m_DxcCompiler->Compile(...)执行。
5. 哈希、PDB 与反射
编译成功后,工具从结果中提取三样关键产物:
- Shaker hash:读取
DXC_OUT_SHADER_HASH,得到 16 字节摘要并格式化为十六进制字符串,作为 permutation 的唯一标识;最终产物命名形如{ShaderName}_{hashDigest}.h; - PDB:当需要调试信息时读取
DXC_OUT_PDB,以{hashDigest}.pdb命名落盘(对超过MAX_PATH的长路径会自动加\\?\前缀规避 Windows 路径长度限制); - Reflection:通过
DXC_OUT_REFLECTION与ID3D12ShaderReflection遍历着色器的 Bound Resources,把 CBV、SRV 纹理、UAV 纹理、SRV/UAV 缓冲区、采样器、光线追踪加速结构分别归类,生成g_{permutation}_{ResourceType}ResourceNames/Bindings/Counts/Spaces静态数组写入头文件,供运行时以零反射成本绑定资源。
-reflection与-embed-arguments开关正是控制头文件中是否包含上述反射数据与编译参数记录。
FidelityFX_SC 命令行完整参数
关于 FidelityFX Shader Compiler 的官方命令行说明位于 docs/tools/ffx-sc.md,其语法为:
FidelityFX_SC.exe [Options] <InputFile>全部选项如下(该表格与 ffx_sc.cpp 中的帮助输出一一对应):
| 选项 | 说明 |
|---|---|
<CompilerArgs> | 以空格分隔的、目标编译器接受的一串参数,原样透传给 dxc/fxc/glslang |
-output=<Path> | shader permutation 的输出目录 |
-D<Name> | 定义一个宏,作用于所有 permutation |
-D<Name>={<Value1>, <Value2>, <Value3> ...} | 声明一个 shader 选项:对每个值生成一个 permutation;使用-表示“不定义该宏”的 permutation |
-num-threads=<Num> | 生成 shader 使用的线程数,默认取当前 CPU 的最大可用线程数 |
-name=<Name> | 生成头文件中变量的前缀名,默认使用输入文件名 |
-reflection | 生成包含反射数据的头文件 |
-embed-arguments | 把每个 permutation 的编译参数写入各自头文件 |
-print-arguments | 打印每个 permutation 使用的编译参数 |
-disable-logs | 禁止输出编译警告与错误日志 |
-compiler=<Compiler> | 选择编译器后端:dxc、gdk.scarlett.x64、gdk.xboxone.x64、fxc或glslang |
-dxcdll=<DXC DLL Path> | 指定要使用的 dxcompiler.dll 路径 |
-d3ddll=<D3D DLL Path> | 指定要使用的 d3dcompiler.dll 路径(fxc 后端) |
-glslangexe=<glslangValidator.exe Path> | 指定 glslangValidator 可执行文件路径(Vulkan 后端) |
-deps=<Format> | 输出记录 include 依赖的 depfile,格式为gcc或msvc |
-debugcompile | 以调试信息编译 shader |
-debugcmdline | 打印所有输入参数(用于排查问题) |
在 SDK 构建中的实际调用示例
FidelityFX_SC.exe并非手动逐个调用,而是由各 GPU 组件的CMakeCompile*Shaders.txt驱动。以 FSR 3 Upscaler 为例,CMakeCompileFSR3UpscalerShaders.txt 展示了典型的调用方式:
set(FSR3UPSCALER_BASE_ARGS -reflection -deps=gcc -DFFX_GPU=1 -DFFX_FSR3UPSCALER_OPTION_UPSAMPLE_USE_LANCZOS_TYPE=2) set(FSR3UPSCALER_PERMUTATION_ARGS -DFFX_FSR3UPSCALER_OPTION_REPROJECT_USE_LANCZOS_TYPE={0,1} -DFFX_FSR3UPSCALER_OPTION_HDR_COLOR_INPUT={0,1} -DFFX_FSR3UPSCALER_OPTION_LOW_RESOLUTION_MOTION_VECTORS={0,1} -DFFX_FSR3UPSCALER_OPTION_JITTERED_MOTION_VECTORS={0,1} -DFFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH={0,1} -DFFX_FSR3UPSCALER_OPTION_APPLY_SHARPENING={0,1}) compile_shaders_with_depfile( "${FFX_SC_EXECUTABLE}" "${FSR3UPSCALER_BASE_ARGS}" "${FSR3UPSCALER_API_BASE_ARGS}" "${FSR3UPSCALER_PERMUTATION_ARGS}" "${FSR3UPSCALER_INCLUDE_ARGS}" "${FSR3UPSCALER_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" FSR3UPSCALER_PERMUTATION_OUTPUTS)这里可以看到:-DFFX_FSR3UPSCALER_OPTION_*={0,1}的花括号语法会为每个开关组合(共 2⁶ = 64 种组合)生成一个 permutation,加上 base args 中的固定宏,最终产出全部变体的二进制与头文件;-deps=gcc同时生成依赖文件用于增量构建。FFX_SC_EXECUTABLE在 sdk/CMakeLists.txt 中定义为tools/binary_store/FidelityFX_SC.exe,与dxcompiler.dll同目录,保证运行时能被LoadLibrary找到。
构建或修改 Shader Compiler 自身
若需要修改或重新构建 shader compiler(例如升级 dxc 后重新打包工具),官方流程是:
- 进入
sdk/tools/ffx_shader_compiler/目录; - 运行 GenerateSolution.bat——该脚本会检测 CMake 与 CPU 架构(x64/ARM64),并在
build/子目录生成解决方案; - 构建成功后,输出二进制位于
sdk/tools/ffx_shader_compiler/bin/下的 Debug 或 Release 子目录(由构建配置决定); - 将新工具连同其运行期依赖(
dxcompiler.dll、dxil.dll等)从bin目录拷贝到binary_store目录,覆盖分发版本,SDK 的正式构建即开始使用新编译器。
GenerateSolution.bat会先检查 CMake 是否安装,并要求 Visual Studio 2019 或更新版本的 MSVC 工具链(142+),未满足条件时会直接报错退出。
结语
FFX_SDK_README.md虽只是一份简短的版本说明,但它承载着 FidelityFX-SDK 中一个不可缺失的编译基础设施:dxc 1.8.2403.2。从 CMake 的 INTERFACE 集成、运行期LoadLibrary动态加载,到D3D12SDKVersion=614与 Agility SDK 的版本对齐,再到 permutation 哈希命名、PDB 与反射数据的产出,dxc 深度嵌入在 FidelityFX Shader Compiler 的每条编译链路中。对于 dlssg-to-fsr3 这类以 FidelityFX-SDK 为依赖的项目,理解 dxc 的版本管理与更新规范,是确保 FSR 3 帧生成、超分等全部 DX12 着色器稳定产出、可复现构建的重要前提。
- 图形学
- 游戏开发
【免费下载链接】dlssg-to-fsr3
Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).
相关推荐
dlssg-to-fsr3 核心依赖解读:AMD FidelityFX SDK 1.1 版本新特性、FSR 3.1 帧生成与 FSR API 全解析
dlssg to fsr3 核心依赖解读:AMD FidelityFX SDK 1.1 版本新特性、FSR 3.1 帧生成与 FSR API 全解析 本文围绕本
图形学游戏开发dlssg-to-fsr3 依赖中的 RenderDoc 集成指南:Cauldron 框架的捕获 API 版本、更新流程与启用方式
dlssg to fsr3 依赖中的 RenderDoc 集成指南:Cauldron 框架的捕获 API 版本、更新流程与启用方式 本篇技术指南以 Fideli
图形学游戏开发FidelityFX Blur 1.1 技术详解:Compute Shader 单趟高斯模糊的集成与实现原理(dlssg-to-fsr3 仓库 FidelityFX SDK 依赖篇)
FidelityFX Blur 1.1 技术详解:Compute Shader 单趟高斯模糊的集成与实现原理(dlssg to fsr3 仓库 Fidelity
图形学游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考