mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
trace: support pipelines, refactor destruction sequence
This commit is contained in:
parent
018417f174
commit
854c1be035
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -840,6 +840,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"raw-window-handle",
|
||||||
"ron",
|
"ron",
|
||||||
"wgpu-core",
|
"wgpu-core",
|
||||||
"wgpu-types",
|
"wgpu-types",
|
||||||
|
|||||||
@ -17,6 +17,7 @@ publish = false
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
env_logger = "0.7"
|
env_logger = "0.7"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
raw-window-handle = "0.3"
|
||||||
ron = "0.5"
|
ron = "0.5"
|
||||||
winit = { version = "0.22", optional = true }
|
winit = { version = "0.22", optional = true }
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use std::{
|
|||||||
fs::File,
|
fs::File,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! gfx_select {
|
macro_rules! gfx_select {
|
||||||
@ -41,7 +42,26 @@ impl Label {
|
|||||||
fn as_ptr(&self) -> *const std::os::raw::c_char {
|
fn as_ptr(&self) -> *const std::os::raw::c_char {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Some(ref c_string) => c_string.as_ptr(),
|
Some(ref c_string) => c_string.as_ptr(),
|
||||||
None => std::ptr::null(),
|
None => ptr::null(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OwnedProgrammableStage {
|
||||||
|
desc: wgc::pipeline::ProgrammableStageDescriptor,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
entry_point: CString,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<trace::ProgrammableStageDescriptor> for OwnedProgrammableStage {
|
||||||
|
fn from(stage: trace::ProgrammableStageDescriptor) -> Self {
|
||||||
|
let entry_point = CString::new(stage.entry_point.as_str()).unwrap();
|
||||||
|
OwnedProgrammableStage {
|
||||||
|
desc: wgc::pipeline::ProgrammableStageDescriptor {
|
||||||
|
module: stage.module,
|
||||||
|
entry_point: entry_point.as_ptr(),
|
||||||
|
},
|
||||||
|
entry_point,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +198,7 @@ fn main() {
|
|||||||
log::info!("Found {} actions", actions.len());
|
log::info!("Found {} actions", actions.len());
|
||||||
|
|
||||||
#[cfg(feature = "winit")]
|
#[cfg(feature = "winit")]
|
||||||
let event_loop = {
|
let mut event_loop = {
|
||||||
log::info!("Creating a window");
|
log::info!("Creating a window");
|
||||||
EventLoop::new()
|
EventLoop::new()
|
||||||
};
|
};
|
||||||
@ -194,12 +214,10 @@ fn main() {
|
|||||||
let mut command_buffer_id_manager = wgc::hub::IdentityManager::default();
|
let mut command_buffer_id_manager = wgc::hub::IdentityManager::default();
|
||||||
|
|
||||||
#[cfg(feature = "winit")]
|
#[cfg(feature = "winit")]
|
||||||
let (_size, surface) = {
|
let surface = global.instance_create_surface(
|
||||||
let size = window.inner_size();
|
raw_window_handle::HasRawWindowHandle::raw_window_handle(&window),
|
||||||
let id = wgc::id::TypedId::zip(1, 0, wgt::Backend::Empty);
|
wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty),
|
||||||
let surface = global.instance_create_surface(window.raw_window_handle(), id);
|
);
|
||||||
(size, surface)
|
|
||||||
};
|
|
||||||
|
|
||||||
let adapter = global
|
let adapter = global
|
||||||
.pick_adapter(
|
.pick_adapter(
|
||||||
@ -272,15 +290,19 @@ fn main() {
|
|||||||
A::DestroySampler(id) => {
|
A::DestroySampler(id) => {
|
||||||
gfx_select!(device => global.sampler_destroy(id));
|
gfx_select!(device => global.sampler_destroy(id));
|
||||||
}
|
}
|
||||||
A::CreateSwapChain { id: _, desc } => {
|
A::CreateSwapChain { id, desc } => {
|
||||||
#[cfg(feature = "winit")]
|
#[cfg(feature = "winit")]
|
||||||
{
|
{
|
||||||
log::info!("Initializing the swapchain");
|
log::info!("Initializing the swapchain");
|
||||||
|
assert_eq!(id.to_surface_id(), surface);
|
||||||
window.set_inner_size(winit::dpi::PhysicalSize::new(desc.width, desc.height));
|
window.set_inner_size(winit::dpi::PhysicalSize::new(desc.width, desc.height));
|
||||||
gfx_select!(device => global.device_create_swap_chain(device, surface, &desc));
|
gfx_select!(device => global.device_create_swap_chain(device, surface, &desc));
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "winit"))]
|
#[cfg(not(feature = "winit"))]
|
||||||
let _ = desc;
|
{
|
||||||
|
let _ = (id, desc);
|
||||||
|
panic!("Enable `winit` feature to work with swapchains");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
A::GetSwapChainTexture { id, parent_id } => {
|
A::GetSwapChainTexture { id, parent_id } => {
|
||||||
gfx_select!(device => global.swap_chain_get_next_texture(parent_id, id)).unwrap();
|
gfx_select!(device => global.swap_chain_get_next_texture(parent_id, id)).unwrap();
|
||||||
@ -374,6 +396,58 @@ fn main() {
|
|||||||
A::DestroyShaderModule(id) => {
|
A::DestroyShaderModule(id) => {
|
||||||
gfx_select!(device => global.shader_module_destroy(id));
|
gfx_select!(device => global.shader_module_destroy(id));
|
||||||
}
|
}
|
||||||
|
A::CreateComputePipeline { id, desc } => {
|
||||||
|
let cs_stage = OwnedProgrammableStage::from(desc.compute_stage);
|
||||||
|
gfx_select!(device => global.device_create_compute_pipeline(
|
||||||
|
device,
|
||||||
|
&wgc::pipeline::ComputePipelineDescriptor {
|
||||||
|
layout: desc.layout,
|
||||||
|
compute_stage: cs_stage.desc,
|
||||||
|
},
|
||||||
|
id));
|
||||||
|
}
|
||||||
|
A::DestroyComputePipeline(id) => {
|
||||||
|
gfx_select!(device => global.compute_pipeline_destroy(id));
|
||||||
|
}
|
||||||
|
A::CreateRenderPipeline { id, desc } => {
|
||||||
|
let vs_stage = OwnedProgrammableStage::from(desc.vertex_stage);
|
||||||
|
let fs_stage = desc.fragment_stage.map(OwnedProgrammableStage::from);
|
||||||
|
let vertex_buffers = desc
|
||||||
|
.vertex_state
|
||||||
|
.vertex_buffers
|
||||||
|
.iter()
|
||||||
|
.map(|vb| wgc::pipeline::VertexBufferLayoutDescriptor {
|
||||||
|
array_stride: vb.array_stride,
|
||||||
|
step_mode: vb.step_mode,
|
||||||
|
attributes: vb.attributes.as_ptr(),
|
||||||
|
attributes_length: vb.attributes.len(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
gfx_select!(device => global.device_create_render_pipeline(
|
||||||
|
device,
|
||||||
|
&wgc::pipeline::RenderPipelineDescriptor {
|
||||||
|
layout: desc.layout,
|
||||||
|
vertex_stage: vs_stage.desc,
|
||||||
|
fragment_stage: fs_stage.as_ref().map_or(ptr::null(), |s| &s.desc),
|
||||||
|
primitive_topology: desc.primitive_topology,
|
||||||
|
rasterization_state: desc.rasterization_state.as_ref().map_or(ptr::null(), |rs| rs),
|
||||||
|
color_states: desc.color_states.as_ptr(),
|
||||||
|
color_states_length: desc.color_states.len(),
|
||||||
|
depth_stencil_state: desc.depth_stencil_state.as_ref().map_or(ptr::null(), |ds| ds),
|
||||||
|
vertex_state: wgc::pipeline::VertexStateDescriptor {
|
||||||
|
index_format: desc.vertex_state.index_format,
|
||||||
|
vertex_buffers: vertex_buffers.as_ptr(),
|
||||||
|
vertex_buffers_length: vertex_buffers.len(),
|
||||||
|
},
|
||||||
|
sample_count: desc.sample_count,
|
||||||
|
sample_mask: desc.sample_mask,
|
||||||
|
alpha_to_coverage_enabled: desc.alpha_to_coverage_enabled,
|
||||||
|
},
|
||||||
|
id));
|
||||||
|
}
|
||||||
|
A::DestroyRenderPipeline(id) => {
|
||||||
|
gfx_select!(device => global.render_pipeline_destroy(id));
|
||||||
|
}
|
||||||
A::WriteBuffer { id, data, range } => {
|
A::WriteBuffer { id, data, range } => {
|
||||||
let bin = std::fs::read(dir.join(data)).unwrap();
|
let bin = std::fs::read(dir.join(data)).unwrap();
|
||||||
let size = (range.end - range.start) as usize;
|
let size = (range.end - range.start) as usize;
|
||||||
@ -383,7 +457,7 @@ fn main() {
|
|||||||
let encoder = gfx_select!(device => global.device_create_command_encoder(
|
let encoder = gfx_select!(device => global.device_create_command_encoder(
|
||||||
device,
|
device,
|
||||||
&wgt::CommandEncoderDescriptor {
|
&wgt::CommandEncoderDescriptor {
|
||||||
label: std::ptr::null(),
|
label: ptr::null(),
|
||||||
},
|
},
|
||||||
command_buffer_id_manager.alloc(device.backend())
|
command_buffer_id_manager.alloc(device.backend())
|
||||||
));
|
));
|
||||||
@ -392,4 +466,33 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("Done replay");
|
||||||
|
#[cfg(feature = "winit")]
|
||||||
|
winit::platform::desktop::EventLoopExtDesktop::run_return(
|
||||||
|
&mut event_loop,
|
||||||
|
move |event, _, control_flow| {
|
||||||
|
use winit::{
|
||||||
|
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||||
|
event_loop::ControlFlow,
|
||||||
|
};
|
||||||
|
|
||||||
|
*control_flow = match event {
|
||||||
|
Event::WindowEvent { event, .. } => match event {
|
||||||
|
WindowEvent::KeyboardInput {
|
||||||
|
input:
|
||||||
|
KeyboardInput {
|
||||||
|
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||||
|
state: ElementState::Pressed,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| WindowEvent::CloseRequested => ControlFlow::Exit,
|
||||||
|
_ => ControlFlow::Poll,
|
||||||
|
},
|
||||||
|
_ => ControlFlow::Poll,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@ use crate::{
|
|||||||
track::TrackerSet,
|
track::TrackerSet,
|
||||||
FastHashMap, RefCount, Stored, SubmissionIndex,
|
FastHashMap, RefCount, Stored, SubmissionIndex,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
use crate::device::trace;
|
||||||
|
|
||||||
use copyless::VecHelper as _;
|
use copyless::VecHelper as _;
|
||||||
use gfx_descriptor::{DescriptorAllocator, DescriptorSet};
|
use gfx_descriptor::{DescriptorAllocator, DescriptorSet};
|
||||||
@ -288,6 +290,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
global: &Global<G>,
|
global: &Global<G>,
|
||||||
trackers: &Mutex<TrackerSet>,
|
trackers: &Mutex<TrackerSet>,
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace: Option<&Mutex<trace::Trace>>,
|
||||||
token: &mut Token<super::Device<B>>,
|
token: &mut Token<super::Device<B>>,
|
||||||
) {
|
) {
|
||||||
let hub = B::hub(global);
|
let hub = B::hub(global);
|
||||||
@ -298,6 +302,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.bind_groups.drain(..) {
|
for id in self.suspected_resources.bind_groups.drain(..) {
|
||||||
if trackers.bind_groups.remove_abandoned(id) {
|
if trackers.bind_groups.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyBindGroup(id)));
|
||||||
hub.bind_groups.free_id(id);
|
hub.bind_groups.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
|
|
||||||
@ -332,6 +338,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.texture_views.drain(..) {
|
for id in self.suspected_resources.texture_views.drain(..) {
|
||||||
if trackers.views.remove_abandoned(id) {
|
if trackers.views.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyTextureView(id)));
|
||||||
hub.texture_views.free_id(id);
|
hub.texture_views.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
|
|
||||||
@ -360,6 +368,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.textures.drain(..) {
|
for id in self.suspected_resources.textures.drain(..) {
|
||||||
if trackers.textures.remove_abandoned(id) {
|
if trackers.textures.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyTexture(id)));
|
||||||
hub.textures.free_id(id);
|
hub.textures.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
|
|
||||||
@ -380,6 +390,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.samplers.drain(..) {
|
for id in self.suspected_resources.samplers.drain(..) {
|
||||||
if trackers.samplers.remove_abandoned(id) {
|
if trackers.samplers.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroySampler(id)));
|
||||||
hub.samplers.free_id(id);
|
hub.samplers.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
|
|
||||||
@ -400,6 +412,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.buffers.drain(..) {
|
for id in self.suspected_resources.buffers.drain(..) {
|
||||||
if trackers.buffers.remove_abandoned(id) {
|
if trackers.buffers.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyBuffer(id)));
|
||||||
hub.buffers.free_id(id);
|
hub.buffers.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
log::debug!("Buffer {:?} is detached", id);
|
log::debug!("Buffer {:?} is detached", id);
|
||||||
@ -421,6 +435,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.compute_pipelines.drain(..) {
|
for id in self.suspected_resources.compute_pipelines.drain(..) {
|
||||||
if trackers.compute_pipes.remove_abandoned(id) {
|
if trackers.compute_pipes.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyComputePipeline(id)));
|
||||||
hub.compute_pipelines.free_id(id);
|
hub.compute_pipelines.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
|
|
||||||
@ -441,6 +457,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
|
|
||||||
for id in self.suspected_resources.render_pipelines.drain(..) {
|
for id in self.suspected_resources.render_pipelines.drain(..) {
|
||||||
if trackers.render_pipes.remove_abandoned(id) {
|
if trackers.render_pipes.remove_abandoned(id) {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyRenderPipeline(id)));
|
||||||
hub.render_pipelines.free_id(id);
|
hub.render_pipelines.free_id(id);
|
||||||
let res = guard.remove(id).unwrap();
|
let res = guard.remove(id).unwrap();
|
||||||
|
|
||||||
@ -465,6 +483,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
{
|
{
|
||||||
//Note: this has to happen after all the suspected pipelines are destroyed
|
//Note: this has to happen after all the suspected pipelines are destroyed
|
||||||
if ref_count.load() == 1 {
|
if ref_count.load() == 1 {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
trace.map(|t| t.lock().add(trace::Action::DestroyPipelineLayout(id)));
|
||||||
hub.pipeline_layouts.free_id(id);
|
hub.pipeline_layouts.free_id(id);
|
||||||
let layout = guard.remove(id).unwrap();
|
let layout = guard.remove(id).unwrap();
|
||||||
self.free_resources.pipeline_layouts.push(layout.raw);
|
self.free_resources.pipeline_layouts.push(layout.raw);
|
||||||
|
|||||||
@ -281,7 +281,13 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
) -> Vec<BufferMapPendingCallback> {
|
) -> Vec<BufferMapPendingCallback> {
|
||||||
let mut life_tracker = self.lock_life(token);
|
let mut life_tracker = self.lock_life(token);
|
||||||
|
|
||||||
life_tracker.triage_suspected(global, &self.trackers, token);
|
life_tracker.triage_suspected(
|
||||||
|
global,
|
||||||
|
&self.trackers,
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
self.trace.as_ref(),
|
||||||
|
token,
|
||||||
|
);
|
||||||
life_tracker.triage_mapped(global, token);
|
life_tracker.triage_mapped(global, token);
|
||||||
life_tracker.triage_framebuffers(global, &mut *self.framebuffers.lock(), token);
|
life_tracker.triage_framebuffers(global, &mut *self.framebuffers.lock(), token);
|
||||||
let _last_done = life_tracker.triage_submissions(&self.raw, force_wait);
|
let _last_done = life_tracker.triage_submissions(&self.raw, force_wait);
|
||||||
@ -575,6 +581,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let id = hub.buffers.register_identity(id_in, buffer, &mut token);
|
let id = hub.buffers.register_identity(id_in, buffer, &mut token);
|
||||||
log::info!("Created mapped buffer {:?} with {:?}", id, desc);
|
log::info!("Created mapped buffer {:?} with {:?}", id, desc);
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
match device.trace {
|
||||||
|
Some(ref trace) => trace.lock().add(trace::Action::CreateBuffer {
|
||||||
|
id,
|
||||||
|
desc: desc.map_label(own_label),
|
||||||
|
}),
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
|
||||||
device
|
device
|
||||||
.trackers
|
.trackers
|
||||||
.lock()
|
.lock()
|
||||||
@ -692,14 +707,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
let device = &device_guard[device_id];
|
device_guard[device_id]
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
match device.trace {
|
|
||||||
Some(ref trace) => trace.lock().add(trace::Action::DestroyBuffer(buffer_id)),
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
device
|
|
||||||
.lock_life(&mut token)
|
.lock_life(&mut token)
|
||||||
.suspected_resources
|
.suspected_resources
|
||||||
.buffers
|
.buffers
|
||||||
@ -752,14 +760,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
let device = &device_guard[device_id];
|
device_guard[device_id]
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
match device.trace {
|
|
||||||
Some(ref trace) => trace.lock().add(trace::Action::DestroyTexture(texture_id)),
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
device
|
|
||||||
.lock_life(&mut token)
|
.lock_life(&mut token)
|
||||||
.suspected_resources
|
.suspected_resources
|
||||||
.textures
|
.textures
|
||||||
@ -882,16 +883,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
let device = &device_guard[device_id];
|
device_guard[device_id]
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
match device.trace {
|
|
||||||
Some(ref trace) => trace
|
|
||||||
.lock()
|
|
||||||
.add(trace::Action::DestroyTextureView(texture_view_id)),
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
device
|
|
||||||
.lock_life(&mut token)
|
.lock_life(&mut token)
|
||||||
.suspected_resources
|
.suspected_resources
|
||||||
.texture_views
|
.texture_views
|
||||||
@ -967,14 +959,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
let device = &device_guard[device_id];
|
device_guard[device_id]
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
match device.trace {
|
|
||||||
Some(ref trace) => trace.lock().add(trace::Action::DestroySampler(sampler_id)),
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
device
|
|
||||||
.lock_life(&mut token)
|
.lock_life(&mut token)
|
||||||
.suspected_resources
|
.suspected_resources
|
||||||
.samplers
|
.samplers
|
||||||
@ -1153,16 +1138,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
let device = &device_guard[device_id];
|
device_guard[device_id]
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
match device.trace {
|
|
||||||
Some(ref trace) => trace
|
|
||||||
.lock()
|
|
||||||
.add(trace::Action::DestroyPipelineLayout(pipeline_layout_id)),
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
device
|
|
||||||
.lock_life(&mut token)
|
.lock_life(&mut token)
|
||||||
.suspected_resources
|
.suspected_resources
|
||||||
.pipeline_layouts
|
.pipeline_layouts
|
||||||
@ -1437,16 +1413,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
let device = &device_guard[device_id];
|
device_guard[device_id]
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
match device.trace {
|
|
||||||
Some(ref trace) => trace
|
|
||||||
.lock()
|
|
||||||
.add(trace::Action::DestroyBindGroup(bind_group_id)),
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
device
|
|
||||||
.lock_life(&mut token)
|
.lock_life(&mut token)
|
||||||
.suspected_resources
|
.suspected_resources
|
||||||
.bind_groups
|
.bind_groups
|
||||||
@ -1505,7 +1472,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
.add(trace::Action::DestroyShaderModule(shader_module_id)),
|
.add(trace::Action::DestroyShaderModule(shader_module_id)),
|
||||||
None => (),
|
None => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
device.raw.destroy_shader_module(module.raw);
|
device.raw.destroy_shader_module(module.raw);
|
||||||
}
|
}
|
||||||
@ -2065,8 +2031,38 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
life_guard: LifeGuard::new(),
|
life_guard: LifeGuard::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
hub.render_pipelines
|
let id = hub.render_pipelines
|
||||||
.register_identity(id_in, pipeline, &mut token)
|
.register_identity(id_in, pipeline, &mut token);
|
||||||
|
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
match device.trace {
|
||||||
|
Some(ref trace) => trace.lock().add(trace::Action::CreateRenderPipeline {
|
||||||
|
id,
|
||||||
|
desc: trace::RenderPipelineDescriptor {
|
||||||
|
layout: desc.layout,
|
||||||
|
vertex_stage: trace::ProgrammableStageDescriptor::new(&desc.vertex_stage),
|
||||||
|
fragment_stage: unsafe { desc.fragment_stage.as_ref() }.map(trace::ProgrammableStageDescriptor::new),
|
||||||
|
primitive_topology: desc.primitive_topology,
|
||||||
|
rasterization_state: unsafe { desc.rasterization_state.as_ref() }.cloned(),
|
||||||
|
color_states: color_states.to_vec(),
|
||||||
|
depth_stencil_state: depth_stencil_state.cloned(),
|
||||||
|
vertex_state: trace::VertexStateDescriptor {
|
||||||
|
index_format: desc.vertex_state.index_format,
|
||||||
|
vertex_buffers: desc_vbs.iter().map(|vbl| trace::VertexBufferLayoutDescriptor {
|
||||||
|
array_stride: vbl.array_stride,
|
||||||
|
step_mode: vbl.step_mode,
|
||||||
|
attributes: unsafe { slice::from_raw_parts(vbl.attributes, vbl.attributes_length) }
|
||||||
|
.iter().cloned().collect(),
|
||||||
|
}).collect(),
|
||||||
|
},
|
||||||
|
sample_count: desc.sample_count,
|
||||||
|
sample_mask: desc.sample_mask,
|
||||||
|
alpha_to_coverage_enabled: desc.alpha_to_coverage_enabled,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_pipeline_destroy<B: GfxBackend>(&self, render_pipeline_id: id::RenderPipelineId) {
|
pub fn render_pipeline_destroy<B: GfxBackend>(&self, render_pipeline_id: id::RenderPipelineId) {
|
||||||
@ -2151,8 +2147,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
},
|
},
|
||||||
life_guard: LifeGuard::new(),
|
life_guard: LifeGuard::new(),
|
||||||
};
|
};
|
||||||
hub.compute_pipelines
|
let id = hub.compute_pipelines
|
||||||
.register_identity(id_in, pipeline, &mut token)
|
.register_identity(id_in, pipeline, &mut token);
|
||||||
|
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
match device.trace {
|
||||||
|
Some(ref trace) => trace.lock().add(trace::Action::CreateComputePipeline {
|
||||||
|
id,
|
||||||
|
desc: trace::ComputePipelineDescriptor {
|
||||||
|
layout: desc.layout,
|
||||||
|
compute_stage: trace::ProgrammableStageDescriptor::new(&desc.compute_stage),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_pipeline_destroy<B: GfxBackend>(
|
pub fn compute_pipeline_destroy<B: GfxBackend>(
|
||||||
|
|||||||
@ -29,6 +29,68 @@ pub enum BindingResource {
|
|||||||
TextureView(id::TextureViewId),
|
TextureView(id::TextureViewId),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
|
pub struct ProgrammableStageDescriptor {
|
||||||
|
pub module: id::ShaderModuleId,
|
||||||
|
pub entry_point: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
impl ProgrammableStageDescriptor {
|
||||||
|
pub fn new(desc: &crate::pipeline::ProgrammableStageDescriptor) -> Self {
|
||||||
|
ProgrammableStageDescriptor {
|
||||||
|
module: desc.module,
|
||||||
|
entry_point: unsafe { std::ffi::CStr::from_ptr(desc.entry_point) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
|
pub struct ComputePipelineDescriptor {
|
||||||
|
pub layout: id::PipelineLayoutId,
|
||||||
|
pub compute_stage: ProgrammableStageDescriptor,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
|
pub struct VertexBufferLayoutDescriptor {
|
||||||
|
pub array_stride: wgt::BufferAddress,
|
||||||
|
pub step_mode: wgt::InputStepMode,
|
||||||
|
pub attributes: Vec<wgt::VertexAttributeDescriptor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
|
pub struct VertexStateDescriptor {
|
||||||
|
pub index_format: wgt::IndexFormat,
|
||||||
|
pub vertex_buffers: Vec<VertexBufferLayoutDescriptor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
|
pub struct RenderPipelineDescriptor {
|
||||||
|
pub layout: id::PipelineLayoutId,
|
||||||
|
pub vertex_stage: ProgrammableStageDescriptor,
|
||||||
|
pub fragment_stage: Option<ProgrammableStageDescriptor>,
|
||||||
|
pub primitive_topology: wgt::PrimitiveTopology,
|
||||||
|
pub rasterization_state: Option<wgt::RasterizationStateDescriptor>,
|
||||||
|
pub color_states: Vec<wgt::ColorStateDescriptor>,
|
||||||
|
pub depth_stencil_state: Option<wgt::DepthStencilStateDescriptor>,
|
||||||
|
pub vertex_state: VertexStateDescriptor,
|
||||||
|
pub sample_count: u32,
|
||||||
|
pub sample_mask: u32,
|
||||||
|
pub alpha_to_coverage_enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
@ -89,6 +151,16 @@ pub enum Action {
|
|||||||
data: FileName,
|
data: FileName,
|
||||||
},
|
},
|
||||||
DestroyShaderModule(id::ShaderModuleId),
|
DestroyShaderModule(id::ShaderModuleId),
|
||||||
|
CreateComputePipeline {
|
||||||
|
id: id::ComputePipelineId,
|
||||||
|
desc: ComputePipelineDescriptor,
|
||||||
|
},
|
||||||
|
DestroyComputePipeline(id::ComputePipelineId),
|
||||||
|
CreateRenderPipeline {
|
||||||
|
id: id::RenderPipelineId,
|
||||||
|
desc: RenderPipelineDescriptor,
|
||||||
|
},
|
||||||
|
DestroyRenderPipeline(id::RenderPipelineId),
|
||||||
WriteBuffer {
|
WriteBuffer {
|
||||||
id: id::BufferId,
|
id: id::BufferId,
|
||||||
data: FileName,
|
data: FileName,
|
||||||
|
|||||||
@ -151,7 +151,7 @@ impl SurfaceId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl SwapChainId {
|
impl SwapChainId {
|
||||||
pub(crate) fn to_surface_id(self) -> SurfaceId {
|
pub fn to_surface_id(self) -> SurfaceId {
|
||||||
let (index, epoch, _) = self.unzip();
|
let (index, epoch, _) = self.unzip();
|
||||||
Id::zip(index, epoch, Backend::Empty)
|
Id::zip(index, epoch, Backend::Empty)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user