XR_EXT_spatial_container_self_rendering

String Nama

XR_EXT_spatial_container_self_rendering

Jenis Ekstensi

Ekstensi instance

Nomor Ekstensi Terdaftar

814

Revisi

1

Status Ratifikasi

Belum diratifikasi

Dependensi Ekstensi dan Versi

XR_EXT_spatial_container

Tanggal Terakhir Diubah

2026-08-06

Status IP

Tidak ada klaim kekayaan intelektual yang diketahui.

Kontributor

Lachlan Ford, Google
Andreas Loeve Selvik, Meta Platforms
Adam Gousetis, Meta Platforms
Bjorn Swenson, LÖVR
Cass Everitt, Meta Platforms
Christian Kruse, Meta Platforms
Denny Rönngren, Varjo Technologies
Fredia Huya-Kouadio, Godot Engine
Jakob Bornecrantz, NVIDIA
Jared Finder, Google
Jonathan Wright, Meta Platforms
Jian Zhang, ByteDance
Kurtis Eveleigh, Qualcomm
Mauricio Narvaez, Meta Platforms
Nick Klingensmith, Qualcomm
Nikita Lutsenko, Meta Platforms
Praveen Babu J D, ByteDance
Rylie Pavlik, Collabora
Salar Khan, Google
Shuai Liu, ByteDance
Walter Luh, Meta Platforms
Yin Li, Microsoft

Ringkasan

Ekstensi ini menentukan "rendering mandiri" untuk penampung spasial. Semua piksel penampung spasial yang dirender sendiri dihasilkan oleh aplikasi dan dikirim ke runtime menggunakan swapchain dan lapisan komposisi OpenXR standar. Karena penampung spasial tidak selalu menggunakan semua piksel layar, runtime akan memberi tahu aplikasi tentang resolusi dan konfigurasi tampilan yang direkomendasikan untuk setiap penampung spasial agar aplikasi dapat merender dengan lebih efisien.

Ekstensi ini, jika digabungkan dengan XR_EXT_spatial_container, dimaksudkan untuk menawarkan superset kemampuan rendering lapisan komposisi inti OpenXR 1.x konvensional. Runtime OpenXR 1.x yang mendukung rendering grafis dan ekstensi ini harus menetapkan XrSystemSpatialContainerPropertiesEXT :: supportsImmersive ke true untuk menunjukkan bahwa runtime tersebut mendukung penampung spasial imersif.

Siklus Proses Rendering Penampung Spasial

Untuk menggunakan rendering mandiri untuk penampung spasial, aplikasi menetapkan XrSpatialContainerCreateInfoEXT :: graphicsPresentation ke XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT saat memanggil xrCreateSpatialContainerEXT . Kemudian, aplikasi tersebut dapat mengelola apakah penampung spasial merender secara aktif dengan memanggil fungsi xrBeginSpatialContainerRenderingEXT dan xrEndSpatialContainerRenderingEXT. Fungsi ini menggantikan xrBeginSession dan xrEndSession . Operasi ini bukan operasi per frame, seperti xrBeginFrame dan xrEndFrame .

Setiap frame, aplikasi akan melalui langkah-langkah berikut:

  • Panggil xrWaitFrame dan xrBeginFrame . Fungsi ini tidak memiliki struktur khusus penampung dan berfungsi seperti dalam spesifikasi inti.
  • Ambil pose tampilan, parameter proyeksi, dan rekomendasi rendering untuk semua penampung spasial yang aktif merender dengan xrLocateSpatialContainerViewsEXT . Untuk setiap penampung spasial, runtime akan melaporkan apakah lapisan komposisinya harus dirender dan cara yang direkomendasikan untuk merender lapisan dengan mengisi XrSpatialContainerViewStateEXT .
  • Merender piksel ke dalam lapisan komposisi secara normal. Operasi ini tidak memiliki struktur khusus container.
  • Kirim lapisan komposisi untuk semua penampung spasial yang aktif merender dengan memanggil xrEndFrame dan merantai XrSpatialContainerLayerFrameEndInfoEXT .

Menghancurkan handle XrSpatialContainerEXT akan menghapusnya secara implisit dari set render aktif. Aplikasi dapat menghancurkan penampung spasial meskipun telah berhasil melakukan panggilan ke xrBeginSpatialContainerRenderingEXT yang tidak terkait dengan panggilan yang sesuai ke xrEndSpatialContainerRenderingEXT . Runtime harus berperilaku seolah-olah xrEndSpatialContainerRenderingEXT dipanggil secara implisit jika diperlukan di awal implementasi xrDestroySpatialContainerEXT jika berhasil ditampilkan.

