Skip to content

Commit

Permalink
Storage is now only for user - wgpu use arcs
Browse files Browse the repository at this point in the history
  • Loading branch information
gents83 committed Sep 8, 2023
1 parent 27d5a68 commit 7394fd7
Show file tree
Hide file tree
Showing 36 changed files with 1,605 additions and 1,651 deletions.
2 changes: 1 addition & 1 deletion player/src/bin/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn main() {
IdentityPassThroughFactory,
wgt::InstanceDescriptor::default(),
);
let mut command_buffer_id_manager = wgc::identity::IdentityManager::default();
let mut command_buffer_id_manager = wgc::identity::IdentityManager::new();

#[cfg(feature = "winit")]
let surface = global.instance_create_surface(
Expand Down
40 changes: 12 additions & 28 deletions player/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,23 @@
#![cfg(not(target_arch = "wasm32"))]
#![warn(unsafe_op_in_unsafe_fn)]

use wgc::device::trace;
use wgc::{device::trace, identity::IdentityManager};

use std::{borrow::Cow, fmt::Debug, fs, marker::PhantomData, path::Path};
use std::{borrow::Cow, fs, path::Path, sync::Arc};

#[derive(Debug)]
pub struct IdentityPassThrough<I>(PhantomData<I>);
pub struct IdentityPassThroughFactory;

impl<I: Clone + Debug + wgc::id::TypedId> wgc::identity::IdentityHandler<I>
for IdentityPassThrough<I>
{
impl<I: wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I> for IdentityPassThroughFactory {
type Input = I;
fn process(&self, id: I, backend: wgt::Backend) -> I {
let (index, epoch, _backend) = id.unzip();
I::zip(index, epoch, backend)
fn spawn(&self) -> Option<Arc<IdentityManager<I>>> {
None
}
fn free(&self, _id: I) {}
}

pub struct IdentityPassThroughFactory;

impl<I: Clone + Debug + wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I>
for IdentityPassThroughFactory
{
type Filter = IdentityPassThrough<I>;
fn spawn(&self) -> Self::Filter {
IdentityPassThrough(PhantomData)
}
}
impl wgc::identity::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {
fn ids_are_generated_in_wgpu() -> bool {
false
fn input_to_id(id_in: Self::Input) -> I {
id_in
}
}
impl wgc::identity::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {}

pub trait GlobalPlay {
fn encode_commands<A: wgc::hal_api::HalApi>(
Expand All @@ -53,7 +37,7 @@ pub trait GlobalPlay {
device: wgc::id::DeviceId,
action: trace::Action,
dir: &Path,
comb_manager: &mut wgc::identity::IdentityManager,
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::CommandBufferId>,
);
}

Expand Down Expand Up @@ -168,7 +152,7 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
device: wgc::id::DeviceId,
action: trace::Action,
dir: &Path,
comb_manager: &mut wgc::identity::IdentityManager,
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::CommandBufferId>,
) {
use wgc::device::trace::Action;
log::debug!("action {:?}", action);
Expand Down Expand Up @@ -390,7 +374,7 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
let (encoder, error) = self.device_create_command_encoder::<A>(
device,
&wgt::CommandEncoderDescriptor { label: None },
comb_manager.alloc(device.backend()),
comb_manager.process(device.backend()),
);
if let Some(e) = error {
panic!("{:?}", e);
Expand Down
2 changes: 1 addition & 1 deletion player/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl Test<'_> {
panic!("{:?}", e);
}

let mut command_buffer_id_manager = wgc::identity::IdentityManager::default();
let mut command_buffer_id_manager = wgc::identity::IdentityManager::new();
println!("\t\t\tRunning...");
for action in self.actions {
wgc::gfx_select!(device_id => global.process(device_id, action, dir, &mut command_buffer_id_manager));
Expand Down
8 changes: 5 additions & 3 deletions tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async fn initialize_device(
}

pub struct TestingContext {
pub instance: Instance,
pub adapter: Adapter,
pub adapter_info: wgt::AdapterInfo,
pub adapter_downlevel_capabilities: wgt::DownlevelCapabilities,
Expand Down Expand Up @@ -210,7 +211,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te

let _test_guard = isolation::OneTestPerProcessGuard::new();

let (adapter, _surface_guard) = initialize_adapter();
let (instance, adapter, _surface_guard) = initialize_adapter();

let adapter_info = adapter.get_info();
let adapter_lowercase_name = adapter_info.name.to_lowercase();
Expand Down Expand Up @@ -256,6 +257,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te
));

let context = TestingContext {
instance,
adapter,
adapter_info: adapter_info.clone(),
adapter_downlevel_capabilities,
Expand Down Expand Up @@ -375,7 +377,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te
}
}

fn initialize_adapter() -> (Adapter, SurfaceGuard) {
fn initialize_adapter() -> (Instance, Adapter, SurfaceGuard) {
let backends = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all);
let dx12_shader_compiler = wgpu::util::dx12_shader_compiler_from_env().unwrap_or_default();
let gles_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default();
Expand Down Expand Up @@ -440,7 +442,7 @@ fn initialize_adapter() -> (Adapter, SurfaceGuard) {
))
.expect("could not find suitable adapter on the system");

(adapter, surface_guard)
(instance, adapter, surface_guard)
}

struct SurfaceGuard {
Expand Down
249 changes: 249 additions & 0 deletions tests/tests/mem_leaks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
use std::num::NonZeroU64;

use wasm_bindgen_test::*;
use wgpu::util::DeviceExt;

use wgpu_test::{initialize_test, TestParameters, TestingContext};

#[cfg(any(
not(target_arch = "wasm32"),
target_os = "emscripten",
feature = "webgl"
))]
fn draw_test_with_reports(
ctx: TestingContext,
expected: &[u32],
function: impl FnOnce(&mut wgpu::RenderPass<'_>),
) {
let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.adapters.num_allocated, 1);
assert_eq!(report.devices.num_allocated, 1);
assert_eq!(report.queues.num_allocated, 1);

let shader = ctx
.device
.create_shader_module(wgpu::include_wgsl!("./vertex_indices/draw.vert.wgsl"));

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.shader_modules.num_allocated, 1);

let bgl = ctx
.device
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Storage { read_only: false },
has_dynamic_offset: false,
min_binding_size: NonZeroU64::new(4),
},
visibility: wgpu::ShaderStages::VERTEX,
count: None,
}],
});

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 0);
assert_eq!(report.bind_groups.num_allocated, 0);
assert_eq!(report.bind_group_layouts.num_allocated, 1);

