mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-28 01:16:50 +00:00
gpu_display: new vulkan display
This is a new display path for creating vulkan-based surfaces. Test: build Change-Id: I28e3b455ed265b615c4f8fe7c6ac28e2da81ec2e Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5214569 Reviewed-by: Dennis Kempin <denniskempin@google.com> Reviewed-by: Ryan Neph <ryanneph@google.com>
This commit is contained in:
parent
f1bcfe1475
commit
7fbd71e5bf
11 changed files with 741 additions and 5 deletions
151
Cargo.lock
generated
151
Cargo.lock
generated
|
@ -136,6 +136,15 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.37.3+1.3.251"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.3.0"
|
||||
|
@ -354,6 +363,26 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
|
@ -505,6 +534,33 @@ dependencies = [
|
|||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics-types"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crash_report"
|
||||
version = "0.1.0"
|
||||
|
@ -651,15 +707,20 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.11"
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
|
||||
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
|
||||
[[package]]
|
||||
name = "crosvm"
|
||||
version = "0.1.0"
|
||||
|
@ -793,6 +854,12 @@ dependencies = [
|
|||
"protos",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.2.5"
|
||||
|
@ -1254,30 +1321,45 @@ name = "gpu_display"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
"base",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"cros_tracing",
|
||||
"data_model",
|
||||
"euclid",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"linux_input_sys",
|
||||
"metrics",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
"protobuf",
|
||||
"protos",
|
||||
"rand",
|
||||
"remain",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"sync",
|
||||
"thiserror",
|
||||
"vm_control",
|
||||
"vulkano",
|
||||
"which",
|
||||
"win_util",
|
||||
"winapi",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
|
@ -1623,6 +1705,15 @@ dependencies = [
|
|||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
version = "0.8.0"
|
||||
|
@ -1845,6 +1936,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
|
@ -2803,6 +2903,15 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vk-parse"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c6a0bda9bbe6b9e50e6456c80aa8fe4cca3b21e4311a1130c41e4915ec2e32a"
|
||||
dependencies = [
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vm_control"
|
||||
version = "0.1.0"
|
||||
|
@ -2878,6 +2987,32 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vulkano"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49e6f6f908670b33ec1fcb1e9c25677cb4d6783893f89bc11d49d2eb5061ccb5"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"bytemuck",
|
||||
"core-graphics-types",
|
||||
"crossbeam-queue",
|
||||
"half",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"libloading",
|
||||
"objc",
|
||||
"parking_lot",
|
||||
"proc-macro2",
|
||||
"quote 1.0.33",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
"vk-parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
|
@ -3159,6 +3294,12 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.5"
|
||||
|
|
|
@ -198,6 +198,9 @@ gfxstream_stub = ["rutabaga_gfx/gfxstream_stub"]
|
|||
## Enables 3D acceleration for the guest via the virglrenderer library over virtio-gpu.
|
||||
virgl_renderer = ["devices/virgl_renderer"]
|
||||
|
||||
## Enables the usage of Vulkan for display on the host.
|
||||
vulkan_display = ["gpu_display/vulkan_display"]
|
||||
|
||||
# Enables the highly experimental vulkan graphics buffer allocator.
|
||||
# see rutabaga_gfx/Cargo.toml for instructions on building with enabled.
|
||||
vulkano = ["rutabaga_gfx/vulkano"]
|
||||
|
@ -382,6 +385,7 @@ all-mingw64 = [
|
|||
"net",
|
||||
"slirp",
|
||||
"stats",
|
||||
"vulkan_display",
|
||||
]
|
||||
|
||||
## All features that are compiled and tested for msvc64
|
||||
|
|
|
@ -24,6 +24,54 @@
|
|||
mod condvar;
|
||||
mod mutex;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::WaitTimeoutResult;
|
||||
use std::time::Duration;
|
||||
|
||||
pub use crate::condvar::Condvar;
|
||||
pub use crate::mutex::Mutex;
|
||||
pub use crate::mutex::WouldBlock;
|
||||
|
||||
/// Waitable allows one thread to wait on a signal from another thread.
|
||||
///
|
||||
/// A Waitable is usually created with a Promise using
|
||||
/// `create_promise_and_waitable`, and the Promise is used by one thread and the
|
||||
/// Waitable can be used by another thread. Promise and Waitable do not use any
|
||||
/// OS-level synchronization primitives.
|
||||
pub struct Waitable(Arc<(Condvar, Mutex<bool>)>);
|
||||
|
||||
impl Waitable {
|
||||
/// Return an already-signaled Waitable.
|
||||
pub fn signaled() -> Self {
|
||||
Waitable(Arc::new((Condvar::new(), Mutex::new(true))))
|
||||
}
|
||||
|
||||
/// Perform a blocking wait on this Waitable.
|
||||
pub fn wait(&self, timeout: Option<Duration>) -> WaitTimeoutResult {
|
||||
let timeout = timeout.unwrap_or(Duration::MAX);
|
||||
let (ref condvar, ref signaled_mutex) = *self.0;
|
||||
condvar
|
||||
.wait_timeout_while(signaled_mutex.lock(), timeout, |signaled| !*signaled)
|
||||
.1
|
||||
}
|
||||
}
|
||||
|
||||
/// Promise allows one thread to signal a waitable that another thread can wait on.
|
||||
pub struct Promise(Arc<(Condvar, Mutex<bool>)>);
|
||||
|
||||
impl Promise {
|
||||
/// Signal this promise, and it's associated Waitable.
|
||||
pub fn signal(&self) {
|
||||
let (ref condvar, ref signaled_mutex) = *self.0;
|
||||
*signaled_mutex.lock() = true;
|
||||
condvar.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a paired Promise and Waitable.
|
||||
///
|
||||
/// Signalling the Promise will signal the Waitable.
|
||||
pub fn create_promise_and_waitable() -> (Promise, Waitable) {
|
||||
let inner = Arc::new((Condvar::new(), Mutex::new(false)));
|
||||
(Promise(Arc::clone(&inner)), Waitable(inner))
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||
[features]
|
||||
x = []
|
||||
kiwi = []
|
||||
vulkan_display = [ "vulkano", "ash", "rand", "protos", "protobuf", "euclid", "smallvec"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "*"
|
||||
|
@ -20,6 +21,14 @@ cfg-if = "*"
|
|||
serde = { version = "1", features = [ "derive" ] }
|
||||
vm_control = { path = "../vm_control", features = ["gpu"] }
|
||||
zerocopy = { version = "0.7", features = ["derive"] }
|
||||
vulkano = { version = "0.31.1", optional = true }
|
||||
ash = { version = "0.37.0", optional = true }
|
||||
rand = { version = "0.8.5", optional = true }
|
||||
protos = { path = "../protos", optional = true }
|
||||
protobuf = { version = "3.2", optional = true }
|
||||
euclid = { version = "*", optional = true }
|
||||
smallvec = { version = "*", optional = true }
|
||||
sync = { path = "../common/sync" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
cros_tracing = { path = "../cros_tracing" }
|
||||
|
@ -31,6 +40,7 @@ once_cell = "*"
|
|||
smallvec = "*"
|
||||
sync = { path = "../common/sync" }
|
||||
euclid = "*"
|
||||
lazy_static = "*"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.25"
|
||||
|
|
|
@ -32,6 +32,8 @@ mod gpu_display_x;
|
|||
#[cfg(any(windows, feature = "x"))]
|
||||
mod keycode_converter;
|
||||
mod sys;
|
||||
#[cfg(feature = "vulkan_display")]
|
||||
pub mod vulkan;
|
||||
|
||||
pub use event_device::EventDevice;
|
||||
pub use event_device::EventDeviceKind;
|
||||
|
|
131
gpu_display/src/vulkan.rs
Normal file
131
gpu_display/src/vulkan.rs
Normal file
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use ash::vk::Extent3D;
|
||||
use ash::vk::{self};
|
||||
use base::SafeDescriptor;
|
||||
|
||||
mod external_image;
|
||||
mod post_worker;
|
||||
mod sys;
|
||||
|
||||
pub use external_image::AcquireImageMemoryBarrier;
|
||||
pub use external_image::ExternalImage;
|
||||
pub use external_image::ExternalImageAccess;
|
||||
pub use external_image::ReleaseImageMemoryBarrier;
|
||||
pub use post_worker::Timepoint;
|
||||
use sync::Promise;
|
||||
use sync::Waitable;
|
||||
use vulkano::image::ImageLayout;
|
||||
use vulkano::VulkanLibrary;
|
||||
|
||||
use self::sys::ApplicationState;
|
||||
use self::sys::ApplicationStateBuilder;
|
||||
use self::sys::PlatformWindowEventLoop;
|
||||
use self::sys::Window;
|
||||
use self::sys::WindowEvent;
|
||||
use self::sys::WindowEventLoop;
|
||||
|
||||
pub struct VulkanDisplayImageImportMetadata {
|
||||
// These fields go into a VkImageCreateInfo
|
||||
pub flags: u32,
|
||||
pub image_type: i32,
|
||||
pub format: i32,
|
||||
pub extent: Extent3D,
|
||||
pub mip_levels: u32,
|
||||
pub array_layers: u32,
|
||||
pub samples: u32,
|
||||
pub tiling: i32,
|
||||
pub usage: u32,
|
||||
pub sharing_mode: i32,
|
||||
pub queue_family_indices: Vec<u32>,
|
||||
pub initial_layout: i32,
|
||||
|
||||
// These fields go into a VkMemoryAllocateInfo
|
||||
pub allocation_size: u64,
|
||||
pub memory_type_index: u32,
|
||||
|
||||
// Additional information
|
||||
pub dedicated_allocation: bool,
|
||||
}
|
||||
|
||||
pub type SemaphoreId = u32;
|
||||
pub type ImageId = u32;
|
||||
|
||||
pub(crate) enum UserEvent {
|
||||
PostCommand {
|
||||
image: ExternalImage,
|
||||
last_layout_transition: (ImageLayout, ImageLayout),
|
||||
acquire_timepoint: Option<Timepoint>,
|
||||
release_timepoint: Timepoint,
|
||||
image_return: Sender<ExternalImage>,
|
||||
promise: Promise,
|
||||
},
|
||||
}
|
||||
|
||||
pub(crate) struct VulkanState {}
|
||||
|
||||
impl ApplicationState for VulkanState {
|
||||
type UserEvent = UserEvent;
|
||||
|
||||
/// Process events coming from the Window.
|
||||
fn process_event(&self, _event: WindowEvent<Self::UserEvent>) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
struct VulkanStateBuilder {
|
||||
vulkan_library: Arc<VulkanLibrary>,
|
||||
device_uuid: [u8; vk::UUID_SIZE],
|
||||
driver_uuid: [u8; vk::UUID_SIZE],
|
||||
}
|
||||
|
||||
impl ApplicationStateBuilder for VulkanStateBuilder {
|
||||
type Target = VulkanState;
|
||||
|
||||
fn build<T: Window>(self, _window: Arc<T>) -> Result<VulkanState> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct VulkanDisplayImpl<T: WindowEventLoop<VulkanState>> {
|
||||
window_event_loop: T,
|
||||
}
|
||||
|
||||
impl<T: WindowEventLoop<VulkanState>> VulkanDisplayImpl<T> {
|
||||
pub fn import_semaphore(
|
||||
&mut self,
|
||||
_semaphore_id: SemaphoreId,
|
||||
_descriptor: SafeDescriptor,
|
||||
) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn import_image(
|
||||
&mut self,
|
||||
_image_id: ImageId,
|
||||
_descriptor: SafeDescriptor,
|
||||
_metadata: VulkanDisplayImageImportMetadata,
|
||||
) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn post(
|
||||
&mut self,
|
||||
_image_id: ImageId,
|
||||
_last_layout_transition: (i32, i32),
|
||||
_acquire_semaphore: Option<(SemaphoreId, u64)>,
|
||||
_release_semaphore: (SemaphoreId, u64),
|
||||
) -> Result<Waitable> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type VulkanDisplay = VulkanDisplayImpl<PlatformWindowEventLoop<VulkanState>>;
|
90
gpu_display/src/vulkan/external_image.rs
Normal file
90
gpu_display/src/vulkan/external_image.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use vulkano::command_buffer::sys::UnsafeCommandBufferBuilder;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::image::sys::UnsafeImage;
|
||||
use vulkano::image::sys::UnsafeImageCreateInfo;
|
||||
use vulkano::image::ImageLayout;
|
||||
use vulkano::image::ImageSubresourceRange;
|
||||
use vulkano::memory::DeviceMemory;
|
||||
use vulkano::memory::MemoryAllocateInfo;
|
||||
use vulkano::memory::MemoryImportInfo;
|
||||
use vulkano::sync::AccessFlags;
|
||||
use vulkano::sync::PipelineStages;
|
||||
use vulkano::DeviceSize;
|
||||
|
||||
pub struct AcquireImageMemoryBarrier {
|
||||
pub source_stages: PipelineStages,
|
||||
pub destination_stages: PipelineStages,
|
||||
pub destination_access: AccessFlags,
|
||||
pub destination_queue_family_index: u32,
|
||||
pub subresource_range: ImageSubresourceRange,
|
||||
}
|
||||
|
||||
pub struct ReleaseImageMemoryBarrier {
|
||||
pub source_stages: PipelineStages,
|
||||
pub source_access: AccessFlags,
|
||||
pub destination_stages: PipelineStages,
|
||||
pub new_layout: ImageLayout,
|
||||
pub source_queue_family_index: u32,
|
||||
}
|
||||
|
||||
/// ExternalImage represents a vulkan image that is imported from an external context.
|
||||
pub struct ExternalImage {
|
||||
image: Arc<UnsafeImage>,
|
||||
memory: DeviceMemory,
|
||||
}
|
||||
|
||||
impl ExternalImage {
|
||||
/// Import an external image into this Device. This function will take the ownership of the
|
||||
/// handle in `memory_import_info` on all platforms.
|
||||
pub fn import(
|
||||
_device: &Arc<Device>,
|
||||
_image_create_info: UnsafeImageCreateInfo,
|
||||
_memory_allocate_info: MemoryAllocateInfo<'_>,
|
||||
_memory_import_info: MemoryImportInfo,
|
||||
_dedicated_allocation: bool,
|
||||
_bind_offset: DeviceSize,
|
||||
) -> Result<Self> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Transition this image from the external source to be useable. This means performing the
|
||||
/// layout transition that it was exported with and applying the appropriate queue family
|
||||
/// transfers.
|
||||
pub fn acquire(
|
||||
self,
|
||||
_command_buffer_builder: &mut UnsafeCommandBufferBuilder,
|
||||
_image_memory_barrier: AcquireImageMemoryBarrier,
|
||||
_last_layout_transition: (ImageLayout, ImageLayout),
|
||||
) -> ExternalImageAccess {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// ExternalImageAccess represents a vulkan image that is imported from an external context and
|
||||
/// transitioned for use by another context.
|
||||
pub struct ExternalImageAccess {
|
||||
image: Arc<UnsafeImage>,
|
||||
memory: DeviceMemory,
|
||||
layout: ImageLayout,
|
||||
subresource_range: ImageSubresourceRange,
|
||||
}
|
||||
|
||||
impl ExternalImageAccess {
|
||||
/// Transition this image back to an ExternalImage, after which it can be used by other
|
||||
/// contexts. This undoes the queue family and layout transitions done by acquire.
|
||||
pub fn release(
|
||||
self,
|
||||
_command_buffer_builder: &mut UnsafeCommandBufferBuilder,
|
||||
_image_memory_barrier: ReleaseImageMemoryBarrier,
|
||||
) -> ExternalImage {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
67
gpu_display/src/vulkan/post_worker.rs
Normal file
67
gpu_display/src/vulkan/post_worker.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use ash::vk::UUID_SIZE;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::image::ImageLayout;
|
||||
use vulkano::image::{self};
|
||||
use vulkano::swapchain::{self};
|
||||
use vulkano::sync::Semaphore;
|
||||
use vulkano::VulkanLibrary;
|
||||
|
||||
use super::sys::Window;
|
||||
use super::ExternalImage;
|
||||
|
||||
type VulkanoWindow = Arc<dyn Any + Send + Sync>;
|
||||
type Surface = swapchain::Surface<VulkanoWindow>;
|
||||
type Swapchain = swapchain::Swapchain<VulkanoWindow>;
|
||||
type SwapchainImage = image::swapchain::SwapchainImage<VulkanoWindow>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Timepoint {
|
||||
pub semaphore: Arc<Semaphore>,
|
||||
pub value: u64,
|
||||
}
|
||||
|
||||
/// PostResource contains the required structures and information for posting to an individual
|
||||
/// swapchain image.
|
||||
pub struct PostResource {}
|
||||
|
||||
/// PostWorker owns the vulkan surface and swapchain, and can post images to it.
|
||||
pub struct PostWorker {
|
||||
device: Arc<Device>,
|
||||
}
|
||||
|
||||
impl PostWorker {
|
||||
pub(crate) fn new(
|
||||
_vulkan_library: Arc<VulkanLibrary>,
|
||||
_device_uuid: &[u8; UUID_SIZE],
|
||||
_driver_uuid: &[u8; UUID_SIZE],
|
||||
_window: Arc<dyn Window>,
|
||||
) -> Result<Self> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn recreate_swapchain(&mut self) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn post(
|
||||
&mut self,
|
||||
_image: ExternalImage,
|
||||
_last_layout_transition: (ImageLayout, ImageLayout),
|
||||
_acquire_timepoint: Option<Timepoint>,
|
||||
_release_timepoint: Timepoint,
|
||||
) -> ExternalImage {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn device(&self) -> Arc<Device> {
|
||||
Arc::clone(&self.device)
|
||||
}
|
||||
}
|
69
gpu_display/src/vulkan/sys.rs
Normal file
69
gpu_display/src/vulkan/sys.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
pub mod unix;
|
||||
pub use unix as platform;
|
||||
pub(crate) use self::unix::StubWindowEventLoop as PlatformWindowEventLoop;
|
||||
} else if #[cfg(windows)] {
|
||||
pub mod windows;
|
||||
pub use windows as platform;
|
||||
pub(crate) use self::windows::WindowsWindowEventLoop as PlatformWindowEventLoop;
|
||||
}
|
||||
}
|
||||
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use euclid::Box2D;
|
||||
use euclid::Size2D;
|
||||
use euclid::UnknownUnit;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::swapchain;
|
||||
|
||||
type Surface = swapchain::Surface<Arc<dyn Any + Send + Sync>>;
|
||||
|
||||
pub(crate) trait Window: Any + Send + Sync {
|
||||
fn get_inner_size(&self) -> Result<Size2D<u32, UnknownUnit>>;
|
||||
fn create_vulkan_surface(self: Arc<Self>, instance: Arc<Instance>) -> Result<Arc<Surface>>;
|
||||
}
|
||||
|
||||
pub(crate) trait ApplicationState {
|
||||
type UserEvent: Send + 'static;
|
||||
|
||||
fn process_event(&self, event: WindowEvent<Self::UserEvent>);
|
||||
}
|
||||
|
||||
pub(crate) trait ApplicationStateBuilder: Send + 'static {
|
||||
type Target: ApplicationState;
|
||||
|
||||
fn build<T: Window>(self, window: Arc<T>) -> Result<Self::Target>;
|
||||
}
|
||||
|
||||
// Some platform may not support all the events.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum WindowEvent<T: Send> {
|
||||
Resized,
|
||||
User(T),
|
||||
}
|
||||
|
||||
pub(crate) trait WindowEventLoop<State: ApplicationState>: Sized {
|
||||
type WindowType: Window;
|
||||
|
||||
/// # Safety
|
||||
/// The parent window must outlive the lifetime of this object.
|
||||
unsafe fn create<Builder>(
|
||||
parent: platform::NativeWindowType,
|
||||
initial_window_size: &Size2D<i32, UnknownUnit>,
|
||||
application_state_builder: Builder,
|
||||
) -> Result<Self>
|
||||
where
|
||||
Builder: ApplicationStateBuilder<Target = State>;
|
||||
|
||||
fn send_event(&self, event: State::UserEvent) -> Result<()>;
|
||||
|
||||
fn move_window(&self, pos: &Box2D<i32, UnknownUnit>) -> Result<()>;
|
||||
}
|
81
gpu_display/src/vulkan/sys/unix.rs
Normal file
81
gpu_display/src/vulkan/sys/unix.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use ash::vk;
|
||||
use base::AsRawDescriptor;
|
||||
use euclid::Size2D;
|
||||
use euclid::UnknownUnit;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::memory::ExternalMemoryHandleTypes;
|
||||
use vulkano::memory::MemoryImportInfo;
|
||||
|
||||
use super::ApplicationState;
|
||||
use super::ApplicationStateBuilder;
|
||||
use super::Surface;
|
||||
use super::Window;
|
||||
use super::WindowEventLoop;
|
||||
|
||||
pub type NativeWindowType = *mut c_void;
|
||||
|
||||
pub(crate) struct StubWindow;
|
||||
|
||||
impl Window for StubWindow {
|
||||
fn create_vulkan_surface(self: Arc<Self>, _instance: Arc<Instance>) -> Result<Arc<Surface>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_inner_size(&self) -> Result<Size2D<u32, UnknownUnit>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct StubWindowEventLoop<AppState: ApplicationState>(PhantomData<AppState>);
|
||||
|
||||
impl<AppState: ApplicationState> WindowEventLoop<AppState> for StubWindowEventLoop<AppState> {
|
||||
type WindowType = StubWindow;
|
||||
|
||||
unsafe fn create<Builder>(
|
||||
_parent: NativeWindowType,
|
||||
_initial_window_size: &Size2D<i32, UnknownUnit>,
|
||||
_application_state_builder: Builder,
|
||||
) -> Result<Self>
|
||||
where
|
||||
Builder: ApplicationStateBuilder<Target = AppState>,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn move_window(&self, _pos: &euclid::Box2D<i32, UnknownUnit>) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn send_event(&self, _event: AppState::UserEvent) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_post_image_external_memory_handle_types() -> ExternalMemoryHandleTypes {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// The ownership of the descriptor is transferred to the returned MemoryImportInfo.
|
||||
pub(crate) fn create_post_image_memory_import_info(
|
||||
_memory_descriptor: &dyn AsRawDescriptor,
|
||||
) -> MemoryImportInfo {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn import_semaphore_from_descriptor(
|
||||
_device: &Arc<Device>,
|
||||
_semaphore: vk::Semaphore,
|
||||
_descriptor: &dyn AsRawDescriptor,
|
||||
) -> vk::Result {
|
||||
unimplemented!()
|
||||
}
|
93
gpu_display/src/vulkan/sys/windows.rs
Normal file
93
gpu_display/src/vulkan/sys/windows.rs
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use ash::vk;
|
||||
use base::AsRawDescriptor;
|
||||
use euclid::Box2D;
|
||||
use euclid::Size2D;
|
||||
use euclid::UnknownUnit;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::memory::ExternalMemoryHandleTypes;
|
||||
use vulkano::memory::MemoryImportInfo;
|
||||
use winapi::shared::windef::HWND;
|
||||
|
||||
use super::ApplicationState;
|
||||
use super::ApplicationStateBuilder;
|
||||
use super::Surface;
|
||||
use super::Window as WindowT;
|
||||
use super::WindowEventLoop;
|
||||
|
||||
pub type NativeWindowType = HWND;
|
||||
|
||||
pub(crate) struct Window {}
|
||||
|
||||
impl WindowT for Window {
|
||||
fn get_inner_size(&self) -> Result<Size2D<u32, euclid::UnknownUnit>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn create_vulkan_surface(self: Arc<Self>, _instance: Arc<Instance>) -> Result<Arc<Surface>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
struct WindowState<AppState: ApplicationState> {
|
||||
app_state: AppState,
|
||||
window: Arc<Window>,
|
||||
}
|
||||
|
||||
pub(crate) struct WindowsWindowEventLoop<AppState: ApplicationState>(PhantomData<AppState>);
|
||||
|
||||
impl<AppState: ApplicationState> WindowEventLoop<AppState> for WindowsWindowEventLoop<AppState> {
|
||||
type WindowType = Window;
|
||||
|
||||
/// # Safety
|
||||
/// The parent window must outlive the lifetime of this object.
|
||||
#[deny(unsafe_op_in_unsafe_fn)]
|
||||
unsafe fn create<Builder>(
|
||||
_parent: NativeWindowType,
|
||||
_initial_window_size: &Size2D<i32, UnknownUnit>,
|
||||
_application_state_builder: Builder,
|
||||
) -> Result<Self>
|
||||
where
|
||||
Builder: ApplicationStateBuilder<Target = AppState>,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn move_window(&self, _pos: &Box2D<i32, UnknownUnit>) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn send_event(&self, _event: AppState::UserEvent) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_post_image_external_memory_handle_types() -> ExternalMemoryHandleTypes {
|
||||
ExternalMemoryHandleTypes {
|
||||
opaque_win32: true,
|
||||
..ExternalMemoryHandleTypes::empty()
|
||||
}
|
||||
}
|
||||
|
||||
// The ownership of the descriptor is transferred to the returned MemoryImportInfo.
|
||||
pub(crate) fn create_post_image_memory_import_info(
|
||||
_memory_descriptor: &dyn AsRawDescriptor,
|
||||
) -> MemoryImportInfo {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn import_semaphore_from_descriptor(
|
||||
_device: &Arc<Device>,
|
||||
_semaphore: vk::Semaphore,
|
||||
_descriptor: &dyn AsRawDescriptor,
|
||||
) -> vk::Result {
|
||||
unimplemented!()
|
||||
}
|
Loading…
Reference in a new issue