Saat aplikasi menerima peristiwa XrEventDataSpatialContainerClosedEXT untuk penampung dalam set render aktif, aplikasi tersebut harus memanggil xrEndSpatialContainerRenderingEXT dan menghancurkan handle XrSpatialContainerEXT.

Fungsi xrBeginSpatialContainerRenderingEXT menambahkan penampung spasial ke set render aktif per sesi, sehingga aplikasi dapat mengirimkan lapisan komposisi untuk penampung spasial ke xrEndFrame .

XrResult xrBeginSpatialContainerRenderingEXT(
    XrSession                                   session,
    const XrSpatialContainerBeginInfoEXT*       beginInfo);

Deskripsi Parameter

Aplikasi biasanya memanggil ini sebagai respons terhadap peristiwa perubahan visibilitas dengan XrEventDataSpatialContainerVisibleChangedEXT :: visible ditetapkan ke benar (true).

Jika penampung spasial tidak dibuat dengan XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT saat memanggil xrCreateSpatialContainerEXT , runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT .

Jika penampung spasial sudah ada dalam set render aktif, runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT .

Jika xrBeginSpatialContainerRenderingEXT dipanggil pada saat aplikasi tidak dapat memanggil xrWaitFrame (yaitu di dalam jendela xrBeginFrame dan xrEndFrame), runtime harus menampilkan XR_ERROR_CALL_ORDER_INVALID .

Penggunaan yang Valid (Implisit)

Keamanan Thread

Kode Status

Berhasil

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Kegagalan

  • XR_ERROR_CALL_ORDER_INVALID
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT
  • XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

Struktur XrSpatialContainerBeginInfoEXT digunakan untuk menentukan parameter untuk memulai rendering penampung spasial.

typedef struct XrSpatialContainerBeginInfoEXT {
    XrStructureType            type;
    const void*                next;
    XrSpatialContainerEXT      spatialContainer;
    XrViewConfigurationType    primaryViewConfigurationType;
} XrSpatialContainerBeginInfoEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • spatialContainer adalah XrSpatialContainerEXT untuk memulai rendering.
  • primaryViewConfigurationType adalah XrViewConfigurationType utama yang akan digunakan untuk penampung spasial.

primaryViewConfigurationType adalah konfigurasi tampilan yang ingin digunakan aplikasi saat merender. Runtime dapat menurunkan konfigurasi tampilan ke jenis dengan tampilan yang lebih sedikit untuk tujuan pengoptimalan (misalnya, penampung sangat jauh dan kecil sehingga stereo tidak terlihat). Runtime menampilkan detail tentang konfigurasi tampilan yang menurun dari panggilan ke xrLocateSpatialContainerViewsEXT .

Penggunaan yang Valid (Implisit)

Fungsi xrEndSpatialContainerRenderingEXT menghapus penampung spasial dari set render aktif.

XrResult xrEndSpatialContainerRenderingEXT(
    XrSession                                   session,
    const XrSpatialContainerEndInfoEXT*         endInfo);

Deskripsi Parameter

Aplikasi biasanya memanggil ini sebagai respons terhadap peristiwa yang terlihat berubah dengan XrEventDataSpatialContainerVisibleChangedEXT :: visible ditetapkan ke salah.

Jika penampung spasial tidak berada dalam set render aktif, runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Jika xrEndSpatialContainerRenderingEXT dipanggil pada saat aplikasi tidak dapat memanggil xrWaitFrame (yaitu selama periode antara panggilan xrBeginFrame dan xrEndFrame), runtime harus menampilkan XR_ERROR_CALL_ORDER_INVALID .

Penggunaan yang Valid (Implisit)

Keamanan Thread

Kode Status

Berhasil

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Kegagalan

  • XR_ERROR_CALL_ORDER_INVALID
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • XR_ERROR_VALIDATION_FAILURE

Struktur XrSpatialContainerEndInfoEXT digunakan untuk menentukan parameter untuk mengakhiri rendering penampung spasial.

typedef struct XrSpatialContainerEndInfoEXT {
    XrStructureType          type;
    const void*              next;
    XrSpatialContainerEXT    spatialContainer;
} XrSpatialContainerEndInfoEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • spatialContainer adalah XrSpatialContainerEXT untuk mengakhiri rendering.

Penggunaan yang Valid (Implisit)

Menemukan tampilan melalui xrLocateSpatialContainerViewsEXT

Fungsi xrLocateSpatialContainerViewsEXT menemukan tampilan untuk sekumpulan penampung spasial.

XrResult xrLocateSpatialContainerViewsEXT(
    XrSession                                   session,
    const XrSpatialContainerViewsLocateInfoEXT* locateInfo,
    uint32_t                                    viewStateCount,
    XrSpatialContainerViewStateEXT*             viewStates,
    uint32_t                                    viewCount,
    XrView*                                     views);

Deskripsi Parameter

Fungsi ini menggantikan xrLocateViews , sehingga aplikasi dapat mengkueri tampilan untuk beberapa penampung spasial secara bersamaan.

Tampilan untuk semua penampung spasial ditampilkan dalam satu array views. Tampilan diurutkan berdasarkan indeks penampung spasial dalam array XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos, lalu indeks tampilan untuk penampung tersebut.

Misalnya, jika aplikasi menyediakan tiga penampung spasial di XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos :

  • Indeks 0: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO (1 tampilan)
  • Indeks 1: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO (2 tampilan)
  • Indeks 2: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET (4 tampilan)

Kemudian, runtime harus mengisi array views dengan 7 tampilan:

  • views [0] adalah tampilan untuk penampung 0.
  • views [1] adalah tampilan mata kiri untuk penampung 1.
  • views [2] adalah tampilan mata kanan untuk penampung 1.
  • views [3] adalah tampilan mata kiri untuk penampung 2.
  • views [4] adalah tampilan mata kanan untuk penampung 2.
  • views [5] adalah tampilan inset mata kiri untuk penampung 2.
  • views [6] adalah tampilan inset mata kanan untuk penampung 2.

Jika viewCount tidak sama dengan jumlah penayangan untuk setiap jenis konfigurasi tampilan yang diminta penampung spasial, runtime harus menampilkan XR_ERROR_VALIDATION_FAILURE .

Runtime dapat menurunkan konfigurasi tampilan ke jenis dengan tampilan yang lebih sedikit untuk tujuan pengoptimalan (misalnya, penampung sangat jauh dan kecil sehingga stereo tidak terlihat). Jika runtime mengurangi konfigurasi tampilan, runtime harus tetap menampilkan jumlah tampilan asli untuk penampung tersebut, dengan mengisi tampilan tambahan dengan duplikat tampilan yang dikurangi. Misalnya, jika XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO didegradasi menjadi XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO , indeks 0 dan indeks 1 akan berisi satu tampilan mono. Oleh karena itu, jumlah total tampilan yang ditampilkan dalam array views tidak bergantung pada apakah runtime memutuskan untuk menghentikan konfigurasi tampilan atau tidak.

Runtime harus menyesuaikan setiap XrView :: fov yang ditampilkan sehingga frustum sekecil mungkin, tetapi tetap berisi seluruh batas penampung spasial yang sesuai. Runtime dapat menampilkan FOV non-simetris, misalnya jika penampung spasial berada pada sudut miring terhadap pandangan pengguna, atau sebagian terhalang oleh objek lain. Runtime dapat memosisikan platform rendering target secara bebas untuk penampung spasial. Karena sifat rendering multi-aplikasi, yang mana penampung spasial dilepaskan dari pengguna, runtime dapat menampilkan nilai XrView yang tidak cocok untuk rendering piksel, misalnya jika penampung spasial tidak terlihat di layar, tidak ada nilai yang valid untuk menetapkan XrView :: fov. Dalam kasus tersebut, runtime harus menetapkan XrSpatialContainerViewStateEXT :: shouldSubmitLayers ke false.

Runtime menampilkan informasi status rendering per penampung spasial tambahan dalam array viewStates. Jika viewStateCount tidak sama dengan XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount , runtime harus menampilkan XR_ERROR_VALIDATION_FAILURE .

Setelah runtime mengantrekan peristiwa XrEventDataSpatialContainerClosedEXT untuk penampung spasial, fungsi ini harus menampilkan XR_FALSE di XrSpatialContainerViewStateEXT :: shouldSubmitLayers dan 0 di XrSpatialContainerViewStateEXT :: viewStateFlags untuk penampung spasial yang sesuai.

Untuk penampung spasial dengan lokasi yang berubah secara aktif di dunia nyata, runtime harus mempertimbangkan gerakan penampung saat mengisi views untuk meminimalkan artefak proyeksi ulang.

Jika xrLocateSpatialContainerViewsEXT dipanggil untuk satu atau beberapa penampung spasial yang saat ini tidak berada dalam set render aktif, runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Penggunaan yang Valid (Implisit)

Kode Status

Berhasil

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Kegagalan

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • XR_ERROR_TIME_INVALID
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

Struktur XrSpatialContainerViewsLocateInfoEXT berisi parameter untuk menemukan tampilan di seluruh koleksi penampung spasial.

typedef struct XrSpatialContainerViewsLocateInfoEXT {
    XrStructureType                               type;
    const void*                                   next;
    XrTime                                        displayTime;
    uint32_t                                      viewLocateInfoCount;
    const XrSpatialContainerViewLocateInfoEXT*    viewLocateInfos;
} XrSpatialContainerViewsLocateInfoEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • displayTime adalah XrTime tempat tampilan berada.
  • viewLocateInfoCount adalah jumlah entri dalam array viewLocateInfos.
  • viewLocateInfos adalah pointer ke array struktur XrSpatialContainerViewLocateInfoEXT.

