Tối ưu hoá Godot Engine Vulkan cho Android

Hình ảnh linh vật của Godot Engine

Tổng quan

Godot Engine là một công cụ phát triển trò chơi nguồn mở đa nền tảng phổ biến, hỗ trợ mạnh mẽ cho Android. Bạn có thể dùng Godot để tạo trò chơi thuộc hầu hết mọi thể loại và có thể tạo cả đồ hoạ 2D và 3D. Godot phiên bản 4 đã ra mắt một hệ thống kết xuất mới với các tính năng nâng cao cho đồ hoạ có độ chân thực cao. Trình kết xuất Godot 4 được thiết kế cho các API đồ hoạ hiện đại như Vulkan.

Quỹ Godot đã thu hút các chuyên gia tối ưu hoá đồ hoạ tại The Forge Interactive và cộng tác với Google để phân tích và cải thiện thêm trình kết xuất Vulkan Godot 4, đồng thời hợp nhất các tính năng tối ưu hoá đó trở lại kho lưu trữ dự án. Các tính năng tối ưu hoá này giúp nhà phát triển cải thiện trình kết xuất Vulkan tuỳ chỉnh trên Android.

Phương pháp và kết quả tối ưu hoá

Quy trình tối ưu hoá sử dụng hai cảnh 3D khác nhau trong Godot làm mục tiêu đo điểm chuẩn. Thời gian kết xuất của các cảnh được đo lường trên nhiều thiết bị trong mỗi lần lặp lại của quá trình tối ưu hoá. Để đủ điều kiện đưa vào, các thay đổi đối với trình kết xuất cần cho thấy hiệu suất được cải thiện trên ít nhất một số thiết bị đã thử nghiệm và không được gây ra sự hồi quy về hiệu suất trên bất kỳ thiết bị nào.

Nhiều cấu trúc GPU Android phổ biến đã được sử dụng trong quá trình kiểm thử. Mặc dù nhiều tính năng tối ưu hoá đã mang lại những điểm cải thiện chung, nhưng một số tính năng tối ưu hoá lại có tác động lớn hơn đến các cấu trúc GPU cụ thể. Tổng số của tất cả công việc tối ưu hoá đã làm giảm tổng thể thời gian kết xuất khung hình GPU từ 10% đến 20%.

Tối ưu hoá Vulkan chung

Forge đã thực hiện tái cấu trúc kiến trúc chung trên phần phụ trợ kết xuất Godot Vulkan để cải thiện hiệu suất và giúp phần phụ trợ mở rộng quy mô khi nhu cầu kết xuất nội dung tăng lên. Các tính năng tối ưu hoá này không dành riêng cho phần cứng di động mà mang lại lợi ích cho tất cả nền tảng Godot Vulkan.

Hỗ trợ độ lệch UBO động

Khi liên kết một tập hợp chỉ số mô tả chứa đối tượng vùng đệm đồng nhất động (UBO), Vulkan cho phép chỉ định các độ dời động vào UBO trong các tham số liên kết. Bạn có thể dùng tính năng này để đóng gói dữ liệu cho nhiều thao tác kết xuất vào một UBO, liên kết lại tập hợp chỉ số mô tả bằng một độ dời động khác để chọn dữ liệu phù hợp cho chương trình đổ bóng. Trình kết xuất Godot Vulkan đã được cập nhật để có thể sử dụng độ dời động thay vì luôn khởi tạo độ dời thành 0. Điểm cải tiến này cho phép tối ưu hoá hiệu quả trong tương lai.

Các nhóm bộ mô tả tuyến tính

Trước đây, hành vi mặc định trong trình kết xuất Godot Vulkan là tạo tất cả các nhóm bộ mô tả bằng cách sử dụng cờ VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, nghĩa là các lượt phân bổ bộ mô tả có thể được giải phóng trở lại nhóm và có thể thực hiện các lượt phân bổ lại từ nhóm. Chế độ này đã áp dụng thêm chi phí hao tổn so với các nhóm bộ mô tả chỉ cho phép phân bổ tuyến tính, sau đó là tổng đặt lại nhóm.

Giờ đây, nếu có thể, các nhóm tập hợp đặc tả sẽ được tạo dưới dạng nhóm tuyến tính mà không cần đặt VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT. Sau đó, các nhóm tuyến tính sẽ được đặt lại toàn bộ khi cần. Công việc này cũng bao gồm việc tối ưu hoá bổ sung để liên kết tập hợp chỉ số mô tả hàng loạt khi khả thi, giảm số lượng lệnh gọi riêng biệt đến vkCmdBindDescriptorSets().

Hỗ trợ bộ lấy mẫu bất biến

