Xây dựng trình biên dịch shader DirectX tốt hơn Microsoft
- Câu chuyện về tình trạng phức tạp của trình biên dịch shader DirectX của Microsoft và nỗ lực mang lại trải nghiệm tốt hơn cho các nhà phát triển game.
- Đang phát triển một API đồ họa thử nghiệm tên là sysgpu, hậu duệ của WebGPU, cho engine Mach bằng Zig, với kế hoạch hỗ trợ các backend Metal, Vulkan, Direct3D và OpenGL.
- Cần biên dịch các chương trình shader có thể dùng trong Direct3D 12.
Lược sử ngắn gọn của DirectX
- API đồ họa DirectX sử dụng HLSL làm ngôn ngữ shading.
- Trước đây, trước thời Direct3D 11, trình biên dịch mang tên
FXC được sử dụng, nhưng nổi tiếng là chậm và sinh mã tối ưu kém.
FXC không còn được dùng nữa, và DXC xuất hiện cùng Direct3D 12
- Cùng với việc ra mắt Direct3D 12 và Shader Model 6.0 (SM6), Microsoft đã loại bỏ FXC và giới thiệu một trình biên dịch mới mang tên
DXC.
- DXC là một nhánh fork chính thức của Microsoft từ LLVM/Clang v3.7, và các thay đổi được đánh dấu rõ ràng bằng chú thích.
Thứ mà driver DirectX dùng làm bữa sáng: DXBC hoặc DXIL
- Dù HLSL là ngôn ngữ được chọn cho lập trình Direct3D, trên thực tế GPU có nhiều kiến trúc tính toán và yêu cầu khác nhau.
- Microsoft cung cấp một API frontend thân thiện với nhà phát triển, còn các nhà cung cấp phần cứng độc lập sẽ viết driver để chuyển đổi nó sang dạng gần nhất với ISA phần cứng thực tế.
- Với sự xuất hiện của DirectX 12 và Shader Model 6.0, một định dạng mới là DXIL được dùng thay cho DXBC.
DXIL
- DXIL hiện là định dạng chính thức mà các nhà sản xuất driver DirectX 12 sử dụng.
- Nhà phát triển game dùng trình biên dịch DXC để tạo bytecode DXIL, rồi chuyển nó cho driver đồ họa để biến thành mã máy thực tế chạy trên phần cứng GPU.
Chỉnh sửa nhánh fork LLVM của Microsoft
- Microsoft nhận thức rằng việc để các nhà sản xuất driver độc lập sử dụng một định dạng LLVM bitcode cụ thể là điều không lý tưởng, và cũng thừa nhận việc duy trì nhánh fork LLVM không hề dễ chịu.
- Microsoft đã bắt đầu công việc nhằm tích hợp trực tiếp hỗ trợ biên dịch HLSL vào LLVM/Clang.
Thách thức cho nhà phát triển game, WebGPU và hơn thế nữa
- Lớp trừu tượng hóa đồ họa cần cung cấp một ngôn ngữ shading thống nhất, và hiện phần lớn các triển khai WebGPU dùng cách biên dịch HLSL sang DXBC hoặc DXIL.
Đường vòng đơn giản: SPIR-V
- Vulkan/SPIR-V cũng sử dụng cách tiếp cận tương tự, và việc SPIR-V có được tối ưu hay không là do nhà sản xuất GPU quyết định.
Có nên dùng dxcompiler.dll không?
- Runtime WebGPU phải quyết định giữa việc dùng trình biên dịch HLSL DXC mới hay dùng trình biên dịch FXC đã chính thức bị khai tử, vốn cho hiệu năng và chất lượng sinh mã kém hơn.
Vì sao không thể liên kết tĩnh?
- Nhánh fork LLVM của Microsoft không hỗ trợ liên kết tĩnh, và nguyên nhân là do độ phức tạp của hệ thống build.
Giới thiệu dxil.dll - blob ký mã độc quyền cho shader DirectX
dxil.dll không được build từ mã nguồn, mà phụ thuộc vào một blob mã độc quyền theo từng nền tảng trong kho lưu trữ “mã nguồn mở” của Microsoft.
Vấn đề hỗ trợ nền tảng
- Microsoft chỉ phát hành
dxil.dll cho Windows (x86/arm) và Linux (x86), không cung cấp binary cho macOS hay Linux aarch64.
Tóm tắt
- Không thể build DXC thành thư viện tĩnh, và việc khôi phục chức năng LLVM do blob ký mã độc quyền sẽ là một công việc quy mô lớn.
- Không thể thực hiện biên dịch shader offline cho game đa nền tảng trong pipeline CI trên macOS hoặc arm Linux.
Cải thiện hệ thống build
- Chuyển hệ thống build từ CMake sang
build.zig để tìm cách build thành một thư viện tĩnh duy nhất.
Giải quyết phụ thuộc thư viện động
- Đã fork codebase DXC và chỉnh sửa mã C++ để loại bỏ phụ thuộc vào thư viện động.
Giải quyết phần ký mã độc quyền
- Đã tìm ra cách biên dịch shader HLSL mà không cần phụ thuộc vào
dxil.dll.
Kết quả
- Cung cấp thư viện
dxcompiler và CLI dxc dưới dạng binary tĩnh, không phụ thuộc vào dxil.dll độc quyền.
- Build các binary cho macOS, Linux và Windows trong pipeline CI.
Lưu ý
- Một số binary vẫn chưa được build hoặc kiểm thử, và có kế hoạch dùng chính Zig thay vì HLSL làm ngôn ngữ shading.
Ghi chú cá nhân
- Sau khi có một công việc kỹ thuật toàn thời gian dưới tên Stephen, tác giả hoạt động trực tuyến để xây dựng engine Mach.
- Có gốc rễ trong FOSS và tin rằng con người nên sở hữu công cụ của mình và được trao quyền nhờ chúng.
- Ước mơ là xây dựng Mach cho mọi người và kiếm sống bằng cách bán các game chất lượng cao.
Cảm ơn bạn đã đọc
- Hãy xem thử machengine.org.
- Hãy cân nhắc hỗ trợ việc phát triển để có thể làm được nhiều hơn.
- Hãy tham gia máy chủ Discord của Mach.
- Hãy tài trợ trên GitHub.
- machengine.org
Ý kiến của GN⁺
- Điều quan trọng nhất trong bài viết này là nỗ lực của cộng đồng phát triển nhằm vượt qua sự phức tạp và các giới hạn của DXC, trình biên dịch shader DirectX của Microsoft.
- Nhà phát triển engine Mach đã dùng Zig để cải thiện hệ thống build của DXC và đưa ra một cách tiếp cận mới để biên dịch shader HLSL mà không phụ thuộc vào
dxil.dll độc quyền, qua đó đóng góp quan trọng cho phát triển game đa nền tảng.
- Bài viết nhấn mạnh tầm quan trọng của phần mềm mã nguồn mở và việc các nhà phát triển cần có quyền sở hữu cũng như kiểm soát công cụ của mình, đồng thời cho thấy giá trị của hợp tác và đổi mới trong cộng đồng kỹ thuật.
1 bình luận
Ý kiến trên Hacker News
Tổng quan rất hay về độ phức tạp của việc biên dịch shader cho API 3D
Các vấn đề liên quan đến Godot
dxil.dllcủa DirectX Shader Compiler được phân phối kèm với Godot.Thảo luận về việc phân phối thêm
.dll.dllkhông phải là điều bất thường, tương tự như nhiều trò chơi điện tử đã dùng các middleware độc quyền như Bink, SpeedTree, PhysX, v.v..DLLriêng.dxil.dlltrong bộ cài.dxil.dllđến từng bit.Câu hỏi về chữ ký của DXIL.dll
Những thay đổi của DXC đối với tầng sinh mã và hạ tầng của LLVM
Lời khuyên về hệ sinh thái Mach
mach-sysgpu, một bản tái hiện thực hoàn chỉnh của WebGPU, chủ yếu do Ali Chraghi, 17 tuổi, viết.Thảo luận về SDL_gpu và SDL3
Ứng dụng của ngôn ngữ Zig
Lời cảm ơn dành cho công việc hạ tầng
Nhắc đến cách phát âm của DXIL