Penggunaan yang Valid (Implisit)

Struktur XrSpatialContainerViewLocateInfoEXT berisi parameter untuk penampung spasial individual guna menemukan tampilan.

typedef struct XrSpatialContainerViewLocateInfoEXT {
    XrStructureType            type;
    const void*                next;
    XrViewConfigurationType    viewConfigurationType;
    XrSpace                    space;
    XrSpatialContainerEXT      spatialContainer;
} XrSpatialContainerViewLocateInfoEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • viewConfigurationType adalah XrViewConfigurationType yang akan digunakan untuk penampung spasial.
  • space adalah XrSpace tempat tampilan penampung spasial berada.
  • spatialContainer adalah handle XrSpatialContainerEXT.

Aplikasi dapat menyediakan XrSpace yang valid di space , tetapi sebaiknya sediakan ruang penampung spasial untuk XrSpatialContainerEXT yang sesuai yang ditentukan dalam struktur XrSpatialContainerViewLocateInfoEXT.

Penggunaan yang Valid (Implisit)

Struktur XrSpatialContainerViewStateEXT diisi oleh panggilan ke xrLocateSpatialContainerViewsEXT dengan informasi kesesuaian rendering per penampung spasial.

typedef struct XrSpatialContainerViewStateEXT {
    XrStructureType            type;
    void*                      next;
    XrViewStateFlags           viewStateFlags;
    XrViewConfigurationType    viewConfigurationType;
    XrBool32                   shouldSubmitLayers;
    XrExtent2Di                recommendedImageExtent;
} XrSpatialContainerViewStateEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • viewStateFlags adalah bitmask dari XrViewStateFlags . Flag ini memiliki tujuan yang sama dengan viewStateFlags dalam struktur XrViewState inti.
  • viewConfigurationType adalah XrViewConfigurationType yang menunjukkan jenis konfigurasi tampilan yang digunakan runtime untuk penampung spasial, yang mungkin diturunkan oleh runtime ke konfigurasi tampilan dengan jumlah tampilan yang lebih rendah daripada yang diminta.
  • shouldSubmitLayers adalah XrBool32 yang ditampilkan oleh runtime. Jika XR_FALSE , aplikasi sebaiknya menghindari pengiriman komposisi untuk penampung spasial ini karena saat ini tidak terlihat atau dalam status yang tidak memerlukan rendering.
  • recommendedImageExtent adalah struktur XrExtent2Di yang mewakili resolusi yang direkomendasikan untuk penampung spasial.

Seperti lokasi tampilan OpenXR inti, aplikasi harus memeriksa XrSpatialContainerViewStateEXT :: viewStateFlags untuk memastikan posisi dan orientasi valid dan dilacak sebelum menggunakan data tampilan untuk rendering.

Aplikasi harus memeriksa shouldSubmitLayers dan viewConfigurationType untuk menghindari rendering lebih dari yang direkomendasikan runtime. Jika shouldSubmitLayers bernilai salah (false), aplikasi akan mengubah perilaku renderingnya sebagai berikut:

  • Aplikasi tidak boleh membaca XrView :: fov yang sesuai.
  • Aplikasi tidak boleh membaca recommendedImageExtent .
  • Aplikasi sebaiknya menghindari rendering ke swapchain dan mengirimkan lapisan komposisi untuk penampung spasial yang sesuai.
  • Aplikasi harus menetapkan XrSpatialContainerLayerEXT :: retainPreviousSubmission ke true. Jika aplikasi tetap memilih untuk mengirimkan lapisan, runtime akan menentukan tindakan yang ingin dilakukan dengan lapisan tersebut (misalnya, runtime dapat memilih untuk menghapusnya).

recommendedImageExtent secara eksplisit ditujukan untuk lapisan yang akan diperbarui berdasarkan posisi penampung atau tampilan pengguna. Saat mengupdate lapisan dengan konten yang bergantung pada posisi penampung spasial atau tampilan pengguna (seperti konten 3D normal), aplikasi harus merender ke area pandang yang lebih kecil ini, bukan ukuran tampilan yang direkomendasikan secara default. Saat mengupdate lapisan dengan konten yang tidak bergantung pada posisi penampung spasial atau tampilan pengguna (seperti lapisan quad statis), aplikasi dapat mengabaikan nilai ini dengan aman. Untuk lapisan yang bergantung pada tampilan, recommendedImageExtent adalah rekomendasi untuk aplikasi dari runtime yang dimaksudkan untuk meminimalkan aliasing dan meningkatkan performa rendering. Aplikasi dapat mengirimkan ikon dalam resolusi penuh jika diinginkan.

