mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Auto merge of #27603 - kunalmohan:gpu-pipelinebase, r=kvark
Implement GPUPipelineBase for implicit pipeline layouts <!-- Please describe your changes on the following line: --> Store `Vec<WebGPUBindGroupLayout>` in `GPUxxxPipeline` to return a new object from `GetBindGroupLayout()`. r?@kvark --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
3ad780bbcc
10 changed files with 201 additions and 97 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -6955,7 +6955,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#7e8b51b4286bd9452567eb1a56edb8e9b7c7f684"
|
source = "git+https://github.com/gfx-rs/wgpu#f7ec6cc1fe73651cfeda44295cd41533ec60f850"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.5.1",
|
"arrayvec 0.5.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -6982,7 +6982,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#7e8b51b4286bd9452567eb1a56edb8e9b7c7f684"
|
source = "git+https://github.com/gfx-rs/wgpu#f7ec6cc1fe73651cfeda44295cd41533ec60f850"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -3,28 +3,37 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
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::codegen::Bindings::GPUComputePipelineBinding::GPUComputePipelineMethods;
|
||||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::reflector::Reflector;
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::USVString;
|
use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::WebGPUComputePipeline;
|
use std::string::String;
|
||||||
|
use webgpu::{WebGPUBindGroupLayout, WebGPUComputePipeline};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUComputePipeline {
|
pub struct GPUComputePipeline {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
label: DomRefCell<Option<USVString>>,
|
label: DomRefCell<Option<USVString>>,
|
||||||
compute_pipeline: WebGPUComputePipeline,
|
compute_pipeline: WebGPUComputePipeline,
|
||||||
|
bind_group_layouts: Vec<WebGPUBindGroupLayout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUComputePipeline {
|
impl GPUComputePipeline {
|
||||||
fn new_inherited(compute_pipeline: WebGPUComputePipeline, label: Option<USVString>) -> Self {
|
fn new_inherited(
|
||||||
|
compute_pipeline: WebGPUComputePipeline,
|
||||||
|
label: Option<USVString>,
|
||||||
|
bgls: Vec<WebGPUBindGroupLayout>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
label: DomRefCell::new(label),
|
label: DomRefCell::new(label),
|
||||||
compute_pipeline,
|
compute_pipeline,
|
||||||
|
bind_group_layouts: bgls,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,9 +41,14 @@ impl GPUComputePipeline {
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
compute_pipeline: WebGPUComputePipeline,
|
compute_pipeline: WebGPUComputePipeline,
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
|
bgls: Vec<WebGPUBindGroupLayout>,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(GPUComputePipeline::new_inherited(compute_pipeline, label)),
|
Box::new(GPUComputePipeline::new_inherited(
|
||||||
|
compute_pipeline,
|
||||||
|
label,
|
||||||
|
bgls,
|
||||||
|
)),
|
||||||
global,
|
global,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -56,4 +70,17 @@ impl GPUComputePipelineMethods for GPUComputePipeline {
|
||||||
fn SetLabel(&self, value: Option<USVString>) {
|
fn SetLabel(&self, value: Option<USVString>) {
|
||||||
*self.label.borrow_mut() = value;
|
*self.label.borrow_mut() = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://gpuweb.github.io/gpuweb/#dom-gpupipelinebase-getbindgrouplayout
|
||||||
|
fn GetBindGroupLayout(&self, index: u32) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
||||||
|
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,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::EventBinding::EventInit;
|
use crate::dom::bindings::codegen::Bindings::EventBinding::EventInit;
|
||||||
use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits;
|
||||||
use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::{
|
use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::{
|
||||||
GPUBindGroupDescriptor, GPUBindingResource,
|
GPUBindGroupDescriptor, GPUBindingResource,
|
||||||
};
|
};
|
||||||
|
@ -18,6 +19,7 @@ use crate::dom::bindings::codegen::Bindings::GPUComputePipelineBinding::GPUCompu
|
||||||
use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{
|
use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{
|
||||||
GPUCommandEncoderDescriptor, GPUDeviceMethods,
|
GPUCommandEncoderDescriptor, GPUDeviceMethods,
|
||||||
};
|
};
|
||||||
|
use crate::dom::bindings::codegen::Bindings::GPUObjectBaseBinding::GPUObjectDescriptorBase;
|
||||||
use crate::dom::bindings::codegen::Bindings::GPUPipelineLayoutBinding::GPUPipelineLayoutDescriptor;
|
use crate::dom::bindings::codegen::Bindings::GPUPipelineLayoutBinding::GPUPipelineLayoutDescriptor;
|
||||||
use crate::dom::bindings::codegen::Bindings::GPURenderBundleEncoderBinding::GPURenderBundleEncoderDescriptor;
|
use crate::dom::bindings::codegen::Bindings::GPURenderBundleEncoderBinding::GPURenderBundleEncoderDescriptor;
|
||||||
use crate::dom::bindings::codegen::Bindings::GPURenderPipelineBinding::{
|
use crate::dom::bindings::codegen::Bindings::GPURenderPipelineBinding::{
|
||||||
|
@ -73,7 +75,9 @@ use std::collections::HashMap;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webgpu::wgpu::{
|
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};
|
use webgpu::{self, identity::WebGPUOpResult, wgt, ErrorScopeId, WebGPU, WebGPURequest};
|
||||||
|
|
||||||
|
@ -278,6 +282,38 @@ impl GPUDevice {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_pipeline_layout_data(
|
||||||
|
&self,
|
||||||
|
layout: &Option<DomRoot<GPUPipelineLayout>>,
|
||||||
|
) -> (
|
||||||
|
Option<PipelineLayoutId>,
|
||||||
|
Option<(PipelineLayoutId, Vec<BindGroupLayoutId>)>,
|
||||||
|
Vec<webgpu::WebGPUBindGroupLayout>,
|
||||||
|
) {
|
||||||
|
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 {
|
impl GPUDeviceMethods for GPUDevice {
|
||||||
|
@ -322,11 +358,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> DomRoot<GPUBuffer> {
|
fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> DomRoot<GPUBuffer> {
|
||||||
let desc =
|
let desc =
|
||||||
wgt::BufferUsage::from_bits(descriptor.usage).map(|usg| wgpu_res::BufferDescriptor {
|
wgt::BufferUsage::from_bits(descriptor.usage).map(|usg| wgpu_res::BufferDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
size: descriptor.size as wgt::BufferAddress,
|
size: descriptor.size as wgt::BufferAddress,
|
||||||
usage: usg,
|
usage: usg,
|
||||||
mapped_at_creation: descriptor.mappedAtCreation,
|
mapped_at_creation: descriptor.mappedAtCreation,
|
||||||
|
@ -482,11 +514,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
|
|
||||||
let desc = if valid {
|
let desc = if valid {
|
||||||
Some(wgpu_bind::BindGroupLayoutDescriptor {
|
Some(wgpu_bind::BindGroupLayoutDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
entries: Cow::Owned(entries),
|
entries: Cow::Owned(entries),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -529,11 +557,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
descriptor: &GPUPipelineLayoutDescriptor,
|
descriptor: &GPUPipelineLayoutDescriptor,
|
||||||
) -> DomRoot<GPUPipelineLayout> {
|
) -> DomRoot<GPUPipelineLayout> {
|
||||||
let desc = wgpu_bind::PipelineLayoutDescriptor {
|
let desc = wgpu_bind::PipelineLayoutDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
bind_group_layouts: Cow::Owned(
|
bind_group_layouts: Cow::Owned(
|
||||||
descriptor
|
descriptor
|
||||||
.bindGroupLayouts
|
.bindGroupLayouts
|
||||||
|
@ -563,11 +587,17 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
))
|
))
|
||||||
.expect("Failed to create WebGPU PipelineLayout");
|
.expect("Failed to create WebGPU PipelineLayout");
|
||||||
|
|
||||||
|
let bgls = descriptor
|
||||||
|
.bindGroupLayouts
|
||||||
|
.iter()
|
||||||
|
.map(|each| each.id())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let pipeline_layout = webgpu::WebGPUPipelineLayout(pipeline_layout_id);
|
let pipeline_layout = webgpu::WebGPUPipelineLayout(pipeline_layout_id);
|
||||||
GPUPipelineLayout::new(
|
GPUPipelineLayout::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
pipeline_layout,
|
pipeline_layout,
|
||||||
descriptor.parent.label.as_ref().cloned(),
|
descriptor.parent.label.as_ref().cloned(),
|
||||||
|
bgls,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,11 +627,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let desc = wgpu_bind::BindGroupDescriptor {
|
let desc = wgpu_bind::BindGroupDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|l| Cow::Owned(l.to_string())),
|
|
||||||
layout: descriptor.layout.id().0,
|
layout: descriptor.layout.id().0,
|
||||||
entries: Cow::Owned(entries),
|
entries: Cow::Owned(entries),
|
||||||
};
|
};
|
||||||
|
@ -686,15 +712,11 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
.create_compute_pipeline_id(self.device.0.backend());
|
.create_compute_pipeline_id(self.device.0.backend());
|
||||||
|
|
||||||
let scope_id = self.use_current_scope();
|
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 {
|
let desc = wgpu_pipe::ComputePipelineDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent.parent),
|
||||||
.parent
|
layout,
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
layout: Some(descriptor.parent.layout.id().0),
|
|
||||||
compute_stage: wgpu_pipe::ProgrammableStageDescriptor {
|
compute_stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||||
module: descriptor.computeStage.module.id().0,
|
module: descriptor.computeStage.module.id().0,
|
||||||
entry_point: Cow::Owned(descriptor.computeStage.entryPoint.to_string()),
|
entry_point: Cow::Owned(descriptor.computeStage.entryPoint.to_string()),
|
||||||
|
@ -709,6 +731,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
device_id: self.device.0,
|
device_id: self.device.0,
|
||||||
compute_pipeline_id,
|
compute_pipeline_id,
|
||||||
descriptor: desc,
|
descriptor: desc,
|
||||||
|
implicit_ids,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.expect("Failed to create WebGPU ComputePipeline");
|
.expect("Failed to create WebGPU ComputePipeline");
|
||||||
|
@ -718,6 +741,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
&self.global(),
|
&self.global(),
|
||||||
compute_pipeline,
|
compute_pipeline,
|
||||||
descriptor.parent.parent.label.as_ref().cloned(),
|
descriptor.parent.parent.label.as_ref().cloned(),
|
||||||
|
bgls,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,11 +763,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
WebGPURequest::CreateCommandEncoder {
|
WebGPURequest::CreateCommandEncoder {
|
||||||
device_id: self.device.0,
|
device_id: self.device.0,
|
||||||
command_encoder_id,
|
command_encoder_id,
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|l| Cow::Owned(l.to_string())),
|
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.expect("Failed to create WebGPU command encoder");
|
.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 size = convert_texture_size_to_dict(&descriptor.size);
|
||||||
let desc =
|
let desc =
|
||||||
wgt::TextureUsage::from_bits(descriptor.usage).map(|usg| wgpu_res::TextureDescriptor {
|
wgt::TextureUsage::from_bits(descriptor.usage).map(|usg| wgpu_res::TextureDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|l| Cow::Owned(l.to_string())),
|
|
||||||
size: convert_texture_size_to_wgt(&size),
|
size: convert_texture_size_to_wgt(&size),
|
||||||
mip_level_count: descriptor.mipLevelCount,
|
mip_level_count: descriptor.mipLevelCount,
|
||||||
sample_count: descriptor.sampleCount,
|
sample_count: descriptor.sampleCount,
|
||||||
|
@ -833,11 +849,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
.create_sampler_id(self.device.0.backend());
|
.create_sampler_id(self.device.0.backend());
|
||||||
let compare_enable = descriptor.compare.is_some();
|
let compare_enable = descriptor.compare.is_some();
|
||||||
let desc = wgpu_res::SamplerDescriptor {
|
let desc = wgpu_res::SamplerDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
address_modes: [
|
address_modes: [
|
||||||
convert_address_mode(descriptor.addressModeU),
|
convert_address_mode(descriptor.addressModeU),
|
||||||
convert_address_mode(descriptor.addressModeV),
|
convert_address_mode(descriptor.addressModeV),
|
||||||
|
@ -904,16 +916,12 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
|
let (layout, implicit_ids, bgls) = self.get_pipeline_layout_data(&descriptor.parent.layout);
|
||||||
|
|
||||||
let desc = if valid {
|
let desc = if valid {
|
||||||
Some(wgpu_pipe::RenderPipelineDescriptor {
|
Some(wgpu_pipe::RenderPipelineDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent.parent),
|
||||||
.parent
|
layout,
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
layout: Some(descriptor.parent.layout.id().0),
|
|
||||||
vertex_stage: wgpu_pipe::ProgrammableStageDescriptor {
|
vertex_stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||||
module: descriptor.vertexStage.module.id().0,
|
module: descriptor.vertexStage.module.id().0,
|
||||||
entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()),
|
entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()),
|
||||||
|
@ -1028,6 +1036,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
device_id: self.device.0,
|
device_id: self.device.0,
|
||||||
render_pipeline_id,
|
render_pipeline_id,
|
||||||
descriptor: desc,
|
descriptor: desc,
|
||||||
|
implicit_ids,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.expect("Failed to create WebGPU render pipeline");
|
.expect("Failed to create WebGPU render pipeline");
|
||||||
|
@ -1037,8 +1046,8 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
GPURenderPipeline::new(
|
GPURenderPipeline::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
self.device,
|
|
||||||
descriptor.parent.parent.label.as_ref().cloned(),
|
descriptor.parent.parent.label.as_ref().cloned(),
|
||||||
|
bgls,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1048,11 +1057,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
descriptor: &GPURenderBundleEncoderDescriptor,
|
descriptor: &GPURenderBundleEncoderDescriptor,
|
||||||
) -> DomRoot<GPURenderBundleEncoder> {
|
) -> DomRoot<GPURenderBundleEncoder> {
|
||||||
let desc = wgpu_com::RenderBundleEncoderDescriptor {
|
let desc = wgpu_com::RenderBundleEncoderDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| Cow::Owned(s.to_string())),
|
|
||||||
color_formats: Cow::Owned(
|
color_formats: Cow::Owned(
|
||||||
descriptor
|
descriptor
|
||||||
.colorFormats
|
.colorFormats
|
||||||
|
@ -1323,3 +1328,7 @@ pub fn convert_texture_size_to_wgt(size: &GPUExtent3DDict) -> wgt::Extent3d {
|
||||||
depth: size.depth,
|
depth: size.depth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_label(parent: &GPUObjectDescriptorBase) -> Option<Cow<'static, str>> {
|
||||||
|
parent.label.as_ref().map(|s| Cow::Owned(s.to_string()))
|
||||||
|
}
|
||||||
|
|
|
@ -9,21 +9,27 @@ use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::USVString;
|
use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::WebGPUPipelineLayout;
|
use webgpu::{WebGPUBindGroupLayout, WebGPUPipelineLayout};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUPipelineLayout {
|
pub struct GPUPipelineLayout {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
label: DomRefCell<Option<USVString>>,
|
label: DomRefCell<Option<USVString>>,
|
||||||
pipeline_layout: WebGPUPipelineLayout,
|
pipeline_layout: WebGPUPipelineLayout,
|
||||||
|
bind_group_layouts: Vec<WebGPUBindGroupLayout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUPipelineLayout {
|
impl GPUPipelineLayout {
|
||||||
fn new_inherited(pipeline_layout: WebGPUPipelineLayout, label: Option<USVString>) -> Self {
|
fn new_inherited(
|
||||||
|
pipeline_layout: WebGPUPipelineLayout,
|
||||||
|
label: Option<USVString>,
|
||||||
|
bgls: Vec<WebGPUBindGroupLayout>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
label: DomRefCell::new(label),
|
label: DomRefCell::new(label),
|
||||||
pipeline_layout,
|
pipeline_layout,
|
||||||
|
bind_group_layouts: bgls,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +37,14 @@ impl GPUPipelineLayout {
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
pipeline_layout: WebGPUPipelineLayout,
|
pipeline_layout: WebGPUPipelineLayout,
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
|
bgls: Vec<WebGPUBindGroupLayout>,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(GPUPipelineLayout::new_inherited(pipeline_layout, label)),
|
Box::new(GPUPipelineLayout::new_inherited(
|
||||||
|
pipeline_layout,
|
||||||
|
label,
|
||||||
|
bgls,
|
||||||
|
)),
|
||||||
global,
|
global,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -43,6 +54,10 @@ impl GPUPipelineLayout {
|
||||||
pub fn id(&self) -> WebGPUPipelineLayout {
|
pub fn id(&self) -> WebGPUPipelineLayout {
|
||||||
self.pipeline_layout
|
self.pipeline_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bind_group_layouts(&self) -> Vec<WebGPUBindGroupLayout> {
|
||||||
|
self.bind_group_layouts.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUPipelineLayoutMethods for GPUPipelineLayout {
|
impl GPUPipelineLayoutMethods for GPUPipelineLayout {
|
||||||
|
|
|
@ -11,11 +11,10 @@ use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::gpubindgroup::GPUBindGroup;
|
use crate::dom::gpubindgroup::GPUBindGroup;
|
||||||
use crate::dom::gpubuffer::GPUBuffer;
|
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::gpurenderbundle::GPURenderBundle;
|
||||||
use crate::dom::gpurenderpipeline::GPURenderPipeline;
|
use crate::dom::gpurenderpipeline::GPURenderPipeline;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use std::borrow::Cow;
|
|
||||||
use webgpu::{
|
use webgpu::{
|
||||||
wgpu::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder},
|
wgpu::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder},
|
||||||
wgt, WebGPU, WebGPURenderBundle, WebGPURequest,
|
wgt, WebGPU, WebGPURenderBundle, WebGPURequest,
|
||||||
|
@ -185,11 +184,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
||||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderbundleencoder-finish
|
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderbundleencoder-finish
|
||||||
fn Finish(&self, descriptor: &GPURenderBundleDescriptor) -> DomRoot<GPURenderBundle> {
|
fn Finish(&self, descriptor: &GPURenderBundleDescriptor) -> DomRoot<GPURenderBundle> {
|
||||||
let desc = wgt::RenderBundleDescriptor {
|
let desc = wgt::RenderBundleDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
|
||||||
.label
|
|
||||||
.as_ref()
|
|
||||||
.map(|l| Cow::Owned(l.to_string())),
|
|
||||||
};
|
};
|
||||||
let encoder = self.render_bundle_encoder.borrow_mut().take().unwrap();
|
let encoder = self.render_bundle_encoder.borrow_mut().take().unwrap();
|
||||||
let render_bundle_id = self
|
let render_bundle_id = self
|
||||||
|
|
|
@ -3,48 +3,51 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
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::codegen::Bindings::GPURenderPipelineBinding::GPURenderPipelineMethods;
|
||||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::reflector::Reflector;
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::USVString;
|
use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::{WebGPUDevice, WebGPURenderPipeline};
|
use std::string::String;
|
||||||
|
use webgpu::{WebGPUBindGroupLayout, WebGPURenderPipeline};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPURenderPipeline {
|
pub struct GPURenderPipeline {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
label: DomRefCell<Option<USVString>>,
|
label: DomRefCell<Option<USVString>>,
|
||||||
render_pipeline: WebGPURenderPipeline,
|
render_pipeline: WebGPURenderPipeline,
|
||||||
device: WebGPUDevice,
|
bind_group_layouts: Vec<WebGPUBindGroupLayout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPURenderPipeline {
|
impl GPURenderPipeline {
|
||||||
fn new_inherited(
|
fn new_inherited(
|
||||||
render_pipeline: WebGPURenderPipeline,
|
render_pipeline: WebGPURenderPipeline,
|
||||||
device: WebGPUDevice,
|
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
|
bgls: Vec<WebGPUBindGroupLayout>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
label: DomRefCell::new(label),
|
label: DomRefCell::new(label),
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
device,
|
bind_group_layouts: bgls,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
render_pipeline: WebGPURenderPipeline,
|
render_pipeline: WebGPURenderPipeline,
|
||||||
device: WebGPUDevice,
|
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
|
bgls: Vec<WebGPUBindGroupLayout>,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(GPURenderPipeline::new_inherited(
|
Box::new(GPURenderPipeline::new_inherited(
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
device,
|
|
||||||
label,
|
label,
|
||||||
|
bgls,
|
||||||
)),
|
)),
|
||||||
global,
|
global,
|
||||||
)
|
)
|
||||||
|
@ -67,4 +70,17 @@ impl GPURenderPipelineMethods for GPURenderPipeline {
|
||||||
fn SetLabel(&self, value: Option<USVString>) {
|
fn SetLabel(&self, value: Option<USVString>) {
|
||||||
*self.label.borrow_mut() = value;
|
*self.label.borrow_mut() = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://gpuweb.github.io/gpuweb/#dom-gpupipelinebase-getbindgrouplayout
|
||||||
|
fn GetBindGroupLayout(&self, index: u32) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
||||||
|
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,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::root::{Dom, DomRoot};
|
||||||
use crate::dom::bindings::str::USVString;
|
use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
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 crate::dom::gputextureview::GPUTextureView;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use webgpu::{
|
use webgpu::{
|
||||||
|
@ -142,15 +143,9 @@ impl GPUTextureMethods for GPUTexture {
|
||||||
|
|
||||||
let desc = if valid {
|
let desc = if valid {
|
||||||
Some(resource::TextureViewDescriptor {
|
Some(resource::TextureViewDescriptor {
|
||||||
label: descriptor
|
label: convert_label(&descriptor.parent),
|
||||||
.parent
|
format: descriptor.format.map(convert_texture_format),
|
||||||
.label
|
dimension: descriptor.dimension.map(convert_texture_view_dimension),
|
||||||
.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)),
|
|
||||||
aspect: match descriptor.aspect {
|
aspect: match descriptor.aspect {
|
||||||
GPUTextureAspect::All => wgt::TextureAspect::All,
|
GPUTextureAspect::All => wgt::TextureAspect::All,
|
||||||
GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
|
GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
interface GPUComputePipeline {
|
interface GPUComputePipeline {
|
||||||
};
|
};
|
||||||
GPUComputePipeline includes GPUObjectBase;
|
GPUComputePipeline includes GPUObjectBase;
|
||||||
|
GPUComputePipeline includes GPUPipelineBase;
|
||||||
|
|
||||||
dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase {
|
dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase {
|
||||||
required GPUPipelineLayout layout;
|
GPUPipelineLayout layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary GPUProgrammableStageDescriptor {
|
dictionary GPUProgrammableStageDescriptor {
|
||||||
|
@ -20,3 +21,7 @@ dictionary GPUProgrammableStageDescriptor {
|
||||||
dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
|
dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
|
||||||
required GPUProgrammableStageDescriptor computeStage;
|
required GPUProgrammableStageDescriptor computeStage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface mixin GPUPipelineBase {
|
||||||
|
[Throws] GPUBindGroupLayout getBindGroupLayout(unsigned long index);
|
||||||
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
interface GPURenderPipeline {
|
interface GPURenderPipeline {
|
||||||
};
|
};
|
||||||
GPURenderPipeline includes GPUObjectBase;
|
GPURenderPipeline includes GPUObjectBase;
|
||||||
|
GPURenderPipeline includes GPUPipelineBase;
|
||||||
|
|
||||||
dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase {
|
dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase {
|
||||||
required GPUProgrammableStageDescriptor vertexStage;
|
required GPUProgrammableStageDescriptor vertexStage;
|
||||||
|
|
|
@ -36,7 +36,7 @@ use wgpu::{
|
||||||
BufferCopyView, ComputePass, RenderBundleDescriptor, RenderBundleEncoder, RenderPass,
|
BufferCopyView, ComputePass, RenderBundleDescriptor, RenderBundleEncoder, RenderPass,
|
||||||
TextureCopyView,
|
TextureCopyView,
|
||||||
},
|
},
|
||||||
device::HostMap,
|
device::{HostMap, ImplicitPipelineIds},
|
||||||
id,
|
id,
|
||||||
instance::RequestAdapterOptions,
|
instance::RequestAdapterOptions,
|
||||||
pipeline::{ComputePipelineDescriptor, RenderPipelineDescriptor},
|
pipeline::{ComputePipelineDescriptor, RenderPipelineDescriptor},
|
||||||
|
@ -141,6 +141,7 @@ pub enum WebGPURequest {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
compute_pipeline_id: id::ComputePipelineId,
|
compute_pipeline_id: id::ComputePipelineId,
|
||||||
descriptor: ComputePipelineDescriptor<'static>,
|
descriptor: ComputePipelineDescriptor<'static>,
|
||||||
|
implicit_ids: Option<(id::PipelineLayoutId, Vec<id::BindGroupLayoutId>)>,
|
||||||
},
|
},
|
||||||
CreateContext(IpcSender<webrender_api::ExternalImageId>),
|
CreateContext(IpcSender<webrender_api::ExternalImageId>),
|
||||||
CreatePipelineLayout {
|
CreatePipelineLayout {
|
||||||
|
@ -152,6 +153,7 @@ pub enum WebGPURequest {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
render_pipeline_id: id::RenderPipelineId,
|
render_pipeline_id: id::RenderPipelineId,
|
||||||
descriptor: Option<RenderPipelineDescriptor<'static>>,
|
descriptor: Option<RenderPipelineDescriptor<'static>>,
|
||||||
|
implicit_ids: Option<(id::PipelineLayoutId, Vec<id::BindGroupLayoutId>)>,
|
||||||
},
|
},
|
||||||
CreateSampler {
|
CreateSampler {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
|
@ -611,13 +613,34 @@ impl<'a> WGPU<'a> {
|
||||||
device_id,
|
device_id,
|
||||||
compute_pipeline_id,
|
compute_pipeline_id,
|
||||||
descriptor,
|
descriptor,
|
||||||
|
implicit_ids,
|
||||||
} => {
|
} => {
|
||||||
let global = &self.global;
|
let global = &self.global;
|
||||||
let result = gfx_select!(compute_pipeline_id =>
|
let bgls = implicit_ids
|
||||||
global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id, None));
|
.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() {
|
if result.is_err() {
|
||||||
let _ = gfx_select!(compute_pipeline_id =>
|
let _ = gfx_select!(compute_pipeline_id =>
|
||||||
global.compute_pipeline_error(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);
|
self.send_result(device_id, scope_id, result);
|
||||||
},
|
},
|
||||||
|
@ -648,14 +671,32 @@ impl<'a> WGPU<'a> {
|
||||||
device_id,
|
device_id,
|
||||||
render_pipeline_id,
|
render_pipeline_id,
|
||||||
descriptor,
|
descriptor,
|
||||||
|
implicit_ids,
|
||||||
} => {
|
} => {
|
||||||
let global = &self.global;
|
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 {
|
if let Some(desc) = descriptor {
|
||||||
let result = gfx_select!(render_pipeline_id =>
|
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() {
|
if result.is_err() {
|
||||||
let _ = gfx_select!(render_pipeline_id =>
|
let _ = gfx_select!(render_pipeline_id =>
|
||||||
global.render_pipeline_error(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);
|
self.send_result(device_id, scope_id, result);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue