diff --git a/Cargo.lock b/Cargo.lock index 6c2fe1c0f0e..53fd8955826 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6955,7 +6955,7 @@ dependencies = [ [[package]] name = "wgpu-core" version = "0.5.0" -source = "git+https://github.com/gfx-rs/wgpu#7e8b51b4286bd9452567eb1a56edb8e9b7c7f684" +source = "git+https://github.com/gfx-rs/wgpu#f7ec6cc1fe73651cfeda44295cd41533ec60f850" dependencies = [ "arrayvec 0.5.1", "bitflags", @@ -6982,7 +6982,7 @@ dependencies = [ [[package]] name = "wgpu-types" version = "0.5.0" -source = "git+https://github.com/gfx-rs/wgpu#7e8b51b4286bd9452567eb1a56edb8e9b7c7f684" +source = "git+https://github.com/gfx-rs/wgpu#f7ec6cc1fe73651cfeda44295cd41533ec60f850" dependencies = [ "bitflags", "serde", diff --git a/components/script/dom/gpucomputepipeline.rs b/components/script/dom/gpucomputepipeline.rs index 598c6a7caee..85d35997eed 100644 --- a/components/script/dom/gpucomputepipeline.rs +++ b/components/script/dom/gpucomputepipeline.rs @@ -3,28 +3,37 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits; use crate::dom::bindings::codegen::Bindings::GPUComputePipelineBinding::GPUComputePipelineMethods; -use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::reflector::Reflector; +use crate::dom::bindings::error::{Error, Fallible}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; +use crate::dom::gpubindgrouplayout::GPUBindGroupLayout; use dom_struct::dom_struct; -use webgpu::WebGPUComputePipeline; +use std::string::String; +use webgpu::{WebGPUBindGroupLayout, WebGPUComputePipeline}; #[dom_struct] pub struct GPUComputePipeline { reflector_: Reflector, label: DomRefCell>, compute_pipeline: WebGPUComputePipeline, + bind_group_layouts: Vec, } impl GPUComputePipeline { - fn new_inherited(compute_pipeline: WebGPUComputePipeline, label: Option) -> Self { + fn new_inherited( + compute_pipeline: WebGPUComputePipeline, + label: Option, + bgls: Vec, + ) -> Self { Self { reflector_: Reflector::new(), label: DomRefCell::new(label), compute_pipeline, + bind_group_layouts: bgls, } } @@ -32,9 +41,14 @@ impl GPUComputePipeline { global: &GlobalScope, compute_pipeline: WebGPUComputePipeline, label: Option, + bgls: Vec, ) -> DomRoot { reflect_dom_object( - Box::new(GPUComputePipeline::new_inherited(compute_pipeline, label)), + Box::new(GPUComputePipeline::new_inherited( + compute_pipeline, + label, + bgls, + )), global, ) } @@ -56,4 +70,17 @@ impl GPUComputePipelineMethods for GPUComputePipeline { fn SetLabel(&self, value: Option) { *self.label.borrow_mut() = value; } + + /// https://gpuweb.github.io/gpuweb/#dom-gpupipelinebase-getbindgrouplayout + fn GetBindGroupLayout(&self, index: u32) -> Fallible> { + if index > self.bind_group_layouts.len() as u32 || index > GPULimits::empty().maxBindGroups + { + return Err(Error::Range(String::from("Index out of bounds"))); + } + return Ok(GPUBindGroupLayout::new( + &self.global(), + self.bind_group_layouts[index as usize], + None, + )); + } } diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index af5f54d919e..4ce23aa5728 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -7,6 +7,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::EventBinding::EventInit; use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; +use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits; use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::{ GPUBindGroupDescriptor, GPUBindingResource, }; @@ -18,6 +19,7 @@ use crate::dom::bindings::codegen::Bindings::GPUComputePipelineBinding::GPUCompu use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{ GPUCommandEncoderDescriptor, GPUDeviceMethods, }; +use crate::dom::bindings::codegen::Bindings::GPUObjectBaseBinding::GPUObjectDescriptorBase; use crate::dom::bindings::codegen::Bindings::GPUPipelineLayoutBinding::GPUPipelineLayoutDescriptor; use crate::dom::bindings::codegen::Bindings::GPURenderBundleEncoderBinding::GPURenderBundleEncoderDescriptor; use crate::dom::bindings::codegen::Bindings::GPURenderPipelineBinding::{ @@ -73,7 +75,9 @@ use std::collections::HashMap; use std::ptr::NonNull; use std::rc::Rc; use webgpu::wgpu::{ - binding_model as wgpu_bind, command as wgpu_com, pipeline as wgpu_pipe, resource as wgpu_res, + binding_model as wgpu_bind, command as wgpu_com, + id::{BindGroupLayoutId, PipelineLayoutId}, + pipeline as wgpu_pipe, resource as wgpu_res, }; use webgpu::{self, identity::WebGPUOpResult, wgt, ErrorScopeId, WebGPU, WebGPURequest}; @@ -278,6 +282,38 @@ impl GPUDevice { }) }) } + + fn get_pipeline_layout_data( + &self, + layout: &Option>, + ) -> ( + Option, + Option<(PipelineLayoutId, Vec)>, + Vec, + ) { + if let Some(ref layout) = layout { + (Some(layout.id().0), None, layout.bind_group_layouts()) + } else { + let layout_id = self + .global() + .wgpu_id_hub() + .lock() + .create_pipeline_layout_id(self.device.0.backend()); + let max_bind_grps = GPULimits::empty().maxBindGroups; + let mut bgls = Vec::with_capacity(max_bind_grps as usize); + let mut bgl_ids = Vec::with_capacity(max_bind_grps as usize); + for _ in 0..max_bind_grps { + let bgl = self + .global() + .wgpu_id_hub() + .lock() + .create_bind_group_layout_id(self.device.0.backend()); + bgls.push(webgpu::WebGPUBindGroupLayout(bgl)); + bgl_ids.push(bgl); + } + (None, Some((layout_id, bgl_ids)), bgls) + } + } } impl GPUDeviceMethods for GPUDevice { @@ -322,11 +358,7 @@ impl GPUDeviceMethods for GPUDevice { fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> DomRoot { let desc = wgt::BufferUsage::from_bits(descriptor.usage).map(|usg| wgpu_res::BufferDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), + label: convert_label(&descriptor.parent), size: descriptor.size as wgt::BufferAddress, usage: usg, mapped_at_creation: descriptor.mappedAtCreation, @@ -482,11 +514,7 @@ impl GPUDeviceMethods for GPUDevice { let desc = if valid { Some(wgpu_bind::BindGroupLayoutDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), + label: convert_label(&descriptor.parent), entries: Cow::Owned(entries), }) } else { @@ -529,11 +557,7 @@ impl GPUDeviceMethods for GPUDevice { descriptor: &GPUPipelineLayoutDescriptor, ) -> DomRoot { let desc = wgpu_bind::PipelineLayoutDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), + label: convert_label(&descriptor.parent), bind_group_layouts: Cow::Owned( descriptor .bindGroupLayouts @@ -563,11 +587,17 @@ impl GPUDeviceMethods for GPUDevice { )) .expect("Failed to create WebGPU PipelineLayout"); + let bgls = descriptor + .bindGroupLayouts + .iter() + .map(|each| each.id()) + .collect::>(); let pipeline_layout = webgpu::WebGPUPipelineLayout(pipeline_layout_id); GPUPipelineLayout::new( &self.global(), pipeline_layout, descriptor.parent.label.as_ref().cloned(), + bgls, ) } @@ -597,11 +627,7 @@ impl GPUDeviceMethods for GPUDevice { .collect::>(); let desc = wgpu_bind::BindGroupDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|l| Cow::Owned(l.to_string())), + label: convert_label(&descriptor.parent), layout: descriptor.layout.id().0, entries: Cow::Owned(entries), }; @@ -686,15 +712,11 @@ impl GPUDeviceMethods for GPUDevice { .create_compute_pipeline_id(self.device.0.backend()); let scope_id = self.use_current_scope(); + let (layout, implicit_ids, bgls) = self.get_pipeline_layout_data(&descriptor.parent.layout); let desc = wgpu_pipe::ComputePipelineDescriptor { - label: descriptor - .parent - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), - layout: Some(descriptor.parent.layout.id().0), + label: convert_label(&descriptor.parent.parent), + layout, compute_stage: wgpu_pipe::ProgrammableStageDescriptor { module: descriptor.computeStage.module.id().0, entry_point: Cow::Owned(descriptor.computeStage.entryPoint.to_string()), @@ -709,6 +731,7 @@ impl GPUDeviceMethods for GPUDevice { device_id: self.device.0, compute_pipeline_id, descriptor: desc, + implicit_ids, }, )) .expect("Failed to create WebGPU ComputePipeline"); @@ -718,6 +741,7 @@ impl GPUDeviceMethods for GPUDevice { &self.global(), compute_pipeline, descriptor.parent.parent.label.as_ref().cloned(), + bgls, ) } @@ -739,11 +763,7 @@ impl GPUDeviceMethods for GPUDevice { WebGPURequest::CreateCommandEncoder { device_id: self.device.0, command_encoder_id, - label: descriptor - .parent - .label - .as_ref() - .map(|l| Cow::Owned(l.to_string())), + label: convert_label(&descriptor.parent), }, )) .expect("Failed to create WebGPU command encoder"); @@ -765,11 +785,7 @@ impl GPUDeviceMethods for GPUDevice { let size = convert_texture_size_to_dict(&descriptor.size); let desc = wgt::TextureUsage::from_bits(descriptor.usage).map(|usg| wgpu_res::TextureDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|l| Cow::Owned(l.to_string())), + label: convert_label(&descriptor.parent), size: convert_texture_size_to_wgt(&size), mip_level_count: descriptor.mipLevelCount, sample_count: descriptor.sampleCount, @@ -833,11 +849,7 @@ impl GPUDeviceMethods for GPUDevice { .create_sampler_id(self.device.0.backend()); let compare_enable = descriptor.compare.is_some(); let desc = wgpu_res::SamplerDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), + label: convert_label(&descriptor.parent), address_modes: [ convert_address_mode(descriptor.addressModeU), convert_address_mode(descriptor.addressModeV), @@ -904,16 +916,12 @@ impl GPUDeviceMethods for GPUDevice { }) .collect::>(), ); + let (layout, implicit_ids, bgls) = self.get_pipeline_layout_data(&descriptor.parent.layout); let desc = if valid { Some(wgpu_pipe::RenderPipelineDescriptor { - label: descriptor - .parent - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), - layout: Some(descriptor.parent.layout.id().0), + label: convert_label(&descriptor.parent.parent), + layout, vertex_stage: wgpu_pipe::ProgrammableStageDescriptor { module: descriptor.vertexStage.module.id().0, entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()), @@ -1028,6 +1036,7 @@ impl GPUDeviceMethods for GPUDevice { device_id: self.device.0, render_pipeline_id, descriptor: desc, + implicit_ids, }, )) .expect("Failed to create WebGPU render pipeline"); @@ -1037,8 +1046,8 @@ impl GPUDeviceMethods for GPUDevice { GPURenderPipeline::new( &self.global(), render_pipeline, - self.device, descriptor.parent.parent.label.as_ref().cloned(), + bgls, ) } @@ -1048,11 +1057,7 @@ impl GPUDeviceMethods for GPUDevice { descriptor: &GPURenderBundleEncoderDescriptor, ) -> DomRoot { let desc = wgpu_com::RenderBundleEncoderDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|s| Cow::Owned(s.to_string())), + label: convert_label(&descriptor.parent), color_formats: Cow::Owned( descriptor .colorFormats @@ -1323,3 +1328,7 @@ pub fn convert_texture_size_to_wgt(size: &GPUExtent3DDict) -> wgt::Extent3d { depth: size.depth, } } + +pub fn convert_label(parent: &GPUObjectDescriptorBase) -> Option> { + parent.label.as_ref().map(|s| Cow::Owned(s.to_string())) +} diff --git a/components/script/dom/gpupipelinelayout.rs b/components/script/dom/gpupipelinelayout.rs index 7547adce843..563d0ca9220 100644 --- a/components/script/dom/gpupipelinelayout.rs +++ b/components/script/dom/gpupipelinelayout.rs @@ -9,21 +9,27 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; use dom_struct::dom_struct; -use webgpu::WebGPUPipelineLayout; +use webgpu::{WebGPUBindGroupLayout, WebGPUPipelineLayout}; #[dom_struct] pub struct GPUPipelineLayout { reflector_: Reflector, label: DomRefCell>, pipeline_layout: WebGPUPipelineLayout, + bind_group_layouts: Vec, } impl GPUPipelineLayout { - fn new_inherited(pipeline_layout: WebGPUPipelineLayout, label: Option) -> Self { + fn new_inherited( + pipeline_layout: WebGPUPipelineLayout, + label: Option, + bgls: Vec, + ) -> Self { Self { reflector_: Reflector::new(), label: DomRefCell::new(label), pipeline_layout, + bind_group_layouts: bgls, } } @@ -31,9 +37,14 @@ impl GPUPipelineLayout { global: &GlobalScope, pipeline_layout: WebGPUPipelineLayout, label: Option, + bgls: Vec, ) -> DomRoot { reflect_dom_object( - Box::new(GPUPipelineLayout::new_inherited(pipeline_layout, label)), + Box::new(GPUPipelineLayout::new_inherited( + pipeline_layout, + label, + bgls, + )), global, ) } @@ -43,6 +54,10 @@ impl GPUPipelineLayout { pub fn id(&self) -> WebGPUPipelineLayout { self.pipeline_layout } + + pub fn bind_group_layouts(&self) -> Vec { + self.bind_group_layouts.clone() + } } impl GPUPipelineLayoutMethods for GPUPipelineLayout { diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs index 13109d0b9b9..722afdebc0e 100644 --- a/components/script/dom/gpurenderbundleencoder.rs +++ b/components/script/dom/gpurenderbundleencoder.rs @@ -11,11 +11,10 @@ use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; use crate::dom::gpubindgroup::GPUBindGroup; use crate::dom::gpubuffer::GPUBuffer; -use crate::dom::gpudevice::GPUDevice; +use crate::dom::gpudevice::{convert_label, GPUDevice}; use crate::dom::gpurenderbundle::GPURenderBundle; use crate::dom::gpurenderpipeline::GPURenderPipeline; use dom_struct::dom_struct; -use std::borrow::Cow; use webgpu::{ wgpu::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder}, wgt, WebGPU, WebGPURenderBundle, WebGPURequest, @@ -185,11 +184,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder { /// https://gpuweb.github.io/gpuweb/#dom-gpurenderbundleencoder-finish fn Finish(&self, descriptor: &GPURenderBundleDescriptor) -> DomRoot { let desc = wgt::RenderBundleDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|l| Cow::Owned(l.to_string())), + label: convert_label(&descriptor.parent), }; let encoder = self.render_bundle_encoder.borrow_mut().take().unwrap(); let render_bundle_id = self diff --git a/components/script/dom/gpurenderpipeline.rs b/components/script/dom/gpurenderpipeline.rs index bb618a248a9..b59ea0e8501 100644 --- a/components/script/dom/gpurenderpipeline.rs +++ b/components/script/dom/gpurenderpipeline.rs @@ -3,48 +3,51 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits; use crate::dom::bindings::codegen::Bindings::GPURenderPipelineBinding::GPURenderPipelineMethods; -use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::reflector::Reflector; +use crate::dom::bindings::error::{Error, Fallible}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; +use crate::dom::gpubindgrouplayout::GPUBindGroupLayout; use dom_struct::dom_struct; -use webgpu::{WebGPUDevice, WebGPURenderPipeline}; +use std::string::String; +use webgpu::{WebGPUBindGroupLayout, WebGPURenderPipeline}; #[dom_struct] pub struct GPURenderPipeline { reflector_: Reflector, label: DomRefCell>, render_pipeline: WebGPURenderPipeline, - device: WebGPUDevice, + bind_group_layouts: Vec, } impl GPURenderPipeline { fn new_inherited( render_pipeline: WebGPURenderPipeline, - device: WebGPUDevice, label: Option, + bgls: Vec, ) -> Self { Self { reflector_: Reflector::new(), label: DomRefCell::new(label), render_pipeline, - device, + bind_group_layouts: bgls, } } pub fn new( global: &GlobalScope, render_pipeline: WebGPURenderPipeline, - device: WebGPUDevice, label: Option, + bgls: Vec, ) -> DomRoot { reflect_dom_object( Box::new(GPURenderPipeline::new_inherited( render_pipeline, - device, label, + bgls, )), global, ) @@ -67,4 +70,17 @@ impl GPURenderPipelineMethods for GPURenderPipeline { fn SetLabel(&self, value: Option) { *self.label.borrow_mut() = value; } + + /// https://gpuweb.github.io/gpuweb/#dom-gpupipelinebase-getbindgrouplayout + fn GetBindGroupLayout(&self, index: u32) -> Fallible> { + if index > self.bind_group_layouts.len() as u32 || index > GPULimits::empty().maxBindGroups + { + return Err(Error::Range(String::from("Index out of bounds"))); + } + return Ok(GPUBindGroupLayout::new( + &self.global(), + self.bind_group_layouts[index as usize], + None, + )); + } } diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs index fc93e300a9e..175ec7c90cc 100644 --- a/components/script/dom/gputexture.rs +++ b/components/script/dom/gputexture.rs @@ -13,10 +13,11 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; -use crate::dom::gpudevice::{convert_texture_format, convert_texture_view_dimension, GPUDevice}; +use crate::dom::gpudevice::{ + convert_label, convert_texture_format, convert_texture_view_dimension, GPUDevice, +}; use crate::dom::gputextureview::GPUTextureView; use dom_struct::dom_struct; -use std::borrow::Cow; use std::num::NonZeroU32; use std::string::String; use webgpu::{ @@ -142,15 +143,9 @@ impl GPUTextureMethods for GPUTexture { let desc = if valid { Some(resource::TextureViewDescriptor { - label: descriptor - .parent - .label - .as_ref() - .map(|l| Cow::Owned(l.to_string())), - format: descriptor.format.map(|fr| convert_texture_format(fr)), - dimension: descriptor - .dimension - .map(|dm| convert_texture_view_dimension(dm)), + label: convert_label(&descriptor.parent), + format: descriptor.format.map(convert_texture_format), + dimension: descriptor.dimension.map(convert_texture_view_dimension), aspect: match descriptor.aspect { GPUTextureAspect::All => wgt::TextureAspect::All, GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly, diff --git a/components/script/dom/webidls/GPUComputePipeline.webidl b/components/script/dom/webidls/GPUComputePipeline.webidl index 671c36ad351..a7599a13803 100644 --- a/components/script/dom/webidls/GPUComputePipeline.webidl +++ b/components/script/dom/webidls/GPUComputePipeline.webidl @@ -7,9 +7,10 @@ interface GPUComputePipeline { }; GPUComputePipeline includes GPUObjectBase; +GPUComputePipeline includes GPUPipelineBase; dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase { - required GPUPipelineLayout layout; + GPUPipelineLayout layout; }; dictionary GPUProgrammableStageDescriptor { @@ -20,3 +21,7 @@ dictionary GPUProgrammableStageDescriptor { dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase { required GPUProgrammableStageDescriptor computeStage; }; + +interface mixin GPUPipelineBase { + [Throws] GPUBindGroupLayout getBindGroupLayout(unsigned long index); +}; diff --git a/components/script/dom/webidls/GPURenderPipeline.webidl b/components/script/dom/webidls/GPURenderPipeline.webidl index a25890112fc..7def381780a 100644 --- a/components/script/dom/webidls/GPURenderPipeline.webidl +++ b/components/script/dom/webidls/GPURenderPipeline.webidl @@ -7,6 +7,7 @@ interface GPURenderPipeline { }; GPURenderPipeline includes GPUObjectBase; +GPURenderPipeline includes GPUPipelineBase; dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { required GPUProgrammableStageDescriptor vertexStage; diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index 3c970a87760..a7169834586 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -36,7 +36,7 @@ use wgpu::{ BufferCopyView, ComputePass, RenderBundleDescriptor, RenderBundleEncoder, RenderPass, TextureCopyView, }, - device::HostMap, + device::{HostMap, ImplicitPipelineIds}, id, instance::RequestAdapterOptions, pipeline::{ComputePipelineDescriptor, RenderPipelineDescriptor}, @@ -141,6 +141,7 @@ pub enum WebGPURequest { device_id: id::DeviceId, compute_pipeline_id: id::ComputePipelineId, descriptor: ComputePipelineDescriptor<'static>, + implicit_ids: Option<(id::PipelineLayoutId, Vec)>, }, CreateContext(IpcSender), CreatePipelineLayout { @@ -152,6 +153,7 @@ pub enum WebGPURequest { device_id: id::DeviceId, render_pipeline_id: id::RenderPipelineId, descriptor: Option>, + implicit_ids: Option<(id::PipelineLayoutId, Vec)>, }, CreateSampler { device_id: id::DeviceId, @@ -611,13 +613,34 @@ impl<'a> WGPU<'a> { device_id, compute_pipeline_id, descriptor, + implicit_ids, } => { let global = &self.global; - let result = gfx_select!(compute_pipeline_id => - global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id, None)); + let bgls = implicit_ids + .as_ref() + .map_or(Vec::with_capacity(0), |(_, bgls)| bgls.clone()); + let implicit = + implicit_ids + .as_ref() + .map(|(layout, _)| ImplicitPipelineIds { + root_id: *layout, + group_ids: bgls.as_slice(), + }); + let result = gfx_select!(compute_pipeline_id => global.device_create_compute_pipeline( + device_id, + &descriptor, + compute_pipeline_id, + implicit + )); if result.is_err() { let _ = gfx_select!(compute_pipeline_id => global.compute_pipeline_error(compute_pipeline_id)); + if let Some((layout, bgls)) = implicit_ids { + let _ = gfx_select!(layout => global.pipeline_layout_error(layout)); + bgls.iter().for_each(|&bgl| { + let _ = gfx_select!(bgl => global.bind_group_layout_error(bgl)); + }); + } } self.send_result(device_id, scope_id, result); }, @@ -648,14 +671,32 @@ impl<'a> WGPU<'a> { device_id, render_pipeline_id, descriptor, + implicit_ids, } => { let global = &self.global; + let bgls = implicit_ids + .as_ref() + .map_or(Vec::with_capacity(0), |(_, bgls)| bgls.clone()); + let implicit = + implicit_ids + .as_ref() + .map(|(layout, _)| ImplicitPipelineIds { + root_id: *layout, + group_ids: bgls.as_slice(), + }); if let Some(desc) = descriptor { let result = gfx_select!(render_pipeline_id => - global.device_create_render_pipeline(device_id, &desc, render_pipeline_id, None)); + global.device_create_render_pipeline(device_id, &desc, render_pipeline_id, implicit)); if result.is_err() { let _ = gfx_select!(render_pipeline_id => global.render_pipeline_error(render_pipeline_id)); + if let Some((layout, bgls)) = implicit_ids { + let _ = + gfx_select!(layout => global.pipeline_layout_error(layout)); + bgls.iter().for_each(|&bgl| { + let _ = gfx_select!(bgl => global.bind_group_layout_error(bgl)); + }); + } } self.send_result(device_id, scope_id, result); } else {