XrExtent2Di :: width dan XrExtent2Di :: height dari recommendedImageExtent harus selalu berupa bilangan bulat positif yang kurang dari atau sama dengan XrViewConfigurationView :: recommendedImageRectWidth dan XrViewConfigurationView :: recommendedImageRectHeight dari XrViewConfigurationView untuk konfigurasi tampilan utama penampung spasial. Aplikasi tidak boleh membuat ulang swapchain hanya karena recommendedImageExtent berubah, karena ini adalah petunjuk dinamis untuk aplikasi yang menentukan XrSwapchainSubImage :: imageRect yang akan digunakan di XrSwapchainSubImage dari setiap lapisan komposisi resolusi penuh yang dikirimkannya, dan dapat mengubah setiap frame.

Penggunaan yang Valid (Implisit)

Melihat ruang referensi

Ruang referensi tampilan tetap tidak berubah seperti di inti OpenXR. Seperti pada core, ini tidak dimaksudkan untuk penggunaan rendering.

Mengirimkan lapisan melalui xrEndFrame

Untuk merender penampung spasial, aplikasi harus menyediakan daftar lapisan yang terkait dengan penampung spasial masing-masing ke xrEndFrame . Hal ini dilakukan melalui struktur XrSpatialContainerLayerFrameEndInfoEXT.

typedef struct XrSpatialContainerLayerFrameEndInfoEXT {
    XrStructureType                      type;
    const void*                          next;
    uint32_t                             containerLayerCount;
    const XrSpatialContainerLayerEXT*    containerLayers;
} XrSpatialContainerLayerFrameEndInfoEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • containerLayerCount adalah jumlah elemen dalam array containerLayers.
  • containerLayers adalah pointer ke array struktur XrSpatialContainerLayerEXT.

Array containerLayers berisi XrSpatialContainerLayerEXT untuk setiap penampung spasial dalam set render aktif (penampung yang dikelola per sesi oleh xrBeginSpatialContainerRenderingEXT dan xrEndSpatialContainerRenderingEXT ). Setiap XrSpatialContainerLayerEXT berisi daftar pointer XrCompositionLayerBaseHeader yang terkait dengan penampung spasial tertentu. Runtime dapat menyusun container dalam urutan apa pun yang dipilihnya, terlepas dari urutan containerLayers . Misalnya, runtime dapat menggabungkan penampung berdasarkan kedalamannya relatif terhadap pengguna, membuat penampung spasial bertindak sebagai lapisan latar belakang, atau 'menyematkan' penampung spasial sehingga selalu berada di atas, terlepas dari kedalamannya. Runtime dapat menggabungkan lapisan komposit menggunakan strategi yang berbeda untuk penampung spasial dalam mode terbatas atau mode imersif. Misalnya, runtime dapat melakukan pra-komposisi setiap lapisan komposisi penampung spasial yang dibatasi menjadi satu lapisan quad stereo yang digabungkan dengan semua penampung lainnya dalam langkah komposisi kedua.

XrFrameEndInfo :: displayTime dan XrFrameEndInfo :: environmentBlendMode akan diterapkan ke semua penampung spasial yang disediakan di XrSpatialContainerLayerFrameEndInfoEXT .

Saat struktur ini diteruskan ke xrEndFrame dengan dihubungkan ke XrFrameEndInfo , kasus error tambahan berikut akan ditambahkan berdasarkan set render aktif:

  • Jika penampung spasial direferensikan oleh lebih dari satu elemen containerLayers , runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT .
  • Jika penampung spasial dalam set render aktif tidak direferensikan oleh elemen containerLayers , runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .
  • Jika penampung spasial yang dirujuk oleh containerLayers bukan anggota set render aktif, runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Selain itu, jika ada penampung spasial dalam set render aktif dan struktur ini tidak dihubungkan ke XrFrameEndInfo , runtime harus menampilkan XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .

Dalam salah satu kasus error di atas, runtime tidak boleh merender konten apa pun untuk penampung spasial apa pun.

Jika tidak ada penampung spasial dalam set render aktif, aplikasi dapat memanggil xrEndFrame selama tidak mengirimkan lapisan komposisi apa pun.

Perhatikan bahwa swapchain individual dapat dikirimkan untuk beberapa penampung melalui lapisan dalam struktur yang valid, misalnya, Lapisan quad yang dirender melalui satu swapchain yang dikirimkan ke beberapa penampung spasial. Kasus ini ditangani secara seragam dengan rendering lainnya: runtime harus merender quad di semua penampung spasial tersebut.

Penggunaan yang Valid (Implisit)

Struktur XrSpatialContainerLayerEXT mengelompokkan lapisan komposisi standar dan mengaitkannya dengan penampung spasial tertentu.

