การใช้งาน Vulkan

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

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

เพื่อให้ใช้งาน Vulkan ได้สำเร็จ อุปกรณ์จะต้องมี:

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

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

วัลแคนโหลดเดอร์

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

NDK รวมไลบรารี่ 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() อื่นๆ ทั้งหมดได้โดยการเรียก vkGetInstanceProcAddr() ของโครงสร้าง hw_device_t

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

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

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

กรณีการใช้งานสำหรับเลเยอร์ประกอบด้วย:

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

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

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

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

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

ตารางต่อไปนี้แสดงเวอร์ชัน Vulkan API สำหรับ Android หลายรุ่น
เวอร์ชันแอนดรอยด์ เวอร์ชั่นวัลแคน
แอนดรอยด์ 13 วัลแคน 1.3
แอนดรอยด์ 9 วัลแคน 1.1
แอนดรอยด์ 7 วัลแคน 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 คือ:

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

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

การเลือกการสนับสนุนวัลแคน

อุปกรณ์ 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 เท่านั้นและจะไม่เปิดเผยต่อแอป

ธงการใช้งานของ Granloc

การใช้งาน 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 หรือแฟล็กการใช้งาน Granloc แบบขยาย

ภาพที่สนับสนุนโดย Granloc

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 ที่แอปจัดเตรียมไว้ให้ (อย่างไรก็ตาม ทั้งวัตถุสัญญาณและรั้วเป็นตัวเลือกในการเรียกนี้) ผู้ขับขี่อาจใช้โอกาสนี้ในการรับรู้และจัดการกับการเปลี่ยนแปลงภายนอกใดๆ ในสถานะบัฟเฟอร์ของ Gralloc ไดรเวอร์จำนวนมากไม่จำเป็นต้องทำอะไรที่นี่ การเรียกนี้ทำให้ VkSemaphore และ VkFence อยู่ในสถานะรอดำเนินการเหมือนกับที่ส่งสัญญาณโดย vkQueueSubmit ดังนั้นคิวสามารถรอที่สัญญาณและแอปสามารถรอที่รั้วได้

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

  • Bits 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 ใดๆ ที่ - ตามแฟล็กคุณลักษณะนี้ - อุปกรณ์ไม่ได้อ้างว่ารองรับ การทดสอบดังกล่าวมีรายงานว่าผ่านเล็กน้อย