Nguyên tắc thiết kế của Vulkan

Vulkan không giống như các API đồ hoạ trước đó vì trình điều khiển không thực hiện một số phương án tối ưu hoá nhất định (chẳng hạn như sử dụng lại quy trình) cho ứng dụng. Thay vào đó, các ứng dụng sử dụng Vulkan phải tự triển khai các phương án tối ưu hoá. Nếu không, hiệu suất của các ứng dụng này sẽ kém hơn so với các ứng dụng chạy OpenGL ES.

Việc các ứng dụng tự triển khai những phương án tối ưu hoá này có thể mang lại hiệu quả tốt hơn so với việc trình điều khiển triển khai. Lý do là các ứng dụng có quyền truy cập vào thông tin cụ thể hơn cho một trường hợp sử dụng cụ thể. Kết quả là việc tối ưu hoá ứng dụng bằng cách sử dụng Vulkan một cách khéo léo có thể mang lại hiệu suất tốt hơn so với khi ứng dụng sử dụng OpenGL ES.

Trang này giới thiệu một số phương án tối ưu hoá mà ứng dụng Android của bạn có thể triển khai để tăng hiệu suất nhờ Vulkan.

Tăng tốc phần cứng

Hầu hết thiết bị hỗ trợ Vulkan 1.1 thông qua tính năng tăng tốc phần cứng, trong khi một số ít thiết bị hỗ trợ Vulkan 1.1 thông qua tính năng mô phỏng phần mềm. Các ứng dụng có thể phát hiện thiết bị hỗ trợ Vulkan dựa trên phần mềm bằng cách sử dụng vkGetPhysicalDeviceProperties và kiểm tra trường deviceType của cấu trúc được trả về. SwiftShader và các phương thức triển khai dựa trên CPU khác đều có giá trị VK_PHYSICAL_DEVICE_TYPE_CPU. Các ứng dụng có thể kiểm tra riêng cho SwiftShader bằng cách kiểm tra các giá trị dành riêng cho SwiftShader trong các trường vendorIDdeviceID của cùng cấu trúc này.

Các ứng dụng nhất thiết phải đảm bảo hiệu suất nên tránh sử dụng các phương thức triển khai Vulkan được mô phỏng bằng phần mềm mà nên quay lại sử dụng OpenGL ES.

Áp dụng chế độ xoay màn hình trong khi kết xuất

Khi hướng chính diện của ứng dụng không khớp với hướng màn hình của thiết bị, trình tổng hợp sẽ xoay hình ảnh trong chuỗi hoán đổi của ứng dụng sao cho phù hợp. Trình tổng hợp thực hiện việc xoay màn hình trong khi vẫn cho thấy hình ảnh, dẫn đến tiêu thụ nhiều (đôi khi là rất nhiều) điện năng hơn so với khi không xoay.

Ngược lại, việc xoay hình ảnh trong chuỗi hoán đổi trong quá trình tạo ra hình ảnh sẽ chỉ tiêu thụ thêm một chút điện năng (nếu có). Trường VkSurfaceCapabilitiesKHR::currentTransform cho biết chế độ xoay mà trình tổng hợp áp dụng cho cửa sổ. Sau khi một ứng dụng áp dụng chế độ xoay đó trong khi kết xuất, ứng dụng sẽ sử dụng trường VkSwapchainCreateInfoKHR::preTransform để báo cáo việc quá trình xoay đã hoàn tất.

Giảm thiểu số lượt kết xuất trên mỗi khung hình

Trên hầu hết kiến trúc GPU của thiết bị di động, việc bắt đầu và kết thúc một lượt kết xuất là một thao tác tốn kém. Ứng dụng của bạn có thể cải thiện hiệu suất bằng cách sắp xếp các hoạt động kết xuất sao cho số lượt kết xuất ít nhất có thể.

Mỗi hoạt động tải thành phần gắn kết và lưu trữ thành phần gắn kết lại có hiệu suất riêng. Ví dụ: nếu không cần giữ lại nội dung của một thành phần gắn kết, bạn có thể sử dụng VK_ATTACHMENT_LOAD_OP_CLEAR hoặc VK_ATTACHMENT_LOAD_OP_DONT_CARE (nhanh hơn nhiều) thay vì VK_ATTACHMENT_LOAD_OP_LOAD. Tương tự, nếu không cần viết các giá trị cuối cùng của thành phần gắn kết vào bộ nhớ để sử dụng sau này, bạn có thể sử dụng VK_ATTACHMENT_STORE_OP_DONT_CARE để đạt được hiệu suất tốt hơn nhiều so với VK_ATTACHMENT_STORE_OP_STORE.

Ngoài ra, trong hầu hết lượt kết xuất, ứng dụng của bạn không cần tải hoặc lưu trữ các thành phần gắn kết chiều sâu/sắc tố. Trong những trường hợp như vậy, bạn có thể tránh tình trạng phải phân bổ bộ nhớ thực tế cho thành phần gắn kết bằng cách sử dụng cờ VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT khi tạo hình ảnh thành phần gắn kết. Bit này đem đến các lợi ích tương tự như glFramebufferDiscard trong OpenGL ES.

Chọn loại bộ nhớ thích hợp

Khi phân bổ bộ nhớ của thiết bị, ứng dụng phải chọn một loại bộ nhớ. Loại bộ nhớ sẽ xác định cách ứng dụng có thể sử dụng bộ nhớ, đồng thời mô tả cách lưu vào bộ nhớ đệm và các thuộc tính kết hợp của bộ nhớ. Mỗi thiết bị lại có loại bộ nhớ riêng và mỗi loại bộ nhớ lại thể hiện đặc điểm riêng.

Ứng dụng có thể sử dụng một thuật toán đơn giản để chọn loại bộ nhớ tốt nhất cho một mục đích sử dụng cụ thể. Thuật toán này chọn loại bộ nhớ đầu tiên trong mảng VkPhysicalDeviceMemoryProperties::memoryTypes đáp ứng hai tiêu chí: Loại bộ nhớ phải được phép sử dụng cho bộ đệm hoặc hình ảnh và phải có các thuộc tính tối thiểu mà ứng dụng cần đến.

Các hệ thống của thiết bị di động thường không có vùng nhớ khối xếp thực tế riêng dành cho CPU và GPU. Trên các hệ thống đó, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT không đóng vai trò quan trọng như trên các hệ thống có GPU riêng biệt với bộ nhớ riêng. Ứng dụng không nên giả định rằng thuộc tính này là bắt buộc.

Nhóm các bộ mô tả theo tần số

Nếu bạn có các mối liên kết tài nguyên thay đổi theo tần số, hãy sử dụng nhiều bộ mô tả cho mỗi quy trình thay vì tái kết hợp tất cả tài nguyên cho mỗi bản vẽ. Ví dụ: bạn có thể có một bộ mô tả cho các mối liên kết ở mỗi cảnh, một bộ khác dành cho các mối liên kết theo loại vật liệu và một bộ thứ ba dành cho các mối liên kết thực thể trên mỗi lưới.

Hãy dùng hằng số tức thì đối với các thay đổi có tần số cao nhất, chẳng hạn như các thay đổi được thực thi qua mỗi lệnh gọi vẽ.