Skip to content

Commit 1abbffe

Browse files
committedApr 22, 2024·
slab manager recycles hybrid and hybridarray allocs
1 parent 35811ee commit 1abbffe

File tree

9 files changed

+714
-490
lines changed

9 files changed

+714
-490
lines changed
 

‎crates/renderling/src/atlas/cpu.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ mod test {
576576
scale: Vec3::new(32.0, 32.0, 1.0),
577577
..Default::default()
578578
});
579-
let _renderlet = stage.draw(&crate::Renderlet {
579+
let _renderlet = stage.draw(crate::Renderlet {
580580
camera,
581581
vertices: geometry,
582582
transform,
@@ -653,7 +653,7 @@ mod test {
653653
.with_uv0(Vec2::splat(3.0));
654654
[tl, bl, br, tl, br, tr]
655655
});
656-
let _clamp_prim = stage.draw(&Renderlet {
656+
let _clamp_prim = stage.draw(Renderlet {
657657
camera,
658658
vertices: geometry,
659659
material: clamp_material_id,
@@ -664,7 +664,7 @@ mod test {
664664
translation: Vec3::new(sheet_w + 1.0, 0.0, 0.0),
665665
..Default::default()
666666
});
667-
stage.draw(&Renderlet {
667+
stage.draw(Renderlet {
668668
camera,
669669
vertices: geometry,
670670
material: repeat_material_id,
@@ -677,7 +677,7 @@ mod test {
677677
translation: Vec3::new(sheet_w as f32 * 2.0 + 2.0, 0.0, 0.0),
678678
..Default::default()
679679
});
680-
stage.draw(&Renderlet {
680+
stage.draw(Renderlet {
681681
camera,
682682
vertices: geometry,
683683
material: mirror_material_id,
@@ -765,7 +765,7 @@ mod test {
765765
stage.append_array(&[tl, bl, br, tl, br, tr])
766766
};
767767

768-
let _clamp_prim = stage.draw(&Renderlet {
768+
let _clamp_prim = stage.draw(Renderlet {
769769
camera,
770770
vertices: geometry,
771771
material: clamp_material_id,
@@ -777,7 +777,7 @@ mod test {
777777
..Default::default()
778778
});
779779

780-
stage.draw(&Renderlet {
780+
stage.draw(Renderlet {
781781
camera,
782782
vertices: geometry,
783783
material: repeat_material_id,
@@ -791,7 +791,7 @@ mod test {
791791
..Default::default()
792792
});
793793

794-
stage.draw(&Renderlet {
794+
stage.draw(Renderlet {
795795
camera,
796796
vertices: geometry,
797797
material: mirror_material_id,

‎crates/renderling/src/lib.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub mod pbr;
3838
#[cfg(not(target_arch = "spirv"))]
3939
mod renderer;
4040
pub mod skybox;
41+
#[cfg(not(target_arch = "spirv"))]
42+
pub mod slab;
4143
mod stage;
4244
#[cfg(not(target_arch = "spirv"))]
4345
mod state;
@@ -313,7 +315,7 @@ mod test {
313315
let (projection, view) = default_ortho2d(100.0, 100.0);
314316
let camera = stage.append(&Camera::new(projection, view));
315317
let geometry = stage.append_array(&right_tri_vertices());
316-
let _tri_id = stage.draw(&Renderlet {
318+
let _tri_id = stage.draw(Renderlet {
317319
camera,
318320
vertices: geometry,
319321
..Default::default()
@@ -363,7 +365,7 @@ mod test {
363365
vs.reverse();
364366
vs
365367
});
366-
let _tri = stage.draw(&Renderlet {
368+
let _tri = stage.draw(Renderlet {
367369
camera,
368370
vertices: geometry,
369371
..Default::default()
@@ -392,7 +394,7 @@ mod test {
392394
let camera = stage.append(&Camera::new(projection, view));
393395
let geometry = stage.append_array(&right_tri_vertices());
394396
let transform = stage.append(&Transform::default());
395-
let _tri = stage.draw(&Renderlet {
397+
let _tri = stage.draw(Renderlet {
396398
camera,
397399
vertices: geometry,
398400
transform,
@@ -471,7 +473,7 @@ mod test {
471473
rotation: Quat::from_axis_angle(Vec3::Y, -std::f32::consts::FRAC_PI_4),
472474
..Default::default()
473475
});
474-
let _cube = stage.draw(&Renderlet {
476+
let _cube = stage.draw(Renderlet {
475477
camera,
476478
vertices: geometry,
477479
transform,
@@ -500,7 +502,7 @@ mod test {
500502
rotation: Quat::from_axis_angle(Vec3::Y, -std::f32::consts::FRAC_PI_4),
501503
..Default::default()
502504
});
503-
let _cube = stage.draw(&Renderlet {
505+
let _cube = stage.draw(Renderlet {
504506
camera,
505507
vertices,
506508
indices,
@@ -542,29 +544,29 @@ mod test {
542544
}),
543545
..Default::default()
544546
};
545-
let _cube_one = stage.draw(&renderlet);
547+
let _cube_one = stage.draw(renderlet);
546548

547549
renderlet.transform = stage.append(&Transform {
548550
translation: Vec3::new(4.5, 0.0, 0.0),
549551
scale: Vec3::new(6.0, 6.0, 6.0),
550552
rotation: Quat::from_axis_angle(Vec3::Y, std::f32::consts::FRAC_PI_4),
551553
});
552-
let cube_two_rendering = stage.draw(&renderlet);
554+
let cube_two_rendering = stage.draw(renderlet);
553555

554556
// we should see two colored cubes
555557
let img = r.render_image().unwrap();
556558
img_diff::assert_img_eq("cmy_cube/visible_before.png", img.clone());
557559
let img_before = img;
558560

559561
// update cube two making it invisible
560-
stage.hide(cube_two_rendering);
562+
cube_two_rendering.modify(|r| r.visible = false);
561563

562564
// we should see only one colored cube
563565
let img = r.render_image().unwrap();
564566
img_diff::assert_img_eq("cmy_cube/visible_after.png", img);
565567

566568
// update cube two making in visible again
567-
stage.show(cube_two_rendering);
569+
cube_two_rendering.modify(|r| r.visible = true);
568570

569571
// we should see two colored cubes again
570572
let img = r.render_image().unwrap();
@@ -595,7 +597,7 @@ mod test {
595597
..Default::default()
596598
});
597599

598-
let cube_id = stage.draw(&Renderlet {
600+
let cube = stage.draw(Renderlet {
599601
camera,
600602
vertices: cube_geometry,
601603
transform,
@@ -608,7 +610,7 @@ mod test {
608610

609611
// Update the cube mesh to a pyramid by overwriting the `.vertices` field
610612
// of `Renderlet`
611-
stage.write(cube_id + Renderlet::offset_of_vertices(), &pyramid_geometry);
613+
cube.modify(|r| r.vertices = pyramid_geometry);
612614

613615
// we should see a pyramid (in sRGB color space)
614616
let img = r.render_image().unwrap();
@@ -686,7 +688,7 @@ mod test {
686688
scale: Vec3::new(10.0, 10.0, 10.0),
687689
..Default::default()
688690
});
689-
let cube = stage.draw(&Renderlet {
691+
let cube = stage.draw(Renderlet {
690692
camera,
691693
vertices: geometry,
692694
material,
@@ -754,7 +756,7 @@ mod test {
754756
]);
755757

756758
let _color_prim = {
757-
stage.draw(&Renderlet {
759+
stage.draw(Renderlet {
758760
camera,
759761
vertices: geometry,
760762
..Default::default()
@@ -766,7 +768,7 @@ mod test {
766768
scale: Vec3::new(0.5, 0.5, 1.0),
767769
..Default::default()
768770
});
769-
stage.draw(&Renderlet {
771+
stage.draw(Renderlet {
770772
camera,
771773
vertices: geometry,
772774
transform,
@@ -820,8 +822,10 @@ mod test {
820822
},
821823
dir_red.into()
822824
);
823-
let lights = stage.append_array(&[dir_red.into(), dir_green.into(), dir_blue.into()]);
824-
stage.set_lights(lights);
825+
let dir_red = stage.append(&Light::from(dir_red));
826+
let dir_green = stage.append(&Light::from(dir_green));
827+
let dir_blue = stage.append(&Light::from(dir_blue));
828+
stage.set_lights(vec![dir_red, dir_green, dir_blue]);
825829

826830
let material = stage.append(&Material::default());
827831
let geometry = stage.append_array(
@@ -835,7 +839,7 @@ mod test {
835839
})
836840
.collect::<Vec<_>>(),
837841
);
838-
let _cube = stage.draw(&Renderlet {
842+
let _cube = stage.draw(Renderlet {
839843
camera,
840844
vertices: geometry,
841845
material,
@@ -951,21 +955,21 @@ mod test {
951955
yellow_node.add_child(&red_node);
952956
println!("red_node: {:#?}", red_node.get_global_transform());
953957

954-
let _cyan_primitive = stage.draw(&Renderlet {
958+
let _cyan_primitive = stage.draw(Renderlet {
955959
vertices: geometry,
956960
camera,
957961
material: cyan_material,
958962
transform: cyan_node.global_transform_id(),
959963
..Default::default()
960964
});
961-
let _yellow_primitive = stage.draw(&Renderlet {
965+
let _yellow_primitive = stage.draw(Renderlet {
962966
vertices: geometry,
963967
camera,
964968
material: yellow_material,
965969
transform: yellow_node.global_transform_id(),
966970
..Default::default()
967971
});
968-
let _red_primitive = stage.draw(&Renderlet {
972+
let _red_primitive = stage.draw(Renderlet {
969973
vertices: geometry,
970974
camera,
971975
material: red_material,
@@ -1057,7 +1061,7 @@ mod test {
10571061
translation: Vec3::new(x, y, 0.0),
10581062
..Default::default()
10591063
});
1060-
let _sphere = stage.draw(&Renderlet {
1064+
let _sphere = stage.draw(Renderlet {
10611065
camera,
10621066
vertices: geometry,
10631067
transform,
Binary file not shown.

‎crates/renderling/src/pbr.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ pub struct PbrConfig {
239239
pub resolution: glam::UVec2,
240240
pub debug_mode: debug::DebugMode,
241241
pub has_lighting: bool,
242-
pub light_array: Array<light::Light>,
242+
pub light_array: Array<Id<light::Light>>,
243243
}
244244

245245
impl Default for PbrConfig {
@@ -565,7 +565,7 @@ pub fn shade_fragment(
565565
prefiltered: Vec3,
566566
brdf: Vec2,
567567

568-
lights: Array<Light>,
568+
lights: Array<Id<Light>>,
569569
slab: &[u32],
570570
) -> Vec4 {
571571
let n = in_norm.alt_norm_or_zero();
@@ -577,7 +577,11 @@ pub fn shade_fragment(
577577
let mut lo = Vec3::ZERO;
578578
for i in 0..lights.len() {
579579
// calculate per-light radiance
580-
let light = slab.read(lights.at(i));
580+
let light_id = slab.read(lights.at(i));
581+
if light_id.is_none() {
582+
break;
583+
}
584+
let light = slab.read(light_id);
581585
let transform = slab.read(light.transform);
582586
let transform = Mat4::from(transform);
583587

‎crates/renderling/src/slab.rs

+573
Large diffs are not rendered by default.

‎crates/renderling/src/stage/cpu.rs

+63-415
Large diffs are not rendered by default.

‎crates/renderling/src/stage/gltf_support.rs

+37-41
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use crate::{
1010
light::{DirectionalLight, Light, LightStyle, PointLight, SpotLight},
1111
Material, PbrConfig,
1212
},
13+
slab::*,
1314
stage::Vertex,
14-
AtlasImage, AtlasTexture, Camera, Hybrid, HybridArray, NestedTransform, Renderlet,
15-
RepackPreview, Stage, TextureAddressMode, TextureModes, Transform,
15+
AtlasImage, AtlasTexture, Camera, NestedTransform, Renderlet, RepackPreview, Stage,
16+
TextureAddressMode, TextureModes, Transform,
1617
};
1718

1819
#[derive(Debug, Snafu)]
@@ -508,16 +509,12 @@ pub struct GltfCamera {
508509
pub name: Option<String>,
509510
pub node_transform: NestedTransform,
510511
projection: Mat4,
511-
pub id: Id<Camera>,
512+
pub camera: Hybrid<Camera>,
512513
}
513514

514515
impl<'a> GltfCamera {
515-
fn new(
516-
stage: &mut impl GrowableSlab,
517-
camera: gltf::Camera<'a>,
518-
transform: &NestedTransform,
519-
) -> Self {
520-
let projection = match camera.projection() {
516+
fn new(stage: &mut Stage, gltf_camera: gltf::Camera<'a>, transform: &NestedTransform) -> Self {
517+
let projection = match gltf_camera.projection() {
521518
gltf::camera::Projection::Orthographic(o) => glam::Mat4::orthographic_rh(
522519
-o.xmag(),
523520
o.xmag(),
@@ -541,12 +538,13 @@ impl<'a> GltfCamera {
541538
}
542539
};
543540
let view = Mat4::from(transform.get_global_transform()).inverse();
541+
let camera = stage.new_hybrid(Camera::new(projection, view));
544542
GltfCamera {
545-
index: camera.index(),
546-
name: camera.name().map(String::from),
543+
index: gltf_camera.index(),
544+
name: gltf_camera.name().map(String::from),
547545
projection,
548546
node_transform: transform.clone(),
549-
id: stage.append(&Camera::new(projection, view)),
547+
camera,
550548
}
551549
}
552550

@@ -753,8 +751,7 @@ impl GltfDocument {
753751
// The bindgroup will have to be remade
754752
let _ = stage.textures_bindgroup.lock().unwrap().take();
755753
// The atlas size must be reset
756-
let size_id = PbrConfig::offset_of_atlas_size().into();
757-
stage.slab.write().unwrap().write(size_id, &size);
754+
stage.pbr_config.modify(|cfg| cfg.atlas_size = size);
758755
}
759756

760757
log::debug!("Loading meshes");
@@ -973,17 +970,14 @@ impl Stage {
973970
.get(mesh_index)
974971
.context(MissingMeshSnafu { index: mesh_index })?;
975972
for prim in mesh.primitives.iter() {
976-
let renderlet = Renderlet {
973+
let hybrid = self.draw(Renderlet {
977974
vertices: prim.vertices.array(),
978975
indices: prim.indices.array(),
979976
camera,
980977
transform: gltf_node.transform.global_transform_id(),
981978
material: prim.material,
982979
..Default::default()
983-
};
984-
let id = self.draw(&renderlet);
985-
let hybrid = Hybrid::new_preallocated(id, renderlet);
986-
self.add_updates(hybrid.clone());
980+
});
987981
renderlets.push(hybrid);
988982
}
989983
}
@@ -1145,7 +1139,7 @@ mod test {
11451139
scale: Vec3::new(100.0, 100.0, 1.0),
11461140
..Default::default()
11471141
});
1148-
let _renderlet = stage.draw(&Renderlet {
1142+
let _renderlet = stage.draw(Renderlet {
11491143
vertices,
11501144
indices,
11511145
material: material_id,
@@ -1179,32 +1173,34 @@ mod test {
11791173
let camera = stage.append(&Camera::new(projection, view));
11801174
let default_scene_index = doc.default_scene.unwrap();
11811175
let nodes = doc.scenes.get(default_scene_index).unwrap().clone();
1182-
let _unit_ids = stage.draw_gltf_scene(&mut doc, nodes, camera).unwrap();
1176+
let _scene = stage.draw_gltf_scene(&mut doc, nodes, camera).unwrap();
11831177

11841178
let img = r.render_image().unwrap();
11851179
img_diff::assert_img_eq("gltf_simple_texture.png", img);
11861180
}
11871181

1188-
// #[test]
1189-
// // Demonstrates how to load and render a gltf file containing lighting and a
1190-
// // normal map.
1191-
// fn normal_mapping_brick_sphere() {
1192-
// let size = 600;
1193-
// let mut r =
1194-
// Renderling::headless(size, size).with_background_color(Vec3::splat(1.0).extend(1.0));
1195-
// let mut stage = r.new_stage().with_lighting(true).with_bloom(true);
1196-
// stage.configure_graph(&mut r, true);
1197-
// let doc = stage
1198-
// .load_gltf_document_from_path("../../gltf/red_brick_03_1k.glb")
1199-
// .unwrap();
1200-
// let camera = stage.create_camera_from_gltf(&cpu_doc, 0).unwrap();
1201-
// let camera_id = stage.append(&camera);
1202-
// let _unit_ids =
1203-
// stage.draw_gltf_scene(&gpu_doc, camera_id, cpu_doc.default_scene().unwrap());
1204-
1205-
// let img = r.render_image().unwrap();
1206-
// img_diff::assert_img_eq("gltf_normal_mapping_brick_sphere.png", img);
1207-
// }
1182+
#[test]
1183+
// Demonstrates how to load and render a gltf file containing lighting and a
1184+
// normal map.
1185+
fn normal_mapping_brick_sphere() {
1186+
let size = 600;
1187+
let mut r =
1188+
Renderling::headless(size, size).with_background_color(Vec3::splat(1.0).extend(1.0));
1189+
let mut stage = r.new_stage().with_lighting(true).with_bloom(true);
1190+
stage.configure_graph(&mut r, true);
1191+
let doc = stage
1192+
.load_gltf_document_from_path("../../gltf/red_brick_03_1k.glb")
1193+
.unwrap();
1194+
let gltf_camera = doc.cameras.get(0).unwrap();
1195+
let scene_index = doc.default_scene.unwrap();
1196+
let nodes = doc.scenes.get(scene_index).unwrap().iter().copied();
1197+
let _scene = stage.draw_gltf_scene(&doc, nodes, gltf_camera.camera.id());
1198+
1199+
stage.set_lights(doc.lights.iter().map(|gltf_light| gltf_light.light.id()));
1200+
1201+
let img = r.render_image().unwrap();
1202+
img_diff::assert_img_eq("gltf_normal_mapping_brick_sphere.png", img);
1203+
}
12081204

12091205
/// A helper struct that contains all outputs of the vertex shader.
12101206
#[allow(unused)]

‎crates/sandbox/src/main.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,10 @@ fn can_read_shader_debug_logs(window: Arc<winit::window::Window>) -> Renderling
7070
.with_position([100.0, 0.0, 0.0])
7171
.with_color([1.0, 0.0, 1.0, 1.0]),
7272
]);
73-
let mut renderlet = Renderlet {
73+
let _tri_id = stage.draw(Renderlet {
7474
camera,
7575
vertices: geometry,
7676
..Default::default()
77-
};
78-
let _tri_id = stage.draw_debug(&mut renderlet);
77+
});
7978
r
8079
}
-15.6 KB
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.