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

Cleanup for standalone usage #51

Merged
merged 3 commits into from
Nov 3, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion blade-egui/src/belt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl BufferBelt {
bp
}

pub fn flush(&mut self, sp: blade_graphics::SyncPoint) {
pub fn flush(&mut self, sp: &blade_graphics::SyncPoint) {
self.buffers
.extend(self.active.drain(..).map(|(rb, _)| (rb, sp.clone())));
}
Expand Down
12 changes: 6 additions & 6 deletions blade-egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@

mod belt;

const SHADER_SOURCE: &'static str = include_str!("../shader.wgsl");

use belt::{BeltDescriptor, BufferBelt};
use std::{
collections::hash_map::{Entry, HashMap},
fs, mem, ptr,
mem, ptr,
};

#[repr(C)]
Expand Down Expand Up @@ -118,14 +120,12 @@ impl GuiPainter {
/// and this attachment format must be The `output_format`.
#[profiling::function]
pub fn new(
context: &blade_graphics::Context,
output_format: blade_graphics::TextureFormat,
context: &blade_graphics::Context,
) -> Self {
let shader_source = fs::read_to_string("blade-egui/shader.wgsl").unwrap();
let shader = context.create_shader(blade_graphics::ShaderDesc {
source: &shader_source,
source: SHADER_SOURCE,
});

let globals_layout = <Globals as blade_graphics::ShaderData>::layout();
let locals_layout = <Locals as blade_graphics::ShaderData>::layout();
let pipeline = context.create_render_pipeline(blade_graphics::RenderPipelineDesc {
Expand Down Expand Up @@ -349,7 +349,7 @@ impl GuiPainter {

/// Call this after submitting work at the given `sync_point`.
#[profiling::function]
pub fn after_submit(&mut self, sync_point: blade_graphics::SyncPoint) {
pub fn after_submit(&mut self, sync_point: &blade_graphics::SyncPoint) {
self.textures_to_delete.extend(
self.textures_dropped
.drain(..)
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions blade-render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod model;
mod render;
pub mod shader;
pub mod texture;
pub mod util;

pub use asset_hub::*;
pub use model::Model;
Expand Down
25 changes: 14 additions & 11 deletions blade-render/src/render/env_map.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fs, num::NonZeroU32};
use std::num::NonZeroU32;

use crate::DummyResources;

Expand All @@ -21,21 +21,20 @@ pub struct EnvironmentMap {
pub weight_texture: blade_graphics::Texture,
pub weight_view: blade_graphics::TextureView,
pub weight_mips: Vec<blade_graphics::TextureView>,
pub preproc_pipeline: blade_graphics::ComputePipeline,
pub prepare_pipeline: blade_graphics::ComputePipeline,
}

impl EnvironmentMap {
pub fn init_pipeline(
shader: &blade_graphics::Shader,
gpu: &blade_graphics::Context,
) -> Result<blade_graphics::ComputePipeline, &'static str> {
let source = fs::read_to_string("blade-render/code/env-preproc.wgsl").unwrap();
let shader = gpu.try_create_shader(blade_graphics::ShaderDesc { source: &source })?;
let layout = <EnvPreprocData as blade_graphics::ShaderData>::layout();
shader.check_struct_size::<EnvPreprocParams>();

Ok(
gpu.create_compute_pipeline(blade_graphics::ComputePipelineDesc {
name: "env-preproc",
name: "env-prepare",
data_layouts: &[&layout],
compute: shader.at("downsample"),
}),
Expand All @@ -44,20 +43,24 @@ impl EnvironmentMap {

pub fn with_pipeline(
dummy: &DummyResources,
preproc_pipeline: blade_graphics::ComputePipeline,
prepare_pipeline: blade_graphics::ComputePipeline,
) -> Self {
Self {
main_view: dummy.white_view,
size: blade_graphics::Extent::default(),
weight_texture: blade_graphics::Texture::default(),
weight_view: dummy.red_view,
weight_mips: Vec::new(),
preproc_pipeline,
prepare_pipeline,
}
}

pub fn new(dummy: &DummyResources, gpu: &blade_graphics::Context) -> Self {
Self::with_pipeline(dummy, Self::init_pipeline(gpu).unwrap())
pub fn new(
shader: &blade_graphics::Shader,
dummy: &DummyResources,
gpu: &blade_graphics::Context,
) -> Self {
Self::with_pipeline(dummy, Self::init_pipeline(shader, gpu).unwrap())
}

fn weight_size(&self) -> blade_graphics::Extent {
Expand Down Expand Up @@ -134,10 +137,10 @@ impl EnvironmentMap {
encoder.init_texture(self.weight_texture);
for target_level in 0..mip_level_count {
let groups = self
.preproc_pipeline
.prepare_pipeline
.get_dispatch_for(weight_extent.at_mip_level(target_level));
let mut compute = encoder.compute();
let mut pass = compute.with(&self.preproc_pipeline);
let mut pass = compute.with(&self.prepare_pipeline);
pass.bind(
0,
&EnvPreprocData {
Expand Down
32 changes: 22 additions & 10 deletions blade-render/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ struct HitEntry {

#[derive(Clone, PartialEq)]
pub struct Shaders {
env_prepare: blade_asset::Handle<crate::Shader>,
fill_gbuf: blade_asset::Handle<crate::Shader>,
ray_trace: blade_asset::Handle<crate::Shader>,
blur: blade_asset::Handle<crate::Shader>,
Expand All @@ -562,6 +563,7 @@ impl Shaders {
pub fn load(path: &Path, asset_hub: &crate::AssetHub) -> (Self, choir::RunningTask) {
let mut ctx = asset_hub.open_context(path, "shader finish");
let shaders = Self {
env_prepare: ctx.load_shader("env-prepare.wgsl"),
fill_gbuf: ctx.load_shader("fill-gbuf.wgsl"),
ray_trace: ctx.load_shader("ray-trace.wgsl"),
blur: ctx.load_shader("blur.wgsl"),
Expand All @@ -581,7 +583,7 @@ struct ShaderPipelines {
post_proc: blade_graphics::RenderPipeline,
debug_draw: blade_graphics::RenderPipeline,
debug_blit: blade_graphics::RenderPipeline,
env_preproc: blade_graphics::ComputePipeline,
env_prepare: blade_graphics::ComputePipeline,
debug_line_size: u32,
debug_buffer_size: u32,
reservoir_size: u32,
Expand Down Expand Up @@ -735,14 +737,24 @@ impl ShaderPipelines {
config.surface_format,
gpu,
),
env_preproc: EnvironmentMap::init_pipeline(gpu)?,
env_prepare: EnvironmentMap::init_pipeline(
shader_man[shaders.env_prepare].raw.as_ref().unwrap(),
gpu,
)?,
debug_line_size: sh_main.get_struct_size("DebugLine"),
debug_buffer_size: sh_main.get_struct_size("DebugBuffer"),
reservoir_size: sh_main.get_struct_size("StoredReservoir"),
})
}
}

/// Temporary resources associated with a GPU frame.
#[derive(Default)]
pub struct FrameResources {
pub buffers: Vec<blade_graphics::Buffer>,
pub acceleration_structures: Vec<blade_graphics::AccelerationStructure>,
}

impl Renderer {
/// Create a new renderer with a given configuration.
///
Expand Down Expand Up @@ -866,7 +878,7 @@ impl Renderer {
atrous_pipeline: sp.atrous,
},
acceleration_structure: blade_graphics::AccelerationStructure::default(),
env_map: EnvironmentMap::with_pipeline(&dummy, sp.env_preproc),
env_map: EnvironmentMap::with_pipeline(&dummy, sp.env_prepare),
dummy,
hit_buffer: blade_graphics::Buffer::default(),
vertex_buffers: blade_graphics::BufferArray::new(),
Expand Down Expand Up @@ -1038,8 +1050,7 @@ impl Renderer {
env_map: Option<blade_asset::Handle<crate::Texture>>,
asset_hub: &crate::AssetHub,
gpu: &blade_graphics::Context,
temp_buffers: &mut Vec<blade_graphics::Buffer>,
temp_acceleration_structures: &mut Vec<blade_graphics::AccelerationStructure>,
temp: &mut FrameResources,
) {
let (env_view, env_extent) = match env_map {
Some(handle) => {
Expand All @@ -1052,7 +1063,8 @@ impl Renderer {
.assign(env_view, env_extent, command_encoder, gpu);

if self.acceleration_structure != blade_graphics::AccelerationStructure::default() {
temp_acceleration_structures.push(self.acceleration_structure);
temp.acceleration_structures
.push(self.acceleration_structure);
}

let geometry_count = objects
Expand All @@ -1065,7 +1077,7 @@ impl Renderer {
let hit_size = (geometry_count.max(1) * mem::size_of::<HitEntry>()) as u64;
//TODO: reuse the hit buffer
if self.hit_buffer != blade_graphics::Buffer::default() {
temp_buffers.push(self.hit_buffer);
temp.buffers.push(self.hit_buffer);
}
self.hit_buffer = gpu.create_buffer(blade_graphics::BufferDesc {
name: "hit entries",
Expand All @@ -1077,7 +1089,7 @@ impl Renderer {
size: hit_size,
memory: blade_graphics::Memory::Upload,
});
temp_buffers.push(hit_staging);
temp.buffers.push(hit_staging);
{
let mut transfers = command_encoder.transfer();
transfers.copy_buffer_to_buffer(hit_staging.at(0), self.hit_buffer.at(0), hit_size);
Expand Down Expand Up @@ -1217,8 +1229,8 @@ impl Renderer {
scratch_buf.at(0),
);

temp_buffers.push(instance_buf);
temp_buffers.push(scratch_buf);
temp.buffers.push(instance_buf);
temp.buffers.push(scratch_buf);
}

/// Prepare to render a frame.
Expand Down
68 changes: 68 additions & 0 deletions blade-render/src/util/frame_pacer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::render::FrameResources;
use std::mem;

/// Utility object that encapsulates the logic
/// of always rendering 1 frame at a time, and
/// cleaning up the temporary resources.
pub struct FramePacer {
frame_index: usize,
prev_resources: FrameResources,
prev_sync_point: Option<blade_graphics::SyncPoint>,
command_encoder: Option<blade_graphics::CommandEncoder>,
next_resources: FrameResources,
}

impl FramePacer {
pub fn new(context: &blade_graphics::Context) -> Self {
let encoder = context.create_command_encoder(blade_graphics::CommandEncoderDesc {
name: "main",
buffer_count: 2,
});
Self {
frame_index: 0,
prev_resources: FrameResources::default(),
prev_sync_point: None,
command_encoder: Some(encoder),
next_resources: FrameResources::default(),
}
}

#[profiling::function]
pub fn wait_for_previous_frame(&mut self, context: &blade_graphics::Context) {
if let Some(sp) = self.prev_sync_point.take() {
context.wait_for(&sp, !0);
}
for buffer in self.prev_resources.buffers.drain(..) {
context.destroy_buffer(buffer);
}
for accel_structure in self.prev_resources.acceleration_structures.drain(..) {
context.destroy_acceleration_structure(accel_structure);
}
}

pub fn last_sync_point(&self) -> Option<&blade_graphics::SyncPoint> {
self.prev_sync_point.as_ref()
}

pub fn destroy(&mut self, context: &blade_graphics::Context) {
self.wait_for_previous_frame(context);
context.destroy_command_encoder(self.command_encoder.take().unwrap());
}

pub fn begin_frame(&mut self) -> (&mut blade_graphics::CommandEncoder, &mut FrameResources) {
let encoder = self.command_encoder.as_mut().unwrap();
encoder.start();
(encoder, &mut self.next_resources)
}

pub fn end_frame(&mut self, context: &blade_graphics::Context) -> &blade_graphics::SyncPoint {
let sync_point = context.submit(self.command_encoder.as_mut().unwrap());
self.frame_index += 1;
// Wait for the previous frame immediately - this ensures that we are
// only processing one frame at a time, and yet not stalling.
self.wait_for_previous_frame(context);
self.prev_sync_point = Some(sync_point);
mem::swap(&mut self.prev_resources, &mut self.next_resources);
self.prev_sync_point.as_ref().unwrap()
}
}
3 changes: 3 additions & 0 deletions blade-render/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod frame_pacer;

pub use self::frame_pacer::*;
23 changes: 18 additions & 5 deletions examples/init/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(irrefutable_let_patterns)]

use std::{env, path::Path, ptr, sync::Arc};

Check warning on line 3 in examples/init/main.rs

View workflow job for this annotation

GitHub Actions / build (MacOS, macos-latest, x86_64-apple-darwin)

unused import: `ptr`

use blade_graphics as gpu;

Expand Down Expand Up @@ -156,10 +156,16 @@

println!("Populating the scene");
let mut load_finish = choir.spawn("load finish").init_dummy();
let (shader_handle, shader_task) = asset_hub
let (shader_main_handle, shader_main_task) = asset_hub
.shaders
.load("examples/init/env-sample.wgsl", blade_render::shader::Meta);
load_finish.depend_on(shader_task);
load_finish.depend_on(shader_main_task);
let (shader_init_handle, shader_init_task) = asset_hub.shaders.load(
"blade-render/code/env-prepare.wgsl",
blade_render::shader::Meta,
);
load_finish.depend_on(shader_init_task);

for arg in env::args().skip(1) {
if arg.ends_with(".exr") {
println!("\tenvironment map = {}", arg);
Expand Down Expand Up @@ -198,7 +204,11 @@
let mut temp_buffers = Vec::new();
asset_hub.flush(&mut command_encoder, &mut temp_buffers);

let mut env_map = blade_render::EnvironmentMap::new(&dummy, &context);
let mut env_map = blade_render::EnvironmentMap::new(
asset_hub.shaders[shader_init_handle].raw.as_ref().unwrap(),
&dummy,
&context,
);
let env_size = match environment_map {
Some(handle) => {
let texture = &asset_hub.textures[handle];
Expand All @@ -207,8 +217,11 @@
}
None => dummy.size,
};
let env_shader = asset_hub.shaders[shader_handle].raw.as_ref().unwrap();
let env_sampler = EnvMapSampler::new(env_size, env_shader, &context);
let env_sampler = EnvMapSampler::new(
env_size,
asset_hub.shaders[shader_main_handle].raw.as_ref().unwrap(),
&context,
);
env_sampler.accumulate(&mut command_encoder, env_map.main_view, env_map.weight_view);
let sync_point = context.submit(&mut command_encoder);

Expand Down
Loading
Loading