Các đối tượng bộ lấy mẫu chứa dữ liệu cấu hình lấy mẫu theo truyền thống được liên kết như một phần của dữ liệu tập hợp chỉ số mô tả. Phương thức này cho phép các đối tượng bộ lấy mẫu được hoán đổi một cách linh động trong dữ liệu tập hợp chỉ số mô tả. Vulkan cũng hỗ trợ các bộ lấy mẫu không thể thay đổi, bộ lấy mẫu này mã hoá dữ liệu bộ lấy mẫu trực tiếp vào bố cục tập hợp chỉ số mô tả. Cấu hình bộ lấy mẫu này được liên kết khi tạo tập hợp chỉ số mô tả và trạng thái quy trình và không thể thay đổi sau khi tạo.

Bộ lấy mẫu không thể thay đổi đánh đổi tính linh hoạt để không còn phải quản lý và liên kết các đối tượng bộ lấy mẫu riêng biệt. Trình kết xuất Godot Vulkan đã được cập nhật để hỗ trợ việc sử dụng bộ lấy mẫu không thể thay đổi; việc sử dụng bộ lấy mẫu đã được thay đổi để sử dụng bộ lấy mẫu không thể thay đổi khi thực tế.

Tối ưu hoá tập trung vào thiết bị di động

Chúng tôi đã triển khai các biện pháp tối ưu hoá bổ sung để cải thiện hiệu suất kết xuất trên phần cứng đồ hoạ dành cho thiết bị di động. Các hoạt động tối ưu hoá này thường không liên quan đến phần cứng đồ hoạ loại máy tính để bàn do các thiết kế kiến trúc khác nhau.

Các hoạt động tối ưu hoá bao gồm:

  • Thay thế việc sử dụng hằng số đẩy lớn
  • Phân bổ vùng đệm từng phần
  • Hỗ trợ vùng đệm liên tục
  • Thay đổi chế độ giải mã ASTC
  • Xoay trước màn hình

Thay thế việc sử dụng hằng số đẩy lớn

Hằng số đẩy là một tính năng cho phép chèn các giá trị hằng số cho chương trình chương trình đổ bóng đang hoạt động vào vùng đệm lệnh. Hằng số đẩy rất thuận tiện vì không yêu cầu tạo và điền vùng đệm cũng như không liên kết với chỉ số mô tả. Tuy nhiên, hằng số đẩy có kích thước tối đa bị giới hạn và có thể ảnh hưởng tiêu cực đến hiệu suất trên phần cứng di động.

Trong quá trình kiểm thử trên thiết bị Android, hiệu suất đã được cải thiện bằng cách thay thế việc sử dụng hằng số đẩy nhiều hơn 16 byte bằng vùng đệm đồng nhất. Các chương trình đổ bóng sử dụng 16 byte dữ liệu hằng số trở xuống có hiệu suất cao hơn với hằng số đẩy. Ngoài các yếu tố cần cân nhắc về hiệu suất, một số phần cứng đồ hoạ có mức căn chỉnh tối thiểu 64 byte cho các vùng đệm đồng nhất, làm giảm hiệu quả sử dụng bộ nhớ do khoảng đệm không sử dụng khi so sánh với việc sử dụng hằng số đẩy.

Phân bổ vùng đệm từng phần

Hầu hết phần cứng đồ hoạ trên thiết bị di động đều sử dụng kiến trúc kết xuất muộn dựa trên ô (TBDR). Các GPU sử dụng TBDR chia vùng màn hình lớn thành một lưới gồm các thẻ thông tin nhỏ hơn và kết xuất trên cơ sở từng thẻ thông tin. Mỗi thẻ thông tin được hỗ trợ bởi một lượng nhỏ RAM tốc độ cao mà GPU sử dụng để lưu trữ khi GPU kết xuất một thẻ thông tin. Với TBDR, các mục tiêu kết xuất không bao giờ được một mục tiêu khác lấy mẫu bên ngoài lượt kết xuất có thể vẫn nằm hoàn toàn trong RAM xếp kề một cách hiệu quả và không yêu cầu vùng đệm cho bộ nhớ sao lưu bộ nhớ chính.

VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT được thêm vào trong quá trình tạo các mục tiêu kết xuất thích hợp, chẳng hạn như mục tiêu màu chính và mục tiêu chiều sâu, để tránh phân bổ bộ nhớ đệm không bao giờ được sử dụng. Mức tiết kiệm bộ nhớ phân bổ Lazy trong các cảnh mẫu được đo lường lên tới khoảng 50 megabyte RAM.

Hỗ trợ vùng đệm liên tục

