การใช้งาน Vulkan

Vulkan เป็น API ข้ามแพลตฟอร์มที่มีค่าใช้จ่ายต่ำสำหรับกราฟิก 3D ประสิทธิภาพสูง เช่นเดียวกับ OpenGL ES (GLES) Vulkan มีเครื่องมือสำหรับสร้างกราฟิกคุณภาพสูงแบบเรียลไทม์ในแอป ข้อดีของการใช้ Vulkan ได้แก่ การลดโอเวอร์เฮดของ CPU และรองรับภาษา SPIR-V Binary Intermediate

ในการใช้งาน Vulkan ให้สำเร็จ อุปกรณ์จะต้องประกอบด้วย:

  • ตัวโหลด Vulkan ให้บริการโดย Android
  • ไดรเวอร์ Vulkan ที่จัดเตรียมโดย SoC เช่น GPU IHV ที่ใช้ Vulkan API เพื่อรองรับการทำงานของ Vulkan อุปกรณ์ Android ต้องใช้ฮาร์ดแวร์ GPU ที่รองรับ Vulkan และไดรเวอร์ที่เกี่ยวข้อง GPU ต้องรองรับ GLES 3.1 ขึ้นไปด้วย ปรึกษาผู้จำหน่าย SoC ของคุณเพื่อขอการสนับสนุนไดรเวอร์

หากอุปกรณ์มีไดรเวอร์ Vulkan อุปกรณ์จะต้องประกาศคุณสมบัติของระบบ FEATURE_VULKAN_HARDWARE_LEVEL และ FEATURE_VULKAN_HARDWARE_VERSION โดยมีเวอร์ชันที่สะท้อนถึงความสามารถของอุปกรณ์ได้อย่างแม่นยำ ซึ่งช่วยให้มั่นใจได้ว่าอุปกรณ์เป็นไปตามข้อกำหนด ความเข้ากันได้ของเอกสาร (CDD)

ตัวโหลดวัลแคน

Vulkan loader platform/frameworks/native/vulkan เป็นอินเทอร์เฟซหลักระหว่างแอพ Vulkan และไดรเวอร์ Vulkan ของอุปกรณ์ ตัวโหลด Vulkan ได้รับการติดตั้งที่ /system/lib[64]/libvulkan.so ตัวโหลดมีจุดเข้าใช้งาน Vulkan API หลัก จุดเข้าใช้งานของส่วนขยายที่ Android CDD ต้องการ และส่วนขยายทางเลือกเพิ่มเติมอีกมากมาย ส่วนขยาย Window System Integration (WSI) ถูกส่งออกโดยตัวโหลดและใช้งานเป็นหลักในตัวโหลดมากกว่าในไดรเวอร์ ตัวโหลดยังรองรับการแจงนับและการโหลดเลเยอร์ที่สามารถเปิดเผยส่วนขยายเพิ่มเติมและสกัดกั้นการเรียก API หลักระหว่างทางไปยังไดรเวอร์

NDK มีไลบรารี stub libvulkan.so สำหรับการเชื่อมโยง ไลบรารีส่งออกสัญลักษณ์เดียวกับตัวโหลด แอปเรียกใช้ฟังก์ชันที่ส่งออกจากไลบรารี libvulkan.so จริงเพื่อป้อนฟังก์ชันแทรมโพลีนในตัวโหลด ซึ่งจะส่งไปยังเลเยอร์หรือไดรเวอร์ที่เหมาะสมตามอาร์กิวเมนต์แรก การ vkGet*ProcAddr() จะส่งกลับตัวชี้ฟังก์ชันที่แทรมโพลีนส่งไป (นั่นคือเรียกโดยตรงไปยังรหัส API หลัก) การโทรผ่านพอยน์เตอร์ของฟังก์ชัน แทนที่จะใช้สัญลักษณ์ที่ส่งออก จะมีประสิทธิภาพมากกว่าเมื่อข้ามแทรมโพลีนและปล่อย

การนับและการโหลดไดรเวอร์

เมื่อสร้างอิมเมจระบบ Android คาดหวังให้ระบบรู้ว่า GPU ตัวใดที่พร้อมใช้งาน ตัวโหลดใช้กลไก HAL ที่มีอยู่ใน hardware.h เพื่อค้นหาและโหลดไดรเวอร์ เส้นทางที่ต้องการสำหรับไดรเวอร์ Vulkan รุ่น 32 บิตและ 64 บิตคือ:

/vendor/lib/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib/hw/vulkan.<ro.product.platform>.so
/vendor/lib64/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib64/hw/vulkan.<ro.product.platform>.so

ใน Android 7.0 ขึ้นไป อนุพันธ์ของ Vulkan hw_module_t ล้อมโครงสร้าง hw_module_t ตัวเดียว รองรับเพียงหนึ่งไดรเวอร์และสตริงคงที่ HWVULKAN_DEVICE_0 ถูกส่งผ่านไปยัง open()

