Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New dynamic graph implementation #304

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ members = [
"graph",
"core",
"texture",
"scheduler",
"cache",
]
16 changes: 16 additions & 0 deletions cache/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "rendy-cache"
version = "0.5.1"
authors = ["Hans Elias B. Josephsen <[email protected]>"]
edition = "2018"

[dependencies]
rendy-core = { version = "0.5.1", path = "../core" }
rendy-resource = { version = "0.5.1", path = "../resource" }
rendy-memory = { version = "0.5.1", path = "../memory" }
#rendy-shader = { version = "0.5.1", path = "../shader" }
rendy-descriptor = { version = "0.5.1", path = "../descriptor" }

parking_lot = "0.9"
smallvec = "1.3"
fxhash = "0.2"
19 changes: 19 additions & 0 deletions cache/resource_graph.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
digraph {
Image -> ImageView
Buffer -> BufferView
Sampler -> DescriptorSetLayout
DescriptorSetLayout -> PipelineLayout
ShaderModule -> GraphicsPipeline
PipelineLayout -> GraphicsPipeline
RenderPass -> GraphicsPipeline
RenderPass -> Framebuffer
ImageView -> Framebuffer

DescriptorPool -> DescriptorSet
DescriptorSetLayout -> DescriptorSet

Sampler -> DescriptorSet
ImageView -> DescriptorSet
Buffer -> DescriptorSet
BufferView -> DescriptorSet
}
Binary file added cache/resource_graph.dot.pdf
Binary file not shown.
11 changes: 11 additions & 0 deletions cache/src/dependent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crate::handle::DynHandle;

pub struct ResourceProbe {}
pub struct ResourceProbeNotifier {}

pub struct ResourceProbeInner {}

pub enum Dependent {
Handle(DynHandle),
Probe(ResourceProbeNotifier),
}
7 changes: 7 additions & 0 deletions cache/src/graph/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use fxhash::FxHashSet;

use crate::handle::DynHandle;

struct Graph {
nodes: FxHashMap<DynHandle, FxHashSet<DynHandle>>,
}
55 changes: 55 additions & 0 deletions cache/src/handle/ephemerial_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::Index;

use fxhash::FxHashMap;

use rendy_core::DeviceId;

use crate::Managed;
use super::{Handle, HandleGen, HasKey, HasValue};

pub struct EphemerialStore<M>
where
M: HasKey + HasValue,
{
gen: HandleGen<M>,
forward: FxHashMap<M::Key, Handle<M>>,
entries: FxHashMap<Handle<M>, Managed<M>>,
}

impl<M> EphemerialStore<M>
where
M: HasKey + HasValue,
{

pub fn new(device: DeviceId) -> Self {
EphemerialStore {
gen: HandleGen::new(device),
forward: HashMap::default(),
entries: HashMap::default(),
}
}

pub fn lookup_key(&self, key: &M::Key) -> Option<Handle<M>> {
self.forward.get(key).cloned()
}

pub fn insert(&mut self, key: M::Key, value: M::Value) -> Handle<M> {
debug_assert!(&self.forward.contains_key(&key));

let handle = self.gen.next();
let managed = Managed::new(value, handle);
self.forward.insert(key, handle);
self.entries.insert(handle, managed);
handle
}

}

impl<M: HasKey + HasValue> Index<Handle<M>> for EphemerialStore<M> {
type Output = Managed<M>;
fn index(&self, idx: Handle<M>) -> &Managed<M> {
unimplemented!()
}
}
45 changes: 45 additions & 0 deletions cache/src/handle/instance_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::ops::Index;
use std::collections::HashMap;

use fxhash::FxHashMap;

use rendy_core::DeviceId;

use crate::Managed;
use super::{Handle, HandleGen, HasValue};

pub struct InstanceStore<M>
where
M: HasValue,
{
gen: HandleGen<M>,
entries: FxHashMap<Handle<M>, Managed<M>>,
}

impl<M> InstanceStore<M>
where
M: HasValue,
{

pub fn new(device: DeviceId) -> Self {
InstanceStore {
gen: HandleGen::new(device),
entries: HashMap::default(),
}
}

pub fn insert(&mut self, value: M::Value) -> Handle<M> {
let handle = self.gen.next();
let managed = Managed::new(value, handle);
self.entries.insert(handle, managed);
handle
}

}

impl<M: HasValue> Index<Handle<M>> for InstanceStore<M> {
type Output = Managed<M>;
fn index(&self, idx: Handle<M>) -> &Managed<M> {
unimplemented!()
}
}
118 changes: 118 additions & 0 deletions cache/src/handle/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use std::marker::PhantomData;
use std::fmt::{Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::any::{Any, TypeId};

use rendy_core::DeviceId;

mod instance_store;
pub use instance_store::InstanceStore;

mod ephemerial_store;
pub use ephemerial_store::EphemerialStore;

pub trait HasKey: HasValue {
type Key: Clone + Eq + Hash + 'static;
}
pub trait HasValue: 'static {
type Value: 'static;
}

