Implement GPUPipelineBase for implicit pipeline layouts

This commit is contained in:
Kunal Mohan 2020-08-19 16:44:26 +05:30
parent 8c576bb02b
commit f082a507da
7 changed files with 176 additions and 25 deletions

View file

@ -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,
};
@ -74,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};
@ -279,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 {
@ -552,11 +587,17 @@ impl GPUDeviceMethods for GPUDevice {
))
.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);
GPUPipelineLayout::new(
&self.global(),
pipeline_layout,
descriptor.parent.label.as_ref().cloned(),
bgls,
)
}
@ -671,10 +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: convert_label(&descriptor.parent.parent),
layout: Some(descriptor.parent.layout.id().0),
layout,
compute_stage: wgpu_pipe::ProgrammableStageDescriptor {
module: descriptor.computeStage.module.id().0,
entry_point: Cow::Owned(descriptor.computeStage.entryPoint.to_string()),
@ -689,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");
@ -698,6 +741,7 @@ impl GPUDeviceMethods for GPUDevice {
&self.global(),
compute_pipeline,
descriptor.parent.parent.label.as_ref().cloned(),
bgls,
)
}
@ -872,11 +916,12 @@ impl GPUDeviceMethods for GPUDevice {
})
.collect::<Vec<_>>(),
);
let (layout, implicit_ids, bgls) = self.get_pipeline_layout_data(&descriptor.parent.layout);
let desc = if valid {
Some(wgpu_pipe::RenderPipelineDescriptor {
label: convert_label(&descriptor.parent.parent),
layout: Some(descriptor.parent.layout.id().0),
layout,
vertex_stage: wgpu_pipe::ProgrammableStageDescriptor {
module: descriptor.vertexStage.module.id().0,
entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()),
@ -991,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");
@ -1000,8 +1046,8 @@ impl GPUDeviceMethods for GPUDevice {
GPURenderPipeline::new(
&self.global(),
render_pipeline,
self.device,
descriptor.parent.parent.label.as_ref().cloned(),
bgls,
)
}