aboutsummaryrefslogtreecommitdiff
path: root/stockton-skeleton/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'stockton-skeleton/src/context.rs')
-rw-r--r--stockton-skeleton/src/context.rs54
1 files changed, 48 insertions, 6 deletions
diff --git a/stockton-skeleton/src/context.rs b/stockton-skeleton/src/context.rs
index 5e2d3a3..be627f2 100644
--- a/stockton-skeleton/src/context.rs
+++ b/stockton-skeleton/src/context.rs
@@ -2,13 +2,15 @@
//! This relies on draw passes for the actual drawing logic.
use std::{
+ any::{Any, TypeId},
+ collections::HashMap,
mem::ManuallyDrop,
ptr::read,
sync::{Arc, RwLock},
};
use anyhow::{Context, Result};
-use hal::pool::CommandPoolCreateFlags;
+use hal::{pool::CommandPoolCreateFlags, PhysicalDeviceProperties};
use log::debug;
use winit::window::Window;
@@ -21,16 +23,15 @@ use super::{
use crate::{
draw_passes::Singular,
error::{EnvironmentError, LockPoisoned},
+ mem::MemoryPool,
types::*,
};
use stockton_types::Session;
-/// Contains all the hal related stuff.
-/// In the end, this takes in a depth-sorted list of faces and a map file and renders them.
-// TODO: Settings for clear colour, buffer sizes, etc
+/// Contains most root vulkan objects, and some precalculated info such as best formats to use.
+/// In most cases, this and the DrawPass should contain all vulkan objects present.
pub struct RenderingContext {
- // Parents for most of these things
/// Vulkan Instance
instance: ManuallyDrop<back::Instance>,
@@ -40,6 +41,9 @@ pub struct RenderingContext {
/// Adapter we're using
adapter: Adapter,
+ /// The properties of the physical device we're using
+ physical_device_properties: PhysicalDeviceProperties,
+
/// Swapchain and stuff
target_chain: ManuallyDrop<TargetChain>,
@@ -47,12 +51,17 @@ pub struct RenderingContext {
/// The command pool used for our buffers
cmd_pool: ManuallyDrop<CommandPoolT>,
+ /// The queue negotiator to use
queue_negotiator: QueueNegotiator,
/// The queue to use for drawing
queue: Arc<RwLock<QueueT>>,
+ /// Number of pixels per standard point
pixels_per_point: f32,
+
+ /// The list of memory pools
+ memory_pools: HashMap<TypeId, Box<dyn Any>>,
}
impl RenderingContext {
@@ -164,6 +173,7 @@ impl RenderingContext {
instance: ManuallyDrop::new(instance),
device: device_lock,
+ physical_device_properties: adapter.physical_device.properties(),
adapter,
queue_negotiator,
@@ -172,8 +182,8 @@ impl RenderingContext {
target_chain: ManuallyDrop::new(target_chain),
cmd_pool: ManuallyDrop::new(cmd_pool),
- // pixels_per_point: window.scale_factor() as f32,
pixels_per_point: window.scale_factor() as f32,
+ memory_pools: HashMap::new(),
})
}
@@ -259,6 +269,36 @@ impl RenderingContext {
pub fn queue_negotiator_mut(&mut self) -> &mut QueueNegotiator {
&mut self.queue_negotiator
}
+
+ /// Get a reference to the physical device's properties.
+ pub fn physical_device_properties(&self) -> &PhysicalDeviceProperties {
+ &self.physical_device_properties
+ }
+
+ /// Get the specified memory pool, lazily initialising it if it's not yet present
+ pub fn memory_pool<'a, P: MemoryPool>(&'a mut self) -> Result<&'a Arc<RwLock<P>>> {
+ self.ensure_memory_pool::<P>()?;
+ Ok(self.existing_memory_pool::<P>().unwrap())
+ }
+
+ /// Ensure the specified memory pool is initialised.
+ pub fn ensure_memory_pool<P: MemoryPool>(&mut self) -> Result<()> {
+ let tid = TypeId::of::<P>();
+ if !self.memory_pools.contains_key(&tid) {
+ self.memory_pools
+ .insert(tid, Box::new(P::from_context(self)?));
+ }
+ Ok(())
+ }
+
+ /// Get the specified memory pool, returning None if it's not yet present
+ /// You should only use this when you're certain it exists, such as when freeing memory
+ /// allocated from that pool
+ pub fn existing_memory_pool<P: MemoryPool>(&self) -> Option<&Arc<RwLock<P>>> {
+ self.memory_pools
+ .get(&TypeId::of::<P>())
+ .map(|x| x.downcast_ref().unwrap())
+ }
}
impl core::ops::Drop for RenderingContext {
@@ -267,6 +307,8 @@ impl core::ops::Drop for RenderingContext {
self.device.write().unwrap().wait_idle().unwrap();
}
+ // TODO: Better deactivation code
+
unsafe {
let mut device = self.device.write().unwrap();