64 个版本

0.40.0-beta.12024 年 8 月 11 日
0.2.8 2024 年 7 月 29 日
0.2.7 2024 年 3 月 8 日
0.2.0-beta.22023 年 11 月 30 日
0.1.0-alpha.42022 年 12 月 5 日

模拟器 中排名第 353

Download history 8/week @ 2024-04-29 13/week @ 2024-05-13 33/week @ 2024-05-20 23/week @ 2024-05-27 24/week @ 2024-06-03 23/week @ 2024-06-10 25/week @ 2024-06-17 19/week @ 2024-06-24 9/week @ 2024-07-08 32/week @ 2024-07-15 16/week @ 2024-07-22 326/week @ 2024-07-29 102/week @ 2024-08-05 81/week @ 2024-08-12

每月下载量 530
用于 9 包(8 个直接使用)

MPL-2.0 OR GPL-3.0-only

485KB
8K SLoC

librashader

Mega Bezel SMOOTH-ADV

在 DirectX 11 上使用 Mega Bezel SMOOTH-ADV

librashader (/ˈli:brəʃeɪdɚ/) 是一个用于 RetroArch 'slang' 着色器的预处理程序、编译器和运行时,用纯 Rust 重写。

Latest Version Docs build result License Nightly rust

安装

对于最终用户,librashader 可从多种 Linux 发行版和平台上的 Open Build Service 获取。Windows 和 macOS 用户可以从 GitHub 发布 获取最新版本的二进制文件。

支持的渲染 API

librashader 支持所有现代图形运行时,包括 wgpu、Vulkan、OpenGL 3.3+ 和 4.6(带 DSA)、Direct3D 11、Direct3D 12 和 Metal。

librashader 不支持旧版渲染 API,如较旧的 OpenGL 或 Direct3D 版本,除非对 Direct3D 9 提供实验性支持。

API 状态 librashader 功能
OpenGL 3.3+ gl
OpenGL 4.6 gl
Vulkan vk
Direct3D 9 ⚠️ d3d9
Direct3D 11 d3d11
Direct3D 12 d3d12
Metal metal
wgpu 🆗 wgpu

✅ 完全支持 — 🆗 次要支持 — ⚠️ 实验性支持

wgpu 可能由于 WGSL 的限制而无法支持所有着色器。Direct3D 9 的支持是实验性的,并且不完全支持如前一帧反馈或历史记录等特性,并且无法支持需要 Direct3D 10+ 特性的着色器。

用法

librashader 提供了在 librashader 包中的 Rust API 和 C API。这两个 API 都是第一类并且完全受支持。C API 更侧重于与现有项目的集成。如果你希望分部分使用 librashader,Rust librashader 包会暴露更多内部结构。

librashader C API最佳使用方法是在项目中包含librashader_ld.h,这实现了一个动态加载器,可以在搜索路径中动态加载librashader(librashader.solibrashader.dlllibrashader.dylib)实现。

C兼容性

推荐通过librashader_ld单头库集成librashader,该库实现了librashader.dll / librashader.so / librashader.dylib的动态加载器。有关librashader如何处理C ABI和API稳定性以及库更新的详细信息,请参阅版本策略。您也可以仅通过librashader.h及其等效的-lrashader进行动态链接。

虽然可以静态链接到librashader.h,但这不是官方支持的方式。您需要确保链接参数正确,以便能够成功链接到librashader.liblibrashader.a。强烈推荐使用corrosion CMake包。

线程安全性

除了Metal运行时之外,通常从不同的线程创建过滤器链实例是安全的,但绘制帧需要对外部同步过滤器链对象进行同步。

过滤器链可以在任何线程中创建,但对于适用的情况(在Direct3D 11中,即时上下文被视为图形设备队列),需要外部同步图形设备队列。可以使用filter_chain_create_deferred函数异步延迟GPU资源初始化,但调用者负责将记录的命令提交到图形设备队列,并在绘制着色器传递帧之前确保工作已完成。

OpenGL有一个额外的限制,即只有在创建的过滤器链实例与绘制线程相同的本地OpenGL上下文已初始化的情况下,在不同的线程中创建过滤器链实例才是安全的。OpenGL不支持GPU资源初始化的延迟。

Metal运行时不支持线程安全。但是,您仍然可以通过filter_chain_create_deferred函数延迟提交GPU资源初始化。

四边形顶点和旋转

