對於最適合 GPU 運算的工作負載,將 RenderScript 指令碼遷移至 Vulkan 運算後,應用程式即可更直接地控管 GPU 硬體,且相較於其他 API,可能獲得額外效能。
以下概略說明內容,可協助您使用 Vulkan 運算著色器取代 RenderScript 指令碼。
Vulkan 初始化
請執行下列步驟,使用 NDK 建立 Vulkan 結構定義,不要在 Kotlin 或 Java 中建立 RenderScript 結構定義物件。
- 建立 Vulkan 例項。 
- 選擇支援運算佇列的 Vulkan 實體裝置。 
- 建立 Vulkan 邏輯裝置,並取得運算佇列。 
您可以選擇在 Android 上設定 Vulkan 驗證層,加快 Vulkan 應用程式的開發速度。
範例應用程式示範了如何在 VulkanContext.h 中初始化 Vulkan 情境。詳情請參閱 Vulkan 規格中的初始化和裝置與佇列章節。
Vulkan 分配
RenderScript 分配可遷移至 Vulkan 儲存空間映像檔或 Vulkan 儲存空間緩衝區。為了提高唯讀圖片的效能,請使用含有擷取作業的取樣圖片,無論是合併圖片取樣器,或有不同的取樣器和取樣圖片繫結都使用。
Vulkan 資源在 Vulkan 中配置。為避免在與其他 Android 元件互動時產生記憶體複製負擔,建議您使用 VK_ANDROID_external_memory_android_hardware_buffer 擴充功能將 Android AHardwareBuffer 匯入 Vulkan。這項擴充功能適用於所有支援 Vulkan 1.1 的 Android 裝置。如需詳細資訊,請參閱 FEATURE_VULKAN_HARDWARE_VERSION。
範例應用程式示範了如何在 VulkanResources.h 中建立 Vulkan 資源。詳情請參閱 Vulkan 規範的資源建立和資源描述元章節。
轉換為 Vulkan 運算著色器
您的 RenderScript 指令碼必須轉換為 Vulkan 運算著色器。您可能還需要根據 RenderScript 全域變數的使用情況來調整程式碼。
撰寫 Vulkan 運算著色器
Vulkan 運算著色器通常是以 OpenGL 著色語言 (GLSL) 編寫,再編譯為 Standard Portable Intermediate Representation-V (SPIR-V) 格式。
如需瞭解如何將著色器整合到應用程式中的詳細資訊和操作說明,請參閱「Android 上的 Vulkan 著色器編譯器」。
調整指令碼全域變數
根據指令碼全域變數的特性,對於未在著色器中修改的全域變數,建議您使用特殊化常數、推送常數或統一緩衝區物件:
- 特殊化常數:建議用於在不同核心叫用中大致一致的指令碼全域變數。變更特殊化常數值需要重新建立運算管線。
- 推送常數:建議用於頻繁變更且小於 maxPushConstantsSize(保證大小下限為 128 個位元組) 的指令碼全域變數。
- 統一緩衝區:建議用於頻繁變更且大於推送常數上限的指令碼全域變數。
對於在著色器內變更的全域變數,您可以使用 Vulkan 儲存空間映像檔或 Vulkan 儲存空間緩衝區。
運算作業
您必須建立 Vulkan 運算管道,才能使 GPU 執行運算著色器。
建立 Vulkan 運算管線
範例應用程式中的 ComputePipeline.h 檔案示範瞭如何建立 Vulkan 運算管道。
如要在 Vulkan 中使用經過編譯的 SPIR-V 著色器,請依下列步驟建構 Vulkan 運算管線:
- 使用經過編譯的 SPIR-V 著色器建立著色器模組。
- 建立描述元集版面配置,以指定資源繫結 (詳情請參閱配置)。
- 根據描述元集版面配置建立描述元集。
- 根據描述元集版面配置建立管線版面配置。
- 使用著色器模組和管線版面配置建立運算管線。
詳情請參閱 Vulkan 規範中的「Compute Pipelines」一節。
開始運算作業
如要開始使用運算管線進行運算,請按照下列步驟操作:
- 使用 Vulkan 資源更新描述元集。
- 建立 Vulkan 指令緩衝區,並記錄下列指令:- 繫結管線和描述元集。
- 調派運算工作群組。
 
- 將指令緩衝區提交至運算佇列。
- 在佇列中等候,或可選擇傳回同步處理圍欄。
如要鏈結多個核心 (例如使用 ScriptGroup 遷移程式碼),請將其記錄在一個指令緩衝區中,並與記憶體障礙進行同步處理。
範例應用程式示範了兩項運算工作:
- HUE 輪替:具有單一運算著色器的簡易運算工作。如需程式碼範例,請參閱 ImageProcessor::rotateHue。
- 模糊處理:較為複雜的運算工作,依序執行兩個運算著色器。如需程式碼範例,請參閱 ImageProcessor::blur。
如要進一步瞭解指令緩衝區或記憶體障礙,請參閱 Vulkan 規格中的「指令緩衝區」和「記憶體障礙」章節。