typedef struct XrSpatialContainerLayerEXT {
    XrStructureType                               type;
    const void*                                   next;
    XrSpatialContainerEXT                         spatialContainer;
    XrBool32                                      retainPreviousSubmission;
    uint32_t                                      layerCount;
    const XrCompositionLayerBaseHeader* const*    layers;
} XrSpatialContainerLayerEXT;

Deskripsi Anggota

  • type adalah XrStructureType dari struktur ini.
  • next adalah NULL atau pointer ke struktur berikutnya dalam rantai struktur.
  • spatialContainer adalah XrSpatialContainerEXT yang mengidentifikasi penampung target.
  • retainPreviousSubmission adalah XrBool32 . Jika XR_TRUE , runtime akan mempertahankan frame terakhir yang dikirimkan untuk penampung spasial ini.
  • layerCount adalah jumlah lapisan komposisi dalam array layers.
  • layers adalah pointer ke array pointer XrCompositionLayerBaseHeader.

Jika retainPreviousSubmission adalah XR_TRUE , runtime harus menggunakan kembali lapisan komposisi dan konten gambar swapchain seperti yang dikunci selama panggilan xrEndFrame terbaru saat retainPreviousSubmission adalah XR_FALSE . Setiap modifikasi berikutnya pada swapchain yang digunakan oleh lapisan yang dipertahankan tidak boleh ditampilkan dalam output yang dirender.

Untuk lapisan yang dikirimkan untuk penampung spasial individual (rendering intra-penampung), runtime harus mengikuti aturan yang telah ditentukan untuk pengurutan komposisi lapisan. Artinya, lapisan dalam penampung harus digambar dalam urutan yang sama seperti yang ditentukan, yang disusun melalui algoritma pelukis.

"Menghapus" penampung spasial mengacu pada penghapusan semua konten dari penampung spasial, sehingga tidak ada yang dirender untuk penampung tersebut dalam frame saat ini. Runtime harus memperlakukan ini setara dengan aplikasi yang mengirimkan warna hitam transparan (semua bit 0) untuk setiap piksel di dalam penampung. "Mempertahankan" penampung spasial mengacu pada runtime yang terus menampilkan kumpulan lapisan yang terakhir dikirimkan untuk penampung tersebut.

Untuk setiap penampung spasial, aplikasi dapat menentukan apakah akan mengirimkan lapisan baru, mempertahankan pengiriman sebelumnya, atau menghapus penampung spasial:

  • Untuk mengirimkan lapisan baru, aplikasi menyediakan layerCount bukan nol dan pointer layers yang valid.
  • Untuk menghapus penampung spasial, layerCount untuk entrinya harus 0 dan retainPreviousSubmission harus XR_FALSE .
  • Untuk mempertahankan lapisan dan gambar swapchain yang terakhir dikirim (mempertahankan), layerCount untuk entrinya harus 0 dan retainPreviousSubmission harus XR_TRUE .

Kontrol eksplisit per penampung ini memastikan bahwa intent aplikasi dikomunikasikan dengan jelas di setiap frame.

Jika retainPreviousSubmission adalah XR_TRUE dan layerCount bukan 0, runtime harus menampilkan XR_ERROR_VALIDATION_FAILURE .

Jika XrSpatialContainerCompositionLayerViewConfigurationEXT tidak dirantai ke XrCompositionLayerProjection yang merupakan bagian dari penampung spasial, runtime harus menampilkan XR_ERROR_VALIDATION_FAILURE . Struktur ini hanya berlaku untuk lapisan XrCompositionLayerProjection. Jika dihubungkan ke jenis lapisan lain (misalnya, lapisan quad atau silinder), runtime harus menampilkan XR_ERROR_VALIDATION_FAILURE .

Penggunaan yang Valid (Implisit)

Menentukan Konfigurasi Tampilan untuk Lapisan Proyeksi

Struktur XrSpatialContainerCompositionLayerViewConfigurationEXT digunakan untuk menentukan konfigurasi tampilan yang digunakan untuk merender lapisan proyeksi untuk penampung spasial.

typedef struct XrSpatialContainerCompositionLayerViewConfigurationEXT {
    XrStructureType            type;
    const void*                next;
    XrViewConfigurationType    viewConfigurationType;
} XrSpatialContainerCompositionLayerViewConfigurationEXT;

Deskripsi Anggota

Saat mengirimkan XrCompositionLayerProjection untuk penampung spasial, aplikasi harus menentukan konfigurasi tampilan yang digunakan untuk merender lapisan. Hal ini diperlukan karena aplikasi dapat memilih setiap frame, baik untuk dirender dengan konfigurasi tampilan utama penampung spasial atau konfigurasi tampilan yang menurun yang disarankan runtime, jika ada.

