Skip to content

Commit f7a3d0d

Browse files
committed
Remove delay slot in object management
1 parent 4709529 commit f7a3d0d

File tree

8 files changed

+23
-115
lines changed

8 files changed

+23
-115
lines changed

rend3-routine/shaders/src/depth.wgsl

-17
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,9 @@ struct VertexOutput {
4747

4848
@vertex
4949
fn vs_main(@builtin(instance_index) instance_index: u32, @builtin(vertex_index) vertex_index: u32) -> VertexOutput {
50-
// If the vertex index is our sentinel invalid value, return a degenerate triangle.
51-
//
52-
// This is used by the culling shader to discard triangles when the ordering of the
53-
// triangles are important, and atomics can't be used.
54-
if vertex_index == INVALID_VERTEX {
55-
var vs_out: VertexOutput;
56-
vs_out.position = vec4<f32>(0.0);
57-
return vs_out;
58-
}
5950
let indices = Indices(instance_index, vertex_index);
6051

6152
let data = object_buffer[indices.object];
62-
// If the object is disabled, return a degenerate triangle.
63-
//
64-
// This happens when the object is deleted, and we're rendering last-frame's objects.
65-
if data.enabled == 0u {
66-
var vs_out: VertexOutput;
67-
vs_out.position = vec4<f32>(0.0);
68-
return vs_out;
69-
}
7053

7154
let vs_in = get_vertices(indices);
7255

rend3-routine/shaders/src/opaque.wgsl

-17
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,9 @@ struct VertexOutput {
8787

8888
@vertex
8989
fn vs_main(@builtin(instance_index) instance_index: u32, @builtin(vertex_index) vertex_index: u32) -> VertexOutput {
90-
// If the vertex index is our sentinel invalid value, return a degenerate triangle.
91-
//
92-
// This is used by the culling shader to discard triangles when the ordering of the
93-
// triangles are important, and atomics can't be used.
94-
if vertex_index == INVALID_VERTEX {
95-
var vs_out: VertexOutput;
96-
vs_out.position = vec4<f32>(0.0);
97-
return vs_out;
98-
}
9990
let indices = Indices(instance_index, vertex_index);
10091

10192
let data = object_buffer[indices.object];
102-
// If the object is disabled, return a degenerate triangle.
103-
//
104-
// This happens when the object is deleted, and we're rendering last-frame's objects.
105-
if data.enabled == 0u {
106-
var vs_out: VertexOutput;
107-
vs_out.position = vec4<f32>(0.0);
108-
return vs_out;
109-
}
11093

11194
let vs_in = get_vertices(indices);
11295

rend3-routine/shaders/src/structures_object.wgsl

-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@ struct Object {
77
index_count: u32,
88
material_index: u32,
99
vertex_attribute_start_offsets: array<u32, {{vertex_array_counts}}>,
10-
// 1 if enabled, 0 if disabled
11-
enabled: u32,
1210
}

rend3/shaders/vertex_attributes.wgsl

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ struct Indices {
55
vertex: u32,
66
}
77

8-
const INVALID_VERTEX: u32 = 0x00FFFFFFu;
9-
108
alias TriangleVertices = array<vec3f, 3>;
119
alias TriangleIndices = array<u32, 3>;
1210
struct Triangle {

rend3/src/managers/handle_alloc.rs

+3-32
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,15 @@ where
1818
{
1919
max_allocated: AtomicUsize,
2020
freelist: Mutex<Vec<usize>>,
21-
/// We want the render routines to be able to rely on deleted handles being valid for at
22-
/// least one frame.
23-
///
24-
/// To facilitate this, we first put the handle in the delay list, then at the top of
25-
/// every frame, we move the handles from the delay list to the freelist.
26-
///
27-
/// We do not need to do this for everything though, only for Object handles, as these
28-
/// are the root handle which the renderer accesses everything.
29-
delay_list: Option<Mutex<Vec<usize>>>,
3021
_phantom: PhantomData<T>,
3122
}
3223

3324
impl<T> HandleAllocator<T>
3425
where
3526
RawResourceHandle<T>: DeletableRawResourceHandle,
3627
{
37-
pub fn new(delay_handle_reclaimation: bool) -> Self {
38-
Self {
39-
max_allocated: AtomicUsize::new(0),
40-
freelist: Mutex::new(Vec::new()),
41-
delay_list: delay_handle_reclaimation.then(|| Mutex::new(Vec::new())),
42-
_phantom: PhantomData,
43-
}
28+
pub fn new() -> Self {
29+
Self { max_allocated: AtomicUsize::new(0), freelist: Mutex::new(Vec::new()), _phantom: PhantomData }
4430
}
4531

4632
pub fn allocate(&self, renderer: &Arc<Renderer>) -> ResourceHandle<T> {
@@ -57,21 +43,6 @@ where
5743

5844
pub fn deallocate(&self, handle: RawResourceHandle<T>) {
5945
let idx = handle.idx;
60-
if let Some(ref delay_list) = self.delay_list {
61-
delay_list.lock().push(idx);
62-
} else {
63-
self.freelist.lock().push(idx);
64-
}
65-
}
66-
67-
pub fn reclaim_delayed_handles(&self) -> Vec<RawResourceHandle<T>> {
68-
if let Some(ref delay_list) = self.delay_list {
69-
let mut locked_delay_list = delay_list.lock();
70-
71-
self.freelist.lock().extend_from_slice(&locked_delay_list);
72-
locked_delay_list.drain(..).map(|idx| RawResourceHandle::new(idx)).collect()
73-
} else {
74-
Vec::new()
75-
}
46+
self.freelist.lock().push(idx);
7647
}
7748
}

rend3/src/managers/object.rs

+10-33
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ pub struct ShaderObject<M: Material> {
3131
pub material_index: u32,
3232
pub vertex_attribute_start_offsets:
3333
<M::SupportedAttributeArrayType as MaterialArray<&'static VertexAttributeId>>::U32Array,
34-
// 1 if enabled, 0 if disabled
35-
pub enabled: u32,
3634
}
3735

3836
impl<M: Material> Default for ShaderObject<M> {
@@ -44,7 +42,6 @@ impl<M: Material> Default for ShaderObject<M> {
4442
index_count: Default::default(),
4543
material_index: Default::default(),
4644
vertex_attribute_start_offsets: Zeroable::zeroed(),
47-
enabled: Default::default(),
4845
}
4946
}
5047
}
@@ -91,7 +88,7 @@ struct ObjectArchetype {
9188
set_object_transform: fn(&mut WasmVecAny, &mut FreelistDerivedBuffer, usize, Mat4),
9289
duplicate_object: fn(&WasmVecAny, usize, ObjectChange) -> Object,
9390
remove: fn(&mut ObjectArchetype, usize),
94-
evaluate: fn(&mut ObjectArchetype, &Device, &mut CommandEncoder, &ScatterCopy, &[RawObjectHandle]),
91+
evaluate: fn(&mut ObjectArchetype, &Device, &mut CommandEncoder, &ScatterCopy),
9592
}
9693

9794
/// Manages objects. That's it. ¯\\\_(ツ)\_/¯
@@ -163,15 +160,9 @@ impl ObjectManager {
163160
(archetype.remove)(archetype, handle.idx);
164161
}
165162

166-
pub fn evaluate(
167-
&mut self,
168-
device: &Device,
169-
encoder: &mut CommandEncoder,
170-
scatter: &ScatterCopy,
171-
deferred_removals: &[RawObjectHandle],
172-
) {
163+
pub fn evaluate(&mut self, device: &Device, encoder: &mut CommandEncoder, scatter: &ScatterCopy) {
173164
for archetype in self.archetype.values_mut() {
174-
(archetype.evaluate)(archetype, device, encoder, scatter, deferred_removals);
165+
(archetype.evaluate)(archetype, device, encoder, scatter);
175166
}
176167
}
177168

@@ -279,7 +270,6 @@ pub(super) fn object_add_callback<M: Material>(_material: &M, args: ObjectAddCal
279270
first_index: (index_range.start / 4) as u32,
280271
index_count: ((index_range.end - index_range.start) / 4) as u32,
281272
vertex_attribute_start_offsets,
282-
enabled: true as u32,
283273
},
284274
material_handle: args.object.material,
285275
mesh_kind: args.object.mesh_kind,
@@ -330,35 +320,22 @@ fn duplicate_object<M: Material>(data: &WasmVecAny, idx: usize, change: ObjectCh
330320
fn remove<M: Material>(archetype: &mut ObjectArchetype, idx: usize) {
331321
let data_vec = archetype.data_vec.downcast_slice_mut::<Option<InternalObject<M>>>().unwrap();
332322

333-
// We don't actually remove the object at this point,
334-
// we just mark it as disabled. Next frame, this handle
335-
// will be provided in `deferred_removals` in `evaluate`
336-
// so we can actually delete it.
337-
//
338-
// We defer objects one frame so that temporal culling
339-
// has valid data.
340-
archetype.buffer.use_index(idx);
341-
data_vec[idx].as_mut().unwrap().inner.enabled = false as u32;
323+
// Only one archetype will have each handle,
324+
// so if we have it, we can be sure it's ours.
325+
let removed_obj = Option::take(&mut data_vec[idx]);
326+
327+
if removed_obj.is_some() {
328+
archetype.object_count -= 1;
329+
}
342330
}
343331

344332
fn evaluate<M: Material>(
345333
archetype: &mut ObjectArchetype,
346334
device: &Device,
347335
encoder: &mut CommandEncoder,
348336
scatter: &ScatterCopy,
349-
deferred_removals: &[RawObjectHandle],
350337
) {
351338
let data_vec = archetype.data_vec.downcast_slice_mut::<Option<InternalObject<M>>>().unwrap();
352339

353-
for removal in deferred_removals {
354-
// Only one archetype will have each handle,
355-
// so if we have it, we can be sure it's ours.
356-
let removed_obj = data_vec[removal.idx].take();
357-
358-
if removed_obj.is_some() {
359-
archetype.object_count -= 1;
360-
}
361-
}
362-
363340
archetype.buffer.apply(device, encoder, scatter, |idx| data_vec[idx].as_ref().map(|o| o.inner).unwrap_or_default())
364341
}

rend3/src/renderer/eval.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ pub fn evaluate_instructions(renderer: &Renderer) -> InstructionEvaluationOutput
1111

1212
let mut instructions = renderer.instructions.consumer.lock();
1313

14-
let delayed_object_handles = renderer.resource_handle_allocators.object.reclaim_delayed_handles();
15-
1614
// 16 encoders is a reasonable default
1715
let mut cmd_bufs = Vec::with_capacity(16);
1816

@@ -157,7 +155,7 @@ pub fn evaluate_instructions(renderer: &Renderer) -> InstructionEvaluationOutput
157155

158156
// Do these in dependency order
159157
// Level 3
160-
data_core.object_manager.evaluate(&renderer.device, &mut encoder, &renderer.scatter, &delayed_object_handles);
158+
data_core.object_manager.evaluate(&renderer.device, &mut encoder, &renderer.scatter);
161159

162160
// Level 2
163161
let d2_texture = data_core.d2_texture_manager.evaluate(&renderer.device);

rend3/src/renderer/mod.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ struct HandleAllocators {
8282
impl Default for HandleAllocators {
8383
fn default() -> Self {
8484
Self {
85-
mesh: HandleAllocator::new(false),
86-
skeleton: HandleAllocator::new(false),
87-
d2_texture: HandleAllocator::new(false),
88-
d2c_texture: HandleAllocator::new(false),
89-
material: HandleAllocator::new(false),
90-
object: HandleAllocator::new(true),
91-
directional_light: HandleAllocator::new(false),
92-
point_light: HandleAllocator::new(false),
93-
graph_storage: HandleAllocator::new(false),
85+
mesh: HandleAllocator::new(),
86+
skeleton: HandleAllocator::new(),
87+
d2_texture: HandleAllocator::new(),
88+
d2c_texture: HandleAllocator::new(),
89+
material: HandleAllocator::new(),
90+
object: HandleAllocator::new(),
91+
directional_light: HandleAllocator::new(),
92+
point_light: HandleAllocator::new(),
93+
graph_storage: HandleAllocator::new(),
9494
}
9595
}
9696
}

0 commit comments

Comments
 (0)