跳至内容

FidelityFX API 简介

FidelityFX API 是一个简单的 API,专为小的 ABI 接口和向前兼容性而设计。它以动态链接库 (DLL) 的形式提供,包含 5 个函数,声明在 ffx_api.h 中。

  • ffxCreateContext
  • ffxDestroyContext
  • ffxDispatch
  • ffxQuery
  • ffxConfigure

参数通过一个结构体链表提供,每个结构体都有一个包含结构体类型和指向下一个结构体指针的头。

使用 FidelityFX API 的应用程序必须使用提供的已签名 DLL 之一。可以通过 `LoadLibrary` 和 `GetProcAddress` 在运行时加载(推荐),或者通过 `.lib` 文件在应用程序启动时使用动态链接器加载。

特定于后端的功能(用于 DirectX 12 或 Vulkan)仅支持相应的 DLL。由于名称解析冲突,无法在同一个应用程序中同时链接两者。

为方便 C++ 应用程序使用,提供了用于正确初始化结构体类型和链接头文件的辅助函数。只需使用每个头的 `.hpp` 版本,并将 `ffx` 前缀替换为 `ffx::` 命名空间。请注意,包装 API 函数的辅助函数仅在链接使用 `.lib` 文件时有效。将它们与运行时加载一起使用将导致链接器错误。

描述符结构

效果功能通过描述符结构体暴露。每个结构体都有一个头

typedef struct ffxApiHeader
{
ffxStructType_t type; ///< The structure type. Must always be set to the corresponding value for any structure (found nearby with a similar name).
struct ffxApiHeader* pNext; ///< Pointer to next structure, used for optional parameters and extensions. Can be null.
} ffxApiHeader;

每个描述符都有一个关联的结构体类型,通常直接在其头文件中声明。头中的 `type` 字段必须设置为该结构体类型。否则将导致未定义的行为,并可能导致崩溃。C++ 头文件(扩展名为 `.hpp`)提供了用于自动初始化的辅助函数。

`pNext` 字段用于在链表(或“链”)中指定附加参数和扩展。某些调用需要链接特定的其他结构体。

创建上下文

通过调用 `ffxCreateContext` 来创建上下文,其声明如下:

ffxReturnCode_t ffxCreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb);

在调用之前,`context` 应初始化为 `null`。请注意,第二个参数是指向结构体头的指针,而不是结构体本身。第三个参数用于自定义分配器,可以为 `null`,请参阅 内存分配 部分。

示例调用

struct ffxCreateBackendDX12Desc createBackend = /*...*/;
struct ffxCreateContextDescUpscale createUpscale = { 0 };
createUpscale.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
// fill struct ...
createUpscale.header.pNext = &createBackend.header;
ffxContext upscaleContext = NULL;
ffxReturnCode_t retCode = ffxContextCreate(&upscaleContext, &createUpscale.header, NULL);
// handle errors

请注意,在使用 C++ 包装器时,第三个参数的位置会提前,以支持可变数量的描述符参数。

// equivalent of above, chain of createUpscale and createBackend will be linked automatically.
ffxReturnCode_t retCode = ffx::ContextCreate(upscaleContext, nullptr, createUpscale, createBackend);

上下文销毁

要销毁上下文,请调用 `ffxDestroyContext`。

ffxReturnCode_t ffxDestroyContext(ffxContext* context, const ffxAllocationCallbacks* memCb);

调用后,上下文将为 `null`。内存回调必须与创建上下文期间使用的分配回调兼容,请参阅 内存分配 部分。

查询

要从效果中查询信息或资源,请使用 `ffxQuery`。

ffxReturnCode_t ffxQuery(ffxContext* context, ffxQueryDescHeader* desc);

除非特定查询的文档另有说明,否则上下文必须是 `ffxCreateContext` 创建的有效上下文。

输出值将通过写入查询描述符中传递的指针来返回。

配置

要配置效果,请使用 `ffxConfigure`。

ffxReturnCode_t ffxConfigure(ffxContext* context, const ffxConfigureDescHeader* desc);

除非特定配置描述符的文档另有说明,否则上下文必须是 `ffxCreateContext` 创建的有效上下文。

