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 = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"raw-window-handle",
|
||||
"ron",
|
||||
"wgpu-core",
|
||||
"wgpu-types",
|
||||
|
||||
@ -17,6 +17,7 @@ publish = false
|
||||
[dependencies]
|
||||
env_logger = "0.7"
|
||||
log = "0.4"
|
||||
raw-window-handle = "0.3"
|
||||
ron = "0.5"
|
||||
winit = { version = "0.22", optional = true }
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ use std::{
|
||||
fs::File,
|
||||
marker::PhantomData,
|
||||
path::{Path, PathBuf},
|
||||
ptr,
|
||||
};
|
||||
|
||||
macro_rules! gfx_select {
|
||||
@ -41,7 +42,26 @@ impl Label {
|
||||
fn as_ptr(&self) -> *const std::os::raw::c_char {
|
||||
match self.0 {
|
||||
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());
|
||||
|
||||
#[cfg(feature = "winit")]
|
||||
let event_loop = {
|
||||
let mut event_loop = {
|
||||
log::info!("Creating a window");
|
||||
EventLoop::new()
|
||||
};
|
||||
@ -194,12 +214,10 @@ fn main() {
|
||||
let mut command_buffer_id_manager = wgc::hub::IdentityManager::default();
|
||||
|
||||
#[cfg(feature = "winit")]
|
||||
let (_size, surface) = {
|
||||
let size = window.inner_size();
|
||||
let id = wgc::id::TypedId::zip(1, 0, wgt::Backend::Empty);
|
||||
let surface = global.instance_create_surface(window.raw_window_handle(), id);
|
||||
(size, surface)
|
||||
};
|
||||
let surface = global.instance_create_surface(
|
||||
raw_window_handle::HasRawWindowHandle::raw_window_handle(&window),
|
||||
wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty),
|
||||
);
|
||||
|
||||
let adapter = global
|
||||
.pick_adapter(
|
||||
@ -272,15 +290,19 @@ fn main() {
|
||||
A::DestroySampler(id) => {
|
||||
gfx_select!(device => global.sampler_destroy(id));
|
||||
}
|
||||
A::CreateSwapChain { id: _, desc } => {
|
||||
A::CreateSwapChain { id, desc } => {
|
||||
#[cfg(feature = "winit")]
|
||||
{
|
||||
log::info!("Initializing the swapchain");
|
||||
assert_eq!(id.to_surface_id(), surface);
|
||||
window.set_inner_size(winit::dpi::PhysicalSize::new(desc.width, desc.height));
|
||||
gfx_select!(device => global.device_create_swap_chain(device, surface, &desc));
|
||||
}
|
||||
#[cfg(not(feature = "winit"))]
|
||||
let _ = desc;
|
||||
{
|
||||
let _ = (id, desc);
|
||||
panic!("Enable `winit` feature to work with swapchains");
|
||||
}
|
||||
}
|
||||
A::GetSwapChainTexture { id, parent_id } => {
|
||||
gfx_select!(device => global.swap_chain_get_next_texture(parent_id, id)).unwrap();
|
||||
@ -374,6 +396,58 @@ fn main() {
|
||||
A::DestroyShaderModule(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 } => {
|
||||
let bin = std::fs::read(dir.join(data)).unwrap();
|
||||
let size = (range.end - range.start) as usize;
|
||||
@ -383,7 +457,7 @@ fn main() {
|
||||
let encoder = gfx_select!(device => global.device_create_command_encoder(
|
||||
device,
|
||||
&wgt::CommandEncoderDescriptor {
|
||||
label: std::ptr::null(),
|
||||
label: ptr::null(),
|
||||
},
|
||||
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,
|
||||
FastHashMap, RefCount, Stored, SubmissionIndex,
|
||||
};
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::device::trace;
|
||||
|
||||
use copyless::VecHelper as _;
|
||||
use gfx_descriptor::{DescriptorAllocator, DescriptorSet};
|
||||
@ -288,6 +290,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
&mut self,
|
||||
global: &Global<G>,
|
||||
trackers: &Mutex<TrackerSet>,
|
||||
#[cfg(feature = "trace")]
|
||||
trace: Option<&Mutex<trace::Trace>>,
|
||||
token: &mut Token<super::Device<B>>,
|
||||
) {
|
||||
let hub = B::hub(global);
|
||||
@ -298,6 +302,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.bind_groups.drain(..) {
|
||||
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);
|
||||
let res = guard.remove(id).unwrap();
|
||||
|
||||
@ -332,6 +338,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.texture_views.drain(..) {
|
||||
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);
|
||||
let res = guard.remove(id).unwrap();
|
||||
|
||||
@ -360,6 +368,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.textures.drain(..) {
|
||||
if trackers.textures.remove_abandoned(id) {
|
||||
#[cfg(feature = "trace")]
|
||||
trace.map(|t| t.lock().add(trace::Action::DestroyTexture(id)));
|
||||
hub.textures.free_id(id);
|
||||
let res = guard.remove(id).unwrap();
|
||||
|
||||
@ -380,6 +390,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.samplers.drain(..) {
|
||||
if trackers.samplers.remove_abandoned(id) {
|
||||
#[cfg(feature = "trace")]
|
||||
trace.map(|t| t.lock().add(trace::Action::DestroySampler(id)));
|
||||
hub.samplers.free_id(id);
|
||||
let res = guard.remove(id).unwrap();
|
||||
|
||||
@ -400,6 +412,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.buffers.drain(..) {
|
||||
if trackers.buffers.remove_abandoned(id) {
|
||||
#[cfg(feature = "trace")]
|
||||
trace.map(|t| t.lock().add(trace::Action::DestroyBuffer(id)));
|
||||
hub.buffers.free_id(id);
|
||||
let res = guard.remove(id).unwrap();
|
||||
log::debug!("Buffer {:?} is detached", id);
|
||||
@ -421,6 +435,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.compute_pipelines.drain(..) {
|
||||
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);
|
||||
let res = guard.remove(id).unwrap();
|
||||
|
||||
@ -441,6 +457,8 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
|
||||
for id in self.suspected_resources.render_pipelines.drain(..) {
|
||||
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);
|
||||
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
|
||||
if ref_count.load() == 1 {
|
||||
#[cfg(feature = "trace")]
|
||||
trace.map(|t| t.lock().add(trace::Action::DestroyPipelineLayout(id)));
|
||||
hub.pipeline_layouts.free_id(id);
|
||||
let layout = guard.remove(id).unwrap();
|
||||
self.free_resources.pipeline_layouts.push(layout.raw);
|
||||
|
||||
@ -281,7 +281,13 @@ impl<B: GfxBackend> Device<B> {
|
||||
) -> Vec<BufferMapPendingCallback> {
|
||||
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_framebuffers(global, &mut *self.framebuffers.lock(), token);
|
||||
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);
|
||||
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
|
||||
.trackers
|
||||
.lock()
|
||||
@ -692,14 +707,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace.lock().add(trace::Action::DestroyBuffer(buffer_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
device
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.buffers
|
||||
@ -752,14 +760,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace.lock().add(trace::Action::DestroyTexture(texture_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
device
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.textures
|
||||
@ -882,16 +883,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace
|
||||
.lock()
|
||||
.add(trace::Action::DestroyTextureView(texture_view_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
device
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.texture_views
|
||||
@ -967,14 +959,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace.lock().add(trace::Action::DestroySampler(sampler_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
device
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.samplers
|
||||
@ -1153,16 +1138,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace
|
||||
.lock()
|
||||
.add(trace::Action::DestroyPipelineLayout(pipeline_layout_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
device
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.pipeline_layouts
|
||||
@ -1437,16 +1413,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace
|
||||
.lock()
|
||||
.add(trace::Action::DestroyBindGroup(bind_group_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
device
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.bind_groups
|
||||
@ -1505,7 +1472,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.add(trace::Action::DestroyShaderModule(shader_module_id)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
unsafe {
|
||||
device.raw.destroy_shader_module(module.raw);
|
||||
}
|
||||
@ -2065,8 +2031,38 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
|
||||
hub.render_pipelines
|
||||
.register_identity(id_in, pipeline, &mut token)
|
||||
let id = hub.render_pipelines
|
||||
.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) {
|
||||
@ -2151,8 +2147,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
},
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
hub.compute_pipelines
|
||||
.register_identity(id_in, pipeline, &mut token)
|
||||
let id = hub.compute_pipelines
|
||||
.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>(
|
||||
|
||||
@ -29,6 +29,68 @@ pub enum BindingResource {
|
||||
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)]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
@ -89,6 +151,16 @@ pub enum Action {
|
||||
data: FileName,
|
||||
},
|
||||
DestroyShaderModule(id::ShaderModuleId),
|
||||
CreateComputePipeline {
|
||||
id: id::ComputePipelineId,
|
||||
desc: ComputePipelineDescriptor,
|
||||
},
|
||||
DestroyComputePipeline(id::ComputePipelineId),
|
||||
CreateRenderPipeline {
|
||||
id: id::RenderPipelineId,
|
||||
desc: RenderPipelineDescriptor,
|
||||
},
|
||||
DestroyRenderPipeline(id::RenderPipelineId),
|
||||
WriteBuffer {
|
||||
id: id::BufferId,
|
||||
data: FileName,
|
||||
|
||||
@ -151,7 +151,7 @@ impl SurfaceId {
|
||||
}
|
||||
}
|
||||
impl SwapChainId {
|
||||
pub(crate) fn to_surface_id(self) -> SurfaceId {
|
||||
pub fn to_surface_id(self) -> SurfaceId {
|
||||
let (index, epoch, _) = self.unzip();
|
||||
Id::zip(index, epoch, Backend::Empty)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user