Skip to content

Commit

Permalink
Merges VMM screen into graphics module (#1134)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Nov 23, 2024
1 parent e83866b commit 2f65374
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 195 deletions.
11 changes: 0 additions & 11 deletions gui/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ struct Profile;
*/
struct RustError;

/**
* Manage a virtual machine that run the kernel.
*/
struct Vmm;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
Expand Down Expand Up @@ -130,12 +125,6 @@ struct RustError *update_firmware(const char *root,
void *cx,
void (*status)(const char*, uint64_t, uint64_t, void*));

void vmm_free(struct Vmm *vmm);

void vmm_shutdown(struct Vmm *vmm);

bool vmm_shutting_down(struct Vmm *vmm);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
9 changes: 0 additions & 9 deletions gui/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,3 @@ inline void Rust<RustError>::free()
m_ptr = nullptr;
}
}

template<>
inline void Rust<Vmm>::free()
{
if (m_ptr) {
vmm_free(m_ptr);
m_ptr = nullptr;
}
}
43 changes: 0 additions & 43 deletions gui/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,26 +218,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
// This will set to accept by QMainWindow::closeEvent.
event->ignore();

// Ask user to confirm.
if (m_vmm) {
// Ask user to confirm only if we did not shutdown the VMM programmatically.
if (!vmm_shutting_down(m_vmm)) {
QMessageBox confirm(this);

confirm.setText("Do you want to exit?");
confirm.setInformativeText("The running game will be terminated.");
confirm.setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
confirm.setDefaultButton(QMessageBox::Cancel);
confirm.setIcon(QMessageBox::Warning);

if (confirm.exec() != QMessageBox::Yes) {
return;
}
}

killVmm();
}

// Save geometry.
QSettings settings;

Expand Down Expand Up @@ -484,27 +464,6 @@ void MainWindow::startDebug(const QString &addr)
}
}

bool MainWindow::requireVmmStopped()
{
if (m_vmm) {
QMessageBox prompt(this);

prompt.setText("Action requires VMM to be stopped to continue.");
prompt.setInformativeText("Do you want to kill the VMM?");
prompt.setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
prompt.setDefaultButton(QMessageBox::Cancel);
prompt.setIcon(QMessageBox::Warning);

if (prompt.exec() != QMessageBox::Yes) {
return false;
}

killVmm();
}

return true;
}

void MainWindow::stopDebug()
{
// We can't free the VMM here because the thread that trigger this method are waiting
Expand All @@ -525,8 +484,6 @@ void MainWindow::stopDebug()

void MainWindow::killVmm()
{
m_vmm.free();

delete m_debugNoti;
m_debugNoti = nullptr;
}
2 changes: 0 additions & 2 deletions gui/main_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ private slots:
void vmmError(const QString &msg);
void waitKernelExit(bool success);
bool loadGame(const QString &gameId);
bool requireVmmStopped();
void stopDebug();
void killVmm();

Expand All @@ -58,7 +57,6 @@ private slots:
Screen *m_screen;
Rust<DebugServer> m_debugServer;
QSocketNotifier *m_debugNoti;
Rust<Vmm> m_vmm; // Destroy first.
};