Saat XrSpatialContainerCompositionLayerViewConfigurationEXT dihubungkan, aplikasi harus memastikan bahwa XrCompositionLayerProjection :: viewCount adalah jumlah tampilan yang valid untuk XrViewConfigurationType yang ditentukan dalam struktur yang dihubungkan. viewConfigurationType yang ditentukan dalam struktur berantai harus berupa XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType yang ditentukan saat penampung dimulai, atau jenis konfigurasi tampilan yang menurun yang ditampilkan oleh runtime di XrSpatialContainerViewStateEXT , atau nilai tambahan yang diaktifkan melalui ekstensi.

Penggunaan yang Valid (Implisit)

Perilaku pemangkasan piksel

Aplikasi harus memberi tahu runtime apakah aplikasi merender piksel di luar batas penampung spasial atau tidak dengan merantai XrSpatialContainerLayerVolumeClippingEXT saat mengirimkan lapisan komposisi.

typedef struct XrSpatialContainerLayerVolumeClippingEXT {
    XrStructureType                        type;
    const void*                            next;
    XrSpatialContainerVolumeClippingEXT    volumeClipping;
} XrSpatialContainerLayerVolumeClippingEXT;

Deskripsi Anggota

Struktur ini berfungsi sebagai petunjuk jika aplikasi merender piksel di luar batas penampung spasial. Saat penampung spasial berada dalam mode imersif, karena batasnya tidak terbatas, petunjuk ini tidak memiliki arti.

Untuk penampung spasial terbatas yang menggunakan rendering mandiri, runtime perlu mempertimbangkan batas volume 3D dan batas piksel 2D. Batas volume 3D ditampilkan dari xrGetSpatialContainerBoundsEXT . Batas piksel 2D adalah proyeksi batas volume 3D ke setiap layar untuk sistem.

Runtime harus menghapus piksel dari gambar swapchain di luar batas piksel 2D, tetapi runtime tidak boleh menghapus piksel yang berada di dalam batas piksel 2D, tetapi di luar batas volume 3D. Efek stereo yang membuat konten tampak meluas ke luar atau ke depan batas volume 3D penampung dapat dilakukan. Aplikasi dapat menghapus piksel di luar batas volume 3D penampung spasial terbatas untuk mengurangi paradoks kedalaman dan harus menetapkan volumeClipping berdasarkan cara melakukannya. Paradoks kedalaman sering kali menyebabkan ketegangan mata dan ketidaknyamanan pengguna.

Runtime dapat menggunakan volumeClipping untuk menyesuaikan cara menampilkan penampung spasial tertentu. Misalnya, jika disetel ke XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT, runtime dapat merender permukaan belakang batas volume 3D yang akan menyebabkan paradoks kedalaman jika penampung spasial menggambar piksel di belakang batas volume 3D penampung.

Ekstensi mendatang mungkin memungkinkan pemangkasan berdasarkan batas volume 3D jika informasi kedalaman dikirimkan.

Penggunaan yang Valid (Implisit)

Perintah Baru

Struktur Baru

Konstanta Enum Baru

  • XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME
  • XR_EXT_spatial_container_self_rendering_SPEC_VERSION
  • Memperluas XrResult :

    • XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT
    • XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • Memperluas XrSpatialContainerGraphicsPresentationEXT :

    • XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
  • Memperluas XrStructureType :

    • XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT
    • XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT

Contoh Kode

// Example: Complete lifecycle, view location, and frame submission for spatial containers
PFN_xrBeginSpatialContainerRenderingEXT xrBeginSpatialContainerRenderingEXT; // previously initialized
PFN_xrEndSpatialContainerRenderingEXT xrEndSpatialContainerRenderingEXT; // previously initialized
PFN_xrLocateSpatialContainerViewsEXT xrLocateSpatialContainerViewsEXT; // previously initialized

XrSession session; // previously initialized

// We want to update this container
XrSpatialContainerEXT containerA; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerASpace; // previously initialized

// We want to retain this container
XrSpatialContainerEXT containerB; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerBSpace; // previously initialized

// 1. Add to active render set when the app is ready to start submitting layers
XrSpatialContainerBeginInfoEXT beginInfoA {
  .type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
  .spatialContainer = containerA,
  .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoA));

XrSpatialContainerBeginInfoEXT beginInfoB {
  .type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
  .spatialContainer = containerB,
  .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoB));

// ... Frame Loop ...


XrTime displayTime; // returned from xrWaitFrame

const std::vector<XrSpatialContainerEXT> containers = {containerA, containerB};
const std::vector<XrSpace> containerSpaces = {containerASpace, containerBSpace};
uint32_t containerCount = static_cast<uint32_t>(containers.size());

// 2. Setup individual locate info for each container
std::vector<XrSpatialContainerViewLocateInfoEXT> containerLocateInfos(containerCount, {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT,
});

