aboutsummaryrefslogtreecommitdiffstats
path: root/components/webgpu/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/webgpu/lib.rs')
-rw-r--r--components/webgpu/lib.rs200
1 files changed, 152 insertions, 48 deletions
diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs
index c0a9d46844b..6c1c5eff622 100644
--- a/components/webgpu/lib.rs
+++ b/components/webgpu/lib.rs
@@ -12,9 +12,10 @@ pub mod identity;
use arrayvec::ArrayVec;
use euclid::default::Size2D;
-use identity::{IdentityRecyclerFactory, WebGPUMsg};
+use identity::{IdentityRecyclerFactory, WebGPUMsg, WebGPUOpResult};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender, IpcSharedMemory};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
+use msg::constellation_msg::PipelineId;
use serde::{Deserialize, Serialize};
use servo_config::pref;
use smallvec::SmallVec;
@@ -82,12 +83,14 @@ pub enum WebGPURequest {
},
CreateBindGroup {
device_id: id::DeviceId,
+ scope_id: Option<u64>,
bind_group_id: id::BindGroupId,
bind_group_layout_id: id::BindGroupLayoutId,
entries: Vec<(u32, WebGPUBindings)>,
},
CreateBindGroupLayout {
device_id: id::DeviceId,
+ scope_id: Option<u64>,
bind_group_layout_id: id::BindGroupLayoutId,
entries: Vec<wgt::BindGroupLayoutEntry>,
},
@@ -104,6 +107,7 @@ pub enum WebGPURequest {
},
CreateComputePipeline {
device_id: id::DeviceId,
+ scope_id: Option<u64>,
compute_pipeline_id: id::ComputePipelineId,
pipeline_layout_id: id::PipelineLayoutId,
program_id: id::ShaderModuleId,
@@ -112,11 +116,13 @@ pub enum WebGPURequest {
CreateContext(IpcSender<webrender_api::ExternalImageId>),
CreatePipelineLayout {
device_id: id::DeviceId,
+ scope_id: Option<u64>,
pipeline_layout_id: id::PipelineLayoutId,
bind_group_layouts: Vec<id::BindGroupLayoutId>,
},
CreateRenderPipeline {
device_id: id::DeviceId,
+ scope_id: Option<u64>,
render_pipeline_id: id::RenderPipelineId,
pipeline_layout_id: id::PipelineLayoutId,
vertex_module: id::ShaderModuleId,
@@ -180,6 +186,7 @@ pub enum WebGPURequest {
adapter_id: WebGPUAdapter,
descriptor: wgt::DeviceDescriptor,
device_id: id::DeviceId,
+ pipeline_id: PipelineId,
},
RunComputePass {
command_encoder_id: id::CommandEncoderId,
@@ -310,7 +317,7 @@ struct WGPU<'a> {
script_sender: IpcSender<WebGPUMsg>,
global: wgpu::hub::Global<IdentityRecyclerFactory>,
adapters: Vec<WebGPUAdapter>,
- devices: Vec<WebGPUDevice>,
+ devices: HashMap<WebGPUDevice, PipelineId>,
// Track invalid adapters https://gpuweb.github.io/gpuweb/#invalid
_invalid_adapters: Vec<WebGPUAdapter>,
// Buffers with pending mapping
@@ -343,7 +350,7 @@ impl<'a> WGPU<'a> {
script_sender,
global: wgpu::hub::Global::new("wgpu-core", factory, wgt::BackendBit::PRIMARY),
adapters: Vec::new(),
- devices: Vec::new(),
+ devices: HashMap::new(),
_invalid_adapters: Vec::new(),
buffer_maps: HashMap::new(),
present_buffer_maps: HashMap::new(),
@@ -443,6 +450,7 @@ impl<'a> WGPU<'a> {
},
WebGPURequest::CreateBindGroup {
device_id,
+ scope_id,
bind_group_id,
bind_group_layout_id,
mut entries,
@@ -467,23 +475,66 @@ impl<'a> WGPU<'a> {
let descriptor = BindGroupDescriptor {
label: None,
layout: bind_group_layout_id,
- bindings: bindings.as_slice(),
+ entries: bindings.as_slice(),
};
- let _ = gfx_select!(bind_group_id =>
+ let result = gfx_select!(bind_group_id =>
global.device_create_bind_group(device_id, &descriptor, bind_group_id));
+ if let Some(s_id) = scope_id {
+ let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
+ let op_result;
+ if let Err(e) = result {
+ let error_msg = format!("{:?}", e);
+ op_result = WebGPUOpResult::ValidationError(error_msg);
+ } else {
+ op_result = WebGPUOpResult::Success;
+ }
+ if let Err(w) = self.script_sender.send(WebGPUMsg::WebGPUOpResult {
+ device: WebGPUDevice(device_id),
+ scope_id: s_id,
+ pipeline_id,
+ result: op_result,
+ }) {
+ warn!(
+ "Failed to send BindGroupResult({:?}) ({})",
+ bind_group_id, w
+ );
+ }
+ }
},
WebGPURequest::CreateBindGroupLayout {
device_id,
+ scope_id,
bind_group_layout_id,
entries,
} => {
let global = &self.global;
let descriptor = wgt::BindGroupLayoutDescriptor {
- bindings: entries.as_slice(),
+ entries: entries.as_slice(),
label: None,
};
- let _ = 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));
+ if let Some(s_id) = scope_id {
+ let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
+ let op_result;
+ if let Err(e) = result {
+ let error_msg = format!("{:?}", e);
+ op_result = WebGPUOpResult::ValidationError(error_msg);
+ } else {
+ op_result = WebGPUOpResult::Success;
+ }
+ if let Err(w) = self.script_sender.send(WebGPUMsg::WebGPUOpResult {
+ device: WebGPUDevice(device_id),
+ pipeline_id,
+ scope_id: s_id,
+ result: op_result,
+ }) {
+ warn!(
+ "Failed to send BindGroupLayoutResult({:?}) ({})",
+ bind_group_layout_id, w
+ );
+ }
+ }
},
WebGPURequest::CreateBuffer {
device_id,
@@ -506,22 +557,43 @@ impl<'a> WGPU<'a> {
},
WebGPURequest::CreateComputePipeline {
device_id,
+ scope_id,
compute_pipeline_id,
pipeline_layout_id,
program_id,
entry_point,
} => {
let global = &self.global;
- let entry_point = std::ffi::CString::new(entry_point).unwrap();
let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor {
layout: pipeline_layout_id,
compute_stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: program_id,
- entry_point: entry_point.as_ptr(),
+ entry_point: entry_point.as_str(),
},
};
- let _ = gfx_select!(compute_pipeline_id =>
+ let result = gfx_select!(compute_pipeline_id =>
global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id));
+ if let Some(s_id) = scope_id {
+ let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
+ let op_result;
+ if let Err(e) = result {
+ let error_msg = format!("{:?}", e);
+ op_result = WebGPUOpResult::ValidationError(error_msg);
+ } else {
+ op_result = WebGPUOpResult::Success;
+ }
+ if let Err(w) = self.script_sender.send(WebGPUMsg::WebGPUOpResult {
+ device: WebGPUDevice(device_id),
+ scope_id: s_id,
+ pipeline_id,
+ result: op_result,
+ }) {
+ warn!(
+ "Failed to send ComputePipelineResult({:?}) ({})",
+ compute_pipeline_id, w
+ );
+ }
+ }
},
WebGPURequest::CreateContext(sender) => {
let id = self
@@ -535,20 +607,43 @@ impl<'a> WGPU<'a> {
},
WebGPURequest::CreatePipelineLayout {
device_id,
+ scope_id,
pipeline_layout_id,
bind_group_layouts,
} => {
let global = &self.global;
- let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor {
- bind_group_layouts: bind_group_layouts.as_ptr(),
- bind_group_layouts_length: bind_group_layouts.len(),
+ let descriptor = wgt::PipelineLayoutDescriptor {
+ bind_group_layouts: bind_group_layouts.as_slice(),
+ push_constant_ranges: &[],
};
- let _ = gfx_select!(pipeline_layout_id =>
+ let result = gfx_select!(pipeline_layout_id =>
global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id));
+ if let Some(s_id) = scope_id {
+ let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
+ let op_result;
+ if let Err(e) = result {
+ let error_msg = format!("{:?}", e);
+ op_result = WebGPUOpResult::ValidationError(error_msg);
+ } else {
+ op_result = WebGPUOpResult::Success;
+ }
+ if let Err(w) = self.script_sender.send(WebGPUMsg::WebGPUOpResult {
+ device: WebGPUDevice(device_id),
+ scope_id: s_id,
+ pipeline_id,
+ result: op_result,
+ }) {
+ warn!(
+ "Failed to send PipelineLayoutResult({:?}) ({})",
+ pipeline_layout_id, w
+ );
+ }
+ }
},
//TODO: consider https://github.com/gfx-rs/wgpu/issues/684
WebGPURequest::CreateRenderPipeline {
device_id,
+ scope_id,
render_pipeline_id,
pipeline_layout_id,
vertex_module,
@@ -565,31 +660,27 @@ impl<'a> WGPU<'a> {
alpha_to_coverage_enabled,
} => {
let global = &self.global;
- let vertex_ep = std::ffi::CString::new(vertex_entry_point).unwrap();
let frag_ep;
- let frag_stage = match fragment_module {
+ let fragment_stage = match fragment_module {
Some(frag) => {
- frag_ep =
- std::ffi::CString::new(fragment_entry_point.unwrap()).unwrap();
+ frag_ep = fragment_entry_point.unwrap().clone();
let frag_module =
wgpu_core::pipeline::ProgrammableStageDescriptor {
module: frag,
- entry_point: frag_ep.as_ptr(),
+ entry_point: frag_ep.as_str(),
};
Some(frag_module)
},
None => None,
};
-
let vert_buffers = vertex_state
.1
.iter()
- .map(|&(array_stride, step_mode, ref attributes)| {
- wgpu_core::pipeline::VertexBufferLayoutDescriptor {
- array_stride,
+ .map(|&(stride, step_mode, ref attributes)| {
+ wgt::VertexBufferDescriptor {
+ stride,
step_mode,
- attributes_length: attributes.len(),
- attributes: attributes.as_ptr(),
+ attributes: attributes.as_slice(),
}
})
.collect::<Vec<_>>();
@@ -597,30 +688,45 @@ impl<'a> WGPU<'a> {
layout: pipeline_layout_id,
vertex_stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: vertex_module,
- entry_point: vertex_ep.as_ptr(),
+ entry_point: vertex_entry_point.as_str(),
},
- fragment_stage: frag_stage
- .as_ref()
- .map_or(ptr::null(), |fs| fs as *const _),
+ fragment_stage,
primitive_topology,
- rasterization_state: &rasterization_state as *const _,
- color_states: color_states.as_ptr(),
- color_states_length: color_states.len(),
- depth_stencil_state: depth_stencil_state
- .as_ref()
- .map_or(ptr::null(), |dss| dss as *const _),
- vertex_state: wgpu_core::pipeline::VertexStateDescriptor {
+ 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_length: vertex_state.1.len(),
- vertex_buffers: vert_buffers.as_ptr(),
+ vertex_buffers: vert_buffers.as_slice(),
},
sample_count,
sample_mask,
alpha_to_coverage_enabled,
};
- let _ = gfx_select!(render_pipeline_id =>
+ let result = gfx_select!(render_pipeline_id =>
global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id));
+ if let Some(s_id) = scope_id {
+ let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
+ let op_result;
+ if let Err(e) = result {
+ let error_msg = format!("{:?}", e);
+ op_result = WebGPUOpResult::ValidationError(error_msg);
+ } else {
+ op_result = WebGPUOpResult::Success;
+ }
+ if let Err(w) = self.script_sender.send(WebGPUMsg::WebGPUOpResult {
+ device: WebGPUDevice(device_id),
+ scope_id: s_id,
+ pipeline_id,
+ result: op_result,
+ }) {
+ warn!(
+ "Failed to send RenderPipelineResult({:?}) ({})",
+ render_pipeline_id, w
+ );
+ }
+ }
},
WebGPURequest::CreateSampler {
device_id,
@@ -764,7 +870,6 @@ impl<'a> WGPU<'a> {
} => {
let adapter_id = match self.global.pick_adapter(
&options,
- wgt::UnsafeFeatures::disallow(),
wgpu::instance::AdapterInputs::IdSet(&ids, |id| id.backend()),
) {
Some(id) => id,
@@ -800,20 +905,22 @@ impl<'a> WGPU<'a> {
adapter_id,
descriptor,
device_id,
+ pipeline_id,
} => {
let global = &self.global;
- let id = gfx_select!(device_id => global.adapter_request_device(
+ let result = gfx_select!(device_id => global.adapter_request_device(
adapter_id.0,
&descriptor,
None,
device_id
));
-
+ // TODO: Handle error gracefully acc. to spec.
+ let id = result.unwrap();
let device = WebGPUDevice(id);
// Note: (zakorgy) Note sure if sending the queue is needed at all,
// since wgpu-core uses the same id for the device and the queue
let queue = WebGPUQueue(id);
- self.devices.push(device);
+ self.devices.insert(device, pipeline_id);
if let Err(e) = sender.send(Ok(WebGPUResponse::RequestDevice {
device_id: device,
queue_id: queue,
@@ -850,10 +957,7 @@ impl<'a> WGPU<'a> {
command_buffers,
} => {
let global = &self.global;
- let _ = gfx_select!(queue_id => global.queue_submit(
- queue_id,
- &command_buffers
- ));
+ gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers));
},
WebGPURequest::SwapChainPresent {
external_id,
@@ -936,7 +1040,7 @@ impl<'a> WGPU<'a> {
height: size.height as u32,
depth: 1,
};
- gfx_select!(encoder_id => global.command_encoder_copy_texture_to_buffer(
+ let _ = gfx_select!(encoder_id => global.command_encoder_copy_texture_to_buffer(
encoder_id,
&texture_cv,
&buffer_cv,