所有效果都有一个键值配置结构体,用于简单的选项,例如:

struct ffxConfigureDescUpscaleKeyValue
{
ffxConfigureDescHeader header;
uint64_t key; ///< Configuration key, member of the FfxApiConfigureUpscaleKey enumeration.
uint64_t u64; ///< Integer value or enum value to set.
void* ptr; ///< Pointer to set or pointer to value to set.
};

可用的键和要传递的值的约束在相关技术的文档中指定。

调度

要分派渲染命令或其他功能,请使用 `ffxDispatch`。

ffxReturnCode_t ffxDispatch(ffxContext* context, const ffxDispatchDescHeader* desc);

上下文必须是 `ffxCreateContext` 创建的有效上下文。

GPU 渲染分派会将命令编码到作为输入的命令列表/缓冲区中。

CPU 分派通常会同步并立即执行其函数。

资源结构

纹理和缓冲区等资源使用 `FfxApiResource` 结构体传递给 FidelityFX API。

对于 C++ 应用程序,后端头文件定义了用于从原生资源句柄构建它的辅助函数。

版本选择

FidelityFX API 支持在上下文创建时覆盖每个效果的版本。这是一个可选功能。如果使用版本覆盖,则 **必须** 保持一致。

  • 仅使用 `ffxQuery` 在 `ffxQueryDescGetVersions` 中返回的、适用于创建结构体类型的版本 ID。
  • 不要硬编码版本 ID。
  • 如果调用 `ffxQuery` 时不带上下文(`NULL` 参数),请使用与 `ffxCreateContext` 相同的版本覆盖。
  • 版本选择应保持默认行为(无覆盖)或由用户选择(在选项 UI 中显示)。

使用 C++ 辅助函数的版本查询示例

ffx::QueryDescGetVersions versionQuery{};
versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
versionQuery.device = GetDX12Device(); // only for DirectX 12 applications
uint64_t versionCount = 0;
versionQuery.outputCount = &versionCount;
// get number of versions for allocation
ffxQuery(nullptr, &versionQuery.header);
std::vector<const char*> versionNames;
std::vector<uint64_t> versionIds;
m_FsrVersionIds.resize(versionCount);
versionNames.resize(versionCount);
versionQuery.versionIds = versionIds.data();
versionQuery.versionNames = versionNames.data();
// fill version ids and names arrays.
ffxQuery(nullptr, &versionQuery.header);

错误处理

对 FidelityFX API 的所有调用都返回 `ffxReturnCode_t` 类型的值。如果使用 C++ 包装器,则会替换为 `ffx::ReturnCode`。

成功的操作将返回 `FFX_API_RETURN_OK`。所有其他返回码均为错误。未来版本可能会添加当前不在头文件中的新返回码。

应用程序应能够优雅地处理错误,即使是无法恢复的错误。

内存分配

要控制内存分配,请将 `ffxAllocationCallbacks` 的指针传递给 `ffxCreateContext` 和 `ffxDestroyContext`。

如果传递空指针,则将使用全局 `malloc` 和 `free`。

对于自定义分配器,需要两个函数:

// Memory allocation function. Must return a valid pointer to at least size bytes of memory aligned to hold any type.
// May return null to indicate failure. Standard library malloc fulfills this requirement.
typedef void* (*ffxAlloc)(void* pUserData, uint64_t size);
// Memory deallocation function. May be called with null pointer as second argument.
typedef void (*ffxDealloc)(void* pUserData, void* pMem);
typedef struct ffxAllocationCallbacks
{
void* pUserData;
ffxAlloc alloc;
ffxDealloc dealloc;
} ffxAllocationCallbacks;

`pUserData` 将被无修改或验证地传递给回调。FidelityFX API 代码不会尝试解引用它,也不会存储它。

如果为上下文创建使用了自定义分配器,则必须为销毁使用兼容的结构体。这意味着在创建上下文期间使用回调和用户数据分配的任何指针,都必须能够使用传递给 `ffxDestroyContext` 的回调和用户数据进行释放。

© . This site is unofficial and not affiliated with AMD.