Skip to content

Commit

Permalink
Embedded gltf textures
Browse files Browse the repository at this point in the history
Also tweaks blade-asset API to borrow choir's ExecutionContext.
  • Loading branch information
kvark committed Nov 7, 2023
1 parent b70036d commit 42e2cc1
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 120 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ log = "0.4"
mint = "0.5"
naga = { version = "0.14", features = ["wgsl-in", "span", "validate"] }
profiling = "1"
slab = "0.4"
strum = { version = "0.25", features = ["derive"] }
web-sys = "0.3.60"

Expand Down
24 changes: 18 additions & 6 deletions blade-asset/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ impl<T: Default> Arena<T> {
unsafe { first_ptr.add(handle.0.index as usize) }
}

pub fn dealloc(&self, handle: Handle<T>) -> T {
pub fn _dealloc(&self, handle: Handle<T>) -> T {
let mut freeman = self.freeman.lock().unwrap();
freeman.free_list.push(handle.0);
let ptr = self.get_mut_ptr(handle);
unsafe { mem::take(&mut *ptr) }
mem::take(unsafe { &mut *ptr })
}

pub fn for_each(&self, mut fun: impl FnMut(Handle<T>, &T)) {
fn for_internal(&self, mut fun: impl FnMut(Address, *mut T)) {
let mut freeman = self.freeman.lock().unwrap();
freeman.free_list.sort(); // enables fast search
for (chunk_index, chunk_start) in self.chunks[..freeman.chunk_bases.len()]
Expand All @@ -147,14 +147,26 @@ impl<T: Default> Arena<T> {
chunk,
};
if freeman.free_list.binary_search(&address).is_err() {
//Note: this is only safe if `get_mut_ptr` isn't called
//Note: accessing this is only safe if `get_mut_ptr` isn't called
// for example, during hot reloading.
let item = unsafe { &*first_ptr.add(index) };
fun(Handle(address, PhantomData), item);
fun(address, unsafe { first_ptr.add(index) });
}
}
}
}

pub fn for_each(&self, mut fun: impl FnMut(Handle<T>, &T)) {
self.for_internal(|address, ptr| fun(Handle(address, PhantomData), unsafe { &*ptr }))
}

pub fn dealloc_each(&self, mut fun: impl FnMut(Handle<T>, T)) {
self.for_internal(|address, ptr| {
fun(
Handle(address, PhantomData),
mem::take(unsafe { &mut *ptr }),
)
})
}
}