อนุพันธ์ของ Vulkan hw_device_t สอดคล้องกับไดรเวอร์เดียวที่สามารถรองรับอุปกรณ์จริงได้หลายเครื่อง โครงสร้าง hw_device_t สามารถขยายเพื่อส่งออก vkGetGlobalExtensionProperties() , vkCreateInstance() และ vkGetInstanceProcAddr() ตัวโหลดสามารถค้นหา VkInstance() , VkPhysicalDevice() และ vkGetDeviceProcAddr() อื่นๆ ทั้งหมดได้โดยการเรียก hw_device_t vkGetInstanceProcAddr() ของโครงสร้าง hw_device_t

การค้นพบและการโหลดเลเยอร์

ตัวโหลด Vulkan รองรับการแจงนับและการโหลดเลเยอร์ที่สามารถเปิดเผยส่วนขยายเพิ่มเติมและสกัดกั้นการเรียก API หลักระหว่างทางไปยังไดรเวอร์ Android ไม่มีเลเยอร์บนอิมเมจระบบ อย่างไรก็ตาม แอปอาจมีเลเยอร์ใน APK

เมื่อใช้เลเยอร์ โปรดทราบว่ารูปแบบและนโยบายด้านความปลอดภัยของ Android แตกต่างจากแพลตฟอร์มอื่นๆ อย่างมาก โดยเฉพาะอย่างยิ่ง Android ไม่อนุญาตให้โหลดโค้ดภายนอกเข้าสู่กระบวนการที่ไม่สามารถแก้ไขข้อบกพร่องได้บนอุปกรณ์ที่ใช้งานจริง (ไม่ได้รูท) และไม่อนุญาตให้โค้ดภายนอกตรวจสอบหรือควบคุมหน่วยความจำ สถานะ และอื่นๆ ของกระบวนการ ซึ่งรวมถึงข้อห้ามในการบันทึกคอร์ดัมพ์ การติดตาม API และอื่นๆ ลงในดิสก์สำหรับการตรวจสอบในภายหลัง มีเพียงเลเยอร์ที่ส่งโดยเป็นส่วนหนึ่งของแอปที่ไม่สามารถแก้ไขข้อบกพร่องได้เท่านั้นที่เปิดใช้งานในอุปกรณ์ที่ใช้งานจริง และไดรเวอร์ต้องไม่มีฟังก์ชันที่ละเมิดนโยบายเหล่านี้

กรณีการใช้งานสำหรับเลเยอร์รวมถึง:

  • เลเยอร์เวลาในการพัฒนา — ไม่ควรติดตั้งเลเยอร์การตรวจสอบและชิมสำหรับเครื่องมือติดตาม/สร้างโปรไฟล์/แก้จุดบกพร่องบนอิมเมจระบบของอุปกรณ์ที่ใช้งานจริง เลเยอร์การตรวจสอบความถูกต้องและชิมสำหรับเครื่องมือติดตาม/สร้างโปรไฟล์/แก้จุดบกพร่องควรอัปเดตได้โดยไม่ต้องใช้อิมเมจระบบ นักพัฒนาที่ต้องการใช้เลเยอร์ใดเลเยอร์หนึ่งเหล่านี้ในระหว่างการพัฒนาสามารถแก้ไขแพ็คเกจของแอปได้ เช่น โดยการเพิ่มไฟล์ลงในไดเร็กทอรีไลบรารีดั้งเดิม วิศวกร IHV และ OEM ที่ต้องการวินิจฉัยความล้มเหลวในการจัดส่งแอปที่ไม่สามารถแก้ไขได้ จะถือว่ามีสิทธิ์เข้าถึงบิวด์ที่ไม่ได้ใช้งานจริง (รูท) ของอิมเมจระบบ เว้นแต่ว่าแอปเหล่านั้นจะแก้ไขจุดบกพร่องได้ สำหรับข้อมูลเพิ่มเติม โปรดดู ที่เลเยอร์การตรวจสอบความถูกต้องของ Vulkan บน Android
  • เลเยอร์ยูทิลิตี้ — เลเยอร์ เหล่านี้เปิดเผยส่วนขยาย เช่น เลเยอร์ที่ใช้ตัวจัดการหน่วยความจำสำหรับหน่วยความจำของอุปกรณ์ นักพัฒนาเลือกเลเยอร์และเวอร์ชันของเลเยอร์เหล่านั้นเพื่อใช้ในแอปของตน แอปต่างๆ ที่ใช้เลเยอร์เดียวกันอาจยังคงใช้เวอร์ชันต่างๆ กัน นักพัฒนาซอฟต์แวร์เลือกเลเยอร์เหล่านี้ที่จะจัดส่งในแพ็คเกจแอป
  • เลเยอร์ที่ แทรก (โดยนัย) — รวมถึงเลเยอร์ต่างๆ เช่น อัตราเฟรม เครือข่ายโซเชียล และโอเวอร์เลย์ตัวเปิดเกมที่ผู้ใช้หรือแอปอื่นๆ ให้มาโดยไม่ได้รับความรู้หรือความยินยอมจากแอป สิ่งเหล่านี้ละเมิดนโยบายความปลอดภัยของ Android และไม่รองรับ