所有运行时都使用单位矩阵MVP和一个范围在[-1, 1]的VBO进行中间传递渲染。默认情况下,最后传递使用范围在[0, 1]的四边形VBO和以下投影矩阵。

static DEFAULT_MVP: &[f32; 16] = &[
  2.0, 0.0, 0.0, 0.0,
  0.0, 2.0, 0.0, 0.0,
  0.0, 0.0, 0.0, 0.0,
  -1.0, -1.0, 0.0, 1.0,
];

与RetroArch一样,对这些运行时而言,此MVP上的旋转只会应用于最后传递。这是将方向信息传递给着色器的唯一方法。

构建

对于Rust项目,只需将crate添加到您的Cargo.toml中。

cargo add librashader

要构建C兼容的动态库,运行构建脚本。

cargo run -p librashader-build-script -- --profile optimized

这将输出目标文件夹中的librashader.dlllibrashader.so。配置可以是debugreleaseoptimized以进行全LTO。

虽然librashader没有构建时依赖,但使用librashader_ld.h可能需要相关运行时图形API的头文件。

编写librashader运行时

如果您希望贡献一个尚不可用的运行时实现,请参阅librashader-runtime存储库,其中包含所有librashader运行时实现中使用的辅助程序和共享逻辑。使用这些辅助程序和特质将确保您的运行时与现有librashader运行时在统一和纹理语义绑定方面具有一致的行为。

这些类型不应在运行时的公共API中公开,而应保留在运行时实现的内部。

示例

以下Rust示例展示了如何使用每个librashader运行时。

还提供了一些使用C API的基本示例。

兼容性

librashader实现了整个RetroArch着色器管道,并且与现有着色器高度兼容。

如果您遇到在RetroArch中工作但在librashader中不工作的着色器,请报告问题。

  • 过滤器链不在后缓冲区终止。
    • 与RetroArch不同,librashader并不完全了解整个渲染状态,并设计为可以在渲染管道的任何位置插入。相反,过滤器链在调用者提供的输出表面和视口处终止。将表面重新绘制回后缓冲区是调用者的责任。
  • 尽可能并行编译着色器。这应该会显著减少预设编译时间。OpenGL不支持并行着色器编译。
  • HDR10支持不是任何着色器运行时的一部分,并且librashader不支持HDR10。
  • 出于性能原因,从不为输入纹理生成米普贴图。从理论上讲,这意味着具有mipmap_input0 = "true"的预设将不会得到米普贴图输入。实际上,没有已知的着色器预设设置了mipmap_input0 = "true"
  • 预设解析器是一个比RetroArch中实现的更加严格的实现。并非所有着色器预设都可能兼容。如果您发现这是这种情况,请提交问题以便添加解决方案。

运行时特定差异

  • OpenGL
    • 通过glBlitFramebuffer将正在运行的帧缓冲区内容复制到历史记录中,而不是将四边形绘制到中间的FBO中。
    • 使用采样器对象而不是glTexParameter
    • 采样器输入和输出不会被重命名。这对于在RenderDoc中调试着色器很有用。
    • UBO和Push Constant Buffer的大小被填充到16字节边界。
    • OpenGL运行时与其他运行时使用相同的VBO,以及用于中间传递的恒等矩阵MVP。RetroArch的OpenGL驱动程序仅使用最终的VBO。
  • OpenGL 4.6+
    • 应考虑OpenGL 3.3+部分的所有注意事项。
    • 应该在OpenGL 4.5上工作,但这不能保证。OpenGL 4.6运行时最终可能切换到使用ARB_spirv_extensions来加载着色器,这不会被视为一个破坏性更改。
    • OpenGL 4.6运行时使用直接状态访问来最小化对OpenGL状态的变化。对于过去5年内发布的GPU,这可能会提高性能。
    • OpenGL运行时与其他运行时使用相同的VBO,以及用于中间传递的恒等矩阵MVP。RetroArch的OpenGL驱动程序仅使用最终的VBO。
  • Vulkan
    • Vulkan运行时可以使用VK_KHR_dynamic_rendering。必须在设备创建时启用此扩展。启用动态渲染可能可以在启用时提高性能,并且由主机硬件支持。
    • 运行时中的分配是通过gpu-allocator而不是手动处理的。
  • Direct3D 11
    • 帧缓冲区复制是通过ID3D11DeviceContext::CopySubresourceRegion来完成的,而不是通过CPU转换加复制。
  • Direct3D 12
    • Direct3D 12运行时使用渲染阶段。这个功能自2018年底发布的Windows 10版本1809以来就已经可用。
    • 为了与着色器实现最大兼容性,使用基于spirv-to-dxil的着色器编译管道,SPIRV-Cross HLSL管道用作后备。这使着色器兼容性超越了RetroArch Direct3D 12驱动器提供的兼容性。随着spirv-to-dxil的改进,HLSL管道后备可能在将来被移除。
    • Direct3D 12运行时需要来自DirectX着色器编译器dxcompiler.dll文件,该文件可能已经作为Direct3D12的一部分安装。不需要dxil.dll
  • Metal
    • Metal运行时与其他运行时使用相同的VBO,以及用于中间阶段的单位矩阵MVP。RetroArch的Metal驱动器仅使用最终的VBO。