pub struct HandleGen<T> {
device: DeviceId,
curr: usize,
_phantom: PhantomData<T>,
}
impl<T> HandleGen<T> {

pub fn new(device: DeviceId) -> Self {
HandleGen {
device,
curr: 0,
_phantom: PhantomData,
}
}

pub fn next(&mut self) -> Handle<T> {
self.curr += 1;
Handle {
device: self.device,
idx: self.curr,
_phantom: PhantomData,
}
}

}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct DynHandle {
device: DeviceId,
idx: usize,
marker: TypeId,
}
impl DynHandle {

pub fn try_cast<T: 'static>(&self) -> Option<Handle<T>> {
let tid = TypeId::of::<T>();
if tid == self.marker {
Some(Handle {
device: self.device,
idx: self.idx,
_phantom: PhantomData,
})
} else {
None
}
}

}

pub struct Handle<T> {
device: DeviceId,
idx: usize,
_phantom: PhantomData<T>,
}

impl<T> Handle<T> {

pub fn device(&self) -> DeviceId {
self.device
}

}

impl<T> Debug for Handle<T> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
let type_name = std::any::type_name::<T>();
write!(fmt, "Handle({}, {})", type_name, self.idx)
}
}
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Handle {
device: self.device,
idx: self.idx,
_phantom: PhantomData,
}
}
}
impl<T> Copy for Handle<T> {}
impl<T> PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool {
self.idx == other.idx
}
}
impl<T> Eq for Handle<T> {}
impl<T> Hash for Handle<T>
where
T: Any,
{
fn hash<H>(&self, hasher: &mut H)
where
H: Hasher,
{
let tid = TypeId::of::<T>();
tid.hash(hasher);
self.idx.hash(hasher);
}
}
21 changes: 21 additions & 0 deletions cache/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
mod handle;

mod resource_manager;
pub use resource_manager::ResourceManager;

mod resource;
pub use resource::{
Managed,
buffer::ManagedBuffer,
image::ManagedImage,
image_view::ManagedImageView,
shader_module::ManagedShaderModule,
sampler::ManagedSampler,
descriptor_set_layout::ManagedDescriptorSetLayout,
pipeline_layout::ManagedPipelineLayout,
render_pass::ManagedRenderPass,
graphics_pipeline::ManagedGraphicsPipeline,
framebuffer::ManagedFramebuffer,
};

mod dependent;
87 changes: 87 additions & 0 deletions cache/src/resource/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use std::marker::PhantomData;

use rendy_core::{hal, Device, hal::device::Device as DeviceTrait};
use rendy_memory::{Heaps, MemoryBlock, MemoryUsage, Block, MappedRange};
use rendy_resource::{BufferInfo, CreationError};

use crate::{
//ManagedDomain,
handle::{HasValue, Handle},
resource::Managed,
};

pub type ManagedBuffer<B> = Managed<BufferMarker<B>>;
pub struct BufferMarker<B>(PhantomData<B>) where B: hal::Backend;
impl<B> HasValue for BufferMarker<B> where B: hal::Backend {
type Value = ManagedBufferData<B>;
}
pub type BufferHandle<B> = Handle<BufferMarker<B>>;

pub struct ManagedBufferData<B>
where
B: hal::Backend,
{
raw: B::Buffer,
block: MemoryBlock<B>,
info: BufferInfo,
}

impl<B: hal::Backend> ManagedBufferData<B> {

pub fn create(
device: &Device<B>,
heaps: &mut Heaps<B>,
//domain: ManagedDomain,
info: BufferInfo,
memory_usage: impl MemoryUsage,
) -> Result<Self, CreationError<hal::buffer::CreationError>>
{
assert_ne!(info.size, 0);

let mut buf = unsafe {
device
.create_buffer(info.size, info.usage)
.map_err(CreationError::Create)?
};
let reqs = unsafe { device.get_buffer_requirements(&buf) };
let block = heaps
.allocate(
device,
reqs.type_mask as u32,
memory_usage,
reqs.size,
reqs.alignment,
)
.map_err(CreationError::Allocate)?;

unsafe {
device
.bind_buffer_memory(block.memory(), block.range().start, &mut buf)
.map_err(CreationError::Bind)?;
}

let data = Self {
raw: buf,
block,
info,
};
Ok(data)
}

}

impl<B: hal::Backend> ManagedBuffer<B> {

pub fn raw(&self) -> &B::Buffer {
&self.inner.value.raw
}
/// Map range of the buffer to the CPU accessible memory.
pub fn map<'a>(
&'a mut self,
device: &Device<B>,
range: std::ops::Range<u64>,
) -> Result<MappedRange<'a, B>, rendy_core::hal::device::MapError> {
self.inner.value.block.map(device, range)
}

}
Loading