สำหรับแอปที่ไม่สามารถแก้ไขข้อบกพร่องได้ ตัวโหลดจะค้นหาเฉพาะเลเยอร์ในไดเรกทอรีไลบรารีดั้งเดิมของแอป และพยายามโหลดไลบรารีใดๆ ที่มีชื่อตรงกับรูปแบบเฉพาะ (เช่น libVKLayer_foo.so )

สำหรับแอปที่แก้ไขข้อบกพร่องได้ ตัวโหลดจะค้นหาเลเยอร์ใน /data/local/debug/vulkan และพยายามโหลดไลบรารีที่ตรงกับรูปแบบเฉพาะ

Android ช่วยให้สามารถพอร์ตเลเยอร์ด้วยการเปลี่ยนแปลงสภาพแวดล้อมของบิลด์ระหว่าง Android และแพลตฟอร์มอื่นๆ สำหรับรายละเอียดเกี่ยวกับอินเทอร์เฟซระหว่างเลเยอร์และตัวโหลด โปรดดู สถาปัตยกรรมของ Vulkan Loader Interfaces เลเยอร์การตรวจสอบความถูกต้องที่ดูแลโดย Khronos นั้นโฮสต์ใน Vulkan Validation Layers

เวอร์ชันและความสามารถของ Vulkan API

ตารางต่อไปนี้แสดงรายการเวอร์ชัน Vulkan API สำหรับ Android หลายรุ่น
เวอร์ชั่น Android เวอร์ชั่นวัลแคน
Android 13 วัลแคน 1.3
Android 9 วัลแคน 1.1
Android 7 วัลแคน 1.0

ภาพรวมฟังก์ชัน Vulkan 1.3

Vulkan 1.3 กำหนดส่วนขยายที่เป็นตัวเลือกก่อนหน้านี้จำนวนหนึ่งในฟังก์ชันหลักของ Vulkan ฟังก์ชันการทำงานส่วนใหญ่นี้มีจุดประสงค์เพื่อเพิ่มการควบคุมและความละเอียดของอินเทอร์เฟซการเขียนโปรแกรม Vulkan อินสแตนซ์การส่งผ่านการแสดงผลแบบ Single-pass ไม่ต้องการวัตถุส่งผ่านหรือเฟรมบัฟเฟอร์อีกต่อไป จำนวนทั้งหมดของอ็อบเจ็กต์สถานะไปป์ไลน์สามารถลดลงได้ และการซิงโครไนซ์ภายใน API จะได้รับการปรับปรุงใหม่ Vulkan 1.3 มีข้อกำหนดด้านฮาร์ดแวร์เหมือนกับ Vulkan 1.2, 1.1 และ 1.0 โดยส่วนใหญ่จะนำไปใช้ในไดรเวอร์กราฟิกเฉพาะ SoC ไม่ใช่ในเฟรมเวิร์ก

คุณสมบัติที่สำคัญที่สุดของ Vulkan 1.3 สำหรับ Android คือ:

  • รองรับอินสแตนซ์พาสเรนเดอร์พาสเดียว
  • รองรับการยกเลิกการร้องขอ shader ทันที
  • ความละเอียดที่ละเอียดยิ่งขึ้นเกี่ยวกับการสร้าง การแชร์ และการควบคุมไปป์ไลน์

Vulkan 1.3 ยังประกอบด้วยคุณสมบัติที่มีขนาดเล็กกว่าหลายรายการและการปรับปรุงความสามารถในการใช้งาน API การเปลี่ยนแปลงทั้งหมดที่ทำกับ Vulkan API หลักที่มีการแก้ไขเล็กน้อย 1.3 สามารถดูได้ที่ Core Revisions (Vulkan 1.3)

ภาพรวมฟังก์ชัน Vulkan 1.2

Vulkan 1.2 เพิ่มคุณสมบัติและส่วนขยายจำนวนหนึ่งที่ทำให้พื้นผิว API ง่ายขึ้น ซึ่งรวมถึง โมเดลหน่วยความจำ แบบรวมและข้อมูลเพิ่มเติมที่สามารถสอบถามจากโปรแกรมควบคุมอุปกรณ์ Vulkan 1.2 มีข้อกำหนดด้านฮาร์ดแวร์เหมือนกับ Vulkan 1.0 และ 1.1; การใช้งานทั้งหมดอยู่ในไดรเวอร์กราฟิกเฉพาะ SoC ไม่ใช่เฟรมเวิร์ก

