Skip to content

Commit

Permalink
Final comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cwfitzgerald committed Nov 11, 2023
1 parent bb2297e commit dfb56bc
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 65 deletions.
23 changes: 14 additions & 9 deletions rend3-routine/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ use rend3::{
};
use wgpu::{BindGroup, Buffer};

use crate::{common, culling, forward::RoutineAddToGraphArgs, pbr, skinning, skybox, tonemapping};
use crate::{
common::{self, CameraIndex},
culling,
forward::RoutineAddToGraphArgs,
pbr, skinning, skybox, tonemapping,
};

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DepthTargets {
Expand Down Expand Up @@ -288,7 +293,7 @@ impl BaseRenderGraphIntermediateState {
for (shadow_index, shadow) in eval_output.shadows.iter().enumerate() {
base.gpu_culler.add_object_uniform_upload_to_graph::<pbr::PbrMaterial>(
graph,
Some(shadow_index),
CameraIndex::Shadow(shadow_index as u32),
UVec2::splat(shadow.map.size),
SampleCount::One,
&format_sso!("Shadow Culling S{}", shadow_index),
Expand All @@ -303,7 +308,7 @@ impl BaseRenderGraphIntermediateState {
graph,
shadow_culled,
self.shadow,
Some(shadow_index),
CameraIndex::Shadow(shadow_index as u32),
&format_sso!("Shadow Culling S{}", shadow_index),
);
}
Expand All @@ -322,7 +327,7 @@ impl BaseRenderGraphIntermediateState {
) {
base.gpu_culler.add_object_uniform_upload_to_graph::<pbr::PbrMaterial>(
graph,
None,
CameraIndex::Viewport,
resolution,
samples,
"Uniform Bake",
Expand All @@ -335,7 +340,7 @@ impl BaseRenderGraphIntermediateState {
graph,
self.cull,
self.depth.single_sample_mipped,
None,
CameraIndex::Viewport,
"Primary Culling",
);
}
Expand Down Expand Up @@ -376,7 +381,7 @@ impl BaseRenderGraphIntermediateState {
extra_bgs: None,
label: &format!("pbr shadow renderering S{shadow_index}"),
samples: SampleCount::One,
camera: Some(shadow_index),
camera: CameraIndex::Shadow(shadow_index as u32),
color: None,
resolve: None,
depth: self
Expand Down Expand Up @@ -423,7 +428,7 @@ impl BaseRenderGraphIntermediateState {
extra_bgs: None,
label: "PBR Forward Pass 1",
samples,
camera: None,
camera: CameraIndex::Viewport,
color: Some(self.color),
resolve: self.resolve,
depth: self.depth.rendering_target(),
Expand All @@ -448,7 +453,7 @@ impl BaseRenderGraphIntermediateState {
extra_bgs: None,
label: "PBR Forward Pass 2",
samples,
camera: None,
camera: CameraIndex::Viewport,
color: Some(self.color),
resolve: self.resolve,
depth: self.depth.rendering_target(),
Expand All @@ -470,7 +475,7 @@ impl BaseRenderGraphIntermediateState {
per_material: &pbr.per_material,
extra_bgs: None,
label: "PBR Forward",
camera: None,
camera: CameraIndex::Viewport,
samples,
color: Some(self.color),
resolve: self.resolve,
Expand Down
36 changes: 36 additions & 0 deletions rend3-routine/src/common/camera.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// Index representing which camera we're referring to.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CameraIndex {
Viewport,
Shadow(u32),
}

impl CameraIndex {
/// Returns `true` if the camera index is [`Viewport`].
///
/// [`Viewport`]: CameraIndex::Viewport
#[must_use]
pub fn is_viewport(&self) -> bool {
matches!(self, Self::Viewport)
}

/// Returns `true` if the camera index is [`Shadow`].
///
/// [`Shadow`]: CameraIndex::Shadow
#[must_use]
pub fn is_shadow(&self) -> bool {
matches!(self, Self::Shadow(..))
}

/// Returns a shader compatible index for the camera, using u32::MAX for the viewport camera.
#[must_use]
pub fn to_shader_index(&self) -> u32 {
match *self {
Self::Viewport => u32::MAX,
Self::Shadow(index) => {
assert_ne!(index, u32::MAX, "Shadow camera index cannot be 0xFFFF_FFFF");
index
}
}
}
}
2 changes: 2 additions & 0 deletions rend3-routine/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Common utilities used throughout the crate.
mod camera;
mod interfaces;
mod samplers;

pub use camera::*;
pub use interfaces::*;
pub use samplers::*;
44 changes: 31 additions & 13 deletions rend3-routine/src/culling/batching.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use std::{cmp::Ordering, collections::HashMap, mem};
use std::{cmp::Ordering, collections::HashMap};

use encase::ShaderType;
use ordered_float::OrderedFloat;
use rend3::{
graph::NodeExecutionContext,
managers::{CameraManager, TextureBindGroupIndex},
types::{GraphDataHandle, Material, RawObjectHandle, SortingOrder, SortingReason},
util::math::round_up,
util::{math::round_up, typedefs::FastHashMap},
};

use crate::common::CameraIndex;

use super::{BATCH_SIZE, WORKGROUP_SIZE};

#[derive(Debug)]
Expand Down Expand Up @@ -97,23 +99,37 @@ pub(super) struct ShaderObjectCullingInformation {
pub atomic_capable: u32,
}

/// Map containing the previous invocation of each object.
pub struct PerCameraPreviousInvocationsMap {
inner: FastHashMap<CameraIndex, FastHashMap<RawObjectHandle, u32>>,
}
impl PerCameraPreviousInvocationsMap {
pub fn new() -> Self {
Self {
inner: HashMap::default(),
}
}

pub fn get_and_reset_camera(&mut self, camera: CameraIndex) -> FastHashMap<RawObjectHandle, u32> {
self.inner.remove(&camera).unwrap_or_default()
}

pub fn set_camera(&mut self, camera: CameraIndex, previous_invocations: FastHashMap<RawObjectHandle, u32>) {
self.inner.insert(camera, previous_invocations);
}
}

pub(super) fn batch_objects<M: Material>(
ctx: &mut NodeExecutionContext,
previous_invocation_map_handle: &GraphDataHandle<HashMap<Option<usize>, HashMap<RawObjectHandle, u32>>>,
previous_invocation_map_handle: &GraphDataHandle<PerCameraPreviousInvocationsMap>,
camera: &CameraManager,
camera_idx: Option<usize>,
camera_idx: CameraIndex,
) -> ShaderBatchDatas {
profiling::scope!("Batch Objects");

let mut current_invocation_map_map = ctx.data_core.graph_storage.get_mut(previous_invocation_map_handle);
let current_invocation_map = current_invocation_map_map
.entry(camera_idx)
.or_insert_with(Default::default);
let current_invocation_map_len = current_invocation_map.len();
let previous_invocation_map = mem::replace(
current_invocation_map,
HashMap::with_capacity(current_invocation_map_len),
);
let mut per_camera_previous_invocation_map = ctx.data_core.graph_storage.get_mut(previous_invocation_map_handle);
let previous_invocation_map = per_camera_previous_invocation_map.get_and_reset_camera(camera_idx);
let mut current_invocation_map = FastHashMap::default();

let mut jobs = ShaderBatchDatas {
jobs: Vec::new(),
Expand Down Expand Up @@ -257,5 +273,7 @@ pub(super) fn batch_objects<M: Material>(
});
}

per_camera_previous_invocation_map.set_camera(camera_idx, current_invocation_map);

jobs
}
47 changes: 25 additions & 22 deletions rend3-routine/src/culling/culler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rend3::{
format_sso,
graph::{DataHandle, DeclaredDependency, NodeExecutionContext, NodeResourceUsage, RenderGraph, RenderTargetHandle},
managers::{CameraManager, ShaderObject, TextureBindGroupIndex},
types::{GraphDataHandle, Material, MaterialArray, RawObjectHandle, SampleCount, VERTEX_ATTRIBUTE_POSITION},
types::{GraphDataHandle, Material, MaterialArray, SampleCount, VERTEX_ATTRIBUTE_POSITION},
util::{frustum::Frustum, math::IntegerExt, typedefs::FastHashMap},
Renderer, ShaderPreProcessor, ShaderVertexBufferConfig,
};
Expand All @@ -25,10 +25,13 @@ use wgpu::{
ShaderModuleDescriptor, ShaderStages, TextureSampleType, TextureViewDimension,
};

use crate::culling::{
batching::{batch_objects, JobSubRegion, ShaderBatchData, ShaderBatchDatas},
suballoc::InputOutputBuffer,
WORKGROUP_SIZE,
use crate::{
common::CameraIndex,
culling::{
batching::{batch_objects, JobSubRegion, PerCameraPreviousInvocationsMap, ShaderBatchData, ShaderBatchDatas},
suballoc::InputOutputBuffer,
WORKGROUP_SIZE,
},
};

#[derive(Debug)]
Expand All @@ -48,10 +51,10 @@ pub struct DrawCall {

#[derive(Default)]
pub struct CullingBufferMap {
inner: FastHashMap<Option<usize>, CullingBuffers>,
inner: FastHashMap<CameraIndex, CullingBuffers>,
}
impl CullingBufferMap {
pub fn get_buffers(&self, camera: Option<usize>) -> Option<&CullingBuffers> {
pub fn get_buffers(&self, camera: CameraIndex) -> Option<&CullingBuffers> {
self.inner.get(&camera)
}

Expand All @@ -60,7 +63,7 @@ impl CullingBufferMap {
queue: &Queue,
device: &Device,
encoder: &mut CommandEncoder,
camera: Option<usize>,
camera: CameraIndex,
sizes: CullingBufferSizes,
) -> &mut CullingBuffers {
match self.inner.entry(camera) {
Expand Down Expand Up @@ -187,9 +190,9 @@ pub struct GpuCuller {
sampler: Sampler,
winding: wgpu::FrontFace,
type_id: TypeId,
per_material_buffer_handle: GraphDataHandle<HashMap<Option<usize>, Arc<Buffer>>>,
per_material_buffer_handle: GraphDataHandle<HashMap<CameraIndex, Arc<Buffer>>>,
pub culling_buffer_map_handle: GraphDataHandle<CullingBufferMap>,
previous_invocation_map_handle: GraphDataHandle<HashMap<Option<usize>, HashMap<RawObjectHandle, u32>>>,
previous_invocation_map_handle: GraphDataHandle<PerCameraPreviousInvocationsMap>,
}

impl GpuCuller {
Expand Down Expand Up @@ -405,7 +408,7 @@ impl GpuCuller {

let per_material_buffer_handle = renderer.add_graph_data(HashMap::default());
let culling_buffer_map_handle = renderer.add_graph_data(CullingBufferMap::default());
let previous_invocation_map_handle = renderer.add_graph_data(HashMap::default());
let previous_invocation_map_handle = renderer.add_graph_data(PerCameraPreviousInvocationsMap::new());

Self {
prep_bgl,
Expand All @@ -425,7 +428,7 @@ impl GpuCuller {
&self,
ctx: &mut NodeExecutionContext,
camera: &CameraManager,
camera_idx: Option<usize>,
camera_idx: CameraIndex,
resolution: UVec2,
samples: SampleCount,
) where
Expand Down Expand Up @@ -477,8 +480,8 @@ impl GpuCuller {
};

let culling = match camera_idx {
Some(_) => wgpu::Face::Front,
None => wgpu::Face::Back,
CameraIndex::Shadow(_) => wgpu::Face::Front,
CameraIndex::Viewport => wgpu::Face::Back,
};

{
Expand All @@ -487,7 +490,7 @@ impl GpuCuller {
let per_camera_data = PerCameraUniform {
view: camera.view(),
view_proj: camera.view_proj(),
shadow_index: camera_idx.unwrap_or(u32::MAX as _) as u32,
shadow_index: camera_idx.to_shader_index(),
frustum: camera.world_frustum(),
resolution: resolution.as_vec2(),
flags: {
Expand Down Expand Up @@ -544,7 +547,7 @@ impl GpuCuller {
ctx: &mut NodeExecutionContext,
jobs: ShaderBatchDatas,
depth_handle: DeclaredDependency<RenderTargetHandle>,
camera_idx: Option<usize>,
camera_idx: CameraIndex,
) -> DrawCallSet
where
M: Material,
Expand Down Expand Up @@ -707,7 +710,7 @@ impl GpuCuller {
pub fn add_object_uniform_upload_to_graph<'node, M: Material>(
&'node self,
graph: &mut RenderGraph<'node>,
camera_idx: Option<usize>,
camera_idx: CameraIndex,
resolution: UVec2,
samples: SampleCount,
name: &str,
Expand All @@ -717,8 +720,8 @@ impl GpuCuller {

node.build(move |mut ctx| {
let camera = match camera_idx {
Some(i) => &ctx.eval_output.shadows[i].camera,
None => &ctx.data_core.camera_manager,
CameraIndex::Shadow(i) => &ctx.eval_output.shadows[i as usize].camera,
CameraIndex::Viewport => &ctx.data_core.camera_manager,
};

self.object_uniform_upload::<M>(&mut ctx, camera, camera_idx, resolution, samples);
Expand All @@ -730,7 +733,7 @@ impl GpuCuller {
graph: &mut RenderGraph<'node>,
draw_calls_hdl: DataHandle<Arc<DrawCallSet>>,
depth_handle: RenderTargetHandle,
camera_idx: Option<usize>,
camera_idx: CameraIndex,
name: &str,
) {
let mut node = graph.add_node(name);
Expand All @@ -739,8 +742,8 @@ impl GpuCuller {

node.build(move |mut ctx| {
let camera = match camera_idx {
Some(i) => &ctx.eval_output.shadows[i].camera,
None => &ctx.data_core.camera_manager,
CameraIndex::Shadow(i) => &ctx.eval_output.shadows[i as usize].camera,
CameraIndex::Viewport => &ctx.data_core.camera_manager,
};

let jobs = batch_objects::<M>(&mut ctx, &self.previous_invocation_map_handle, camera, camera_idx);
Expand Down
8 changes: 4 additions & 4 deletions rend3-routine/src/forward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use wgpu::{
};

use crate::{
common::{PerMaterialArchetypeInterface, WholeFrameInterfaces},
common::{CameraIndex, PerMaterialArchetypeInterface, WholeFrameInterfaces},
culling::{self, CullingBufferMap, DrawCall, DrawCallSet, InputOutputPartition},
};

Expand Down Expand Up @@ -82,7 +82,7 @@ pub struct RoutineAddToGraphArgs<'a, 'node, M> {
pub color: Option<RenderTargetHandle>,
pub resolve: Option<RenderTargetHandle>,
pub depth: RenderTargetHandle,
pub camera: Option<usize>,
pub camera: CameraIndex,
}

/// A set of pipelines for rendering a specific combination of a material.
Expand All @@ -91,7 +91,7 @@ pub struct ForwardRoutine<M: Material> {
pub pipeline_s4: RenderPipeline,
pub material_key: u64,
pub culling_buffer_map_handle: GraphDataHandle<CullingBufferMap>,
pub draw_call_set_cache_handle: GraphDataHandle<FastHashMap<Option<usize>, Arc<DrawCallSet>>>,
pub draw_call_set_cache_handle: GraphDataHandle<FastHashMap<CameraIndex, Arc<DrawCallSet>>>,
pub _phantom: PhantomData<M>,
}
impl<M: Material> ForwardRoutine<M> {
Expand Down Expand Up @@ -204,7 +204,7 @@ impl<M: Material> ForwardRoutine<M> {
draw_call_set
}
};
let residual = culling_output_handle.is_some() && args.camera.is_none();
let residual = culling_output_handle.is_some() && args.camera.is_viewport();

let culling_buffer_storage = ctx.data_core.graph_storage.get(&self.culling_buffer_map_handle);

Expand Down
Loading

0 comments on commit dfb56bc

Please sign in to comment.