diff --git a/Cargo.lock b/Cargo.lock index 331cddc4ef..efe9490be3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 753a10b6b6..04bf1abc84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/common/sync/src/lib.rs b/common/sync/src/lib.rs index 0a9f80cb98..295109caeb 100644 --- a/common/sync/src/lib.rs +++ b/common/sync/src/lib.rs @@ -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)>); + +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) -> 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)>); + +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)) +} diff --git a/gpu_display/Cargo.toml b/gpu_display/Cargo.toml index 6ccc643ce7..04eb27e6ab 100644 --- a/gpu_display/Cargo.toml +++ b/gpu_display/Cargo.toml @@ -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" diff --git a/gpu_display/src/lib.rs b/gpu_display/src/lib.rs index 43b9f7cb63..f2d674bd27 100644 --- a/gpu_display/src/lib.rs +++ b/gpu_display/src/lib.rs @@ -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; diff --git a/gpu_display/src/vulkan.rs b/gpu_display/src/vulkan.rs new file mode 100644 index 0000000000..d10ffebfc7 --- /dev/null +++ b/gpu_display/src/vulkan.rs @@ -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, + 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, + release_timepoint: Timepoint, + image_return: Sender, + 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) { + unimplemented!() + } +} + +struct VulkanStateBuilder { + vulkan_library: Arc, + device_uuid: [u8; vk::UUID_SIZE], + driver_uuid: [u8; vk::UUID_SIZE], +} + +impl ApplicationStateBuilder for VulkanStateBuilder { + type Target = VulkanState; + + fn build(self, _window: Arc) -> Result { + unimplemented!() + } +} + +pub(crate) struct VulkanDisplayImpl> { + window_event_loop: T, +} + +impl> VulkanDisplayImpl { + 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 { + unimplemented!() + } +} + +pub(crate) type VulkanDisplay = VulkanDisplayImpl>; diff --git a/gpu_display/src/vulkan/external_image.rs b/gpu_display/src/vulkan/external_image.rs new file mode 100644 index 0000000000..cb39bc3a34 --- /dev/null +++ b/gpu_display/src/vulkan/external_image.rs @@ -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, + 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, + _image_create_info: UnsafeImageCreateInfo, + _memory_allocate_info: MemoryAllocateInfo<'_>, + _memory_import_info: MemoryImportInfo, + _dedicated_allocation: bool, + _bind_offset: DeviceSize, + ) -> Result { + 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, + 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!() + } +} diff --git a/gpu_display/src/vulkan/post_worker.rs b/gpu_display/src/vulkan/post_worker.rs new file mode 100644 index 0000000000..dc2eac4e93 --- /dev/null +++ b/gpu_display/src/vulkan/post_worker.rs @@ -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; +type Surface = swapchain::Surface; +type Swapchain = swapchain::Swapchain; +type SwapchainImage = image::swapchain::SwapchainImage; + +#[derive(Clone)] +pub struct Timepoint { + pub semaphore: Arc, + 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, +} + +impl PostWorker { + pub(crate) fn new( + _vulkan_library: Arc, + _device_uuid: &[u8; UUID_SIZE], + _driver_uuid: &[u8; UUID_SIZE], + _window: Arc, + ) -> Result { + unimplemented!() + } + + pub fn recreate_swapchain(&mut self) -> Result<()> { + unimplemented!() + } + + pub fn post( + &mut self, + _image: ExternalImage, + _last_layout_transition: (ImageLayout, ImageLayout), + _acquire_timepoint: Option, + _release_timepoint: Timepoint, + ) -> ExternalImage { + unimplemented!() + } + + pub fn device(&self) -> Arc { + Arc::clone(&self.device) + } +} diff --git a/gpu_display/src/vulkan/sys.rs b/gpu_display/src/vulkan/sys.rs new file mode 100644 index 0000000000..70e9c92c35 --- /dev/null +++ b/gpu_display/src/vulkan/sys.rs @@ -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>; + +pub(crate) trait Window: Any + Send + Sync { + fn get_inner_size(&self) -> Result>; + fn create_vulkan_surface(self: Arc, instance: Arc) -> Result>; +} + +pub(crate) trait ApplicationState { + type UserEvent: Send + 'static; + + fn process_event(&self, event: WindowEvent); +} + +pub(crate) trait ApplicationStateBuilder: Send + 'static { + type Target: ApplicationState; + + fn build(self, window: Arc) -> Result; +} + +// Some platform may not support all the events. +#[allow(dead_code)] +pub(crate) enum WindowEvent { + Resized, + User(T), +} + +pub(crate) trait WindowEventLoop: Sized { + type WindowType: Window; + + /// # Safety + /// The parent window must outlive the lifetime of this object. + unsafe fn create( + parent: platform::NativeWindowType, + initial_window_size: &Size2D, + application_state_builder: Builder, + ) -> Result + where + Builder: ApplicationStateBuilder; + + fn send_event(&self, event: State::UserEvent) -> Result<()>; + + fn move_window(&self, pos: &Box2D) -> Result<()>; +} diff --git a/gpu_display/src/vulkan/sys/unix.rs b/gpu_display/src/vulkan/sys/unix.rs new file mode 100644 index 0000000000..6dda1f74a4 --- /dev/null +++ b/gpu_display/src/vulkan/sys/unix.rs @@ -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, _instance: Arc) -> Result> { + unimplemented!(); + } + + fn get_inner_size(&self) -> Result> { + unimplemented!() + } +} + +pub(crate) struct StubWindowEventLoop(PhantomData); + +impl WindowEventLoop for StubWindowEventLoop { + type WindowType = StubWindow; + + unsafe fn create( + _parent: NativeWindowType, + _initial_window_size: &Size2D, + _application_state_builder: Builder, + ) -> Result + where + Builder: ApplicationStateBuilder, + { + unimplemented!() + } + + fn move_window(&self, _pos: &euclid::Box2D) -> 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, + _semaphore: vk::Semaphore, + _descriptor: &dyn AsRawDescriptor, +) -> vk::Result { + unimplemented!() +} diff --git a/gpu_display/src/vulkan/sys/windows.rs b/gpu_display/src/vulkan/sys/windows.rs new file mode 100644 index 0000000000..17ec889b40 --- /dev/null +++ b/gpu_display/src/vulkan/sys/windows.rs @@ -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> { + unimplemented!() + } + + fn create_vulkan_surface(self: Arc, _instance: Arc) -> Result> { + unimplemented!() + } +} + +struct WindowState { + app_state: AppState, + window: Arc, +} + +pub(crate) struct WindowsWindowEventLoop(PhantomData); + +impl WindowEventLoop for WindowsWindowEventLoop { + type WindowType = Window; + + /// # Safety + /// The parent window must outlive the lifetime of this object. + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn create( + _parent: NativeWindowType, + _initial_window_size: &Size2D, + _application_state_builder: Builder, + ) -> Result + where + Builder: ApplicationStateBuilder, + { + unimplemented!() + } + + fn move_window(&self, _pos: &Box2D) -> 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, + _semaphore: vk::Semaphore, + _descriptor: &dyn AsRawDescriptor, +) -> vk::Result { + unimplemented!() +}