ฟีเจอร์ Vulkan 1.2 ที่สำคัญที่สุดสำหรับ Android คือการรองรับพื้นที่เก็บข้อมูล 8 บิต

Vulkan 1.2 ยังประกอบด้วยคุณสมบัติที่เล็กกว่าและการปรับปรุงความสามารถในการใช้งาน API การเปลี่ยนแปลงทั้งหมดที่ทำกับ Vulkan API หลักที่มีการแก้ไขเล็กน้อย 1.2 สามารถดูได้ที่ Core Revisions (Vulkan 1.2)

ภาพรวมฟังก์ชัน Vulkan 1.1

Vulkan 1.1 มีการรองรับการทำงานร่วมกันของหน่วยความจำ/การซิงโครไนซ์ ซึ่งช่วยให้ OEM สามารถรองรับ Vulkan 1.1 บนอุปกรณ์ได้ นอกจากนี้ การทำงานร่วมกันของหน่วยความจำ/การซิงโครไนซ์ช่วยให้นักพัฒนาตรวจสอบว่า Vulkan 1.1 ได้รับการสนับสนุนบนอุปกรณ์หรือไม่ และใช้งานได้อย่างมีประสิทธิภาพเมื่อถึงเวลานั้น Vulkan 1.1 มีข้อกำหนดฮาร์ดแวร์เหมือนกับ Vulkan 1.0 แต่การใช้งานส่วนใหญ่อยู่ในไดรเวอร์กราฟิกเฉพาะ SOC ไม่ใช่ในเฟรมเวิร์ก

คุณสมบัติที่สำคัญที่สุดของ Vulkan 1.1 สำหรับ Android คือ:

  • รองรับการนำเข้าและส่งออกบัฟเฟอร์หน่วยความจำและวัตถุซิงโครไนซ์จากภายนอก Vulkan (สำหรับการทำงานร่วมกับกล้อง ตัวแปลงสัญญาณ และ GLES)
  • รองรับรูปแบบ YCbCr

Vulkan 1.1 ยังมีฟีเจอร์ขนาดเล็กกว่าหลายรายการและการปรับปรุงความสามารถในการใช้งาน API การเปลี่ยนแปลงทั้งหมดที่ทำกับ Vulkan API หลักที่มีการแก้ไขเล็กน้อย 1.1 สามารถดูได้ที่ Core Revisions (Vulkan 1.1)

การเลือก Vulkan Support

อุปกรณ์ Android ควรสนับสนุนชุดคุณลักษณะ Vulkan ที่ล้ำหน้าที่สุดที่มี หากว่ารองรับ ABI แบบ 64 บิตและไม่ใช่หน่วยความจำเหลือน้อย

อุปกรณ์ที่เปิดตัวด้วย Android 13 ขึ้นไปควรรองรับ Vulkan 1.3

อุปกรณ์ที่เปิดตัวผ่าน Android 10 ควรรองรับ Vulkan 1.1

อุปกรณ์อื่นๆ สามารถเลือกสนับสนุน Vulkan 1.3, 1.2 และ 1.1 ได้

รองรับเวอร์ชัน Vulkan