impl<T> Drop for FreeManager<T> {
Expand Down
1 change: 1 addition & 0 deletions blade-asset/src/flat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ macro_rules! impl_basic {
impl_basic!(bool);
impl_basic!(u32);
impl_basic!(u64);
impl_basic!(usize);
impl_basic!(f32);

/*
Expand Down
78 changes: 61 additions & 17 deletions blade-asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl<T> Default for Slot<T> {
}
}

#[derive(Default)]
struct Inner {
result: Vec<u8>,
dependencies: Vec<PathBuf>,
Expand Down Expand Up @@ -143,6 +144,21 @@ impl<B: Baker> Cooker<B> {
}
}

/// Create a new container with no data, no path, and no hasher.
pub fn new_embedded() -> Self {
Self {
inner: Mutex::new(Inner::default()),
base_path: Default::default(),
_phantom: PhantomData,
}
}

pub fn extract_embedded(&self) -> Vec<u8> {
let mut inner = self.inner.lock().unwrap();
assert!(inner.dependencies.is_empty());
mem::take(&mut inner.result)
}

/// Return the base path of the asset.
pub fn base_path(&self) -> &Path {
&self.base_path
Expand Down Expand Up @@ -197,12 +213,12 @@ pub trait Baker: Sized + Send + Sync + 'static {
extension: &str,
meta: Self::Meta,
cooker: Arc<Cooker<Self>>,
exe_context: choir::ExecutionContext,
exe_context: &choir::ExecutionContext,
);
/// Produce the output bsed on a cooked asset.
///
/// This method is also called within a task `exe_context`.
fn serve(&self, cooked: Self::Data<'_>, exe_context: choir::ExecutionContext) -> Self::Output;
fn serve(&self, cooked: Self::Data<'_>, exe_context: &choir::ExecutionContext) -> Self::Output;
/// Delete the output of an asset.
fn delete(&self, output: Self::Output);
}
Expand Down Expand Up @@ -318,8 +334,8 @@ impl<B: Baker> AssetManager<B> {
}
}

pub fn get_main_source_path(&self, handle: Handle<B::Output>) -> &Path {
self.slots[handle.inner].sources.first().unwrap()
pub fn get_main_source_path(&self, handle: Handle<B::Output>) -> Option<&PathBuf> {
self.slots[handle.inner].sources.first()
}

fn make_target_path(&self, base_path: &Path, file_name: &Path, meta: &B::Meta) -> PathBuf {
Expand Down Expand Up @@ -405,7 +421,7 @@ impl<B: Baker> AssetManager<B> {
baker.delete(data);
}
let cooked = unsafe { <B::Data<'_> as Flat>::read(inner.result.as_ptr()) };
let target = baker.serve(cooked, exe_context);
let target = baker.serve(cooked, &exe_context);
unsafe {
*dr.data = Some(target);
*dr.version = version;
Expand All @@ -427,7 +443,7 @@ impl<B: Baker> AssetManager<B> {
Some(data) => data,
None => cooker_arg.add_dependency(&file_name),
};
baker.cook(&source, extension, meta, cooker_arg, exe_context);
baker.cook(&source, extension, meta, cooker_arg, &exe_context);
});

load_task.depend_on(&cook_task);
Expand All @@ -447,7 +463,7 @@ impl<B: Baker> AssetManager<B> {
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
let cooked = unsafe { <B::Data<'_> as Flat>::read(data.as_ptr()) };
let target = baker.serve(cooked, exe_context);
let target = baker.serve(cooked, &exe_context);
let dr = data_ref;
unsafe {
*dr.data = Some(target);
Expand All @@ -467,11 +483,14 @@ impl<B: Baker> AssetManager<B> {
let (handle, slot_ptr) = self.slots.alloc_default();
let slot = unsafe { &mut *slot_ptr };
assert_eq!(slot.version, 0);
slot.base_path = source_path
.parent()
.unwrap_or_else(|| Path::new("."))
.to_owned();
slot.meta = Box::into_raw(Box::new(meta)) as *const _;
*slot = Slot {
base_path: source_path
.parent()
.unwrap_or_else(|| Path::new("."))
.to_owned(),
meta: Box::into_raw(Box::new(meta)) as *const _,
..Default::default()
};

let file_name = Path::new(source_path.file_name().unwrap());
let (version, _) = self.create_impl(slot, file_name, None).unwrap();
Expand All @@ -495,8 +514,10 @@ impl<B: Baker> AssetManager<B> {
let (handle, slot_ptr) = self.slots.alloc_default();
let slot = unsafe { &mut *slot_ptr };
assert_eq!(slot.version, 0);
slot.base_path = Default::default();
slot.meta = Box::into_raw(Box::new(meta)) as *const _;
*slot = Slot {
meta: Box::into_raw(Box::new(meta)) as *const _,
..Default::default()
};

let (version, _) = self.create_impl(slot, name, Some(data)).unwrap();

Expand Down Expand Up @@ -533,12 +554,35 @@ impl<B: Baker> AssetManager<B> {
(handle, task)
}

/// Load an asset that has been pre-cooked already.
///
/// Expected to run inside a task.
pub fn load_cooked_inside_task(
&self,
cooked: B::Data<'_>,
exe_context: &choir::ExecutionContext,
) -> Handle<B::Output> {
let value = self.baker.serve(cooked, exe_context);
let (handle, slot_ptr) = self.slots.alloc_default();
let slot = unsafe { &mut *slot_ptr };
assert_eq!(slot.version, 0);
*slot = Slot {
version: 1,
data: Some(value),
..Slot::default()
};
Handle {
inner: handle,
version: slot.version,
}
}

/// Clear the asset manager by deleting all the stored assets.
///
/// Invalidates all handles produced from loading assets.
pub fn clear(&self) {
for (_key, handle) in self.paths.lock().unwrap().drain() {
let slot = self.slots.dealloc(handle.inner);
self.paths.lock().unwrap().clear();
self.slots.dealloc_each(|_handle, slot| {
if let Some(task) = slot.load_task {
task.join();
}
Expand All @@ -550,7 +594,7 @@ impl<B: Baker> AssetManager<B> {
let _ = Box::from_raw(slot.meta as *mut B::Meta);
}
}
}
})
}

/// Hot reload a changed asset.
Expand Down
4 changes: 2 additions & 2 deletions blade-asset/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ impl blade_asset::Baker for Baker {
_extension: &str,
meta: u32,
cooker: Arc<blade_asset::Cooker<Self>>,
_exe_context: choir::ExecutionContext,
_exe_context: &choir::ExecutionContext,
) {
assert!(self.allow_cooking.load(Ordering::SeqCst));
let _ = cooker.add_dependency("README.md".as_ref());
cooker.finish(meta);
}
fn serve(&self, cooked: u32, _exe_context: choir::ExecutionContext) -> usize {
fn serve(&self, cooked: u32, _exe_context: &choir::ExecutionContext) -> usize {
cooked as usize
}
fn delete(&self, _output: usize) {}
Expand Down
2 changes: 1 addition & 1 deletion blade-graphics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ash-window = "0.12"
gpu-alloc = "0.6"
gpu-alloc-ash = "0.6"
naga = { workspace = true, features = ["spv-out"] }
slab = "0.4"
slab = { workspace = true }

[target.'cfg(any(gles, target_arch = "wasm32"))'.dependencies]
# Version contains `glGetProgramResource`
Expand Down
3 changes: 2 additions & 1 deletion blade-render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repository = "https://github.com/kvark/blade"

[features]
default = ["asset"]
asset = ["gltf" , "base64", "exr", "mikktspace", "texpresso", "zune-core", "zune-jpeg", "zune-png", "zune-imageprocs"]
asset = ["gltf" , "base64", "exr", "mikktspace", "slab", "texpresso", "zune-core", "zune-jpeg", "zune-png", "zune-imageprocs"]

[dependencies]
base64 = { workspace = true, optional = true }
Expand All @@ -28,6 +28,7 @@ log = { workspace = true }
mikktspace = { package = "bevy_mikktspace", version = "0.10", optional = true }
mint = { workspace = true }
profiling = { workspace = true }
slab = { workspace = true, optional = true }
strum = { workspace = true }
texpresso = { version = "2.0", optional = true }
#zune-core = { version = "0.2", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion blade-render/code/fill-gbuf.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
if (enable_debug && (debug.draw_flags & DebugDrawFlags_SPACE) != 0u) {
let normal_len = 0.15 * intersection.t;
let side = 0.05 * intersection.t;
debug_line(hit_position, hit_position + normal_len * normal_geo, 0xFFFFFFu);
debug_line(hit_position, hit_position + normal_len * qrot(geo_to_world_rot, normal_geo), 0xFFFFFFu);
debug_line(hit_position - side * tangent_geo, hit_position + side * tangent_geo, 0x808080u);
debug_line(hit_position - side * bitangent_geo, hit_position + side * bitangent_geo, 0x808080u);
}
Expand Down
Loading

0 comments on commit 42e2cc1

Please sign in to comment.