Migracja skryptów do interfejsu Vulkan

W przypadku zadań, w których idealne są obliczenia za pomocą GPU, migracja skryptów RenderScript do interfejsu Vulkan daje aplikacji bardziej bezpośrednią kontrolę nad sprzętem GPU i może zwiększyć wydajność w porównaniu z innymi interfejsami API.

Poniżej znajdziesz ogólny opis, który pomoże Ci zastępować skrypty RenderScript za pomocą shaderów obliczeniowych Vulkan.

Inicjacja interfejsu Vulkan

Zamiast tworzyć obiekt kontekstu RenderScript w języku Kotlin lub Java, wykonaj te czynności, aby utworzyć kontekst interfejsu Vulkan za pomocą pakietu NDK.

  1. utworzyć instancję Vulkan;

  2. Wybierz urządzenie fizyczne z interfejsem Vulkan, które obsługuje kolejkę obliczeniową.

  3. Utworzyć urządzenie logiczne z interfejsem Vulkan i pobrać kolejkę obliczeniową.

Opcjonalnie możesz skonfigurować warstwy walidacji interfejsu Vulkan na Androidzie, aby przyspieszyć tworzenie aplikacji Vulkan.

Przykładowa aplikacja pokazuje, jak zainicjować kontekst interfejsu Vulkan w narzędziu VulkanContext.h. Więcej informacji znajdziesz w sekcjach Zdarzenie inicjujące oraz Urządzenia i kolejki w specyfikacji interfejsu Vulkan.

Przydziały platformy Vulkan

Alokację RenderScript można przenieść do obrazu pamięci Vulkan lub bufora pamięci Vulkan. Aby uzyskać lepszą wydajność w przypadku obrazów tylko do odczytu, użyj obrazu próbkowanego w ramach operacji pobierania jako zestawu próbek obrazów lub jako osobne wiązania próbnika i spróbkowanego obrazu.

Zasoby Vulkan są przydzielane w obrębie platformy Vulkan. Aby uniknąć nadmiernego kopiowania pamięci podczas interakcji z innymi komponentami Androida, rozważ użycie rozszerzenia VK_ANDROID_external_memory_android_hardware_buffer do zaimportowania Androida AHardwareBuffer do interfejsu Vulkan. To rozszerzenie jest dostępne na wszystkich urządzeniach z Androidem obsługujących interfejs Vulkan 1.1. Więcej informacji: FEATURE_VULKAN_HARDWARE_VERSION.

Ta przykładowa aplikacja pokazuje, jak tworzyć zasoby Vulkan w zadaniu VulkanResources.h. Więcej informacji znajdziesz w sekcjach na temat tworzenia zasobów i deskryptorów zasobów specyfikacji interfejsu Vulkan.

Przejście na cieniowanie obliczeniowe Vulkan

Skrypty RenderScript musisz przekonwertować na cieniowania oparte na platformie Vulkan. W zależności od wykorzystania globalnych skryptów RenderScript może być też konieczne dostosowanie kodu.

Napisz program do cieniowania interfejsu Vulkan Compute

Program do cieniowania interfejsu Vulkan Compute Engine jest zwykle napisany w języku OpenGL Shading Language (GLSL), a następnie kompilowany do formatu Standard Portable Intermediate Representation-V (SPIR-V).

Szczegółowe informacje i instrukcje dotyczące integrowania programów do cieniowania z aplikacją znajdziesz w artykule na temat kompilacji programu do cieniowania Vulkan na Androidzie.

Dostosowanie globalnych skryptów

Na podstawie charakterystyki globalnych skryptów zalecamy korzystanie ze stałych specjalizacji, stałych wypychania lub jednolitych obiektów bufora w przypadku globalnych globalnych działań, które nie są modyfikowane w cieniu,:

  • Stałe specjalizacji: zalecane w przypadku globalnych globalnych skryptów, które są w większości spójne we wszystkich wywołaniach jądra. Zmiana wartości stałych specjalizacji będzie wymagać odtworzenia potoku obliczeniowego.
  • Stałe push: zalecane w przypadku często zmienianych globalnych skryptów o rozmiarach mniejszych niż maxPushConstantsSize (gwarantowane minimum: 128 bajtów).
  • Jednolity bufor: zalecany w przypadku często zmienianych globalnych globalnych skryptów o rozmiarach większych niż wartość stałej push.

W przypadku globalnych zmian w obrębie programu do cieniowania możesz użyć obrazu pamięci masowej Vulkan lub bufora pamięci Vulkan.

Obliczenia

Musisz utworzyć potok obliczeniowy Vulkan, aby procesor graficzny wykonywał Twój program do cieniowania.

Tworzenie potoku obliczeniowego Vulkan

Plik ComputePipeline.h w przykładowej aplikacji pokazuje, jak utworzyć potok obliczeniowy Vulkan.

Aby użyć skompilowanego programu do cieniowania SPIR-V w interfejsie Vulkan, utwórz potok obliczeniowy Vulkan w następujący sposób:

  1. utworzyć moduł cieniowania za pomocą skompilowanego programu do cieniowania SPIR-V,
  2. Utwórz układ zestawu deskryptorów, który określa powiązania zasobów (więcej informacji znajdziesz w sekcji Przydziały).
  3. Utwórz zestaw deskryptorów na podstawie układu zestawu deskryptorów.
  4. Utwórz układ potoku na podstawie układu zestawu deskryptorów.
  5. Utwórz potok obliczeniowy z modułem cieniowania i układem potoku.

Więcej informacji znajdziesz w sekcji Potoki Compute w specyfikacji interfejsu Vulkan.

Rozpoczynanie obliczeń

Aby rozpocząć obliczenia za pomocą potoku obliczeniowego:

  1. Zaktualizuj zestaw deskryptorów za pomocą zasobów Vulkan.
  2. Utwórz bufor poleceń interfejsu Vulkan i zarejestruj te polecenia:
    1. Wiązanie potoku i zestawu deskryptorów.
    2. Wysyłanie grup roboczych obliczeniowych.
  3. Prześlij bufor poleceń do kolejki obliczeniowej.
  4. Poczekaj na kolejkę lub opcjonalnie zwróć ogrodzenie synchronizacji.

Aby połączyć kilka jąderów ze sobą (na przykład przenieść kody przy użyciu ScriptGroup), zapisz je w pojedynczym buforze poleceń i zsynchronizuj z barierami pamięci.

Przykładowa aplikacja demonstruje 2 zadania obliczeniowe:

  • Rotacja HUE: proste zadanie obliczeniowe z pojedynczym cieniem. Przykładowy kod znajdziesz w sekcji ImageProcessor::rotateHue.
  • Rozmycie: bardziej złożone zadanie obliczeniowe, które sekwencyjnie wykonuje 2 shadery obliczeniowe. Przykładowy kod znajdziesz na ImageProcessor::blur.

Więcej informacji o buforach poleceń i barierach pamięci znajdziesz w specyfikacjach interfejsu Vulkan: Bufory poleceń i Bufory pamięci.