首页 > 基础资料 博客日记

Zenith.NET v0.0.7:Metal 后端落地,.NET GPU 抽象的跨平台旅程

2026-04-01 12:00:04基础资料围观1

文章Zenith.NET v0.0.7:Metal 后端落地,.NET GPU 抽象的跨平台旅程分享给大家,欢迎收藏极客资料网,专注分享技术知识

从第一行代码写下 GraphicsContext.CreateDirectX12() 到今天 GraphicsContext.CreateMetal() 跑通全部测试,Zenith.NET 终于实现了最初的承诺——用同一套 .NET API 覆盖三大图形后端

这篇文章聊聊 Metal 后端的技术选型、架构设计,以及 Zenith.NET 作为一个 .NET GPU 抽象层的设计哲学。

为什么要做 Zenith.NET?

.NET 生态有不少图形相关的库——绑定层如 Silk.NET、Vortice,抽象层如 Veldrid、Evergine。但现有的抽象层要么停留在较旧的 API 版本(如 DX11/OpenGL),要么是商业引擎的一部分,难以作为独立的 GPU 抽象层使用。

Zenith.NET 的定位是:一个面向现代图形 API(DirectX 12、Metal 4、Vulkan 1.4)的轻量 GPU 抽象层,只做抽象、不做引擎,让开发者写一次代码、跑在所有平台上。

这就是 Zenith.NET 要做的事:

后端 策略
DirectX 12 Windows 独占,性能天花板
Metal 4 Apple 全平台,仅支持 Apple Silicon
Vulkan 1.4 跨平台兜底,覆盖 Linux/Android

三个后端不是互相替代的关系,而是各守一方——在每个平台上选最原生的那个 API

Metal 后端:架构决策

为什么选 Metal.NET?

v0.0.6 的 release notes 里提到过,当时在 SharpMetal 和 .NET macios TFM 之间评估。最终选了 Metal.NET(NuGet 包 Metal.NET 2.3.0)——这是我在开发期间制作的绑定库。相比 SharpMetal,Metal.NET 提供更完善的 Metal 4 API 覆盖,并且所有接口都是类型安全的。

不过坦率地说,Metal.NET 基于 class 封装 Objective-C 对象,在 GC 方面会有一定开销。

整体结构

Zenith.NET 抽象 Metal 实现
GraphicsContext MTLDevice + MTL4Compiler + MTLResidencySet
CommandBuffer MTL4CommandBuffer + 双编码器(Render/Compute)
ResourceLayout 绑定槽位计数(Buffer/Texture/Sampler)
ResourceTable MTL4ArgumentTable,通过 GPU 地址绑定资源
Pipeline MTLRenderPipelineState + MTLDepthStencilState
SwapChain CAMetalLayer + CAMetalDrawable
AccelerationStructure MTLAccelerationStructure + 实例缓冲区

Metal 4 新特性的应用

Metal 4 引入了几个对抽象层至关重要的新特性,Zenith.NET 的 Metal 后端全面采用了它们。

MTL4ArgumentTable——这是 Metal 4 全新的资源绑定模型。相比旧版 Metal 需要逐个 setBuffer/setTexture/setSampler 绑定资源,Argument Table 允许将所有资源打包到一张表中,通过 GPU 地址一次性绑定。这与 Zenith.NET 的 ResourceLayout + ResourceTable 抽象天然吻合:

Zenith.NET Metal 4
ResourceLayout 声明 Buffer/Texture/Sampler 槽位计数
ResourceTable 创建 MTL4ArgumentTable,填入 GPU 地址
SetResourceTable() 一次调用绑定整张表

MTL4CommandBuffer 采用双编码器模型——同一时刻只能有一种活跃编码器。CommandBuffer 默认开启 Compute 编码器,当用户开启渲染 Pass 时关闭 Compute、切换到 Render 编码器;Pass 结束后自动切回 Compute:

[Compute 编码器] → 开启 Pass → [Render 编码器] → 结束 Pass → [Compute 编码器]

这样设计的好处是:Compute 编码器始终可用于拷贝(Blit)和计算调度,用户无需手动管理编码器生命周期。所有拷贝操作都走 Compute Encoder 的 Blit 路径,统一了屏障语义。

MTL4Compiler 支持设备端编译——把 Slang 输出的 metallib IR 在目标 GPU 上编译为最终 ISA,比传统 offline 编译能更好地利用 GPU 特定优化。

Objective-C 内存桥接

Metal API 基于 Objective-C 运行时,返回的对象都是 autoreleased 的——出了当前 autorelease pool 就会被回收。在 .NET 的托管环境里,这是个隐蔽的坑。

解决方案是一个统一的桥接工具:

public static T Own<T>(Func<T> func) where T : NSObject
{
    using NSAutoreleasePool _ = new();
    return func().Retain();
}

所有从 Metal API 获取的对象都通过 NSAutorelease.Own() 包装,确保 Retain 延长生命周期,后续由 .NET 的 Dispose 模式释放。

Shader 编译:Slang 统一管线

三个后端共享同一套 Slang 着色器源码:

.slang 源文件
    ├─→ metallib (Metal Shader Library)
    ├─→ dxil     (DirectX Intermediate Language)
    └─→ spirv    (SPIR-V for Vulkan)

开发者只需维护一份 .slang 着色器,编译到哪个后端由 Slangc.NET 自动处理。

光线追踪

Metal 后端完整支持硬件光线追踪:

  • BLAS/TLAS:标准的两级加速结构
  • 实例缓冲区:CPU 可写的间接寻址,更新 transform 无需重建 TLAS
  • RayQuery:在任意着色器阶段内联查询,无需专用光追管线

这与 v0.0.6 移除 RayTracingPipeline 的决策一脉相承——统一用 RayQuery,三个后端的光追能力完全对齐。

设计哲学

只暴露共同能力

Zenith.NET 的核心原则是:采用最新 API 版本,只暴露三个后端共同支持的能力。平台特有的特性被刻意排除,以维护一致的跨平台体验。

这意味着你不会在 Zenith.NET 的 API 里看到 DX12 的 Enhanced Barriers、Vulkan 的 Push Descriptors 或 Metal 的 Tile Shading——这些都是某个 API 独有的。暴露出来只会让其他后端无法实现,破坏"一次编写、处处运行"的承诺。

对于硬件能力差异(比如并非所有 GPU 都支持光追),则通过 Capabilities 动态查询:

if (context.Capabilities.RayTracingSupported) { /* 光追路径 */ }
if (context.Capabilities.MeshShadingSupported) { /* Mesh Shader 路径 */ }

共同能力统一暴露,硬件差异动态检测——这是 Zenith.NET 和其他抽象层最大的区别。

每个平台用最原生的 API

Zenith.NET 不像 bgfx 那样用 Vulkan 覆盖所有平台。在 Windows 上用 DirectX 12,在 Apple 上用 Metal 4,在 Linux/Android 上用 Vulkan 1.4。

虽然上层只暴露共同能力,但每个后端内部都用对应 API 最地道的方式实现——不需要在一种 API 上模拟另一种 API 的行为模式。

AOT 友好

整个库从第一天就为 Native AOT 设计。没有反射、没有动态代码生成、没有 Activator.CreateInstance。Metal.NET 和 Silk.NET 底层都是 P/Invoke + 函数指针,AOT 编译器能完整处理。

下一步

Metal 后端落地后,Zenith.NET 的三大后端全部就位。接下来的重点:

  • SkiaSharp 集成——用 GPU 后端加速 2D 渲染
  • API 稳定化——向 1.0 迈进

Zenith.NET 是开源项目,欢迎关注:

本文由 AI 辅助生成,经作者审核校对。


文章来源:https://www.cnblogs.com/xymfblogs/p/19805856
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云