Phần cứng di động sử dụng Kiến trúc bộ nhớ hợp nhất (UMA) thay vì phân biệt phần cứng giữa RAM chính và RAM đồ hoạ. Khi RAM chính và RAM đồ hoạ tách biệt, dữ liệu phải được chuyển từ RAM chính sang RAM đồ hoạ để GPU sử dụng. Godot đã triển khai quy trình chuyển này trong trình kết xuất Vulkan thông qua việc sử dụng vùng đệm giai đoạn. Trên phần cứng UMA,vùng đệm lưu trữ không cần thiết cho nhiều loại dữ liệu; cả CPU và GPU đều có thể sử dụng bộ nhớ. Forge đã triển khai tính năng hỗ trợ cho vùng đệm dùng chung ổn định trên phần cứng được hỗ trợ để loại bỏ việc tạo bản dựng khi có thể.

Hình ảnh của một cảnh trong Godot hiển thị thông tin phân tích tài nguyên khi bật và không bật vùng đệm ổn định.
Hình 1. Phân tích sự khác biệt giữa vùng đệm ổn định được bật và tắt trong một cảnh mẫu.

Thay đổi chế độ giải mã ASTC

Nén kết cấu thích ứng có thể mở rộng (ASTC) là định dạng nén kết cấu hiện đại được ưu tiên trên phần cứng di động. Trong quá trình giải nén, theo mặc định, GPU có thể giải mã texel thành một giá trị trung gian có độ chính xác lớn hơn mức cần thiết để đảm bảo độ trung thực về hình ảnh, dẫn đến việc giảm hiệu quả kết cấu. Nếu phần cứng mục tiêu hỗ trợ, tiện ích VK_EXT_astc_decode_mode sẽ được dùng để chỉ định các giá trị chưa chuẩn hoá 8 bit cho mỗi thành phần khi giải mã thay vì các giá trị dấu phẩy động 16 bit.

Xoay trước màn hình

Để đạt được hiệu suất tối ưu khi sử dụng Vulkan trên Android, trò chơi phải điều chỉnh hướng thiết bị của màn hình với hướng giao diện kết xuất. Quá trình này được gọi là xoay trước. Việc không thực hiện thao tác xoay trước có thể làm giảm hiệu suất do hệ điều hành Android cần thêm một lượt truyền trình tổng hợp để xoay hình ảnh theo cách thủ công. Thêm tính năng hỗ trợ xoay trước trên Android vào trình kết xuất Godot.

Cải tiến tính năng gỡ lỗi

Ngoài việc tối ưu hoá hiệu suất, The Forge còn cải thiện trải nghiệm gỡ lỗi các vấn đề về đồ hoạ trong trình kết xuất Godot bằng các tính năng bổ sung sau:

  • Gia hạn lỗi thiết bị
  • Đường dẫn
  • Điểm đánh dấu gỡ lỗi

Gia hạn lỗi thiết bị

Khi GPU gặp sự cố trong quá trình kết xuất, trình điều khiển Vulkan có thể trả về kết quả VK_ERROR_DEVICE_LOST từ lệnh gọi API Vulkan. Theo mặc định, hệ thống sẽ không cung cấp thêm thông tin ngữ cảnh về lý do trình điều khiển trả về VK_ERROR_DEVICE_LOST. Tiện ích VK_EXT_device_fault cung cấp một cơ chế để trình điều khiển cung cấp thêm thông tin về bản chất của lỗi. Godot đã thêm tính năng hỗ trợ để bật tiện ích lỗi thiết bị (nếu có) và để báo cáo thông tin do trình điều khiển trả về.

Sự cố GPU hoặc tình trạng bị treo khi thực thi có thể gây khó khăn cho việc gỡ lỗi. Để giúp xác định nội dung đồ hoạ có thể đã được kết xuất tại thời điểm xảy ra lỗi, tính năng hỗ trợ breadcrumb đã được thêm vào trình kết xuất Godot. Dấu vết là các giá trị do người dùng xác định có thể được đính kèm vào nội dung trong danh sách vẽ trong biểu đồ kết xuất. Dữ liệu đường dẫn dạng chuỗi được ghi trước khi bắt đầu một lượt kết xuất mới. Nếu xảy ra sự cố hoặc tình trạng bị treo khi thực thi, bạn có thể sử dụng giá trị của chuỗi liên kết hiện tại để xác định dữ liệu nào có thể gây ra sự cố.

Điểm đánh dấu gỡ lỗi

Điểm đánh dấu gỡ lỗi (khi được trình điều khiển hỗ trợ) được dùng để đặt tên tài nguyên. Điều này cho phép các chuỗi mà người dùng có thể đọc được liên kết với các thao tác như lượt kết xuất và tài nguyên như vùng đệm và hoạ tiết khi sử dụng một công cụ đồ hoạ như RenderDoc. Thêm tính năng hỗ trợ chú giải điểm đánh dấu gỡ lỗi vào trình kết xuất Godot Vulkan.

Blog Godot Engine – Thông tin cập nhật về việc cộng tác với Google và The Forge

Yêu cầu lấy dữ liệu cộng tác Godot Engine Vulkan