API GPU mới của SDL3 đã được hợp nhất
(github.com/libsdl-org)- PR #9312 cho API GPU mới của SDL3 đã được hợp nhất vào ngày 29/08/2024; khi SDL 3.0 đang đến gần, hướng tiếp cận dựa trên Refresh được đưa lên nhanh để nhận thêm nhiều đánh giá hơn
- Đề xuất chọn Refresh, thành phần đồ họa của MoonWorks, làm ứng viên API cuối cùng cho SDL_gpu; hỗ trợ Vulkan và API đồ họa PS5, còn hỗ trợ D3D11 deferred context khi đó đang được triển khai
- Thiết kế API dùng mô hình render hiện đại chia công việc thành render pass, compute pass và copy pass; các thao tác ghi tài nguyên được cấu hình để có thể cycle nội bộ nhằm tránh phụ thuộc giữa các frame
- Phần shader được điều chỉnh từ đề xuất ban đầu tập trung vào biên dịch offline sang hướng kiểm chứng hỗ trợ tạo shader lúc chạy; cấu trúc nhận các định dạng IR theo từng backend được thảo luận để bản thân SDL không bọc trình biên dịch shader
- Ngay sau khi hợp nhất, các điều chỉnh tiếp theo đã diễn ra như tên hàm API, macro thiết lập build, UTF-8 BOM, giới hạn 60 FPS của D3D12 swapchain; thatcosmonaut cũng được thêm quyền commit
Điểm khởi đầu của PR và trạng thái hợp nhất
- PR #9312 bắt đầu là đề xuất API GPU mới được đưa lên để SDL_gpu nhanh chóng nhận đánh giá
- Mục tiêu là sớm có “thêm nhiều cặp mắt” khi SDL 3.0 đang đến gần
- Được hợp nhất vào ngày 29/08/2024 sau xác nhận
It's merged
- Ngay sau khi hợp nhất, có yêu cầu tạm hoãn thay đổi trong chốc lát để tiến hành review và điều chỉnh
- Sau đó trạng thái trở thành
everything is merged, và có hướng dẫn rằng có thể tiếp tục hợp nhất các thay đổi phía GPU - thatcosmonaut được thêm vào danh sách có quyền commit vì nhiều khả năng sẽ review các thay đổi sắp tới
- Sau đó trạng thái trở thành
Ứng viên API dựa trên Refresh
- Trọng tâm của đề xuất là chọn Refresh, thành phần đồ họa của MoonWorks, làm ứng viên API cuối cùng cho SDL_gpu
- MoonWorks được giới thiệu là dự án gần với phần kế nhiệm của XNA hơn là tái triển khai XNA như FNA
- Refresh tương tự FNA3D nhưng nhắm tới các API hiện đại như Vulkan
- Vào thời điểm đó, Refresh hỗ trợ Vulkan và API đồ họa PS5
- Hỗ trợ D3D11 deferred context đang được triển khai
- Được giới thiệu là đang dùng trong production cho Samurai Gunn 2 trên PC và console
- Tác giả PR cho biết thatcosmonaut là đầu mối liên hệ chính, và FNA core team cũng sẽ tham gia vào quá trình này
Thiết kế API và xử lý tài nguyên
- API được cấu thành xoay quanh deferred context, theo phong cách API render hiện đại
- Công việc được chia thành render pass, compute pass và copy pass
- Phần còn lại của API được mô tả là có dạng khá tiêu chuẩn, gần với các lời gọi binding, render và compute dispatch
- Mọi thao tác ghi vào tài nguyên đều có thể tránh phụ thuộc giữa các frame thông qua cycle
- Các handle tài nguyên đồ họa như
GpuBuffersđóng vai trò container để cycle tham chiếu tài nguyên nội bộ - Về sau, khái niệm cycle được đơn giản hóa thành bool, và nhiều enum
WriteOptionsbị loại bỏ
- Các handle tài nguyên đồ họa như
- Ban đầu có nhiều enum
WriteOptionsdo vấn đề hành vi của data API liên quan tới driver AMD D3D11- Có giải thích rằng chưa thể hoàn toàn обход qua việc D3D11 data API không hoạt động như kỳ vọng trên AMD
- Sau đó phần này được đơn giản hóa và cách hoạt động được ghi tài liệu trong mã
Thảo luận về hệ thống shader
- Giải pháp shader ban đầu là một script tên
shaderbuild.py- Script này đóng vai trò lớp trước của công cụ build shader offline trên máy client
- Cấu trúc là đóng gói nhiều định dạng và chuyển tới từng render backend phù hợp
- Cách này được mô tả là thiết kế không chặn biên dịch shader online
- Có giải thích rằng có thể đưa mã nguồn SDLSL trong tương lai vào binary và chuyển đổi ngay sang bytecode backend cần thiết trong
CreateShaderModule - Ưu điểm được nêu là có thể cho phép biên dịch online mà không phá vỡ public API
- Có giải thích rằng có thể đưa mã nguồn SDLSL trong tương lai vào binary và chuyển đổi ngay sang bytecode backend cần thiết trong
- Phản hồi bên ngoài nêu lo ngại rằng biên dịch thuần offline không phù hợp với một số engine
- Có ý kiến rằng việc phải cài Python,
glslc,spirv-crossvào PATH có thể gây phiền cho nhà phát triển - Cũng có ý kiến rằng trong hệ sinh thái SDL, một công cụ biên dịch shader offline ở dạng satellite library riêng có thể tự nhiên hơn
- Có ý kiến rằng việc phải cài Python,
- Sau đó hệ thống shader được điều chỉnh theo hướng phân biệt shader “raw” và shader “portable”
- Bản port FNA3D được dùng làm stress test cho hỗ trợ tạo shader lúc chạy
- Có nhắc tới cấu hình dùng MojoShader SPIR-V emitter để chuyển trực tiếp trên Vulkan, còn với các backend khác thì chuyển đổi bằng thư viện riêng tùy chọn SDL_shader
- Mục tiêu là bản thân SDL không biết hoặc không quan tâm shader đến từ đâu
Backend và tiến trình kiểm thử
- Việc triển khai ban đầu dựa trên Refresh được đánh giá là có lợi thế vì backend Vulkan đã tồn tại
- Có ý kiến rằng backend Vulkan có hiệu năng cao theo chuẩn Refresh 2.0
- Việc compute là tính năng hạng nhất cũng được chỉ ra là khác biệt quan trọng so với bản nháp SDL_GPU trước đó
- Từ cuối tháng 3 đến đầu tháng 4/2024, nhiều trường hợp chạy game thực tế đã được chia sẻ
- Được mô tả là đã đạt trạng thái hoạt động mà không cần biên dịch shader offline
- Revision hiện tại có thể boot Streets of Rage 4 được chia sẻ
- Wizorb chạy trên Metal
- Celeste vào được trạng thái in-game trên phần đáng kể của trace database
- Việc bổ sung tính năng cũng diễn ra song song
- Có nhắc rằng hỗ trợ hardware instancing sẽ được thêm trong lần push tiếp theo
- Sau đó instancing và occlusion queries đã được đưa vào, và trạng thái được chia sẻ là cần lấp đầy phần triển khai phía Metal
Các vấn đề build, API và nền tảng phát sinh trong review
- Lỗi tái định nghĩa typedef
VkInstance,VkSurfaceKHRxảy ra do thứ tự include Vulkan- Một bản sửa được đề xuất là đổi thứ tự include header Vulkan và
SDL_vulkan.htrongSDL_gpu_vulkan.c - Cũng có bản sửa đề xuất khởi tạo bằng 0 để dập cảnh báo rằng
suitableQueueFamilyIndexcó thể chưa được khởi tạo
- Một bản sửa được đề xuất là đổi thứ tự include header Vulkan và
- Nhu cầu cập nhật dynapi cũng được nêu ra
- Có hướng dẫn rằng chạy
gendynapi.pydướisrc/dynapi/sẽ cập nhật - Cũng có caveat rằng khi chạy sẽ xuất hiện nhiều cảnh báo thiếu tài liệu
- Có hướng dẫn rằng chạy
- Đã có đề xuất đổi kiểu byte size trong chữ ký hàm API sang
size_t, nhưng kết luận là giữUint32trong GPU API- Có ý kiến rằng khi kích thước buffer trở nên rất lớn, việc tương thích đồng thời 32/64-bit có thể khó hơn
Uint64được nhắc tới như một phương án thay thế, nhưng cuối cùng ý kiến được đưa ra là giữUint32
Điều chỉnh tiếp theo sau khi hợp nhất
- Sau khi hợp nhất, nhiều tweak được thực hiện trong #10622
- Có thông báo rằng các tên hàm mới sẽ được hợp nhất trước để người dùng beta có thể nhận được
- Vấn đề trong thiết lập build, nơi các macro bên phải phải được định nghĩa như
SDL_GPU_VULKAN SDL_VIDEO_VULKAN,SDL_GPU_METAL SDL_VIDEO_METAL, đã được sửa trong #10622 - Vấn đề UTF-8 BOM trong các file nguồn GPU cũng được sửa trong #10622
- Ở phía D3D12, đã xác nhận hiện tượng
D3D12_ClaimWindow()thiết lập swapchain với VSYNC khiếntestspritebị giới hạn ở 60 FPS- Workflow dự kiến được giải thích là tạo swapchain ở bước claim window với các tham số được hỗ trợ phổ biến là SDR và VSYNC, sau đó truy vấn khả năng hỗ trợ rồi gọi
SetSwapchainParameters - Dù render driver đã gọi
SetSwapchainParameterssau claim, giới hạn 60 FPS vẫn còn trong driver D3D12 nên trở thành đối tượng cần điều tra
- Workflow dự kiến được giải thích là tạo swapchain ở bước claim window với các tham số được hỗ trợ phổ biến là SDR và VSYNC, sau đó truy vấn khả năng hỗ trợ rồi gọi
1 bình luận
Ý kiến trên Hacker News
SDL3 vẫn đang ở giai đoạn xem trước, nhưng GPU API mới đã được hợp nhất vào nhánh chính và các maintainer của SDL3 đang thực hiện những tinh chỉnh cuối cùng
Theo những gì tôi hiểu, điểm cốt lõi của GPU API mới này là bạn có thể viết mã đồ họa và shader một lần rồi cho chúng chạy trên nhiều nền tảng, bao gồm cả console, mà không phải vất vả quá nhiều. Trước đây thường phải dùng Unity, Unreal, hoặc một giải pháp tùy biến riêng
WebGPU/WGSL cũng là một ngăn xếp đồ họa đa nền tảng tương tự, nhưng theo tôi biết thì chưa có ai làm backend cho console. Ngược lại, có vẻ SDL3 GPU API hiện chưa hỗ trợ WebGPU làm backend
Tôi kỳ vọng vào SDL3 vì nó đưa vào lớp trừu tượng cho console, nhờ đó GPU API không cần thêm phụ thuộc bổ sung. Hơn nữa, Godot chính thức hỗ trợ Steam Deck, và hy vọng sau này sẽ hỗ trợ thêm nhiều console hơn. Liên quan đến việc này, Miguel de Icaza đang thúc đẩy việc đưa Swift vào Godot, đồng thời cũng đang port trình biên tập trên iPad sang SwiftUI. Tiến triển [3] khá thú vị
[1] https://bkaradzic.github.io/bgfx/overview.html
[2] https://github.com/bgbernovici/myndsmith
[3] https://blog.la-terminal.net/xogot-code-editing/
Có thêm bối cảnh ở đây: https://icculus.org/finger/flibitijibibo?date=2024-06-15&time=13-14-16
Tôi rất mong xem hướng đi này sẽ định hình ra sao. Xét cho cùng, sẽ tốt nếu có thêm nhiều lựa chọn để làm game engine và ứng dụng tùy biến
Gần đây tôi đang đào sâu vào Vulkan, và dù việc học khá thú vị cũng như mang lại nhiều điều ngộ ra, bản chất của Vulkan khiến tiến độ có cảm giác chậm. Nếu lúc bắt đầu đã có SDL3, có lẽ tôi đã sẵn sàng chọn nó, và có lẽ giờ đã có nhiều thứ để trình bày hơn so với lượng thời gian đã bỏ ra
Phải chờ thêm thời gian mới biết API này có thực sự dùng ổn không. Đặc biệt, đồng bộ hóa tài nguyên và cách đổi tên đối tượng sẽ là điểm then chốt
Cũng phải xem liệu hiệu năng của nó có tốt hơn WebGPU hay các lớp trừu tượng khác không. Và cũng cần theo dõi xem nó có còn giữ được sự gọn nhẹ khi phải lách các lỗi driver hay không
Tôi cũng hoài nghi về bytecode mới cho ngôn ngữ shading. Với WebGPU, việc phân tích shader lúc chạy chưa bao giờ là nỗi lo và nó rất nhanh. Việc tạo shader native cũng nhanh [1]. Thứ chậm là tạo pipeline, và bytecode này không giúp được gì cho việc đó
[1] http://kvark.github.io/naga/shader/2022/02/17/shader-translation-benchmark.html
Tò mò không biết họ đã làm được nhanh như vậy bằng cách nào. WebGPU native mất thời gian phát triển rất lâu và đến giờ vẫn chưa chốt окончательно, trong khi API GPU của SDL còn hỗ trợ nhiều nền tảng hơn nên nhìn qua tưởng như sẽ còn lâu hơn nữa
Có một dự án anh em cho ngôn ngữ shading đa nền tảng [1] và một dự án khác để chuyển đổi qua lại giữa các ngôn ngữ hiện có [2], nhưng mấy thứ đó xong khi nào thì xong, phần còn lại của API không cần phải chờ chúng
WebGPU là sản phẩm do một ủy ban gồm các vendor và các “luật sư ngôn ngữ”, hay đúng hơn là “luật sư tiêu chuẩn”, tạo ra giữa chính trị và quan liêu, và điều đó lộ rất rõ. SDL_GPU thì trước hết do các nhà phát triển game coi trọng tính thực dụng tạo ra, nên vì vậy đôi khi còn bị giới tháp ngà xem thường
[1]: https://github.com/libsdl-org/SDL_shader_tools
[2]: https://github.com/flibitijibibo/SDL_gpu_shadercross
Vui vì đã đóng góp cho phần dx12 :)
Có thể tôi sẽ thử dùng. Từ trước đến nay tôi luôn cảm thấy SDL là phần mềm chất lượng cao. Biên dịch nhanh, dễ biên dịch trên nhiều nền tảng, và luôn hoạt động tốt. Vì thế tôi cũng kỳ vọng vào API mới này
Nhìn chung tôi là fan rất nhiệt thành của SDL
Khi tìm một thư viện game đa nền tảng, SDL và API của nó cho tôi cảm giác có sự cân bằng vừa đúng. Tôi chỉ muốn một thư viện C/C++ có thể gọi để tạo cửa sổ và graphics context, cùng một framework render sprite nhanh. Tôi không cần cả một IDE hoàn chỉnh hay thư viện phình to, cũng không muốn phải học thêm ngôn ngữ mới
Tôi có cảm giác SDL3 đang gặp hiệu ứng hệ thống thứ hai. SDL2 gần giống SDL1 gắn thêm window handle tường minh, nên SDL3 là hệ thống thứ hai chứ không phải thứ ba. SDL1/2 là một lớp mỏng bọc lấy boilerplate theo từng nền tảng để mở cửa sổ và xử lý sự kiện đầu vào, giúp đi nhanh vào phần mã render OpenGL mà người ta thực sự muốn viết
Nhưng nếu muốn hỗ trợ cả các hệ điều hành của Apple thì sẽ bị trói vào OpenGL 4.1. Apple đã chính thức đánh dấu chuẩn bị khai tử nó từ 5 năm trước, nên không dùng được các tính năng GPU hiện đại như compute shader
Cũng có thể đi theo hướng Vulkan và dùng MoltenVK trên hệ thống Apple, nhưng Vulkan phức tạp hơn OpenGL khá nhiều. Như người ta hay nói, kiểu “1000 dòng code cho một tam giác”. Mục tiêu của API GPU trong SDL3 là đưa ra một phương án thay thế dễ tiếp cận hơn mà vẫn đủ linh hoạt
Console chắc cũng là câu chuyện tương tự
Nhiều người đã yêu cầu kiểu “có thể thêm hỗ trợ shader giống SDL_render nhưng chạy trên mọi nền tảng không?”, và nghe nói đó chính là điểm khởi đầu
SDL3 cũng bổ sung API âm thanh ở mức cao hơn, nhưng tôi chưa rõ lợi ích của phần đó
Ngoài ra SDL2 đã tiến hóa đáng kể sau 2.0.0, và SDL3 tiếp tục sự tiến hóa đó trong khi cho phép các thay đổi phá vỡ tương thích API. SDL3 không phải được viết lại từ đầu, và từ góc nhìn người dùng SDL thì việc chuyển từ SDL2 sang SDL3 có lẽ sẽ không quá khó
Và SDL1/2 cũng chưa từng “chỉ mỏng” đến mức không có hệ thống đồ họa mức cao của riêng mình. Việc có sẵn mặc định để người dùng mới hay người dùng cơ bản có thể hiện ngay thứ gì đó lên màn hình là điều hữu ích
Như ahefner đã chỉ ra, SDL1 theo tiêu chuẩn hiện đại thì khá “mỏng”, nhưng vẫn cung cấp đủ để vẽ những thứ cơ bản lên màn hình mà không phải tự viết toán học pixel, và vào thập niên 90 điều đó khá hữu ích
Dù vậy, lớp trừu tượng này có thể giúp đáp ứng các nhu cầu vượt ra ngoài game 2D đơn giản, đồng thời nhắm tới hệ sinh thái API đồ họa đang ngày càng phân mảnh một cách đáng tiếc. Giấc mơ về một tương lai OpenGL(Next) phổ quát đã tan biến. Chỉ có điều phần khó nhất là chuyển đổi shader dường như vẫn chưa có
Tôi chưa từng dùng thư viện này, nhưng nếu tôi hiểu đúng từ thread được liên kết thì giờ đây đã có cả GPU compute đa nền tảng. Tôi muốn xem các ví dụ về tính năng đó. Không biết nên bắt đầu từ đâu, có ai gợi ý được không?