update wgpu, use serializable descriptors

This commit is contained in:
Kunal Mohan 2020-07-22 23:22:13 +05:30
parent a242913629
commit 75abccb16b
5 changed files with 249 additions and 354 deletions

4
Cargo.lock generated
View file

@ -6861,7 +6861,7 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu#73b230871ea4428ed3fb1e6e8bff81a7364fcdb2" source = "git+https://github.com/gfx-rs/wgpu#4ed2c0a313deb48a99f15e8fe0558ad3d095ca01"
dependencies = [ dependencies = [
"arrayvec 0.5.1", "arrayvec 0.5.1",
"bitflags", "bitflags",
@ -6890,7 +6890,7 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-types" name = "wgpu-types"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu#73b230871ea4428ed3fb1e6e8bff81a7364fcdb2" source = "git+https://github.com/gfx-rs/wgpu#4ed2c0a313deb48a99f15e8fe0558ad3d095ca01"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"serde", "serde",

View file

@ -25,6 +25,7 @@ use crate::dom::gpucomputepassencoder::GPUComputePassEncoder;
use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt}; use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt};
use crate::dom::gpurenderpassencoder::GPURenderPassEncoder; use crate::dom::gpurenderpassencoder::GPURenderPassEncoder;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashSet; use std::collections::HashSet;
use webgpu::wgpu::command as wgpu_com; use webgpu::wgpu::command as wgpu_com;
@ -135,12 +136,50 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
GPUCommandEncoderState::Open, GPUCommandEncoderState::Open,
); );
let colors = descriptor let depth_stencil = descriptor.depthStencilAttachment.as_ref().map(|depth| {
let (depth_load_op, clear_depth) = match depth.depthLoadValue {
GPULoadOpOrFloat::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0.0f32),
GPULoadOpOrFloat::Float(f) => (wgpu_com::LoadOp::Clear, *f),
};
let (stencil_load_op, clear_stencil) = match depth.stencilLoadValue {
GPUStencilLoadValue::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0u32),
GPUStencilLoadValue::RangeEnforcedUnsignedLong(l) => (wgpu_com::LoadOp::Clear, l),
};
let depth_channel = wgpu_com::PassChannel {
load_op: depth_load_op,
store_op: match depth.depthStoreOp {
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
},
clear_value: clear_depth,
read_only: depth.depthReadOnly,
};
let stencil_channel = wgpu_com::PassChannel {
load_op: stencil_load_op,
store_op: match depth.stencilStoreOp {
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
},
clear_value: clear_stencil,
read_only: depth.stencilReadOnly,
};
wgpu_com::DepthStencilAttachmentDescriptor {
attachment: depth.attachment.id().0,
depth: depth_channel,
stencil: stencil_channel,
}
});
let desc = wgpu_com::RenderPassDescriptor {
color_attachments: Cow::Owned(
descriptor
.colorAttachments .colorAttachments
.iter() .iter()
.map(|color| { .map(|color| {
let (load_op, clear_value) = match color.loadValue { let (load_op, clear_value) = match color.loadValue {
GPUColorLoad::GPULoadOp(_) => (wgpu_com::LoadOp::Load, wgt::Color::TRANSPARENT), GPUColorLoad::GPULoadOp(_) => {
(wgpu_com::LoadOp::Load, wgt::Color::TRANSPARENT)
},
GPUColorLoad::DoubleSequence(ref s) => { GPUColorLoad::DoubleSequence(ref s) => {
let mut w = s.clone(); let mut w = s.clone();
if w.len() < 3 { if w.len() < 3 {
@ -182,44 +221,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
channel, channel,
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>(),
),
let depth_stencil = descriptor.depthStencilAttachment.as_ref().map(|depth| {
let (depth_load_op, clear_depth) = match depth.depthLoadValue {
GPULoadOpOrFloat::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0.0f32),
GPULoadOpOrFloat::Float(f) => (wgpu_com::LoadOp::Clear, *f),
};
let (stencil_load_op, clear_stencil) = match depth.stencilLoadValue {
GPUStencilLoadValue::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0u32),
GPUStencilLoadValue::RangeEnforcedUnsignedLong(l) => (wgpu_com::LoadOp::Clear, l),
};
let depth_channel = wgpu_com::PassChannel {
load_op: depth_load_op,
store_op: match depth.depthStoreOp {
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
},
clear_value: clear_depth,
read_only: depth.depthReadOnly,
};
let stencil_channel = wgpu_com::PassChannel {
load_op: stencil_load_op,
store_op: match depth.stencilStoreOp {
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
},
clear_value: clear_stencil,
read_only: depth.stencilReadOnly,
};
wgpu_com::DepthStencilAttachmentDescriptor {
attachment: depth.attachment.id().0,
depth: depth_channel,
stencil: stencil_channel,
}
});
let desc = wgpu_com::RenderPassDescriptor {
color_attachments: colors.as_slice(),
depth_stencil_attachment: depth_stencil.as_ref(), depth_stencil_attachment: depth_stencil.as_ref(),
}; };

View file

@ -57,16 +57,16 @@ use crate::dom::gputexture::GPUTexture;
use crate::dom::promise::Promise; use crate::dom::promise::Promise;
use crate::realms::InRealm; use crate::realms::InRealm;
use crate::script_runtime::JSContext as SafeJSContext; use crate::script_runtime::JSContext as SafeJSContext;
use arrayvec::ArrayVec;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject}; use js::jsapi::{Heap, JSObject};
use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc; use std::rc::Rc;
use std::string::String; use std::string::String;
use webgpu::wgpu::binding_model::BufferBinding; use webgpu::wgpu::{binding_model as wgpu_bind, pipeline as wgpu_pipe};
use webgpu::{self, wgt, WebGPU, WebGPUBindings, WebGPURequest}; use webgpu::{self, wgt, WebGPU, WebGPURequest};
type ErrorScopeId = u64; type ErrorScopeId = u64;
@ -401,6 +401,15 @@ impl GPUDeviceMethods for GPUDevice {
} }
} }
let desc = wgt::BindGroupLayoutDescriptor {
label: descriptor
.parent
.label
.as_ref()
.map(|s| Cow::Owned(s.to_string())),
entries: Cow::Owned(entries.clone()),
};
let bind_group_layout_id = self let bind_group_layout_id = self
.global() .global()
.wgpu_id_hub() .wgpu_id_hub()
@ -411,13 +420,8 @@ impl GPUDeviceMethods for GPUDevice {
.send(WebGPURequest::CreateBindGroupLayout { .send(WebGPURequest::CreateBindGroupLayout {
device_id: self.device.0, device_id: self.device.0,
bind_group_layout_id, bind_group_layout_id,
entries: entries.clone(),
scope_id, scope_id,
label: descriptor descriptor: desc,
.parent
.label
.as_ref()
.map(|s| String::from(s.as_ref())),
}) })
.expect("Failed to create WebGPU BindGroupLayout"); .expect("Failed to create WebGPU BindGroupLayout");
@ -437,11 +441,16 @@ impl GPUDeviceMethods for GPUDevice {
&self, &self,
descriptor: &GPUPipelineLayoutDescriptor, descriptor: &GPUPipelineLayoutDescriptor,
) -> DomRoot<GPUPipelineLayout> { ) -> DomRoot<GPUPipelineLayout> {
let mut bgl_ids = Vec::new(); let desc = wgt::PipelineLayoutDescriptor {
bind_group_layouts: Cow::Owned(
descriptor descriptor
.bindGroupLayouts .bindGroupLayouts
.iter() .iter()
.for_each(|each| bgl_ids.push(each.id().0)); .map(|each| each.id().0)
.collect::<Vec<_>>(),
),
push_constant_ranges: Cow::Owned(vec![]),
};
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
@ -455,7 +464,7 @@ impl GPUDeviceMethods for GPUDevice {
.send(WebGPURequest::CreatePipelineLayout { .send(WebGPURequest::CreatePipelineLayout {
device_id: self.device.0, device_id: self.device.0,
pipeline_layout_id, pipeline_layout_id,
bind_group_layouts: bgl_ids, descriptor: desc,
scope_id, scope_id,
}) })
.expect("Failed to create WebGPU PipelineLayout"); .expect("Failed to create WebGPU PipelineLayout");
@ -469,26 +478,36 @@ impl GPUDeviceMethods for GPUDevice {
let entries = descriptor let entries = descriptor
.entries .entries
.iter() .iter()
.map(|bind| { .map(|bind| wgpu_bind::BindGroupEntry {
( binding: bind.binding,
bind.binding, resource: match bind.resource {
match bind.resource { GPUBindingResource::GPUSampler(ref s) => {
GPUBindingResource::GPUSampler(ref s) => WebGPUBindings::Sampler(s.id().0), wgpu_bind::BindingResource::Sampler(s.id().0)
},
GPUBindingResource::GPUTextureView(ref t) => { GPUBindingResource::GPUTextureView(ref t) => {
WebGPUBindings::TextureView(t.id().0) wgpu_bind::BindingResource::TextureView(t.id().0)
}, },
GPUBindingResource::GPUBufferBindings(ref b) => { GPUBindingResource::GPUBufferBindings(ref b) => {
WebGPUBindings::Buffer(BufferBinding { wgpu_bind::BindingResource::Buffer(wgpu_bind::BufferBinding {
buffer_id: b.buffer.id().0, buffer_id: b.buffer.id().0,
offset: b.offset, offset: b.offset,
size: b.size.and_then(wgt::BufferSize::new), size: b.size.and_then(wgt::BufferSize::new),
}) })
}, },
}, },
)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let desc = wgpu_bind::BindGroupDescriptor {
label: descriptor
.parent
.label
.as_ref()
.map(|l| Cow::Owned(l.to_string())),
layout: descriptor.layout.id().0,
entries: Cow::Owned(entries),
};
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
let bind_group_id = self let bind_group_id = self
@ -501,14 +520,8 @@ impl GPUDeviceMethods for GPUDevice {
.send(WebGPURequest::CreateBindGroup { .send(WebGPURequest::CreateBindGroup {
device_id: self.device.0, device_id: self.device.0,
bind_group_id, bind_group_id,
bind_group_layout_id: descriptor.layout.id().0, descriptor: desc,
entries,
scope_id, scope_id,
label: descriptor
.parent
.label
.as_ref()
.map(|s| String::from(s.as_ref())),
}) })
.expect("Failed to create WebGPU BindGroup"); .expect("Failed to create WebGPU BindGroup");
@ -551,9 +564,6 @@ impl GPUDeviceMethods for GPUDevice {
&self, &self,
descriptor: &GPUComputePipelineDescriptor, descriptor: &GPUComputePipelineDescriptor,
) -> DomRoot<GPUComputePipeline> { ) -> DomRoot<GPUComputePipeline> {
let pipeline = descriptor.parent.layout.id();
let program = descriptor.computeStage.module.id();
let entry_point = descriptor.computeStage.entryPoint.to_string();
let compute_pipeline_id = self let compute_pipeline_id = self
.global() .global()
.wgpu_id_hub() .wgpu_id_hub()
@ -562,15 +572,21 @@ impl GPUDeviceMethods for GPUDevice {
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
let desc = wgpu_pipe::ComputePipelineDescriptor {
layout: descriptor.parent.layout.id().0,
compute_stage: wgpu_pipe::ProgrammableStageDescriptor {
module: descriptor.computeStage.module.id().0,
entry_point: Cow::Owned(descriptor.computeStage.entryPoint.to_string()),
},
};
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateComputePipeline { .send(WebGPURequest::CreateComputePipeline {
device_id: self.device.0, device_id: self.device.0,
scope_id, scope_id,
compute_pipeline_id, compute_pipeline_id,
pipeline_layout_id: pipeline.0, descriptor: desc,
program_id: program.0,
entry_point,
}) })
.expect("Failed to create WebGPU ComputePipeline"); .expect("Failed to create WebGPU ComputePipeline");
@ -712,23 +728,22 @@ impl GPUDeviceMethods for GPUDevice {
&self, &self,
descriptor: &GPURenderPipelineDescriptor, descriptor: &GPURenderPipelineDescriptor,
) -> DomRoot<GPURenderPipeline> { ) -> DomRoot<GPURenderPipeline> {
let vertex_module = descriptor.vertexStage.module.id().0;
let vertex_entry_point = descriptor.vertexStage.entryPoint.to_string();
let (fragment_module, fragment_entry_point) = match descriptor.fragmentStage {
Some(ref frag) => (Some(frag.module.id().0), Some(frag.entryPoint.to_string())),
None => (None, None),
};
let primitive_topology = match descriptor.primitiveTopology {
GPUPrimitiveTopology::Point_list => wgt::PrimitiveTopology::PointList,
GPUPrimitiveTopology::Line_list => wgt::PrimitiveTopology::LineList,
GPUPrimitiveTopology::Line_strip => wgt::PrimitiveTopology::LineStrip,
GPUPrimitiveTopology::Triangle_list => wgt::PrimitiveTopology::TriangleList,
GPUPrimitiveTopology::Triangle_strip => wgt::PrimitiveTopology::TriangleStrip,
};
let ref rs_desc = descriptor.rasterizationState; let ref rs_desc = descriptor.rasterizationState;
let rasterization_state = wgt::RasterizationStateDescriptor { let ref vs_desc = descriptor.vertexState;
let desc = wgpu_pipe::RenderPipelineDescriptor {
layout: descriptor.parent.layout.id().0,
vertex_stage: wgpu_pipe::ProgrammableStageDescriptor {
module: descriptor.vertexStage.module.id().0,
entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()),
},
fragment_stage: descriptor.fragmentStage.as_ref().map(|stage| {
wgpu_pipe::ProgrammableStageDescriptor {
module: stage.module.id().0,
entry_point: Cow::Owned(stage.entryPoint.to_string()),
}
}),
rasterization_state: Some(wgt::RasterizationStateDescriptor {
front_face: match rs_desc.frontFace { front_face: match rs_desc.frontFace {
GPUFrontFace::Ccw => wgt::FrontFace::Ccw, GPUFrontFace::Ccw => wgt::FrontFace::Ccw,
GPUFrontFace::Cw => wgt::FrontFace::Cw, GPUFrontFace::Cw => wgt::FrontFace::Cw,
@ -741,9 +756,16 @@ impl GPUDeviceMethods for GPUDevice {
depth_bias: rs_desc.depthBias, depth_bias: rs_desc.depthBias,
depth_bias_slope_scale: *rs_desc.depthBiasSlopeScale, depth_bias_slope_scale: *rs_desc.depthBiasSlopeScale,
depth_bias_clamp: *rs_desc.depthBiasClamp, depth_bias_clamp: *rs_desc.depthBiasClamp,
}; }),
primitive_topology: match descriptor.primitiveTopology {
let color_states = descriptor GPUPrimitiveTopology::Point_list => wgt::PrimitiveTopology::PointList,
GPUPrimitiveTopology::Line_list => wgt::PrimitiveTopology::LineList,
GPUPrimitiveTopology::Line_strip => wgt::PrimitiveTopology::LineStrip,
GPUPrimitiveTopology::Triangle_list => wgt::PrimitiveTopology::TriangleList,
GPUPrimitiveTopology::Triangle_strip => wgt::PrimitiveTopology::TriangleStrip,
},
color_states: Cow::Owned(
descriptor
.colorStates .colorStates
.iter() .iter()
.map(|state| wgt::ColorStateDescriptor { .map(|state| wgt::ColorStateDescriptor {
@ -755,10 +777,10 @@ impl GPUDeviceMethods for GPUDevice {
None => wgt::ColorWrite::empty(), None => wgt::ColorWrite::empty(),
}, },
}) })
.collect::<ArrayVec<_>>(); .collect::<Vec<_>>(),
),
let depth_stencil_state = if let Some(ref dss_desc) = descriptor.depthStencilState { depth_stencil_state: descriptor.depthStencilState.as_ref().map(|dss_desc| {
Some(wgt::DepthStencilStateDescriptor { wgt::DepthStencilStateDescriptor {
format: convert_texture_format(dss_desc.format), format: convert_texture_format(dss_desc.format),
depth_write_enabled: dss_desc.depthWriteEnabled, depth_write_enabled: dss_desc.depthWriteEnabled,
depth_compare: convert_compare_function(dss_desc.depthCompare), depth_compare: convert_compare_function(dss_desc.depthCompare),
@ -776,27 +798,24 @@ impl GPUDeviceMethods for GPUDevice {
}, },
stencil_read_mask: dss_desc.stencilReadMask, stencil_read_mask: dss_desc.stencilReadMask,
stencil_write_mask: dss_desc.stencilWriteMask, stencil_write_mask: dss_desc.stencilWriteMask,
}) }
} else { }),
None vertex_state: wgt::VertexStateDescriptor {
}; index_format: match vs_desc.indexFormat {
let ref vs_desc = descriptor.vertexState;
let vertex_state = (
match vs_desc.indexFormat {
GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16, GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16,
GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32, GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32,
}, },
vertex_buffers: Cow::Owned(
vs_desc vs_desc
.vertexBuffers .vertexBuffers
.iter() .iter()
.map(|buffer| { .map(|buffer| wgt::VertexBufferDescriptor {
( stride: buffer.arrayStride,
buffer.arrayStride, step_mode: match buffer.stepMode {
match buffer.stepMode {
GPUInputStepMode::Vertex => wgt::InputStepMode::Vertex, GPUInputStepMode::Vertex => wgt::InputStepMode::Vertex,
GPUInputStepMode::Instance => wgt::InputStepMode::Instance, GPUInputStepMode::Instance => wgt::InputStepMode::Instance,
}, },
attributes: Cow::Owned(
buffer buffer
.attributes .attributes
.iter() .iter()
@ -806,10 +825,15 @@ impl GPUDeviceMethods for GPUDevice {
shader_location: att.shaderLocation, shader_location: att.shaderLocation,
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
) ),
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
); ),
},
sample_count: descriptor.sampleCount,
sample_mask: descriptor.sampleMask,
alpha_to_coverage_enabled: descriptor.alphaToCoverageEnabled,
};
let render_pipeline_id = self let render_pipeline_id = self
.global() .global()
@ -825,19 +849,7 @@ impl GPUDeviceMethods for GPUDevice {
device_id: self.device.0, device_id: self.device.0,
render_pipeline_id, render_pipeline_id,
scope_id, scope_id,
pipeline_layout_id: descriptor.parent.layout.id().0, descriptor: desc,
vertex_module,
vertex_entry_point,
fragment_module,
fragment_entry_point,
primitive_topology,
rasterization_state,
color_states,
depth_stencil_state,
vertex_state,
sample_count: descriptor.sampleCount,
sample_mask: descriptor.sampleMask,
alpha_to_coverage_enabled: descriptor.alphaToCoverageEnabled,
}) })
.expect("Failed to create WebGPU render pipeline"); .expect("Failed to create WebGPU render pipeline");

View file

@ -57,12 +57,12 @@ pub enum WebGPUMsg {
#[derive(Debug)] #[derive(Debug)]
pub struct IdentityRecycler { pub struct IdentityRecycler {
sender: IpcSender<WebGPUMsg>, sender: IpcSender<WebGPUMsg>,
self_sender: IpcSender<WebGPURequest>, self_sender: IpcSender<WebGPURequest<'static>>,
} }
pub struct IdentityRecyclerFactory { pub struct IdentityRecyclerFactory {
pub sender: IpcSender<WebGPUMsg>, pub sender: IpcSender<WebGPUMsg>,
pub self_sender: IpcSender<WebGPURequest>, pub self_sender: IpcSender<WebGPURequest<'static>>,
} }
macro_rules! impl_identity_handler { macro_rules! impl_identity_handler {

View file

@ -31,11 +31,12 @@ use webrender_traits::{
WebrenderImageSource, WebrenderImageSource,
}; };
use wgpu::{ use wgpu::{
binding_model::{BindGroupDescriptor, BindGroupEntry, BindingResource, BufferBinding}, binding_model::BindGroupDescriptor,
command::{BufferCopyView, ComputePass, RenderPass, TextureCopyView}, command::{BufferCopyView, ComputePass, RenderPass, TextureCopyView},
device::HostMap, device::HostMap,
id, id,
instance::RequestAdapterOptions, instance::RequestAdapterOptions,
pipeline::{ComputePipelineDescriptor, RenderPipelineDescriptor},
resource::{BufferMapAsyncStatus, BufferMapOperation}, resource::{BufferMapAsyncStatus, BufferMapOperation},
}; };
@ -60,7 +61,7 @@ pub enum WebGPUResponse {
pub type WebGPUResponseResult = Result<WebGPUResponse, String>; pub type WebGPUResponseResult = Result<WebGPUResponse, String>;
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub enum WebGPURequest { pub enum WebGPURequest<'a> {
BufferMapAsync { BufferMapAsync {
sender: IpcSender<WebGPUResponseResult>, sender: IpcSender<WebGPUResponseResult>,
buffer_id: id::BufferId, buffer_id: id::BufferId,
@ -104,16 +105,13 @@ pub enum WebGPURequest {
// TODO: Consider using NonZeroU64 to reduce enum size // TODO: Consider using NonZeroU64 to reduce enum size
scope_id: Option<u64>, scope_id: Option<u64>,
bind_group_id: id::BindGroupId, bind_group_id: id::BindGroupId,
bind_group_layout_id: id::BindGroupLayoutId, descriptor: BindGroupDescriptor<'a>,
entries: Vec<(u32, WebGPUBindings)>,
label: Option<String>,
}, },
CreateBindGroupLayout { CreateBindGroupLayout {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>, scope_id: Option<u64>,
bind_group_layout_id: id::BindGroupLayoutId, bind_group_layout_id: id::BindGroupLayoutId,
entries: Vec<wgt::BindGroupLayoutEntry>, descriptor: wgt::BindGroupLayoutDescriptor<'a>,
label: Option<String>,
}, },
CreateBuffer { CreateBuffer {
device_id: id::DeviceId, device_id: id::DeviceId,
@ -131,37 +129,20 @@ pub enum WebGPURequest {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>, scope_id: Option<u64>,
compute_pipeline_id: id::ComputePipelineId, compute_pipeline_id: id::ComputePipelineId,
pipeline_layout_id: id::PipelineLayoutId, descriptor: ComputePipelineDescriptor<'a>,
program_id: id::ShaderModuleId,
entry_point: String,
}, },
CreateContext(IpcSender<webrender_api::ExternalImageId>), CreateContext(IpcSender<webrender_api::ExternalImageId>),
CreatePipelineLayout { CreatePipelineLayout {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>, scope_id: Option<u64>,
pipeline_layout_id: id::PipelineLayoutId, pipeline_layout_id: id::PipelineLayoutId,
bind_group_layouts: Vec<id::BindGroupLayoutId>, descriptor: wgt::PipelineLayoutDescriptor<'a, id::BindGroupLayoutId>,
}, },
CreateRenderPipeline { CreateRenderPipeline {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>, scope_id: Option<u64>,
render_pipeline_id: id::RenderPipelineId, render_pipeline_id: id::RenderPipelineId,
pipeline_layout_id: id::PipelineLayoutId, descriptor: RenderPipelineDescriptor<'a>,
vertex_module: id::ShaderModuleId,
vertex_entry_point: String,
fragment_module: Option<id::ShaderModuleId>,
fragment_entry_point: Option<String>,
primitive_topology: wgt::PrimitiveTopology,
rasterization_state: wgt::RasterizationStateDescriptor,
color_states: ArrayVec<[wgt::ColorStateDescriptor; wgpu::device::MAX_COLOR_TARGETS]>,
depth_stencil_state: Option<wgt::DepthStencilStateDescriptor>,
vertex_state: (
wgt::IndexFormat,
Vec<(u64, wgt::InputStepMode, Vec<wgt::VertexAttributeDescriptor>)>,
),
sample_count: u32,
sample_mask: u32,
alpha_to_coverage_enabled: bool,
}, },
CreateSampler { CreateSampler {
device_id: id::DeviceId, device_id: id::DeviceId,
@ -255,13 +236,6 @@ pub enum WebGPURequest {
}, },
} }
#[derive(Debug, Deserialize, Serialize)]
pub enum WebGPUBindings {
Buffer(BufferBinding),
Sampler(id::SamplerId),
TextureView(id::TextureViewId),
}
struct BufferMapInfo<'a, T> { struct BufferMapInfo<'a, T> {
buffer_id: id::BufferId, buffer_id: id::BufferId,
sender: IpcSender<T>, sender: IpcSender<T>,
@ -271,7 +245,7 @@ struct BufferMapInfo<'a, T> {
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WebGPU(pub IpcSender<WebGPURequest>); pub struct WebGPU(pub IpcSender<WebGPURequest<'static>>);
impl WebGPU { impl WebGPU {
pub fn new( pub fn new(
@ -335,8 +309,8 @@ impl WebGPU {
} }
struct WGPU<'a> { struct WGPU<'a> {
receiver: IpcReceiver<WebGPURequest>, receiver: IpcReceiver<WebGPURequest<'static>>,
sender: IpcSender<WebGPURequest>, sender: IpcSender<WebGPURequest<'static>>,
script_sender: IpcSender<WebGPUMsg>, script_sender: IpcSender<WebGPUMsg>,
global: wgpu::hub::Global<IdentityRecyclerFactory>, global: wgpu::hub::Global<IdentityRecyclerFactory>,
adapters: Vec<WebGPUAdapter>, adapters: Vec<WebGPUAdapter>,
@ -346,7 +320,7 @@ struct WGPU<'a> {
// Buffers with pending mapping // Buffers with pending mapping
buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPUResponseResult>>>, buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPUResponseResult>>>,
// Presentation Buffers with pending mapping // Presentation Buffers with pending mapping
present_buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPURequest>>>, present_buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPURequest<'static>>>>,
webrender_api: webrender_api::RenderApi, webrender_api: webrender_api::RenderApi,
webrender_document: webrender_api::DocumentId, webrender_document: webrender_api::DocumentId,
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>, external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
@ -356,8 +330,8 @@ struct WGPU<'a> {
impl<'a> WGPU<'a> { impl<'a> WGPU<'a> {
fn new( fn new(
receiver: IpcReceiver<WebGPURequest>, receiver: IpcReceiver<WebGPURequest<'static>>,
sender: IpcSender<WebGPURequest>, sender: IpcSender<WebGPURequest<'static>>,
script_sender: IpcSender<WebGPUMsg>, script_sender: IpcSender<WebGPUMsg>,
webrender_api_sender: webrender_api::RenderApiSender, webrender_api_sender: webrender_api::RenderApiSender,
webrender_document: webrender_api::DocumentId, webrender_document: webrender_api::DocumentId,
@ -420,7 +394,8 @@ impl<'a> WGPU<'a> {
BufferMapAsyncStatus::Success => { BufferMapAsyncStatus::Success => {
let global = &info.global; let global = &info.global;
let data_pt = gfx_select!(info.buffer_id => let data_pt = gfx_select!(info.buffer_id =>
global.buffer_get_mapped_range(info.buffer_id, 0, None)); global.buffer_get_mapped_range(info.buffer_id, 0, None))
.unwrap();
let data = slice::from_raw_parts(data_pt, info.size); let data = slice::from_raw_parts(data_pt, info.size);
if let Err(e) = if let Err(e) =
info.sender.send(Ok(WebGPUResponse::BufferMapAsync( info.sender.send(Ok(WebGPUResponse::BufferMapAsync(
@ -442,7 +417,7 @@ impl<'a> WGPU<'a> {
), ),
}; };
let global = &self.global; let global = &self.global;
gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation)); let _ = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation));
}, },
WebGPURequest::BufferMapComplete(buffer_id) => { WebGPURequest::BufferMapComplete(buffer_id) => {
self.buffer_maps.remove(&buffer_id); self.buffer_maps.remove(&buffer_id);
@ -518,32 +493,9 @@ impl<'a> WGPU<'a> {
device_id, device_id,
scope_id, scope_id,
bind_group_id, bind_group_id,
bind_group_layout_id, descriptor,
mut entries,
label,
} => { } => {
let global = &self.global; let global = &self.global;
let bindings = entries
.drain(..)
.map(|(bind, res)| {
let resource = match res {
WebGPUBindings::Sampler(s) => BindingResource::Sampler(s),
WebGPUBindings::TextureView(t) => {
BindingResource::TextureView(t)
},
WebGPUBindings::Buffer(b) => BindingResource::Buffer(b),
};
BindGroupEntry {
binding: bind,
resource,
}
})
.collect::<Vec<_>>();
let descriptor = BindGroupDescriptor {
label: label.as_deref(),
layout: bind_group_layout_id,
entries: bindings.as_slice(),
};
let result = gfx_select!(bind_group_id => let result = gfx_select!(bind_group_id =>
global.device_create_bind_group(device_id, &descriptor, bind_group_id)); global.device_create_bind_group(device_id, &descriptor, bind_group_id));
if let Some(s_id) = scope_id { if let Some(s_id) = scope_id {
@ -554,14 +506,9 @@ impl<'a> WGPU<'a> {
device_id, device_id,
scope_id, scope_id,
bind_group_layout_id, bind_group_layout_id,
entries, descriptor,
label,
} => { } => {
let global = &self.global; let global = &self.global;
let descriptor = wgt::BindGroupLayoutDescriptor {
entries: entries.as_slice(),
label: label.as_deref(),
};
let result = gfx_select!(bind_group_layout_id => let result = gfx_select!(bind_group_layout_id =>
global.device_create_bind_group_layout(device_id, &descriptor, bind_group_layout_id)); global.device_create_bind_group_layout(device_id, &descriptor, bind_group_layout_id));
if let Some(s_id) = scope_id { if let Some(s_id) = scope_id {
@ -607,18 +554,9 @@ impl<'a> WGPU<'a> {
device_id, device_id,
scope_id, scope_id,
compute_pipeline_id, compute_pipeline_id,
pipeline_layout_id, descriptor,
program_id,
entry_point,
} => { } => {
let global = &self.global; let global = &self.global;
let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor {
layout: pipeline_layout_id,
compute_stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: program_id,
entry_point: entry_point.as_str(),
},
};
let result = gfx_select!(compute_pipeline_id => let result = gfx_select!(compute_pipeline_id =>
global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id)); global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id));
if let Some(s_id) = scope_id { if let Some(s_id) = scope_id {
@ -639,13 +577,9 @@ impl<'a> WGPU<'a> {
device_id, device_id,
scope_id, scope_id,
pipeline_layout_id, pipeline_layout_id,
bind_group_layouts, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
let descriptor = wgt::PipelineLayoutDescriptor {
bind_group_layouts: bind_group_layouts.as_slice(),
push_constant_ranges: &[],
};
let result = gfx_select!(pipeline_layout_id => let result = gfx_select!(pipeline_layout_id =>
global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id)); global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id));
if let Some(s_id) = scope_id { if let Some(s_id) = scope_id {
@ -657,65 +591,9 @@ impl<'a> WGPU<'a> {
device_id, device_id,
scope_id, scope_id,
render_pipeline_id, render_pipeline_id,
pipeline_layout_id, descriptor,
vertex_module,
vertex_entry_point,
fragment_module,
fragment_entry_point,
primitive_topology,
rasterization_state,
color_states,
depth_stencil_state,
vertex_state,
sample_count,
sample_mask,
alpha_to_coverage_enabled,
} => { } => {
let global = &self.global; let global = &self.global;
let frag_ep;
let fragment_stage = match fragment_module {
Some(frag) => {
frag_ep = fragment_entry_point.unwrap().clone();
let frag_module =
wgpu_core::pipeline::ProgrammableStageDescriptor {
module: frag,
entry_point: frag_ep.as_str(),
};
Some(frag_module)
},
None => None,
};
let vert_buffers = vertex_state
.1
.iter()
.map(|&(stride, step_mode, ref attributes)| {
wgt::VertexBufferDescriptor {
stride,
step_mode,
attributes: attributes.as_slice(),
}
})
.collect::<Vec<_>>();
let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor {
layout: pipeline_layout_id,
vertex_stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: vertex_module,
entry_point: vertex_entry_point.as_str(),
},
fragment_stage,
primitive_topology,
rasterization_state: Some(rasterization_state),
color_states: color_states.as_slice(),
depth_stencil_state,
vertex_state: wgt::VertexStateDescriptor {
index_format: vertex_state.0,
vertex_buffers: vert_buffers.as_slice(),
},
sample_count,
sample_mask,
alpha_to_coverage_enabled,
};
let result = gfx_select!(render_pipeline_id => let result = gfx_select!(render_pipeline_id =>
global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id)); global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id));
if let Some(s_id) = scope_id { if let Some(s_id) = scope_id {
@ -1117,7 +995,7 @@ impl<'a> WGPU<'a> {
self.present_buffer_maps.get(&buffer_id).unwrap().clone(), self.present_buffer_maps.get(&buffer_id).unwrap().clone(),
), ),
}; };
gfx_select!(buffer_id => global.buffer_map_async(buffer_id, 0..buffer_size, map_op)); let _ = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, 0..buffer_size, map_op));
}, },
WebGPURequest::UnmapBuffer { WebGPURequest::UnmapBuffer {
buffer_id, buffer_id,
@ -1132,11 +1010,12 @@ impl<'a> WGPU<'a> {
buffer_id, buffer_id,
offset, offset,
wgt::BufferSize::new(size) wgt::BufferSize::new(size)
)); ))
.unwrap();
unsafe { slice::from_raw_parts_mut(map_ptr, size as usize) } unsafe { slice::from_raw_parts_mut(map_ptr, size as usize) }
.copy_from_slice(&array_buffer); .copy_from_slice(&array_buffer);
} }
gfx_select!(buffer_id => global.buffer_unmap(buffer_id)); let _ = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
}, },
WebGPURequest::UpdateWebRenderData { WebGPURequest::UpdateWebRenderData {
buffer_id, buffer_id,
@ -1145,7 +1024,8 @@ impl<'a> WGPU<'a> {
} => { } => {
let global = &self.global; let global = &self.global;
let data_pt = gfx_select!(buffer_id => let data_pt = gfx_select!(buffer_id =>
global.buffer_get_mapped_range(buffer_id, 0, None)); global.buffer_get_mapped_range(buffer_id, 0, None))
.unwrap();
let data = unsafe { slice::from_raw_parts(data_pt, buffer_size) }.to_vec(); let data = unsafe { slice::from_raw_parts(data_pt, buffer_size) }.to_vec();
if let Some(present_data) = if let Some(present_data) =
self.wgpu_image_map.lock().unwrap().get_mut(&external_id) self.wgpu_image_map.lock().unwrap().get_mut(&external_id)
@ -1167,7 +1047,7 @@ impl<'a> WGPU<'a> {
} else { } else {
warn!("Data not found for ExternalImageId({:?})", external_id); warn!("Data not found for ExternalImageId({:?})", external_id);
} }
gfx_select!(buffer_id => global.buffer_unmap(buffer_id)); let _ = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
self.present_buffer_maps.remove(&buffer_id); self.present_buffer_maps.remove(&buffer_id);
}, },
WebGPURequest::WriteBuffer { WebGPURequest::WriteBuffer {