大多数,如果不是所有着色器预设都应该在librashader上工作得很好。特定运行时的差异不应该影响输出,更多的是为了将librashader集成到您的项目中提供提示。

版本

Latest Version C ABI C API

librashader通常遵循语义版本控制,针对Rust API,其中次要版本号的增加表示在0.x.y期间的“破坏性变更”,并且在1.x.y之后是“非破坏性变更”。导致版本号增加的“破坏性变更”并不对应于0.1.0版本之后的C API的破坏。

C API是单独版本化的,通过两个单调递增的版本号导出到librashader C头文件中

LIBRASHADER_CURRENT_VERSION的增加保证了对相同的LIBRASHADER_CURRENT_ABI的向后兼容。它大致对应于语义版本控制术语中的“次要”版本,除了它是始终单调递增的。向后兼容的C API添加将导致LIBRASHADER_CURRENT_VERSION的增加。

在某个LIBRASHADER_CURRENT_VERSION之后引入的API可能在先前版本中可用也可能不可用。特别是,由过滤器或帧选项结构体启用的新功能需要LIBRASHADER_CURRENT_VERSION大于或等于引入选项的版本,否则将传递默认值,这可能或可能不会根据该特定功能的向后兼容性启用该功能。

LIBRASHADER_CURRENT_ABI的任何更改都表示C ABI破坏性变更。出于安全原因,librashader_ld.h将检查确保LIBRASHADER_CURRENT_ABI与加载的librashader二进制文件匹配。如果不匹配,librashader将无法加载。如果LIBRASHADER_CURRENT_ABI的值为0,则表示“null”实例,其中每个操作都是无操作,这发生在找不到兼容的librashader实现时。

通过包管理器安装的librashader.soSONAME设置为LIBRASHADER_CURRENT_ABI

以上内容不适用于librashader版本低于0.1.0的发布版本,这些版本允许在不增加LIBRASHADER_CURRENT_VERSIONLIBRASHADER_CURRENT_ABI的情况下,破坏Rust和C API的兼容性。

MSRV策略

虽然librashader需要nightly Rust,但对于不稳定库特性,以下MSRV策略被强制执行。

  • Windows和macOS:最新nightly版本
  • Linux:1.76

每周运行一个CI作业,以确保librashader可以继续在nightly上构建。请注意,MSRV仅用于简化Linux上的分发,并且随时可以更改。它通常跟踪Ubuntu最新版本中可用的最新Rust版本,但补丁版本发布时可能会没有警告而更改。

许可证

librashader的核心部分,如预处理器、预设解析器、反射库和运行时,均采用Mozilla公共许可证版本2.0授权。

librashader的C API,即其头文件和定义,不包括librashader-capi中的实现,采用更宽松的许可证,可能允许你在许可宽松或专有项目中使用librashader。

为了方便在不符合MPL-2.0的项目中使用librashader,librashader_ld实现了一个加载器,该加载器将调用重定向到在加载路径中找到的任何librashader.solibrashader.dlllibrashader.dylib库。一个不兼容MPL-2.0的项目可以将librashader_ld链接到使用librashader运行时,前提是librashader.solibrashader.dlllibrashader.dylib是在MPLv2的约束下分发的

请注意,这意味着如果你的项目无法满足MPL-2.0的要求,你不能与你的项目一起分发librashader.solibrashader.dlllibrashader.dylib。最终用户必须自行获取librashader的实现。更多信息,请参阅MPL 2.0 FAQ

根据你的意愿,你也可以选择在GPLv3的条款下而不是MPL-2.0下分发librashader

依赖项

~25–34MB
~578K SLoC