ใช้งาน Vulkan

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

อุปกรณ์ต้องมีสิ่งต่อไปนี้จึงจะใช้ Vulkan ได้สําเร็จ

  • โปรแกรมโหลด Vulkan ที่ Android มีให้
  • โปรแกรมควบคุม Vulkan ที่ SoC เช่น IHV ของ GPU ให้มา ซึ่งใช้ Vulkan API อุปกรณ์ Android ต้องมีฮาร์ดแวร์ GPU ที่รองรับ Vulkan และไดร์เวอร์ที่เกี่ยวข้องจึงจะรองรับฟังก์ชันการทำงานของ 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 loader แล้วที่ /system/lib[64]/libvulkan.so โปรแกรมโหลดจะมีจุดแรกเข้าหลักของ Vulkan API, จุดแรกเข้าของส่วนขยายที่จําเป็นตาม CDD ของ Android และส่วนขยายเพิ่มเติมอื่นๆ อีกมากมายที่ไม่บังคับ โปรแกรมโหลดจะส่งออกส่วนขยายการผสานรวมระบบ (WSI) และนำไปใช้งานในโปรแกรมโหลดเป็นหลัก มากกว่าในไดรเวอร์ นอกจากนี้ โปรแกรมโหลดยังรองรับการระบุรายการและโหลดเลเยอร์ที่สามารถแสดงส่วนขยายเพิ่มเติมและขัดจังหวะการเรียก API หลักระหว่างทางไปยังไดรเวอร์

NDK มีไลบรารี libvulkan.so จำลองสําหรับการลิงก์ ไลบรารีจะส่งออกสัญลักษณ์เดียวกันกับตัวโหลด แอปเรียกใช้ฟังก์ชันที่ส่งออกจากไลบรารี libvulkan.so จริงเพื่อเข้าสู่ฟังก์ชันแทรมโปลีนในโปรแกรมโหลด ซึ่งจะส่งไปยังเลเยอร์หรือไดรเวอร์ที่เหมาะสมตามอาร์กิวเมนต์แรก vkGet*ProcAddr() call จะแสดงผลตัวชี้ฟังก์ชันที่ส่งผ่านไปยังแทรมโปลีน (กล่าวคือ เรียกใช้โค้ด 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 ขึ้นไป อนุพันธ์ 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

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

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

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

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

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

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

นอกจากนี้ Vulkan 1.3 ยังมีฟีเจอร์เล็กๆ น้อยๆ และการเพิ่มประสิทธิภาพการทํางานของ API อีกด้วย ดูการเปลี่ยนแปลงทั้งหมดที่ทำกับ Vulkan API หลักที่มีการแก้ไขเล็กน้อย 1.3 ได้ที่การแก้ไขหลัก (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 ได้ที่การปรับแก้หลัก (Vulkan 1.2)

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

Vulkan 1.1 รองรับการทำงานร่วมกันของหน่วยความจำ/การซิงค์ ซึ่งช่วยให้ OEM รองรับ Vulkan 1.1 ในอุปกรณ์ได้ นอกจากนี้ การทํางานร่วมกันของหน่วยความจํา/การซิงค์ยังช่วยให้นักพัฒนาแอปตรวจสอบได้ว่าอุปกรณ์รองรับ 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 ได้ที่การปรับแก้หลัก (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
  • พื้นที่สีแบบตัวแปรผ่าน VK_EXT_swapchain_colorspace
  • ตัวอย่างการแรเงาและการปักหมุดหลายตัวอย่างผ่าน sampleRateShading

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

ใน libvulkan.so โปรแกรมควบคุมจะใช้ส่วนขยายการผสานรวมระบบหน้าต่าง (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 เท่านั้นและจะไม่แสดงต่อแอป

Flag การใช้งาน Gralloc

การติดตั้งใช้งาน Vulkan อาจต้องมีการจัดสรรบัฟเฟอร์ Swapchain ด้วยธงการใช้งาน Gralloc ส่วนตัวที่กําหนดโดยการติดตั้งใช้งาน เมื่อสร้าง Swapchain Android จะขอให้ไดรเวอร์แปลงรูปแบบและ Flag การใช้งานรูปภาพที่ขอเป็น Flag การใช้งาน 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 ด้วย Flag การใช้งาน Gralloc ที่จําเป็นสําหรับรูปแบบและการใช้งาน ระบบจะรวม Flag การใช้งานที่ได้จากไดรเวอร์เข้ากับ Flag การใช้งานที่ผู้ใช้ Swapchain ขอเมื่อจัดสรรบัฟเฟอร์

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

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

vkGetSwapchainGrallocUsageANDROID() ไม่รองรับ Flag การใช้งาน Swapchain หรือ Flag การใช้งาน Gralloc แบบขยาย

รูปภาพจาก Gralloc

VkNativeBufferANDROID คือโครงสร้างส่วนขยาย vkCreateImage สำหรับการสร้างรูปภาพที่สำรองข้อมูลโดยบัฟเฟอร์ Gralloc VkNativeBufferANDROID มีการระบุให้กับ vkCreateImage() ในเชนโครงสร้าง VkImageCreateInfo การโทรหา vkCreateImage() จาก VkNativeBufferANDROID เกิดขึ้นขณะโทรหา vkCreateSwapchainKHR การใช้งาน WSI จะจัดสรรจำนวนบัฟเฟอร์เนทีฟที่ขอสำหรับสวิตช์เชน จากนั้นจะสร้าง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 เมื่อต้องใช้ Flag การใช้งานรูปภาพ Swapchain สำหรับ Swapchain โครงสร้างส่วนขยายมี Flag การใช้งานรูปภาพ 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 เพื่อให้ไดรเวอร์ทราบว่าต้องเชื่อมโยง VkImage กับบัฟเฟอร์ Gralloc รายการใด

รับรูปภาพ

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 เพื่อให้คิวรอที่เซมาโฟร์และแอปรอที่รั้วได้

ทั้ง 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 semaphore ทั้งหมดใน 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 ต้องแสดง Flag ฟีเจอร์ android.software.vulkan.deqp.level ค่าของ Flag ฟีเจอร์นี้คือวันที่ที่เข้ารหัสเป็นค่าจำนวนเต็ม ข้อมูลนี้ระบุวันที่ที่เชื่อมโยงกับการทดสอบ dEQP ของ Vulkan ที่อุปกรณ์อ้างว่าผ่าน

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

  • บิต 0-15 จัดเก็บปี
  • บิต 16-23 จัดเก็บข้อมูลเดือน
  • บิต 24-31 จัดเก็บวัน

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

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

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

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

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