for (uint32_t i = 0; i < containerCount; ++i) {
    containerLocateInfos[i].viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
    containerLocateInfos[i].space = containerSpaces[i]; // Recommended to use container's own space
    containerLocateInfos[i].spatialContainer = containers[i];
}

// Setup bulk locate info
XrSpatialContainerViewsLocateInfoEXT locateInfo {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT,
  .displayTime = displayTime,
  .viewLocateInfoCount = containerCount,
  .viewLocateInfos = containerLocateInfos.data(),
};

// Prepare states to be populated by the runtime
std::vector<XrSpatialContainerViewStateEXT> viewStates(containerCount, {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT,
});

// Call the dedicated locate views function
// We know the required view count is 2 per container for STEREO
const uint32_t viewsPerConfig = 2;
uint32_t totalViewCount = containerCount * viewsPerConfig;
std::vector<XrView> views(totalViewCount, {.type = XR_TYPE_VIEW});

CHK_XR(xrLocateSpatialContainerViewsEXT(session, &locateInfo, containerCount, viewStates.data(), totalViewCount, views.data()));

// Process results
for (uint32_t i = 0; i < containerCount; ++i) {
    XrBool32 shouldSubmitLayers = viewStates[i].shouldSubmitLayers;
    XrExtent2Di recommendedImageExtent = viewStates[i].recommendedImageExtent;
    XrViewConfigurationType viewConfigurationType = viewStates[i].viewConfigurationType;
    bool isDecayedToMono = (viewConfigurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO);
    if (shouldSubmitLayers) {
        // App is expected to also verify viewStates[i].viewStateFlags has valid orientation/position bits before rendering
        XrView& leftView = views[i * viewsPerConfig];
        XrView& rightView = views[i * viewsPerConfig + 1];
        // If isDecayedToMono is true, left and right will be identical.
    } else {
        // Skip layer submission but retain previous submission when calling
        // xrEndFrame.
    }
}

// 3. Setup projection layer for container A
XrCompositionLayerProjection projectionLayer = {.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION};
// ... standard projection layer setup (space, viewCount, views, etc.) ...

// Specify which view configuration was used to render this specific layer
XrSpatialContainerCompositionLayerViewConfigurationEXT containerViewConfig {
  .type = XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT,
  // Even if the runtime decayed to MONO, we indicate what we actually rendered
  .viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};

// Chain it to the projection layer
projectionLayer.next = &containerViewConfig;
const XrCompositionLayerBaseHeader* layersA[1] = {reinterpret_cast<const XrCompositionLayerBaseHeader*>(&projectionLayer)};

// Note: In a real app, you are required to submit ALL active containers in the render set.

XrSpatialContainerLayerVolumeClippingEXT containerClippingA = {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
  // Set volumeClipping appropriately for the rendering done.
  .volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};

// Setup container A (Update with new pixels)
XrSpatialContainerLayerEXT containerLayerA {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
  .next = &containerClippingA,
  .spatialContainer = containerA,
  .retainPreviousSubmission = XR_FALSE,
  .layerCount = 1,
  .layers = layersA,
};

XrSpatialContainerLayerVolumeClippingEXT containerClippingB {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
  // Set volumeClipping appropriately for the rendering done.
  .volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};

// Setup container B (Explicitly retain previous frame)
XrSpatialContainerLayerEXT containerLayerB {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
  .next = &containerClippingB,
  .spatialContainer = containerB,
  .retainPreviousSubmission = XR_TRUE,
  .layerCount = 0, // Required to be 0 when retaining
  .layers = nullptr,
};

// Aggregate all container layers
XrSpatialContainerLayerEXT containerLayers[] = { containerLayerA, containerLayerB };

XrSpatialContainerLayerFrameEndInfoEXT spatialEndInfo {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT,
  .containerLayerCount = 2, // Must equal the number of active containers
  .containerLayers = containerLayers,
};

XrFrameEndInfo frameEndInfo {
  .type = XR_TYPE_FRAME_END_INFO,
  .next = &spatialEndInfo,
  .displayTime = displayTime,
  .environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND,
  .layerCount = 0, // MANDATORY: Must be 0 for self rendering extension
};

CHK_XR(xrEndFrame(session, &frameEndInfo));

// ... End Frame Loop ...

// 4. Remove from active render set when the container is destroyed or no longer needs rendering
XrSpatialContainerEndInfoEXT endInfoA {
  .type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
  .spatialContainer = containerA,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoA));

XrSpatialContainerEndInfoEXT endInfoB {
  .type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
  .spatialContainer = containerB,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoB));

Riwayat Versi

  • Revisi 1, 06-08-2026 (Lachlan Ford)

    • Deskripsi ekstensi awal