let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: 4 * expected.len() as u64,
usage: wgpu::BufferUsages::COPY_SRC
| wgpu::BufferUsages::STORAGE
| wgpu::BufferUsages::MAP_READ,
mapped_at_creation: false,
});

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);

let bg = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
label: None,
layout: &bgl,
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: buffer.as_entire_binding(),
}],
});

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);

let ppl = ctx
.device
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[&bgl],
push_constant_ranges: &[],
});

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.pipeline_layouts.num_allocated, 1);
assert_eq!(report.render_pipelines.num_allocated, 0);
assert_eq!(report.compute_pipelines.num_allocated, 0);

let pipeline = ctx
.device
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&ppl),
vertex: wgpu::VertexState {
buffers: &[],
entry_point: "vs_main",
module: &shader,
},
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
fragment: Some(wgpu::FragmentState {
entry_point: "fs_main",
module: &shader,
targets: &[Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Unorm,
blend: None,
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
assert_eq!(report.pipeline_layouts.num_allocated, 1);
assert_eq!(report.render_pipelines.num_allocated, 1);
assert_eq!(report.compute_pipelines.num_allocated, 0);

let texture = ctx.device.create_texture_with_data(
&ctx.queue,
&wgpu::TextureDescriptor {
label: Some("dummy"),
size: wgpu::Extent3d {
width: 1,
height: 1,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Unorm,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
},
&[0, 0, 0, 1],
);
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.texture_views.num_allocated, 1);
assert_eq!(report.textures.num_allocated, 1);

drop(texture);

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.texture_views.num_allocated, 1);
assert_eq!(report.textures.num_allocated, 1);
assert_eq!(report.textures.num_kept_from_user, 0);

let mut encoder = ctx
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.command_buffers.num_allocated, 1);
assert_eq!(report.buffers.num_allocated, 1);

let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
ops: wgpu::Operations::default(),
resolve_target: None,
view: &texture_view,
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});

rpass.set_pipeline(&pipeline);
rpass.set_bind_group(0, &bg, &[]);

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
assert_eq!(report.pipeline_layouts.num_allocated, 1);
assert_eq!(report.render_pipelines.num_allocated, 1);
assert_eq!(report.compute_pipelines.num_allocated, 0);
assert_eq!(report.command_buffers.num_allocated, 1);
assert_eq!(report.render_bundles.num_allocated, 0);
assert_eq!(report.texture_views.num_allocated, 1);
assert_eq!(report.textures.num_allocated, 1);

function(&mut rpass);

drop(rpass);
drop(pipeline);
drop(texture_view);

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.command_buffers.num_allocated, 1);
assert_eq!(report.render_pipelines.num_allocated, 1);
assert_eq!(report.render_pipelines.num_kept_from_user, 0);
assert_eq!(report.texture_views.num_allocated, 1);
assert_eq!(report.texture_views.num_kept_from_user, 0);
assert_eq!(report.textures.num_allocated, 1);
assert_eq!(report.textures.num_kept_from_user, 0);

ctx.queue.submit(Some(encoder.finish()));

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.command_buffers.num_allocated, 0);

ctx.device.poll(wgpu::Maintain::Wait);

let global_report = ctx.instance.generate_report();
let report = global_report.hub_report();
assert_eq!(report.render_pipelines.num_allocated, 0);
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
assert_eq!(report.pipeline_layouts.num_allocated, 1);
assert_eq!(report.texture_views.num_allocated, 0);
}

#[test]
#[wasm_bindgen_test]
#[cfg(any(
not(target_arch = "wasm32"),
target_os = "emscripten",
feature = "webgl"
))]
fn simple_draw_leaks() {
initialize_test(TestParameters::default().test_features_limits(), |ctx| {
draw_test_with_reports(ctx, &[0, 1, 2, 3, 4, 5], |cmb| {
cmb.draw(0..6, 0..1);
})
})
}
1 change: 1 addition & 0 deletions tests/tests/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod encoder;
mod example_wgsl;
mod external_texture;
mod instance;
mod mem_leaks;
mod occlusion_query;
mod partially_bounded_arrays;
mod poll;
Expand Down
Loading

0 comments on commit 7394fd7

Please sign in to comment.