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

Interior mutablilty for re_renderer's static resource pools (RenderPipeline/Shader/Layouts/etc.) #4421

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/re_renderer/examples/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ impl<E: Example + 'static> Application<E> {
);

{
// Lock render pipelines for the lifetime of the composite pass.
let render_pipelines =
self.re_ctx.gpu_resources.render_pipelines.resources();

let mut composite_pass =
composite_cmd_encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
Expand All @@ -295,6 +299,7 @@ impl<E: Example + 'static> Application<E> {
for draw_result in &draw_results {
draw_result.view_builder.composite(
&self.re_ctx,
&render_pipelines,
&mut composite_pass,
draw_result.target_location,
);
Expand Down
21 changes: 19 additions & 2 deletions crates/re_renderer/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
global_bindings::GlobalBindings,
renderer::Renderer,
resource_managers::{MeshManager, TextureManager2D},
wgpu_resources::WgpuResourcePools,
wgpu_resources::{GpuRenderPipelinePoolMoveAccessor, WgpuResourcePools},
FileResolver, FileServer, FileSystem, RecommendedFileResolver,
};

Expand Down Expand Up @@ -116,7 +116,7 @@ impl RenderContext {
log_adapter_info(&adapter.get_info());

let mut gpu_resources = WgpuResourcePools::default();
let global_bindings = GlobalBindings::new(&mut gpu_resources, &device);
let global_bindings = GlobalBindings::new(&gpu_resources, &device);

// Validate capabilities of the device.
assert!(
Expand Down Expand Up @@ -187,6 +187,7 @@ impl RenderContext {
let active_frame = ActiveFrameContext {
before_view_builder_encoder: Mutex::new(FrameGlobalCommandEncoder::new(&device)),
per_frame_data_helper: TypeMap::new(),
pinned_render_pipelines: None,
frame_index: 0,
};

Expand Down Expand Up @@ -299,9 +300,18 @@ impl RenderContext {
// Map all read staging buffers.
self.gpu_readback_belt.get_mut().after_queue_submit();

// Give back moved render pipelines to the pool if any were moved out.
if let Some(moved_render_pipelines) = self.active_frame.pinned_render_pipelines.take() {
self.gpu_resources
.render_pipelines
.return_resources(moved_render_pipelines);
}

// New active frame!
self.active_frame = ActiveFrameContext {
before_view_builder_encoder: Mutex::new(FrameGlobalCommandEncoder::new(&self.device)),
frame_index: self.active_frame.frame_index + 1,
pinned_render_pipelines: None,
per_frame_data_helper: TypeMap::new(),
};
let frame_index = self.active_frame.frame_index;
Expand Down Expand Up @@ -431,6 +441,13 @@ pub struct ActiveFrameContext {
/// Utility type map that will be cleared every frame.
pub per_frame_data_helper: TypeMap,

/// Render pipelines that were moved out of the resource pool.
///
/// Will be moved back to the resource pool at the start of the frame.
/// This is needed for accessing the render pipelines without keeping a reference
/// to the resource pool lock during the lifetime of a render pass.
pub pinned_render_pipelines: Option<GpuRenderPipelinePoolMoveAccessor>,

/// Index of this frame. Is incremented for every render frame.
frame_index: u64,
}
Expand Down
18 changes: 7 additions & 11 deletions crates/re_renderer/src/draw_phases/outlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ use crate::{
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuRenderPipelineHandle, GpuTexture, PipelineLayoutDesc, PoolError, RenderPipelineDesc,
SamplerDesc, WgpuResourcePools,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, GpuTexture, PipelineLayoutDesc,
PoolError, RenderPipelineDesc, SamplerDesc,
},
DebugLabel, RenderContext,
};
Expand Down Expand Up @@ -372,11 +372,9 @@ impl OutlineMaskProcessor {

pub fn compute_outlines(
self,
pools: &WgpuResourcePools,
pipelines: &GpuRenderPipelinePoolAccessor<'_>,
encoder: &mut wgpu::CommandEncoder,
) -> Result<(), PoolError> {
let pipelines = &pools.render_pipelines;

let ops = wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT), // Clear is the closest to "don't care"
store: wgpu::StoreOp::Store,
Expand All @@ -396,16 +394,14 @@ impl OutlineMaskProcessor {
occlusion_query_set: None,
});

let render_pipeline_init =
pipelines.get_resource(self.render_pipeline_jumpflooding_init)?;
let render_pipeline_init = pipelines.get(self.render_pipeline_jumpflooding_init)?;
jumpflooding_init.set_bind_group(0, &self.bind_group_jumpflooding_init, &[]);
jumpflooding_init.set_pipeline(render_pipeline_init);
jumpflooding_init.draw(0..3, 0..1);
}

// Perform jump flooding.
let render_pipeline_step =
pipelines.get_resource(self.render_pipeline_jumpflooding_step)?;
let render_pipeline_step = pipelines.get(self.render_pipeline_jumpflooding_step)?;
for (i, bind_group) in self.bind_group_jumpflooding_steps.into_iter().enumerate() {
let mut jumpflooding_step = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: DebugLabel::from(format!("{} - jumpflooding_step {i}", self.label)).get(),
Expand All @@ -429,7 +425,7 @@ impl OutlineMaskProcessor {
}

fn create_bind_group_jumpflooding_init(
ctx: &mut RenderContext,
ctx: &RenderContext,
instance_label: &DebugLabel,
mask_texture: &GpuTexture,
) -> (GpuBindGroup, GpuBindGroupLayoutHandle) {
Expand Down Expand Up @@ -466,7 +462,7 @@ impl OutlineMaskProcessor {

fn create_bind_groups_for_jumpflooding_steps(
config: &OutlineConfig,
ctx: &mut RenderContext,
ctx: &RenderContext,
instance_label: &DebugLabel,
voronoi_textures: &[GpuTexture; 2],
) -> (Vec<GpuBindGroup>, GpuBindGroupLayoutHandle) {
Expand Down
27 changes: 15 additions & 12 deletions crates/re_renderer/src/draw_phases/picking_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use crate::{
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuRenderPipelineHandle,
GpuTexture, GpuTextureHandle, PipelineLayoutDesc, PoolError, RenderPipelineDesc,
TextureDesc, WgpuResourcePools,
GpuRenderPipelinePoolAccessor, GpuTexture, GpuTextureHandle, PipelineLayoutDesc, PoolError,
RenderPipelineDesc, TextureDesc,
},
DebugLabel, GpuReadbackBuffer, GpuReadbackIdentifier, RectInt, RenderContext,
};
Expand Down Expand Up @@ -344,20 +344,23 @@ impl PickingLayerProcessor {
pub fn end_render_pass(
self,
encoder: &mut wgpu::CommandEncoder,
pools: &WgpuResourcePools,
render_pipelines: &GpuRenderPipelinePoolAccessor<'_>,
) -> Result<(), PickingLayerError> {
let extent = glam::uvec2(
self.picking_target.texture.width(),
self.picking_target.texture.height(),
);

let readable_depth_texture = if let Some(depth_copy_workaround) =
self.depth_readback_workaround.as_ref()
{
depth_copy_workaround.copy_to_readable_texture(encoder, pools, &self.bind_group_0)?
} else {
&self.picking_depth_target
};
let readable_depth_texture =
if let Some(depth_copy_workaround) = self.depth_readback_workaround.as_ref() {
depth_copy_workaround.copy_to_readable_texture(
encoder,
render_pipelines,
&self.bind_group_0,
)?
} else {
&self.picking_depth_target
};

self.readback_buffer.read_multiple_texture2d(
encoder,
Expand Down Expand Up @@ -581,7 +584,7 @@ impl DepthReadbackWorkaround {
fn copy_to_readable_texture(
&self,
encoder: &mut wgpu::CommandEncoder,
pools: &WgpuResourcePools,
render_pipelines: &GpuRenderPipelinePoolAccessor<'_>,
global_binding_bind_group: &GpuBindGroup,
) -> Result<&GpuTexture, PoolError> {
// Copy depth texture to a readable (color) texture with a screen filling triangle.
Expand All @@ -600,7 +603,7 @@ impl DepthReadbackWorkaround {
occlusion_query_set: None,
});

let pipeline = pools.render_pipelines.get_resource(self.render_pipeline)?;
let pipeline = render_pipelines.get(self.render_pipeline)?;
pass.set_pipeline(pipeline);
pass.set_bind_group(0, global_binding_bind_group, &[]);
pass.set_bind_group(1, &self.bind_group, &[]);
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/global_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub(crate) struct GlobalBindings {
}

impl GlobalBindings {
pub fn new(pools: &mut WgpuResourcePools, device: &wgpu::Device) -> Self {
pub fn new(pools: &WgpuResourcePools, device: &wgpu::Device) -> Self {
Self {
layout: pools.bind_group_layouts.get_or_create(
device,
Expand Down
11 changes: 6 additions & 5 deletions crates/re_renderer/src/queuable_draw_data.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{
context::Renderers,
draw_phases::DrawPhase,
renderer::{DrawData, DrawError, Renderer},
RenderContext,
wgpu_resources::GpuRenderPipelinePoolAccessor,
};

#[derive(thiserror::Error, Debug)]
Expand All @@ -17,7 +18,8 @@ pub enum QueueableDrawDataError {
}

type DrawFn = dyn for<'a, 'b> Fn(
&'b RenderContext,
&Renderers,
&'b GpuRenderPipelinePoolAccessor<'b>,
DrawPhase,
&'a mut wgpu::RenderPass<'b>,
&'b dyn std::any::Any,
Expand All @@ -36,8 +38,7 @@ pub struct QueueableDrawData {
impl<D: DrawData + Sync + Send + 'static> From<D> for QueueableDrawData {
fn from(draw_data: D) -> Self {
QueueableDrawData {
draw_func: Box::new(move |ctx, phase, pass, draw_data| {
let renderers = ctx.renderers.read();
draw_func: Box::new(move |renderers, gpu_resources, phase, pass, draw_data| {
let renderer = renderers.get::<D::Renderer>().ok_or(
QueueableDrawDataError::FailedToRetrieveRenderer(std::any::type_name::<
D::Renderer,
Expand All @@ -47,7 +48,7 @@ impl<D: DrawData + Sync + Send + 'static> From<D> for QueueableDrawData {
QueueableDrawDataError::UnexpectedDrawDataType(std::any::type_name::<D>()),
)?;
renderer
.draw(&ctx.gpu_resources, phase, pass, draw_data)
.draw(gpu_resources, phase, pass, draw_data)
.map_err(QueueableDrawDataError::from)
}),
draw_data: Box::new(draw_data),
Expand Down
8 changes: 4 additions & 4 deletions crates/re_renderer/src/renderer/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::{
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuRenderPipelineHandle, GpuTexture, PipelineLayoutDesc, RenderPipelineDesc,
WgpuResourcePools,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, GpuTexture, PipelineLayoutDesc,
RenderPipelineDesc, WgpuResourcePools,
},
OutlineConfig, Rgba,
};
Expand Down Expand Up @@ -206,7 +206,7 @@ impl Renderer for Compositor {

fn draw<'a>(
&self,
pools: &'a WgpuResourcePools,
render_pipelines: &'a GpuRenderPipelinePoolAccessor<'a>,
phase: DrawPhase,
pass: &mut wgpu::RenderPass<'a>,
draw_data: &'a CompositorDrawData,
Expand All @@ -216,7 +216,7 @@ impl Renderer for Compositor {
DrawPhase::CompositingScreenshot => self.render_pipeline_screenshot,
_ => unreachable!("We were called on a phase we weren't subscribed to: {phase:?}"),
};
let pipeline = pools.render_pipelines.get_resource(pipeline_handle)?;
let pipeline = render_pipelines.get(pipeline_handle)?;

pass.set_pipeline(pipeline);
pass.set_bind_group(1, &draw_data.bind_group, &[]);
Expand Down
8 changes: 4 additions & 4 deletions crates/re_renderer/src/renderer/debug_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::{
include_shader_module,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuRenderPipelineHandle, GpuTexture, PipelineLayoutDesc, RenderPipelineDesc,
WgpuResourcePools,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, GpuTexture, PipelineLayoutDesc,
RenderPipelineDesc, WgpuResourcePools,
},
RectInt,
};
Expand Down Expand Up @@ -239,12 +239,12 @@ impl Renderer for DebugOverlayRenderer {

fn draw<'a>(
&self,
pools: &'a WgpuResourcePools,
render_pipelines: &'a GpuRenderPipelinePoolAccessor<'a>,
_phase: DrawPhase,
pass: &mut wgpu::RenderPass<'a>,
draw_data: &'a DebugOverlayDrawData,
) -> Result<(), DrawError> {
let pipeline = pools.render_pipelines.get_resource(self.render_pipeline)?;
let pipeline = render_pipelines.get(self.render_pipeline)?;

pass.set_pipeline(pipeline);
pass.set_bind_group(1, &draw_data.bind_group, &[]);
Expand Down
7 changes: 4 additions & 3 deletions crates/re_renderer/src/renderer/depth_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use crate::{
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuRenderPipelineHandle, PipelineLayoutDesc, RenderPipelineDesc,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, PipelineLayoutDesc,
RenderPipelineDesc,
},
Colormap, OutlineMaskPreference, PickingLayerObjectId, PickingLayerProcessor,
};
Expand Down Expand Up @@ -500,7 +501,7 @@ impl Renderer for DepthCloudRenderer {

fn draw<'a>(
&self,
pools: &'a WgpuResourcePools,
render_pipelines: &'a GpuRenderPipelinePoolAccessor<'a>,
phase: DrawPhase,
pass: &mut wgpu::RenderPass<'a>,
draw_data: &'a Self::RendererDrawData,
Expand All @@ -516,7 +517,7 @@ impl Renderer for DepthCloudRenderer {
DrawPhase::OutlineMask => self.render_pipeline_outline_mask,
_ => unreachable!("We were called on a phase we weren't subscribed to: {phase:?}"),
};
let pipeline = pools.render_pipelines.get_resource(pipeline_handle)?;
let pipeline = render_pipelines.get(pipeline_handle)?;

pass.set_pipeline(pipeline);

Expand Down
7 changes: 4 additions & 3 deletions crates/re_renderer/src/renderer/generic_skybox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::{
renderer::screen_triangle_vertex_shader,
view_builder::ViewBuilder,
wgpu_resources::{
GpuRenderPipelineHandle, PipelineLayoutDesc, RenderPipelineDesc, WgpuResourcePools,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, PipelineLayoutDesc,
RenderPipelineDesc, WgpuResourcePools,
},
};

Expand Down Expand Up @@ -96,14 +97,14 @@ impl Renderer for GenericSkybox {

fn draw<'a>(
&self,
pools: &'a WgpuResourcePools,
render_pipelines: &'a GpuRenderPipelinePoolAccessor<'a>,
_phase: DrawPhase,
pass: &mut wgpu::RenderPass<'a>,
_draw_data: &GenericSkyboxDrawData,
) -> Result<(), DrawError> {
re_tracing::profile_function!();

let pipeline = pools.render_pipelines.get_resource(self.render_pipeline)?;
let pipeline = render_pipelines.get(self.render_pipeline)?;

pass.set_pipeline(pipeline);
pass.draw(0..3, 0..1);
Expand Down
7 changes: 4 additions & 3 deletions crates/re_renderer/src/renderer/lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ use crate::{
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuRenderPipelineHandle, PipelineLayoutDesc, PoolError, RenderPipelineDesc, TextureDesc,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, PipelineLayoutDesc, PoolError,
RenderPipelineDesc, TextureDesc,
},
Color32, DebugLabel, DepthOffset, LineStripSeriesBuilder, OutlineMaskPreference,
PickingLayerObjectId, PickingLayerProcessor,
Expand Down Expand Up @@ -961,7 +962,7 @@ impl Renderer for LineRenderer {

fn draw<'a>(
&self,
pools: &'a WgpuResourcePools,
render_pipelines: &'a GpuRenderPipelinePoolAccessor<'a>,
phase: DrawPhase,
pass: &mut wgpu::RenderPass<'a>,
draw_data: &'a Self::RendererDrawData,
Expand All @@ -982,7 +983,7 @@ impl Renderer for LineRenderer {
return Ok(()); // No lines submitted.
};

let pipeline = pools.render_pipelines.get_resource(pipeline_handle)?;
let pipeline = render_pipelines.get(pipeline_handle)?;

pass.set_pipeline(pipeline);
pass.set_bind_group(1, bind_group_all_lines, &[]);
Expand Down