namespace Args {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::ScreenBuffer;
use crate::graphics::ScreenBuffer;

/// Manages Metal off-screen buffers.
pub struct MetalBuffer {}
Expand Down
21 changes: 15 additions & 6 deletions gui/src/graphics/metal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use self::screen::MetalScreen;
use super::Graphics;
use metal::Device;
use std::ops::Deref;
use thiserror::Error;

mod buffer;
mod screen;

pub struct Metal {
devices: Vec<metal::Device>,
}

impl super::GraphicsApi for Metal {
impl Graphics for Metal {
type Err = MetalError;
type PhysicalDevice = metal::Device;
type Screen = MetalScreen;

type CreateError = MetalCreateError;

fn new() -> Result<Self, Self::CreateError> {
fn new() -> Result<Self, Self::Err> {
Ok(Self {
devices: Device::all(),
})
Expand All @@ -21,6 +26,10 @@ impl super::GraphicsApi for Metal {
fn physical_devices(&self) -> &[Self::PhysicalDevice] {
&self.devices
}

fn create_screen(&mut self) -> Result<Self::Screen, Self::Err> {
todo!()
}
}

impl super::PhysicalDevice for metal::Device {
Expand All @@ -29,6 +38,6 @@ impl super::PhysicalDevice for metal::Device {
}
}

/// Represents an error when [`Metal::new()`] fails.
/// Implementation of [`Graphics::Err`] for Metal.
#[derive(Debug, Error)]
pub enum MetalCreateError {}
pub enum MetalError {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use self::buffer::MetalBuffer;
use crate::graphics::{Screen, ScreenBuffer};
use super::buffer::MetalBuffer;
use crate::graphics::Screen;
use crate::vmm::VmmScreen;
use metal::{CAMetalLayer, Device, MetalLayer};
use objc::runtime::{Object, NO, YES};
Expand All @@ -9,8 +9,6 @@ use std::ptr::null_mut;
use std::sync::Arc;
use thiserror::Error;

mod buffer;

/// Implementation of [`Screen`] using Metal.
///
/// Fields in this struct need to be dropped in a correct order.
Expand Down
10 changes: 5 additions & 5 deletions gui/src/graphics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ pub type DefaultApi = self::engine::Vulkan;
pub type DefaultApi = self::engine::Metal;

/// The underlying graphics engine (e.g. Vulkan).
pub trait GraphicsApi: Sized + 'static {
pub trait Graphics: Sized + 'static {
type Err: Error;
type PhysicalDevice: PhysicalDevice;
type Screen: Screen;

type CreateError: core::error::Error;

fn new() -> Result<Self, Self::CreateError>;

fn new() -> Result<Self, Self::Err>;
fn physical_devices(&self) -> &[Self::PhysicalDevice];
fn create_screen(&mut self) -> Result<Self::Screen, Self::Err>;
}

pub trait PhysicalDevice: Sized {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::ScreenBuffer;
use crate::graphics::ScreenBuffer;

/// Manages Vulkan off-screen buffers.
pub struct VulkanBuffer {}
Expand Down
61 changes: 34 additions & 27 deletions gui/src/graphics/vulkan/mod.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,54 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use self::screen::VulkanScreen;
use super::Graphics;
use ash::vk::{ApplicationInfo, InstanceCreateInfo};
use std::ffi::CStr;
use thiserror::Error;

mod buffer;
mod screen;

pub struct Vulkan {
entry: ash::Entry,
instance: ash::Instance,
devices: Vec<VulkanPhysicalDevice>,
}

impl super::GraphicsApi for Vulkan {
impl Graphics for Vulkan {
type Err = VulkanError;
type PhysicalDevice = VulkanPhysicalDevice;
type Screen = VulkanScreen;

type CreateError = VulkanCreateError;

fn new() -> Result<Self, Self::CreateError> {
fn new() -> Result<Self, Self::Err> {
let entry = ash::Entry::linked();

let app_info = ApplicationInfo::default().application_name(c"Obliteration");

let create_info = InstanceCreateInfo::default().application_info(&app_info);

let instance = unsafe { entry.create_instance(&create_info, None) }
.map_err(VulkanCreateError::CreateInstanceFailed)?;
.map_err(VulkanError::CreateInstanceFailed)?;

let devices = unsafe { instance.enumerate_physical_devices() }
.map_err(VulkanCreateError::EnumeratePhysicalDevicesFailed)?
.map_err(VulkanError::EnumeratePhysicalDevicesFailed)?
.into_iter()
.map(
|device| -> Result<VulkanPhysicalDevice, VulkanCreateError> {
let properties = unsafe { instance.get_physical_device_properties(device) };

let name = CStr::from_bytes_until_nul(unsafe {
std::slice::from_raw_parts(
properties.device_name.as_ptr().cast(),
properties.device_name.len(),
)
})
.map_err(|_| VulkanCreateError::DeviceNameInvalid)?
.to_str()
.map_err(VulkanCreateError::DeviceNameInvalidUtf8)?
.to_owned();

Ok(VulkanPhysicalDevice { device, name })
},
)
.collect::<Result<_, VulkanCreateError>>()?;
.map(|device| -> Result<VulkanPhysicalDevice, VulkanError> {
let properties = unsafe { instance.get_physical_device_properties(device) };

let name = CStr::from_bytes_until_nul(unsafe {
std::slice::from_raw_parts(
properties.device_name.as_ptr().cast(),
properties.device_name.len(),
)
})
.map_err(|_| VulkanError::DeviceNameInvalid)?
.to_str()
.map_err(VulkanError::DeviceNameInvalidUtf8)?
.to_owned();

Ok(VulkanPhysicalDevice { device, name })
})
.collect::<Result<_, VulkanError>>()?;

Ok(Self {
entry,
Expand All @@ -57,6 +60,10 @@ impl super::GraphicsApi for Vulkan {
fn physical_devices(&self) -> &[Self::PhysicalDevice] {
&self.devices
}

fn create_screen(&mut self) -> Result<Self::Screen, Self::Err> {
todo!()
}
}

impl Drop for Vulkan {
Expand All @@ -76,9 +83,9 @@ impl super::PhysicalDevice for VulkanPhysicalDevice {
}
}

/// Represents an error when [`Vulkan::new()`] fails.
/// Implementation of [`Graphics::Err`] for Vulkan.
#[derive(Debug, Error)]
pub enum VulkanCreateError {
pub enum VulkanError {
#[error("couldn't create Vulkan instance")]
CreateInstanceFailed(#[source] ash::vk::Result),

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use self::buffer::VulkanBuffer;
use crate::graphics::{Screen, ScreenBuffer};
use super::buffer::VulkanBuffer;
use crate::graphics::Screen;
use crate::vmm::VmmScreen;
use ash::vk::{DeviceCreateInfo, DeviceQueueCreateInfo, Handle, QueueFlags};
use ash::Device;
use std::sync::Arc;
use thiserror::Error;

mod buffer;

/// Implementation of [`Screen`] using Vulkan.
pub struct VulkanScreen {
buffer: Arc<VulkanBuffer>,
Expand Down
1 change: 0 additions & 1 deletion gui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mod hv;
mod param;
mod pkg;
mod profile;
mod screen;
mod string;
mod system;
mod vmm;
Expand Down
Loading

0 comments on commit 2f65374

Please sign in to comment.