อุปกรณ์ Android รองรับเวอร์ชัน Vulkan หากตรงตามเงื่อนไขต่อไปนี้:

  1. เพิ่มไดรเวอร์ Vulkan ที่สนับสนุนเวอร์ชัน Vulkan ที่น่าสนใจ (ต้องเป็นหนึ่งใน Vulkan เวอร์ชัน 1.3, 1.1 หรือ 1.0) ควบคู่ไปกับ ข้อกำหนด CDD เพิ่มเติมของเวอร์ชัน Android หรืออัปเดตไดรเวอร์ Vulkan ที่มีอยู่ของหมายเลขเวอร์ชัน vulkan ที่ต่ำกว่า
  2. สำหรับ Vulkan 1.3 หรือ 1.1 ตรวจสอบให้แน่ใจว่าคุณลักษณะของระบบที่ส่งคืนโดยตัวจัดการแพ็คเกจคืนค่า true สำหรับเวอร์ชัน vulkan ที่ถูกต้อง
    • สำหรับ Vulkan 1.3 คุณลักษณะคือ PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000)
    • สำหรับ Vulkan 1.1 คุณลักษณะคือ PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000)
    ตัวจัดการแพ็คเกจจะคืนค่า true สำหรับ Vulkan 1.3 และ Vulkan 1.1 โดยเพิ่มกฎดังที่แสดงต่อไปนี้ ลงในไฟล์ device.mk ที่เหมาะสม
    • เพิ่มข้อมูลต่อไปนี้สำหรับ Vulkan 1.3:
      PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.vulkan.version-1_3.xml:
      $(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml
      
    • เพิ่มข้อมูลต่อไปนี้สำหรับ Vulkan 1.1:
      PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.vulkan.version-1_1.xml:
      $(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml
      

การรวมระบบหน้าต่าง (WSI)

ใน libvulkan.so ไดรเวอร์ใช้ส่วนขยาย Window System Integration (WSI) ต่อไปนี้:

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties ใช้สำหรับ Vulkan 1.1 ใน Android 10 เท่านั้น
  • VK_GOOGLE_display_timing ใช้กับ Vulkan เวอร์ชันใดก็ได้ใน Android 10

ออบเจ็กต์ VkSurfaceKHR และ VkSwapchainKHR และการโต้ตอบทั้งหมดกับ ANativeWindow ได้รับการจัดการโดยแพลตฟอร์มและจะไม่เปิดเผยต่อไดรเวอร์ การใช้งาน WSI อาศัยส่วนขยาย VK_ANDROID_native_buffer ซึ่งต้องได้รับการสนับสนุนโดยไดรเวอร์ ส่วนขยายนี้ใช้โดยการติดตั้ง WSI เท่านั้นและจะไม่แสดงต่อแอป

แฟล็กการใช้งาน Gralloc

การใช้งาน Vulkan อาจต้องใช้บัฟเฟอร์ swapchain เพื่อจัดสรรด้วยแฟล็กการใช้งาน Gralloc ส่วนตัวที่กำหนดการใช้งาน เมื่อสร้าง swapchain Android จะขอให้ไดรเวอร์แปลรูปแบบที่ร้องขอและแฟล็กการใช้รูปภาพเป็นแฟล็กการใช้งาน Gralloc โดยการโทร:

typedef enum VkSwapchainImageUsageFlagBitsANDROID {
    VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID = 0x00000001,
    VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkSwapchainImageUsageFlagBitsANDROID;
typedef VkFlags VkSwapchainImageUsageFlagsANDROID;

VkResult VKAPI vkGetSwapchainGrallocUsage2ANDROID(
    VkDevice                          device,
    VkFormat                          format,
    VkImageUsageFlags                 imageUsage,
    VkSwapchainImageUsageFlagsANDROID swapchainUsage,
    uint64_t*                         grallocConsumerUsage,
    uint64_t*                         grallocProducerUsage
);

พารามิเตอร์ format และ imageUsage นำมาจากโครงสร้าง VkSwapchainCreateInfoKHR ไดรเวอร์ควรเติม *grallocConsumerUsage และ *grallocProducerUsage ด้วยแฟล็กการใช้งาน Gralloc ที่จำเป็นสำหรับรูปแบบและการใช้งาน แฟล็กการใช้งานที่ส่งคืนโดยไดรเวอร์จะถูกรวมเข้ากับแฟล็กการใช้งานที่ร้องขอโดยผู้ใช้ swapchain เมื่อจัดสรรบัฟเฟอร์

Android 7.x เรียกใช้ VkSwapchainImageUsageFlagsANDROID() เวอร์ชันก่อนหน้า ชื่อ vkGetSwapchainGrallocUsageANDROID() Android 8.0 ขึ้นไปเลิกใช้ vkGetSwapchainGrallocUsageANDROID() แต่ยังคงเรียก vkGetSwapchainGrallocUsageANDROID() หากไดรเวอร์ไม่ได้ให้ vkGetSwapchainGrallocUsage2ANDROID()

VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
    VkDevice            device,
    VkFormat            format,
    VkImageUsageFlags   imageUsage,
    int*                grallocUsage
);

vkGetSwapchainGrallocUsageANDROID() ไม่รองรับแฟล็กการใช้งาน swapchain หรือแฟล็กการใช้งาน Gralloc ที่ขยายออกไป

รูปภาพที่ได้รับการสนับสนุนจาก Gralloc

VkNativeBufferANDROID เป็นโครงสร้างส่วนขยาย vkCreateImage สำหรับการสร้างอิมเมจที่ได้รับการสนับสนุนโดยบัฟเฟอร์ Gralloc VkNativeBufferANDROID ถูกจัดเตรียมให้กับ vkCreateImage() ในสายโครงสร้าง VkImageCreateInfo การเรียก vkCreateImage() ด้วย VkNativeBufferANDROID เกิดขึ้นระหว่างการเรียก vkCreateSwapchainKHR การใช้งาน WSI จะจัดสรรจำนวนบัฟเฟอร์ดั้งเดิมที่ร้องขอสำหรับ swapchain จากนั้นสร้าง VkImage สำหรับแต่ละอัน:

typedef struct {
    VkStructureType             sType; // must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID
    const void*                 pNext;

    // Buffer handle and stride returned from gralloc alloc()
    buffer_handle_t             handle;
    int                         stride;

    // Gralloc format and usage requested when the buffer was allocated.
    int                         format;
    int                         usage;
    // Beginning in Android 8.0, the usage field above is deprecated and the
    // usage2 struct below was added. The usage field is still filled in for
    // compatibility with Android 7.0 drivers. Drivers for Android 8.0
    // should prefer the usage2 struct, especially if the
    // android.hardware.graphics.allocator HAL uses the extended usage bits.
    struct {
        uint64_t                consumer;
        uint64_t                producer;
    } usage2;
} VkNativeBufferANDROID;

เมื่อสร้างอิมเมจที่ได้รับการสนับสนุนจาก VkImageCreateInfo จะมีข้อมูลดังต่อไปนี้:

  .sType               = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
  .pNext               = the above VkNativeBufferANDROID structure
  .imageType           = VK_IMAGE_TYPE_2D
  .format              = a VkFormat matching the format requested for the gralloc buffer
  .extent              = the 2D dimensions requested for the gralloc buffer
  .mipLevels           = 1
  .arraySize           = 1
  .samples             = 1
  .tiling              = VK_IMAGE_TILING_OPTIMAL
  .usage               = VkSwapchainCreateInfoKHR::imageUsage
  .flags               = 0
  .sharingMode         = VkSwapchainCreateInfoKHR::imageSharingMode
  .queueFamilyCount    = VkSwapchainCreateInfoKHR::queueFamilyIndexCount
  .pQueueFamilyIndices = VkSwapchainCreateInfoKHR::pQueueFamilyIndices

ใน Android 8.0 ขึ้นไป แพลตฟอร์มมีโครงสร้างส่วนขยาย VkSwapchainImageCreateInfoKHR ในสายโซ่ VkImageCreateInfo ที่จัดเตรียมให้กับ vkCreateImage เมื่อต้องใช้แฟล็กการใช้ภาพ swapchain สำหรับ swapchain โครงสร้างส่วนขยายประกอบด้วยแฟล็กการใช้รูปภาพ swapchain:

typedef struct {
    VkStructureType                        sType; // must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID
    const void*                            pNext;

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

ใน Android 10 ขึ้นไป แพลตฟอร์มรองรับ VK_KHR_swapchain v70 ดังนั้นแอป Vulkan จึงสามารถสร้าง VkImage ที่สนับสนุนโดยหน่วยความจำ swapchain แอปเรียก vkCreateImage ด้วยโครงสร้าง VkImageSwapchainCreateInfoKHR ที่เชื่อมโยงกับโครงสร้าง VkImageCreateInfo จากนั้นแอปจะเรียก vkBindImageMemory2(KHR) ด้วยโครงสร้าง VkBindImageMemorySwapchainInfoKHR ที่เชื่อมโยงกับโครงสร้าง VkBindImageMemoryInfo imageIndex ที่ระบุในโครงสร้าง VkBindImageMemorySwapchainInfoKHR ต้องเป็นดัชนีรูปภาพ swapchain ที่ถูกต้อง ในขณะเดียวกัน แพลตฟอร์มมีโครงสร้างส่วนขยาย VkNativeBufferANDROID พร้อมข้อมูลบัฟเฟอร์ Gralloc ที่สอดคล้องกับสายโซ่ VkBindImageMemoryInfo ดังนั้นไดรเวอร์จึงรู้ว่าบัฟเฟอร์ Gralloc ใดที่จะผูก VkImage ด้วย

การรับภาพ

vkAcquireImageANDROID ได้มาซึ่งความเป็นเจ้าของของอิมเมจ swapchain และนำเข้ารั้วดั้งเดิมที่ส่งสัญญาณจากภายนอกไปยังทั้งอ็อบเจ็กต์ VkFence ที่มีอยู่และอ็อบเจ็กต์ VkSemaphore ที่มีอยู่:

VkResult VKAPI vkAcquireImageANDROID(
    VkDevice            device,
    VkImage             image,
    int                 nativeFenceFd,
    VkSemaphore         semaphore,
    VkFence             fence
);

vkAcquireImageANDROID() ถูกเรียกระหว่าง vkAcquireNextImageKHR เพื่อนำเข้ารั้วดั้งเดิมไปยังวัตถุ VkSemaphore และ VkFence ที่แอปจัดเตรียมไว้ (อย่างไรก็ตาม ทั้งวัตถุสัญญาณและวัตถุรั้วเป็นทางเลือกในการเรียกนี้) คนขับอาจใช้โอกาสนี้เพื่อรับรู้และจัดการการเปลี่ยนแปลงภายนอกใดๆ ต่อสถานะบัฟเฟอร์ของ Gralloc คนขับหลายคนไม่จำเป็นต้องทำอะไรที่นี่ การเรียกนี้ทำให้ VkSemaphore และ VkFence อยู่ในสถานะรอดำเนินการเหมือนกัน ราวกับว่าส่งสัญญาณโดย vkQueueSubmit ดังนั้นคิวจึงสามารถรอบนสัญญาณและแอปสามารถรอบนรั้วได้

ออบเจ็กต์ทั้งสองจะส่งสัญญาณเมื่อรั้วดั้งเดิมส่งสัญญาณ หากรั้วดั้งเดิมส่งสัญญาณแล้ว สัญญาณจะอยู่ในสถานะส่งสัญญาณเมื่อฟังก์ชันนี้กลับมา ไดรเวอร์ใช้ความเป็นเจ้าของของตัวอธิบายไฟล์ Fence และปิดตัวอธิบายไฟล์ Fence เมื่อไม่ต้องการอีกต่อไป ไดรเวอร์ต้องทำเช่นนั้นแม้ว่าจะไม่ได้จัดเตรียมวัตถุสัญญาณหรือรั้วไว้ หรือแม้แต่ vkAcquireImageANDROID ล้มเหลวและส่งคืนข้อผิดพลาด ถ้า fenceFd เป็น -1 ก็เหมือนกับว่าสัญญาณรั้วดั้งเดิมนั้นส่งสัญญาณไปแล้ว

ปล่อยภาพ

vkQueueSignalReleaseImageANDROID เตรียมภาพ swapchain สำหรับการใช้งานภายนอก สร้างรั้วดั้งเดิม และกำหนดเวลาให้รั้วดั้งเดิมส่งสัญญาณหลังจากที่สัญญาณอินพุตสัญญาณเข้าแล้ว:

VkResult VKAPI vkQueueSignalReleaseImageANDROID(
    VkQueue             queue,
    uint32_t            waitSemaphoreCount,
    const VkSemaphore*  pWaitSemaphores,
    VkImage             image,
    int*                pNativeFenceFd
);

vkQueuePresentKHR() เรียก vkQueueSignalReleaseImageANDROID() บนคิวที่ให้มา ไดรเวอร์ต้องสร้างรั้วดั้งเดิมที่ไม่ส่งสัญญาณจนกว่าสัญญาณ waitSemaphoreCount ทั้งหมดในสัญญาณ pWaitSemaphores และงานเพิ่มเติมที่จำเป็นในการเตรียม image สำหรับการนำเสนอจะเสร็จสมบูรณ์

หากสัญญาณการรอ (ถ้ามี) ส่งสัญญาณแล้ว และ queue ไม่ได้ใช้งานแล้ว ไดรเวอร์สามารถตั้งค่า *pNativeFenceFd เป็น -1 แทนตัวอธิบายไฟล์รั้วดั้งเดิมจริง ๆ ซึ่งบ่งชี้ว่าไม่มีอะไรให้รอ ผู้โทรเป็นเจ้าของและปิด file descriptor ที่ส่งคืนใน *pNativeFenceFd

ไดรเวอร์จำนวนมากสามารถละเว้นพารามิเตอร์รูปภาพได้ แต่บางตัวอาจจำเป็นต้องเตรียมโครงสร้างข้อมูลฝั่ง CPU ที่เชื่อมโยงกับบัฟเฟอร์ Gralloc เพื่อใช้งานโดยผู้บริโภครูปภาพภายนอก การเตรียมเนื้อหาบัฟเฟอร์สำหรับผู้บริโภคภายนอกควรทำแบบอะซิงโครนัสซึ่งเป็นส่วนหนึ่งของการเปลี่ยนอิมเมจเป็น VK_IMAGE_LAYOUT_PRESENT_SRC_KHR

หากอิมเมจถูกสร้างขึ้นด้วย VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID ไดรเวอร์ต้องอนุญาตให้ vkQueueSignalReleaseImageANDROID() ซ้ำ ๆ โดยไม่รบกวนการเรียก vkAcquireImageANDROID()

รองรับภาพที่เรียบร้อยที่ใช้ร่วมกัน

อุปกรณ์บางอย่างสามารถแชร์ความเป็นเจ้าของภาพเดียวระหว่างไปป์ไลน์การแสดงผลและการใช้งาน Vulkan เพื่อลดเวลาแฝง ใน Android 9 ขึ้นไป ตัวโหลดจะโฆษณาส่วนขยาย VK_KHR_shared_presentable_image ตามเงื่อนไขตามการตอบสนองของไดรเวอร์ต่อการเรียก vkGetPhysicalDeviceProperties2

หากไดรเวอร์ไม่รองรับ Vulkan 1.1 หรือส่วนขยาย VK_KHR_physical_device_properties2 ตัวโหลดจะไม่โฆษณาการสนับสนุนสำหรับรูปภาพที่แสดงได้ที่ใช้ร่วมกัน มิฉะนั้น ตัวโหลดจะสอบถามความสามารถของไดรเวอร์โดยการเรียก vkGetPhysicalDeviceProperties2() และรวมถึงโครงสร้างต่อไปนี้ในสาย VkPhysicalDeviceProperties2::pNext :

typedef struct {
    VkStructureType sType; // must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID
    const void*     pNext;
    VkBool32        sharedImage;
} VkPhysicalDevicePresentationPropertiesANDROID;

หากผู้ขับขี่สามารถแชร์ความเป็นเจ้าของรูปภาพกับระบบแสดงผลได้ ระบบจะตั้งค่าสมาชิก sharedImage เป็น VK_TRUE

การตรวจสอบความถูกต้อง

OEM สามารถทดสอบการใช้งาน Vulkan ได้โดยใช้ CTS ซึ่งรวมถึงสิ่งต่อไปนี้:

  • การทดสอบความสอดคล้องของ Khronos Vulkan ในโมดูล CtsDeqpTestCases ซึ่งรวมถึงการทดสอบ API การทำงานสำหรับ Vulkan 1.0, 1.1, 1.2 และ 1.3
  • โมดูล CtsGraphicsTestCases ซึ่งทดสอบว่าอุปกรณ์ได้รับการกำหนดค่าอย่างถูกต้องสำหรับความสามารถของ Vulkan ที่รองรับ

ธงคุณลักษณะของวัลแคน

อุปกรณ์ที่รองรับ Android 11 ขึ้นไปและรองรับ Vulkan API จะต้องแสดงแฟล็กคุณลักษณะ android.software.vulkan.deqp.level ค่าของแฟล็กคุณลักษณะนี้คือวันที่ ซึ่งเข้ารหัสเป็นค่าจำนวนเต็ม ระบุวันที่ที่เกี่ยวข้องกับการทดสอบ Vulkan dEQP ที่อุปกรณ์อ้างว่าผ่าน

วันที่ของแบบฟอร์ม YYYY-MM-DD ถูกเข้ารหัสเป็นจำนวนเต็ม 32 บิตดังนี้:

  • บิต 0-15 เก็บปี
  • Bits 16-23 เก็บเดือน
  • Bits 24-31 เก็บได้ทั้งวัน

ค่าที่อนุญาตขั้นต่ำสำหรับการตั้งค่าสถานะคุณลักษณะคือ 0x07E30301 ซึ่งตรงกับวันที่ 2019-03-01 ซึ่งเป็นวันที่ที่เกี่ยวข้องกับการทดสอบ Vulkan dEQP สำหรับ Android 10 หากการตั้งค่าสถานะคุณลักษณะเป็นค่านี้อย่างน้อย อุปกรณ์จะอ้างว่า ผ่านการทดสอบ Android 10 Vulkan dEQP ทั้งหมด

ค่า 0x07E40301 ตรงกับวันที่ 2020-03-01 ซึ่งเป็นวันที่ที่เกี่ยวข้องกับการทดสอบ Vulkan dEQP สำหรับ Android 11 หากการตั้งค่าสถานะฟีเจอร์เป็นอย่างน้อยค่านี้ อุปกรณ์อ้างว่าผ่านการทดสอบ Android 11 Vulkan dEQP ทั้งหมด

ค่า 0x07E60301 ตรงกับวันที่ 2022-03-01 ซึ่งเป็นวันที่ที่เกี่ยวข้องกับการทดสอบ Vulkan dEQP สำหรับ Android 13 หากการตั้งค่าสถานะคุณลักษณะเป็นค่านี้อย่างน้อย อุปกรณ์อ้างว่าผ่านการทดสอบ Android 13 Vulkan dEQP ทั้งหมด

อุปกรณ์ที่แสดงการตั้งค่าสถานะคุณลักษณะเฉพาะ ( เช่น 0x07E30301 , 0x07E40301 , 0x07E60301 ) อ้างว่าผ่านการทดสอบ Android Vulkan dEQP ทั้งหมดของการตั้งค่าสถานะคุณลักษณะนั้น (Android 10, Android 11, Android 13 ตามลำดับ) อุปกรณ์นี้ อาจ ผ่านการทดสอบ Vulkan dEQP จาก Android รุ่นที่ใหม่กว่า

Vulkan dEQP เป็นส่วนหนึ่งของ Android CTS จาก Android 11 คอมโพเนนต์ตัวดำเนินการทดสอบ dEQP ของ CTS จะรับรู้ถึงแฟล็กคุณลักษณะ android.software.vulkan.deqp.level และข้ามการทดสอบ Vulkan dEQP ใดๆ ก็ตาม - ตามการตั้งค่าสถานะคุณลักษณะนี้ - อุปกรณ์ไม่ได้อ้างว่าสนับสนุน การทดสอบดังกล่าวได้รับการรายงานว่าผ่านเล็กน้อย