ปรับใช้วัลแคน

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)

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

platform/frameworks/native/vulkan 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() อื่นๆ ทั้งหมดได้โดยการเรียก 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 เลเยอร์การตรวจสอบที่ดูแลโดย Khronos นั้นโฮสต์อยู่ใน Vulkan Validation Layers

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

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

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

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

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

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

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 การเปลี่ยนแปลงทั้งหมดที่ทำกับ core 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 ได้

รองรับเวอร์ชันวัลแคน

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

  • พื้นผิวที่ถูกบีบอัดผ่าน ASTC และ ETC
  • ปริภูมิสีที่เปลี่ยนแปลงได้ผ่าน VK_EXT_swapchain_colorspace
  • การแรเงาตัวอย่างและการแก้ไขหลายตัวอย่างผ่าน sampleRateShading

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

ใน libvulkan.so ไดรเวอร์ใช้ส่วนขยาย window system integrated (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;

เมื่อสร้างอิมเมจที่ได้รับการสนับสนุนจาก 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 ในโมดูล 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 เก็บปี
  • บิต 16-23 เก็บเดือน
  • Bits 24-31 เก็บทั้งวัน

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

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

ค่า 0x07E60301 ตรงกับวันที่ 03-03-2022 ซึ่งเป็นวันที่ที่เกี่ยวข้องกับการทดสอบ 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 ใดๆ ที่อุปกรณ์ไม่ได้อ้างสิทธิ์ในการรองรับ ตามแฟล็กฟีเจอร์นี้ การทดสอบดังกล่าวได้รับการรายงานว่าผ่านเล็กน้อย