ใช้ Vulkan

Vulkan เป็น API แบบข้ามแพลตฟอร์มที่มีค่าใช้จ่ายต่ำ สำหรับกราฟิก 3 มิติ ที่มีประสิทธิภาพสูง เช่นเดียวกับ 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

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

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

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

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

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

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

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

ตั้งแต่ Android 15 เป็นต้นไป ตัวโหลดจะรองรับ APEX เพื่อ โหลดไดรเวอร์ Vulkan ตั้งค่า ro.vulkan.apex เป็นชื่อของ Vulkan APEX เพื่อโหลด Vulkan จาก APEX

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

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

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

กรณีการใช้งานเลเยอร์มีดังนี้

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

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

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

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

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

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

ภาพรวมฟังก์ชันการทำงานของ Vulkan 1.3

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

ฟีเจอร์ที่สำคัญที่สุดของ Vulkan 1.3 สำหรับ Android มีดังนี้

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

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

ภาพรวมฟังก์ชันการทำงานของ Vulkan 1.2

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

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

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

เลือกการรองรับ Vulkan

อุปกรณ์ 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

โปรไฟล์พื้นฐานของ Android (ABP)

เราขอแนะนำให้อุปกรณ์ Android ทั้งหมดเป็นไปตามโปรไฟล์ Android Baseline 2022 ล่าสุดตามที่ระบุไว้ในคู่มือโปรไฟล์ Android Baseline

อุปกรณ์ที่รองรับ Android 14 ขึ้นไปและ Vulkan API ต้อง มีฟังก์ชันการทำงานทั้งหมดที่กำหนดไว้ใน โปรไฟล์ Android Baseline 2021 รายการฟังก์ชันการทำงานที่จำเป็นทั้งหมดระบุไว้ในไฟล์โปรไฟล์ Vulkan json แต่ฟังก์ชันการทำงานที่จำเป็น ที่สำคัญมีดังนี้

  • พื้นผิวที่บีบอัดผ่าน ASTC และ ETC
  • Color Space ที่เปลี่ยนแปลงได้ผ่าน VK_EXT_swapchain_colorspace
  • การแรเงาตัวอย่างและการประมาณค่าแบบหลายตัวอย่างผ่าน sampleRateShading

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

ใน libvulkan.so ไดรเวอร์จะใช้ส่วนขยายการผสานรวมระบบหน้าต่าง (WSI) ต่อไปนี้

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties, implemented for Vulkan 1.1 in Android 10 only
  • 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;

เมื่อสร้างรูปภาพที่ Gralloc สนับสนุน 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 และนำเข้าฟันดาบดั้งเดิมที่ส่งสัญญาณภายนอกไปยังทั้งออบเจ็กต์ VkSemaphore และออบเจ็กต์ VkFence ที่มีอยู่

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

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

ออบเจ็กต์ทั้ง 2 จะได้รับสัญญาณเมื่อรั้วเนทีฟพื้นฐานส่งสัญญาณ หากรั้วเนทีฟส่งสัญญาณแล้ว ตัวแปรซีมาฟอร์จะอยู่ในสถานะส่งสัญญาณเมื่อฟังก์ชันนี้แสดงผล ไดรเวอร์จะเป็นเจ้าของตัวอธิบายไฟล์รั้ว และปิดตัวอธิบายไฟล์รั้วเมื่อไม่จำเป็นต้องใช้แล้ว ไดรเวอร์ ต้องทำเช่นนั้นแม้ว่าจะไม่มีออบเจ็กต์ Semaphore หรือ 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 แทนที่จะเป็นตัวอธิบายไฟล์รั้วดั้งเดิมจริง ซึ่งบ่งชี้ว่า ไม่มีอะไรให้รอ ผู้เรียกเป็นเจ้าของและปิดตัวอธิบายไฟล์ ที่ส่งคืนใน *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 ที่รองรับ

แฟล็กฟีเจอร์ Vulkan

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

วันที่ในรูปแบบ YYYY-MM-DD จะได้รับการเข้ารหัสเป็นจำนวนเต็ม 32 บิตดังนี้

  • บิต 0-15 จัดเก็บปี
  • บิตที่ 16-23 จะจัดเก็บเดือน
  • บิต 24-31 จัดเก็บวัน

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

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

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

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

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