mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
webgpu: Move actual Create* implementations from GPUDevice
to Self (#33320)
* Move actual Create* implementations from `GPUDevice` to Self Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * move Create*Pipeline to Self::create Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * `parse_render_pipeline` outside`GPURenderPipeline::create` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
312cf0df08
commit
ebed9218f2
14 changed files with 594 additions and 486 deletions
|
@ -2,16 +2,23 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* 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 std::borrow::Cow;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use webgpu::wgc::binding_model::BindGroupDescriptor;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroup, WebGPUDevice, WebGPURequest};
|
use webgpu::{WebGPU, WebGPUBindGroup, WebGPUDevice, WebGPURequest};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUBindGroupMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
GPUBindGroupDescriptor, GPUBindGroupMethods,
|
||||||
|
};
|
||||||
|
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::gpubindgrouplayout::GPUBindGroupLayout;
|
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||||
|
use crate::dom::gpuconvert::convert_label;
|
||||||
|
use crate::dom::gpudevice::GPUDevice;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUBindGroup {
|
pub struct GPUBindGroup {
|
||||||
|
@ -66,6 +73,49 @@ impl GPUBindGroup {
|
||||||
pub fn id(&self) -> &WebGPUBindGroup {
|
pub fn id(&self) -> &WebGPUBindGroup {
|
||||||
&self.bind_group
|
&self.bind_group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUBindGroupDescriptor,
|
||||||
|
) -> DomRoot<GPUBindGroup> {
|
||||||
|
let entries = descriptor
|
||||||
|
.entries
|
||||||
|
.iter()
|
||||||
|
.map(|bind| bind.into())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let desc = BindGroupDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
layout: descriptor.layout.id().0,
|
||||||
|
entries: Cow::Owned(entries),
|
||||||
|
};
|
||||||
|
|
||||||
|
let bind_group_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_bind_group_id(device.id().0.backend());
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateBindGroup {
|
||||||
|
device_id: device.id().0,
|
||||||
|
bind_group_id,
|
||||||
|
descriptor: desc,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU BindGroup");
|
||||||
|
|
||||||
|
let bind_group = WebGPUBindGroup(bind_group_id);
|
||||||
|
|
||||||
|
GPUBindGroup::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
bind_group,
|
||||||
|
device.id(),
|
||||||
|
&descriptor.layout,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for GPUBindGroup {
|
impl Drop for GPUBindGroup {
|
||||||
|
|
|
@ -2,15 +2,23 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* 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 std::borrow::Cow;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use webgpu::wgc::binding_model::BindGroupLayoutDescriptor;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURequest};
|
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURequest};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUBindGroupLayoutMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
GPUBindGroupLayoutDescriptor, GPUBindGroupLayoutMethods,
|
||||||
|
};
|
||||||
|
use crate::dom::bindings::error::Fallible;
|
||||||
|
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::gpuconvert::{convert_bind_group_layout_entry, convert_label};
|
||||||
|
use crate::dom::gpudevice::GPUDevice;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUBindGroupLayout {
|
pub struct GPUBindGroupLayout {
|
||||||
|
@ -58,6 +66,52 @@ impl GPUBindGroupLayout {
|
||||||
pub fn id(&self) -> WebGPUBindGroupLayout {
|
pub fn id(&self) -> WebGPUBindGroupLayout {
|
||||||
self.bind_group_layout
|
self.bind_group_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUBindGroupLayoutDescriptor,
|
||||||
|
) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
||||||
|
let entries = descriptor
|
||||||
|
.entries
|
||||||
|
.iter()
|
||||||
|
.map(|bgle| convert_bind_group_layout_entry(bgle, device))
|
||||||
|
.collect::<Fallible<Result<Vec<_>, _>>>()?;
|
||||||
|
|
||||||
|
let desc = match entries {
|
||||||
|
Ok(entries) => Some(BindGroupLayoutDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
entries: Cow::Owned(entries),
|
||||||
|
}),
|
||||||
|
Err(error) => {
|
||||||
|
device.dispatch_error(error);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let bind_group_layout_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_bind_group_layout_id(device.id().0.backend());
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateBindGroupLayout {
|
||||||
|
device_id: device.id().0,
|
||||||
|
bind_group_layout_id,
|
||||||
|
descriptor: desc,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU BindGroupLayout");
|
||||||
|
|
||||||
|
let bgl = WebGPUBindGroupLayout(bind_group_layout_id);
|
||||||
|
|
||||||
|
Ok(GPUBindGroupLayout::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
bgl,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for GPUBindGroupLayout {
|
impl Drop for GPUBindGroupLayout {
|
||||||
|
|
|
@ -14,14 +14,15 @@ use webgpu::{wgt, Mapping, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse};
|
||||||
|
|
||||||
use super::bindings::buffer_source::DataBlock;
|
use super::bindings::buffer_source::DataBlock;
|
||||||
use super::bindings::codegen::Bindings::WebGPUBinding::{
|
use super::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUBufferMapState, GPUFlagsConstant, GPUMapModeFlags,
|
GPUBufferDescriptor, GPUBufferMapState, GPUFlagsConstant, GPUMapModeFlags,
|
||||||
};
|
};
|
||||||
|
use super::gpuconvert::convert_label;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUBufferMethods, GPUMapModeConstants, GPUSize64,
|
GPUBufferMethods, GPUMapModeConstants, GPUSize64,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::error::{Error, Fallible};
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
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;
|
||||||
|
@ -130,6 +131,54 @@ impl GPUBuffer {
|
||||||
pub fn id(&self) -> WebGPUBuffer {
|
pub fn id(&self) -> WebGPUBuffer {
|
||||||
self.buffer
|
self.buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUBufferDescriptor,
|
||||||
|
) -> Fallible<DomRoot<GPUBuffer>> {
|
||||||
|
let desc = wgt::BufferDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
size: descriptor.size as wgt::BufferAddress,
|
||||||
|
usage: wgt::BufferUsages::from_bits_retain(descriptor.usage),
|
||||||
|
mapped_at_creation: descriptor.mappedAtCreation,
|
||||||
|
};
|
||||||
|
let id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_buffer_id(device.id().0.backend());
|
||||||
|
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateBuffer {
|
||||||
|
device_id: device.id().0,
|
||||||
|
buffer_id: id,
|
||||||
|
descriptor: desc,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU buffer");
|
||||||
|
|
||||||
|
let buffer = WebGPUBuffer(id);
|
||||||
|
let mapping = if descriptor.mappedAtCreation {
|
||||||
|
Some(ActiveBufferMapping::new(
|
||||||
|
GPUMapModeConstants::WRITE,
|
||||||
|
0..descriptor.size,
|
||||||
|
)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(GPUBuffer::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
buffer,
|
||||||
|
device,
|
||||||
|
descriptor.size,
|
||||||
|
descriptor.usage,
|
||||||
|
mapping,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for GPUBuffer {
|
impl Drop for GPUBuffer {
|
||||||
|
|
|
@ -4,15 +4,18 @@
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::wgc::command as wgpu_com;
|
use webgpu::wgc::command as wgpu_com;
|
||||||
use webgpu::wgt::Color;
|
use webgpu::{
|
||||||
use webgpu::{self, wgt, WebGPU, WebGPUComputePass, WebGPURenderPass, WebGPURequest};
|
wgt, WebGPU, WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePass, WebGPUDevice,
|
||||||
|
WebGPURenderPass, WebGPURequest,
|
||||||
|
};
|
||||||
|
|
||||||
use super::bindings::error::Fallible;
|
use super::bindings::error::Fallible;
|
||||||
use super::gpuconvert::convert_label;
|
use super::gpuconvert::convert_label;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUCommandBufferDescriptor, GPUCommandEncoderMethods, GPUComputePassDescriptor, GPUExtent3D,
|
GPUCommandBufferDescriptor, GPUCommandEncoderDescriptor, GPUCommandEncoderMethods,
|
||||||
GPUImageCopyBuffer, GPUImageCopyTexture, GPURenderPassDescriptor, GPUSize64,
|
GPUComputePassDescriptor, GPUExtent3D, GPUImageCopyBuffer, GPUImageCopyTexture,
|
||||||
|
GPURenderPassDescriptor, GPUSize64,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
|
@ -33,7 +36,7 @@ pub struct GPUCommandEncoder {
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
label: DomRefCell<USVString>,
|
label: DomRefCell<USVString>,
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
encoder: webgpu::WebGPUCommandEncoder,
|
encoder: WebGPUCommandEncoder,
|
||||||
device: Dom<GPUDevice>,
|
device: Dom<GPUDevice>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ impl GPUCommandEncoder {
|
||||||
pub fn new_inherited(
|
pub fn new_inherited(
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
device: &GPUDevice,
|
device: &GPUDevice,
|
||||||
encoder: webgpu::WebGPUCommandEncoder,
|
encoder: WebGPUCommandEncoder,
|
||||||
label: USVString,
|
label: USVString,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -57,7 +60,7 @@ impl GPUCommandEncoder {
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
device: &GPUDevice,
|
device: &GPUDevice,
|
||||||
encoder: webgpu::WebGPUCommandEncoder,
|
encoder: WebGPUCommandEncoder,
|
||||||
label: USVString,
|
label: USVString,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
|
@ -70,13 +73,45 @@ impl GPUCommandEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUCommandEncoder {
|
impl GPUCommandEncoder {
|
||||||
pub fn id(&self) -> webgpu::WebGPUCommandEncoder {
|
pub fn id(&self) -> WebGPUCommandEncoder {
|
||||||
self.encoder
|
self.encoder
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn device_id(&self) -> webgpu::WebGPUDevice {
|
pub fn device_id(&self) -> WebGPUDevice {
|
||||||
self.device.id()
|
self.device.id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcommandencoder>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUCommandEncoderDescriptor,
|
||||||
|
) -> DomRoot<GPUCommandEncoder> {
|
||||||
|
let command_encoder_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_command_encoder_id(device.id().0.backend());
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateCommandEncoder {
|
||||||
|
device_id: device.id().0,
|
||||||
|
command_encoder_id,
|
||||||
|
desc: wgt::CommandEncoderDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU command encoder");
|
||||||
|
|
||||||
|
let encoder = WebGPUCommandEncoder(command_encoder_id);
|
||||||
|
|
||||||
|
GPUCommandEncoder::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
device,
|
||||||
|
encoder,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
|
@ -283,7 +318,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
})
|
})
|
||||||
.expect("Failed to send Finish");
|
.expect("Failed to send Finish");
|
||||||
|
|
||||||
let buffer = webgpu::WebGPUCommandBuffer(self.encoder.0.into_command_buffer_id());
|
let buffer = WebGPUCommandBuffer(self.encoder.0.into_command_buffer_id());
|
||||||
GPUCommandBuffer::new(
|
GPUCommandBuffer::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
self.channel.clone(),
|
self.channel.clone(),
|
||||||
|
|
|
@ -3,16 +3,21 @@
|
||||||
* 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 dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPURequest};
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use webgpu::wgc::pipeline::ComputePipelineDescriptor;
|
||||||
|
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPURequest, WebGPUResponse};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUComputePipelineMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
|
GPUComputePipelineDescriptor, GPUComputePipelineMethods,
|
||||||
|
};
|
||||||
use crate::dom::bindings::error::Fallible;
|
use crate::dom::bindings::error::Fallible;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
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::gpubindgrouplayout::GPUBindGroupLayout;
|
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||||
|
use crate::dom::gpuconvert::convert_label;
|
||||||
use crate::dom::gpudevice::GPUDevice;
|
use crate::dom::gpudevice::GPUDevice;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -63,6 +68,41 @@ impl GPUComputePipeline {
|
||||||
pub fn id(&self) -> &WebGPUComputePipeline {
|
pub fn id(&self) -> &WebGPUComputePipeline {
|
||||||
&self.compute_pipeline
|
&self.compute_pipeline
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUComputePipelineDescriptor,
|
||||||
|
async_sender: Option<IpcSender<WebGPUResponse>>,
|
||||||
|
) -> WebGPUComputePipeline {
|
||||||
|
let compute_pipeline_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_compute_pipeline_id(device.id().0.backend());
|
||||||
|
|
||||||
|
let (layout, implicit_ids, _) = device.get_pipeline_layout_data(&descriptor.parent.layout);
|
||||||
|
|
||||||
|
let desc = ComputePipelineDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent.parent),
|
||||||
|
layout,
|
||||||
|
stage: (&descriptor.compute).into(),
|
||||||
|
cache: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateComputePipeline {
|
||||||
|
device_id: device.id().0,
|
||||||
|
compute_pipeline_id,
|
||||||
|
descriptor: desc,
|
||||||
|
implicit_ids,
|
||||||
|
async_sender,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU ComputePipeline");
|
||||||
|
|
||||||
|
WebGPUComputePipeline(compute_pipeline_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUComputePipelineMethods for GPUComputePipeline {
|
impl GPUComputePipelineMethods for GPUComputePipeline {
|
||||||
|
|
|
@ -5,20 +5,23 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
|
use webgpu::wgc::binding_model::{BindGroupEntry, BindingResource, BufferBinding};
|
||||||
use webgpu::wgc::command as wgpu_com;
|
use webgpu::wgc::command as wgpu_com;
|
||||||
use webgpu::wgc::pipeline::ProgrammableStageDescriptor;
|
use webgpu::wgc::pipeline::ProgrammableStageDescriptor;
|
||||||
use webgpu::wgt::{self, AstcBlock, AstcChannel};
|
use webgpu::wgt::{self, AstcBlock, AstcChannel};
|
||||||
|
|
||||||
use super::bindings::codegen::Bindings::WebGPUBinding::GPUProgrammableStage;
|
use super::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
|
GPUProgrammableStage, GPUTextureDimension,
|
||||||
|
};
|
||||||
use super::bindings::error::Error;
|
use super::bindings::error::Error;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUAddressMode, GPUBindGroupLayoutEntry, GPUBlendComponent, GPUBlendFactor, GPUBlendOperation,
|
GPUAddressMode, GPUBindGroupEntry, GPUBindGroupLayoutEntry, GPUBindingResource,
|
||||||
GPUBufferBindingType, GPUColor, GPUCompareFunction, GPUCullMode, GPUExtent3D, GPUFilterMode,
|
GPUBlendComponent, GPUBlendFactor, GPUBlendOperation, GPUBufferBindingType, GPUColor,
|
||||||
GPUFrontFace, GPUImageCopyBuffer, GPUImageCopyTexture, GPUImageDataLayout, GPUIndexFormat,
|
GPUCompareFunction, GPUCullMode, GPUExtent3D, GPUFilterMode, GPUFrontFace, GPUImageCopyBuffer,
|
||||||
GPULoadOp, GPUObjectDescriptorBase, GPUOrigin3D, GPUPrimitiveState, GPUPrimitiveTopology,
|
GPUImageCopyTexture, GPUImageDataLayout, GPUIndexFormat, GPULoadOp, GPUObjectDescriptorBase,
|
||||||
GPUSamplerBindingType, GPUStencilOperation, GPUStorageTextureAccess, GPUStoreOp,
|
GPUOrigin3D, GPUPrimitiveState, GPUPrimitiveTopology, GPUSamplerBindingType,
|
||||||
GPUTextureAspect, GPUTextureFormat, GPUTextureSampleType, GPUTextureViewDimension,
|
GPUStencilOperation, GPUStorageTextureAccess, GPUStoreOp, GPUTextureAspect, GPUTextureFormat,
|
||||||
GPUVertexFormat,
|
GPUTextureSampleType, GPUTextureViewDimension, GPUVertexFormat,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::error::Fallible;
|
use crate::dom::bindings::error::Fallible;
|
||||||
use crate::dom::types::GPUDevice;
|
use crate::dom::types::GPUDevice;
|
||||||
|
@ -624,3 +627,32 @@ impl<'a> From<&GPUProgrammableStage> for ProgrammableStageDescriptor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&GPUBindGroupEntry> for BindGroupEntry<'_> {
|
||||||
|
fn from(entry: &GPUBindGroupEntry) -> Self {
|
||||||
|
Self {
|
||||||
|
binding: entry.binding,
|
||||||
|
resource: match entry.resource {
|
||||||
|
GPUBindingResource::GPUSampler(ref s) => BindingResource::Sampler(s.id().0),
|
||||||
|
GPUBindingResource::GPUTextureView(ref t) => BindingResource::TextureView(t.id().0),
|
||||||
|
GPUBindingResource::GPUBufferBinding(ref b) => {
|
||||||
|
BindingResource::Buffer(BufferBinding {
|
||||||
|
buffer_id: b.buffer.id().0,
|
||||||
|
offset: b.offset,
|
||||||
|
size: b.size.and_then(wgt::BufferSize::new),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<GPUTextureDimension> for wgt::TextureDimension {
|
||||||
|
fn from(dimension: GPUTextureDimension) -> Self {
|
||||||
|
match dimension {
|
||||||
|
GPUTextureDimension::_1d => wgt::TextureDimension::D1,
|
||||||
|
GPUTextureDimension::_2d => wgt::TextureDimension::D2,
|
||||||
|
GPUTextureDimension::_3d => wgt::TextureDimension::D3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,23 +11,18 @@ use std::rc::Rc;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use js::jsapi::{Heap, JSObject};
|
use js::jsapi::{Heap, JSObject};
|
||||||
use webgpu::wgc::id::{BindGroupLayoutId, PipelineLayoutId};
|
use webgpu::wgc::id::{BindGroupLayoutId, PipelineLayoutId};
|
||||||
|
use webgpu::wgc::pipeline as wgpu_pipe;
|
||||||
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
||||||
use webgpu::wgc::{
|
use webgpu::wgt::TextureFormat;
|
||||||
binding_model as wgpu_bind, command as wgpu_com, pipeline as wgpu_pipe, resource as wgpu_res,
|
|
||||||
};
|
|
||||||
use webgpu::wgt::{BlendComponent, TextureFormat};
|
|
||||||
use webgpu::{
|
use webgpu::{
|
||||||
self, wgt, PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest,
|
wgt, PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest,
|
||||||
WebGPUResponse,
|
WebGPUResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::bindings::codegen::Bindings::WebGPUBinding::{
|
use super::bindings::codegen::Bindings::WebGPUBinding::{GPUPipelineErrorReason, GPUTextureFormat};
|
||||||
GPUMapModeConstants, GPUPipelineErrorReason, GPUTextureFormat,
|
|
||||||
};
|
|
||||||
use super::bindings::codegen::UnionTypes::GPUPipelineLayoutOrGPUAutoLayoutMode;
|
use super::bindings::codegen::UnionTypes::GPUPipelineLayoutOrGPUAutoLayoutMode;
|
||||||
use super::bindings::error::Fallible;
|
use super::bindings::error::Fallible;
|
||||||
use super::gpu::AsyncWGPUListener;
|
use super::gpu::AsyncWGPUListener;
|
||||||
use super::gpuconvert::convert_bind_group_layout_entry;
|
|
||||||
use super::gpudevicelostinfo::GPUDeviceLostInfo;
|
use super::gpudevicelostinfo::GPUDeviceLostInfo;
|
||||||
use super::gpupipelineerror::GPUPipelineError;
|
use super::gpupipelineerror::GPUPipelineError;
|
||||||
use super::gpusupportedlimits::GPUSupportedLimits;
|
use super::gpusupportedlimits::GPUSupportedLimits;
|
||||||
|
@ -36,12 +31,12 @@ 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::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUBindGroupDescriptor, GPUBindGroupLayoutDescriptor, GPUBindingResource, GPUBufferDescriptor,
|
GPUBindGroupDescriptor, GPUBindGroupLayoutDescriptor, GPUBufferDescriptor,
|
||||||
GPUCommandEncoderDescriptor, GPUComputePipelineDescriptor, GPUDeviceLostReason,
|
GPUCommandEncoderDescriptor, GPUComputePipelineDescriptor, GPUDeviceLostReason,
|
||||||
GPUDeviceMethods, GPUErrorFilter, GPUPipelineLayoutDescriptor,
|
GPUDeviceMethods, GPUErrorFilter, GPUPipelineLayoutDescriptor,
|
||||||
GPURenderBundleEncoderDescriptor, GPURenderPipelineDescriptor, GPUSamplerDescriptor,
|
GPURenderBundleEncoderDescriptor, GPURenderPipelineDescriptor, GPUSamplerDescriptor,
|
||||||
GPUShaderModuleDescriptor, GPUSupportedLimitsMethods, GPUTextureDescriptor,
|
GPUShaderModuleDescriptor, GPUSupportedLimitsMethods, GPUTextureDescriptor,
|
||||||
GPUTextureDimension, GPUUncapturedErrorEventInit, GPUVertexStepMode,
|
GPUUncapturedErrorEventInit, GPUVertexStepMode,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::error::Error;
|
use crate::dom::bindings::error::Error;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
|
@ -54,7 +49,7 @@ use crate::dom::gpu::response_async;
|
||||||
use crate::dom::gpuadapter::GPUAdapter;
|
use crate::dom::gpuadapter::GPUAdapter;
|
||||||
use crate::dom::gpubindgroup::GPUBindGroup;
|
use crate::dom::gpubindgroup::GPUBindGroup;
|
||||||
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||||
use crate::dom::gpubuffer::{ActiveBufferMapping, GPUBuffer};
|
use crate::dom::gpubuffer::GPUBuffer;
|
||||||
use crate::dom::gpucommandencoder::GPUCommandEncoder;
|
use crate::dom::gpucommandencoder::GPUCommandEncoder;
|
||||||
use crate::dom::gpucomputepipeline::GPUComputePipeline;
|
use crate::dom::gpucomputepipeline::GPUComputePipeline;
|
||||||
use crate::dom::gpuconvert::convert_label;
|
use crate::dom::gpuconvert::convert_label;
|
||||||
|
@ -211,7 +206,7 @@ impl GPUDevice {
|
||||||
self.lost_promise.borrow().is_fulfilled()
|
self.lost_promise.borrow().is_fulfilled()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_pipeline_layout_data(
|
pub fn get_pipeline_layout_data(
|
||||||
&self,
|
&self,
|
||||||
layout: &GPUPipelineLayoutOrGPUAutoLayoutMode,
|
layout: &GPUPipelineLayoutOrGPUAutoLayoutMode,
|
||||||
) -> (
|
) -> (
|
||||||
|
@ -241,7 +236,7 @@ impl GPUDevice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_render_pipeline<'a>(
|
pub fn parse_render_pipeline<'a>(
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPURenderPipelineDescriptor,
|
descriptor: &GPURenderPipelineDescriptor,
|
||||||
) -> Fallible<(
|
) -> Fallible<(
|
||||||
|
@ -401,46 +396,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer>
|
||||||
fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> Fallible<DomRoot<GPUBuffer>> {
|
fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> Fallible<DomRoot<GPUBuffer>> {
|
||||||
let desc = wgpu_res::BufferDescriptor {
|
GPUBuffer::create(self, descriptor)
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
size: descriptor.size as wgt::BufferAddress,
|
|
||||||
usage: wgt::BufferUsages::from_bits_retain(descriptor.usage),
|
|
||||||
mapped_at_creation: descriptor.mappedAtCreation,
|
|
||||||
};
|
|
||||||
let id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_buffer_id(self.device.0.backend());
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateBuffer {
|
|
||||||
device_id: self.device.0,
|
|
||||||
buffer_id: id,
|
|
||||||
descriptor: desc,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU buffer");
|
|
||||||
|
|
||||||
let buffer = webgpu::WebGPUBuffer(id);
|
|
||||||
let mapping = if descriptor.mappedAtCreation {
|
|
||||||
Some(ActiveBufferMapping::new(
|
|
||||||
GPUMapModeConstants::WRITE,
|
|
||||||
0..descriptor.size,
|
|
||||||
)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(GPUBuffer::new(
|
|
||||||
&self.global(),
|
|
||||||
self.channel.clone(),
|
|
||||||
buffer,
|
|
||||||
self,
|
|
||||||
descriptor.size,
|
|
||||||
descriptor.usage,
|
|
||||||
mapping,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
|
/// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
|
||||||
|
@ -449,44 +405,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPUBindGroupLayoutDescriptor,
|
descriptor: &GPUBindGroupLayoutDescriptor,
|
||||||
) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
||||||
let entries = descriptor
|
GPUBindGroupLayout::create(self, descriptor)
|
||||||
.entries
|
|
||||||
.iter()
|
|
||||||
.map(|bgle| convert_bind_group_layout_entry(bgle, &self))
|
|
||||||
.collect::<Fallible<Result<Vec<_>, _>>>()?;
|
|
||||||
|
|
||||||
let desc = match entries {
|
|
||||||
Ok(entries) => Some(wgpu_bind::BindGroupLayoutDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
entries: Cow::Owned(entries),
|
|
||||||
}),
|
|
||||||
Err(error) => {
|
|
||||||
self.dispatch_error(error);
|
|
||||||
None
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let bind_group_layout_id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_bind_group_layout_id(self.device.0.backend());
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateBindGroupLayout {
|
|
||||||
device_id: self.device.0,
|
|
||||||
bind_group_layout_id,
|
|
||||||
descriptor: desc,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU BindGroupLayout");
|
|
||||||
|
|
||||||
let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id);
|
|
||||||
|
|
||||||
Ok(GPUBindGroupLayout::new(
|
|
||||||
&self.global(),
|
|
||||||
self.channel.clone(),
|
|
||||||
bgl,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
|
||||||
|
@ -494,100 +413,12 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPUPipelineLayoutDescriptor,
|
descriptor: &GPUPipelineLayoutDescriptor,
|
||||||
) -> DomRoot<GPUPipelineLayout> {
|
) -> DomRoot<GPUPipelineLayout> {
|
||||||
let desc = wgpu_bind::PipelineLayoutDescriptor {
|
GPUPipelineLayout::create(self, descriptor)
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
bind_group_layouts: Cow::Owned(
|
|
||||||
descriptor
|
|
||||||
.bindGroupLayouts
|
|
||||||
.iter()
|
|
||||||
.map(|each| each.id().0)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
),
|
|
||||||
push_constant_ranges: Cow::Owned(vec![]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let pipeline_layout_id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_pipeline_layout_id(self.device.0.backend());
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreatePipelineLayout {
|
|
||||||
device_id: self.device.0,
|
|
||||||
pipeline_layout_id,
|
|
||||||
descriptor: desc,
|
|
||||||
})
|
|
||||||
.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(),
|
|
||||||
self.channel.clone(),
|
|
||||||
pipeline_layout,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
bgls,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
|
||||||
fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> {
|
fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> {
|
||||||
let entries = descriptor
|
GPUBindGroup::create(self, descriptor)
|
||||||
.entries
|
|
||||||
.iter()
|
|
||||||
.map(|bind| wgpu_bind::BindGroupEntry {
|
|
||||||
binding: bind.binding,
|
|
||||||
resource: match bind.resource {
|
|
||||||
GPUBindingResource::GPUSampler(ref s) => {
|
|
||||||
wgpu_bind::BindingResource::Sampler(s.id().0)
|
|
||||||
},
|
|
||||||
GPUBindingResource::GPUTextureView(ref t) => {
|
|
||||||
wgpu_bind::BindingResource::TextureView(t.id().0)
|
|
||||||
},
|
|
||||||
GPUBindingResource::GPUBufferBinding(ref b) => {
|
|
||||||
wgpu_bind::BindingResource::Buffer(wgpu_bind::BufferBinding {
|
|
||||||
buffer_id: b.buffer.id().0,
|
|
||||||
offset: b.offset,
|
|
||||||
size: b.size.and_then(wgt::BufferSize::new),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let desc = wgpu_bind::BindGroupDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
layout: descriptor.layout.id().0,
|
|
||||||
entries: Cow::Owned(entries),
|
|
||||||
};
|
|
||||||
|
|
||||||
let bind_group_id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_bind_group_id(self.device.0.backend());
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateBindGroup {
|
|
||||||
device_id: self.device.0,
|
|
||||||
bind_group_id,
|
|
||||||
descriptor: desc,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU BindGroup");
|
|
||||||
|
|
||||||
let bind_group = webgpu::WebGPUBindGroup(bind_group_id);
|
|
||||||
|
|
||||||
GPUBindGroup::new(
|
|
||||||
&self.global(),
|
|
||||||
self.channel.clone(),
|
|
||||||
bind_group,
|
|
||||||
self.device,
|
|
||||||
&descriptor.layout,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule>
|
||||||
|
@ -596,30 +427,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>,
|
descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>,
|
||||||
comp: InRealm,
|
comp: InRealm,
|
||||||
) -> DomRoot<GPUShaderModule> {
|
) -> DomRoot<GPUShaderModule> {
|
||||||
let program_id = self
|
GPUShaderModule::create(self, descriptor, comp)
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_shader_module_id(self.device.0.backend());
|
|
||||||
let promise = Promise::new_in_current_realm(comp);
|
|
||||||
let shader_module = GPUShaderModule::new(
|
|
||||||
&self.global(),
|
|
||||||
self.channel.clone(),
|
|
||||||
webgpu::WebGPUShaderModule(program_id),
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
promise.clone(),
|
|
||||||
);
|
|
||||||
let sender = response_async(&promise, &*shader_module);
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateShaderModule {
|
|
||||||
device_id: self.device.0,
|
|
||||||
program_id,
|
|
||||||
program: descriptor.code.0.clone(),
|
|
||||||
label: None,
|
|
||||||
sender,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU ShaderModule");
|
|
||||||
shader_module
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline>
|
||||||
|
@ -627,32 +435,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPUComputePipelineDescriptor,
|
descriptor: &GPUComputePipelineDescriptor,
|
||||||
) -> DomRoot<GPUComputePipeline> {
|
) -> DomRoot<GPUComputePipeline> {
|
||||||
let compute_pipeline_id = self
|
let compute_pipeline = GPUComputePipeline::create(self, descriptor, None);
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_compute_pipeline_id(self.device.0.backend());
|
|
||||||
|
|
||||||
let (layout, implicit_ids, _) = self.get_pipeline_layout_data(&descriptor.parent.layout);
|
|
||||||
|
|
||||||
let desc = wgpu_pipe::ComputePipelineDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent.parent),
|
|
||||||
layout,
|
|
||||||
stage: (&descriptor.compute).into(),
|
|
||||||
cache: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateComputePipeline {
|
|
||||||
device_id: self.device.0,
|
|
||||||
compute_pipeline_id,
|
|
||||||
descriptor: desc,
|
|
||||||
implicit_ids,
|
|
||||||
async_sender: None,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU ComputePipeline");
|
|
||||||
|
|
||||||
let compute_pipeline = webgpu::WebGPUComputePipeline(compute_pipeline_id);
|
|
||||||
GPUComputePipeline::new(
|
GPUComputePipeline::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
compute_pipeline,
|
compute_pipeline,
|
||||||
|
@ -669,30 +452,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
let promise = Promise::new_in_current_realm(comp);
|
let promise = Promise::new_in_current_realm(comp);
|
||||||
let sender = response_async(&promise, self);
|
let sender = response_async(&promise, self);
|
||||||
let compute_pipeline_id = self
|
GPUComputePipeline::create(self, descriptor, Some(sender));
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_compute_pipeline_id(self.device.0.backend());
|
|
||||||
|
|
||||||
let (layout, implicit_ids, _) = self.get_pipeline_layout_data(&descriptor.parent.layout);
|
|
||||||
|
|
||||||
let desc = wgpu_pipe::ComputePipelineDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent.parent),
|
|
||||||
layout,
|
|
||||||
stage: (&descriptor.compute).into(),
|
|
||||||
cache: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateComputePipeline {
|
|
||||||
device_id: self.device.0,
|
|
||||||
compute_pipeline_id,
|
|
||||||
descriptor: desc,
|
|
||||||
implicit_ids,
|
|
||||||
async_sender: Some(sender),
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU ComputePipeline");
|
|
||||||
promise
|
promise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,130 +461,17 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPUCommandEncoderDescriptor,
|
descriptor: &GPUCommandEncoderDescriptor,
|
||||||
) -> DomRoot<GPUCommandEncoder> {
|
) -> DomRoot<GPUCommandEncoder> {
|
||||||
let command_encoder_id = self
|
GPUCommandEncoder::create(self, descriptor)
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_command_encoder_id(self.device.0.backend());
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateCommandEncoder {
|
|
||||||
device_id: self.device.0,
|
|
||||||
command_encoder_id,
|
|
||||||
desc: wgt::CommandEncoderDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU command encoder");
|
|
||||||
|
|
||||||
let encoder = webgpu::WebGPUCommandEncoder(command_encoder_id);
|
|
||||||
|
|
||||||
GPUCommandEncoder::new(
|
|
||||||
&self.global(),
|
|
||||||
self.channel.clone(),
|
|
||||||
self,
|
|
||||||
encoder,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
|
||||||
fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> {
|
fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> {
|
||||||
let size = (&descriptor.size).try_into()?;
|
GPUTexture::create(self, descriptor)
|
||||||
let desc = wgpu_res::TextureDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
size,
|
|
||||||
mip_level_count: descriptor.mipLevelCount,
|
|
||||||
sample_count: descriptor.sampleCount,
|
|
||||||
dimension: match descriptor.dimension {
|
|
||||||
GPUTextureDimension::_1d => wgt::TextureDimension::D1,
|
|
||||||
GPUTextureDimension::_2d => wgt::TextureDimension::D2,
|
|
||||||
GPUTextureDimension::_3d => wgt::TextureDimension::D3,
|
|
||||||
},
|
|
||||||
format: self.validate_texture_format_required_features(&descriptor.format)?,
|
|
||||||
usage: wgt::TextureUsages::from_bits_retain(descriptor.usage),
|
|
||||||
view_formats: descriptor
|
|
||||||
.viewFormats
|
|
||||||
.iter()
|
|
||||||
.map(|tf| self.validate_texture_format_required_features(tf))
|
|
||||||
.collect::<Fallible<_>>()?,
|
|
||||||
};
|
|
||||||
|
|
||||||
let texture_id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_texture_id(self.device.0.backend());
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateTexture {
|
|
||||||
device_id: self.device.0,
|
|
||||||
texture_id,
|
|
||||||
descriptor: desc,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU Texture");
|
|
||||||
|
|
||||||
let texture = webgpu::WebGPUTexture(texture_id);
|
|
||||||
|
|
||||||
Ok(GPUTexture::new(
|
|
||||||
&self.global(),
|
|
||||||
texture,
|
|
||||||
self,
|
|
||||||
self.channel.clone(),
|
|
||||||
size,
|
|
||||||
descriptor.mipLevelCount,
|
|
||||||
descriptor.sampleCount,
|
|
||||||
descriptor.dimension,
|
|
||||||
descriptor.format,
|
|
||||||
descriptor.usage,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler>
|
||||||
fn CreateSampler(&self, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
|
fn CreateSampler(&self, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
|
||||||
let sampler_id = self
|
GPUSampler::create(self, descriptor)
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_sampler_id(self.device.0.backend());
|
|
||||||
let compare_enable = descriptor.compare.is_some();
|
|
||||||
let desc = wgpu_res::SamplerDescriptor {
|
|
||||||
label: convert_label(&descriptor.parent),
|
|
||||||
address_modes: [
|
|
||||||
descriptor.addressModeU.into(),
|
|
||||||
descriptor.addressModeV.into(),
|
|
||||||
descriptor.addressModeW.into(),
|
|
||||||
],
|
|
||||||
mag_filter: descriptor.magFilter.into(),
|
|
||||||
min_filter: descriptor.minFilter.into(),
|
|
||||||
mipmap_filter: descriptor.mipmapFilter.into(),
|
|
||||||
lod_min_clamp: *descriptor.lodMinClamp,
|
|
||||||
lod_max_clamp: *descriptor.lodMaxClamp,
|
|
||||||
compare: descriptor
|
|
||||||
.compare
|
|
||||||
.map(|gpu_compare_function| gpu_compare_function.into()),
|
|
||||||
anisotropy_clamp: 1,
|
|
||||||
border_color: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateSampler {
|
|
||||||
device_id: self.device.0,
|
|
||||||
sampler_id,
|
|
||||||
descriptor: desc,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU sampler");
|
|
||||||
|
|
||||||
let sampler = webgpu::WebGPUSampler(sampler_id);
|
|
||||||
|
|
||||||
GPUSampler::new(
|
|
||||||
&self.global(),
|
|
||||||
self.channel.clone(),
|
|
||||||
self.device,
|
|
||||||
compare_enable,
|
|
||||||
sampler,
|
|
||||||
descriptor.parent.label.clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline>
|
||||||
|
@ -833,25 +480,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
descriptor: &GPURenderPipelineDescriptor,
|
descriptor: &GPURenderPipelineDescriptor,
|
||||||
) -> Fallible<DomRoot<GPURenderPipeline>> {
|
) -> Fallible<DomRoot<GPURenderPipeline>> {
|
||||||
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
|
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
|
||||||
|
let render_pipeline = GPURenderPipeline::create(self, implicit_ids, desc, None)?;
|
||||||
let render_pipeline_id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_render_pipeline_id(self.device.0.backend());
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateRenderPipeline {
|
|
||||||
device_id: self.device.0,
|
|
||||||
render_pipeline_id,
|
|
||||||
descriptor: desc,
|
|
||||||
implicit_ids,
|
|
||||||
async_sender: None,
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU render pipeline");
|
|
||||||
|
|
||||||
let render_pipeline = webgpu::WebGPURenderPipeline(render_pipeline_id);
|
|
||||||
|
|
||||||
Ok(GPURenderPipeline::new(
|
Ok(GPURenderPipeline::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
|
@ -867,26 +496,9 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
comp: InRealm,
|
comp: InRealm,
|
||||||
) -> Fallible<Rc<Promise>> {
|
) -> Fallible<Rc<Promise>> {
|
||||||
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
|
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
|
||||||
|
|
||||||
let promise = Promise::new_in_current_realm(comp);
|
let promise = Promise::new_in_current_realm(comp);
|
||||||
let sender = response_async(&promise, self);
|
let sender = response_async(&promise, self);
|
||||||
|
GPURenderPipeline::create(self, implicit_ids, desc, Some(sender))?;
|
||||||
let render_pipeline_id = self
|
|
||||||
.global()
|
|
||||||
.wgpu_id_hub()
|
|
||||||
.create_render_pipeline_id(self.device.0.backend());
|
|
||||||
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(WebGPURequest::CreateRenderPipeline {
|
|
||||||
device_id: self.device.0,
|
|
||||||
render_pipeline_id,
|
|
||||||
descriptor: desc,
|
|
||||||
implicit_ids,
|
|
||||||
async_sender: Some(sender),
|
|
||||||
})
|
|
||||||
.expect("Failed to create WebGPU render pipeline");
|
|
||||||
|
|
||||||
Ok(promise)
|
Ok(promise)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,46 +507,7 @@ impl GPUDeviceMethods for GPUDevice {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPURenderBundleEncoderDescriptor,
|
descriptor: &GPURenderBundleEncoderDescriptor,
|
||||||
) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
|
) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
|
||||||
let desc = wgpu_com::RenderBundleEncoderDescriptor {
|
GPURenderBundleEncoder::create(self, descriptor)
|
||||||
label: convert_label(&descriptor.parent.parent),
|
|
||||||
color_formats: Cow::Owned(
|
|
||||||
descriptor
|
|
||||||
.parent
|
|
||||||
.colorFormats
|
|
||||||
.iter()
|
|
||||||
.map(|format| {
|
|
||||||
self.validate_texture_format_required_features(format)
|
|
||||||
.map(|f| Some(f))
|
|
||||||
})
|
|
||||||
.collect::<Fallible<Vec<_>>>()?,
|
|
||||||
),
|
|
||||||
depth_stencil: descriptor
|
|
||||||
.parent
|
|
||||||
.depthStencilFormat
|
|
||||||
.map(|dsf| {
|
|
||||||
self.validate_texture_format_required_features(&dsf)
|
|
||||||
.map(|format| wgt::RenderBundleDepthStencil {
|
|
||||||
format,
|
|
||||||
depth_read_only: descriptor.depthReadOnly,
|
|
||||||
stencil_read_only: descriptor.stencilReadOnly,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.transpose()?,
|
|
||||||
sample_count: descriptor.parent.sampleCount,
|
|
||||||
multiview: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle error gracefully
|
|
||||||
let render_bundle_encoder =
|
|
||||||
wgpu_com::RenderBundleEncoder::new(&desc, self.device.0, None).unwrap();
|
|
||||||
|
|
||||||
Ok(GPURenderBundleEncoder::new(
|
|
||||||
&self.global(),
|
|
||||||
render_bundle_encoder,
|
|
||||||
self,
|
|
||||||
self.channel.clone(),
|
|
||||||
descriptor.parent.parent.label.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope>
|
||||||
|
|
|
@ -2,15 +2,22 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* 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 std::borrow::Cow;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use webgpu::wgc::binding_model::PipelineLayoutDescriptor;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUPipelineLayout, WebGPURequest};
|
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUPipelineLayout, WebGPURequest};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUPipelineLayoutMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
GPUPipelineLayoutDescriptor, GPUPipelineLayoutMethods,
|
||||||
|
};
|
||||||
|
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::gpuconvert::convert_label;
|
||||||
|
use crate::dom::gpudevice::GPUDevice;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUPipelineLayout {
|
pub struct GPUPipelineLayout {
|
||||||
|
@ -68,6 +75,47 @@ impl GPUPipelineLayout {
|
||||||
pub fn bind_group_layouts(&self) -> Vec<WebGPUBindGroupLayout> {
|
pub fn bind_group_layouts(&self) -> Vec<WebGPUBindGroupLayout> {
|
||||||
self.bind_group_layouts.clone()
|
self.bind_group_layouts.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUPipelineLayoutDescriptor,
|
||||||
|
) -> DomRoot<GPUPipelineLayout> {
|
||||||
|
let bgls = descriptor
|
||||||
|
.bindGroupLayouts
|
||||||
|
.iter()
|
||||||
|
.map(|each| each.id())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let desc = PipelineLayoutDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
bind_group_layouts: Cow::Owned(bgls.iter().map(|l| l.0).collect::<Vec<_>>()),
|
||||||
|
push_constant_ranges: Cow::Owned(vec![]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pipeline_layout_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_pipeline_layout_id(device.id().0.backend());
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreatePipelineLayout {
|
||||||
|
device_id: device.id().0,
|
||||||
|
pipeline_layout_id,
|
||||||
|
descriptor: desc,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU PipelineLayout");
|
||||||
|
|
||||||
|
let pipeline_layout = WebGPUPipelineLayout(pipeline_layout_id);
|
||||||
|
GPUPipelineLayout::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
pipeline_layout,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
bgls,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUPipelineLayoutMethods for GPUPipelineLayout {
|
impl GPUPipelineLayoutMethods for GPUPipelineLayout {
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::IpcSharedMemory;
|
use ipc_channel::ipc::IpcSharedMemory;
|
||||||
use webgpu::wgt::Extent3d;
|
|
||||||
use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest, WebGPUResponse};
|
use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest, WebGPUResponse};
|
||||||
|
|
||||||
use super::bindings::codegen::Bindings::WebGPUBinding::{GPUImageCopyTexture, GPUImageDataLayout};
|
use super::bindings::codegen::Bindings::WebGPUBinding::{GPUImageCopyTexture, GPUImageDataLayout};
|
||||||
|
|
|
@ -2,15 +2,20 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* 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 std::borrow::Cow;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::wgc::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder};
|
use webgpu::wgc::command::{
|
||||||
|
bundle_ffi as wgpu_bundle, RenderBundleEncoder, RenderBundleEncoderDescriptor,
|
||||||
|
};
|
||||||
use webgpu::{wgt, WebGPU, WebGPURenderBundle, WebGPURequest};
|
use webgpu::{wgt, WebGPU, WebGPURenderBundle, WebGPURequest};
|
||||||
|
|
||||||
use super::bindings::codegen::Bindings::WebGPUBinding::GPUIndexFormat;
|
use super::bindings::codegen::Bindings::WebGPUBinding::GPUIndexFormat;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPURenderBundleDescriptor, GPURenderBundleEncoderMethods,
|
GPURenderBundleDescriptor, GPURenderBundleEncoderDescriptor, GPURenderBundleEncoderMethods,
|
||||||
};
|
};
|
||||||
|
use crate::dom::bindings::import::module::Fallible;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
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;
|
||||||
|
@ -70,6 +75,56 @@ impl GPURenderBundleEncoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GPURenderBundleEncoder {
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderbundleencoder>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPURenderBundleEncoderDescriptor,
|
||||||
|
) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
|
||||||
|
let desc = RenderBundleEncoderDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent.parent),
|
||||||
|
color_formats: Cow::Owned(
|
||||||
|
descriptor
|
||||||
|
.parent
|
||||||
|
.colorFormats
|
||||||
|
.iter()
|
||||||
|
.map(|format| {
|
||||||
|
device
|
||||||
|
.validate_texture_format_required_features(format)
|
||||||
|
.map(|f| Some(f))
|
||||||
|
})
|
||||||
|
.collect::<Fallible<Vec<_>>>()?,
|
||||||
|
),
|
||||||
|
depth_stencil: descriptor
|
||||||
|
.parent
|
||||||
|
.depthStencilFormat
|
||||||
|
.map(|dsf| {
|
||||||
|
device
|
||||||
|
.validate_texture_format_required_features(&dsf)
|
||||||
|
.map(|format| wgt::RenderBundleDepthStencil {
|
||||||
|
format,
|
||||||
|
depth_read_only: descriptor.depthReadOnly,
|
||||||
|
stencil_read_only: descriptor.stencilReadOnly,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.transpose()?,
|
||||||
|
sample_count: descriptor.parent.sampleCount,
|
||||||
|
multiview: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle error gracefully
|
||||||
|
let render_bundle_encoder = RenderBundleEncoder::new(&desc, device.id().0, None).unwrap();
|
||||||
|
|
||||||
|
Ok(GPURenderBundleEncoder::new(
|
||||||
|
&device.global(),
|
||||||
|
render_bundle_encoder,
|
||||||
|
device,
|
||||||
|
device.channel().clone(),
|
||||||
|
descriptor.parent.parent.label.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
|
||||||
fn Label(&self) -> USVString {
|
fn Label(&self) -> USVString {
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
* 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 dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURenderPipeline, WebGPURequest};
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use webgpu::wgc::id::{BindGroupLayoutId, PipelineLayoutId};
|
||||||
|
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
||||||
|
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURenderPipeline, WebGPURequest, WebGPUResponse};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPURenderPipelineMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPURenderPipelineMethods;
|
||||||
|
@ -63,6 +66,33 @@ impl GPURenderPipeline {
|
||||||
pub fn id(&self) -> WebGPURenderPipeline {
|
pub fn id(&self) -> WebGPURenderPipeline {
|
||||||
self.render_pipeline
|
self.render_pipeline
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
implicit_ids: Option<(PipelineLayoutId, Vec<BindGroupLayoutId>)>,
|
||||||
|
descriptor: RenderPipelineDescriptor<'static>,
|
||||||
|
async_sender: Option<IpcSender<WebGPUResponse>>,
|
||||||
|
) -> Fallible<WebGPURenderPipeline> {
|
||||||
|
let render_pipeline_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_render_pipeline_id(device.id().0.backend());
|
||||||
|
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateRenderPipeline {
|
||||||
|
device_id: device.id().0,
|
||||||
|
render_pipeline_id,
|
||||||
|
descriptor,
|
||||||
|
implicit_ids,
|
||||||
|
async_sender,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU render pipeline");
|
||||||
|
|
||||||
|
Ok(WebGPURenderPipeline(render_pipeline_id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPURenderPipelineMethods for GPURenderPipeline {
|
impl GPURenderPipelineMethods for GPURenderPipeline {
|
||||||
|
|
|
@ -3,14 +3,19 @@
|
||||||
* 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 dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use webgpu::wgc::resource::SamplerDescriptor;
|
||||||
use webgpu::{WebGPU, WebGPUDevice, WebGPURequest, WebGPUSampler};
|
use webgpu::{WebGPU, WebGPUDevice, WebGPURequest, WebGPUSampler};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUSamplerMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
GPUSamplerDescriptor, GPUSamplerMethods,
|
||||||
|
};
|
||||||
|
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::gpuconvert::convert_label;
|
||||||
|
use crate::dom::gpudevice::GPUDevice;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUSampler {
|
pub struct GPUSampler {
|
||||||
|
@ -69,6 +74,52 @@ impl GPUSampler {
|
||||||
pub fn id(&self) -> WebGPUSampler {
|
pub fn id(&self) -> WebGPUSampler {
|
||||||
self.sampler
|
self.sampler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler>
|
||||||
|
pub fn create(device: &GPUDevice, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
|
||||||
|
let sampler_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_sampler_id(device.id().0.backend());
|
||||||
|
let compare_enable = descriptor.compare.is_some();
|
||||||
|
let desc = SamplerDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
address_modes: [
|
||||||
|
descriptor.addressModeU.into(),
|
||||||
|
descriptor.addressModeV.into(),
|
||||||
|
descriptor.addressModeW.into(),
|
||||||
|
],
|
||||||
|
mag_filter: descriptor.magFilter.into(),
|
||||||
|
min_filter: descriptor.minFilter.into(),
|
||||||
|
mipmap_filter: descriptor.mipmapFilter.into(),
|
||||||
|
lod_min_clamp: *descriptor.lodMinClamp,
|
||||||
|
lod_max_clamp: *descriptor.lodMaxClamp,
|
||||||
|
compare: descriptor.compare.map(Into::into),
|
||||||
|
anisotropy_clamp: 1,
|
||||||
|
border_color: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateSampler {
|
||||||
|
device_id: device.id().0,
|
||||||
|
sampler_id,
|
||||||
|
descriptor: desc,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU sampler");
|
||||||
|
|
||||||
|
let sampler = WebGPUSampler(sampler_id);
|
||||||
|
|
||||||
|
GPUSampler::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
device.id(),
|
||||||
|
compare_enable,
|
||||||
|
sampler,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUSamplerMethods for GPUSampler {
|
impl GPUSamplerMethods for GPUSampler {
|
||||||
|
|
|
@ -10,12 +10,18 @@ use webgpu::{WebGPU, WebGPURequest, WebGPUResponse, WebGPUShaderModule};
|
||||||
use super::gpu::AsyncWGPUListener;
|
use super::gpu::AsyncWGPUListener;
|
||||||
use super::gpucompilationinfo::GPUCompilationInfo;
|
use super::gpucompilationinfo::GPUCompilationInfo;
|
||||||
use super::promise::Promise;
|
use super::promise::Promise;
|
||||||
|
use super::types::GPUDevice;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUShaderModuleMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
|
GPUShaderModuleDescriptor, GPUShaderModuleMethods,
|
||||||
|
};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, 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::bindings::trace::RootedTraceableBox;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::gpu::response_async;
|
||||||
|
use crate::realms::InRealm;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct GPUShaderModule {
|
pub struct GPUShaderModule {
|
||||||
|
@ -69,6 +75,39 @@ impl GPUShaderModule {
|
||||||
pub fn id(&self) -> WebGPUShaderModule {
|
pub fn id(&self) -> WebGPUShaderModule {
|
||||||
self.shader_module
|
self.shader_module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>,
|
||||||
|
comp: InRealm,
|
||||||
|
) -> DomRoot<GPUShaderModule> {
|
||||||
|
let program_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_shader_module_id(device.id().0.backend());
|
||||||
|
let promise = Promise::new_in_current_realm(comp);
|
||||||
|
let shader_module = GPUShaderModule::new(
|
||||||
|
&device.global(),
|
||||||
|
device.channel().clone(),
|
||||||
|
WebGPUShaderModule(program_id),
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
promise.clone(),
|
||||||
|
);
|
||||||
|
let sender = response_async(&promise, &*shader_module);
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateShaderModule {
|
||||||
|
device_id: device.id().0,
|
||||||
|
program_id,
|
||||||
|
program: descriptor.code.0.clone(),
|
||||||
|
label: None,
|
||||||
|
sender,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU ShaderModule");
|
||||||
|
shader_module
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUShaderModuleMethods for GPUShaderModule {
|
impl GPUShaderModuleMethods for GPUShaderModule {
|
||||||
|
|
|
@ -12,8 +12,8 @@ use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView};
|
||||||
use super::bindings::error::Fallible;
|
use super::bindings::error::Fallible;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUTextureAspect, GPUTextureDimension, GPUTextureFormat, GPUTextureMethods,
|
GPUTextureAspect, GPUTextureDescriptor, GPUTextureDimension, GPUTextureFormat,
|
||||||
GPUTextureViewDescriptor,
|
GPUTextureMethods, GPUTextureViewDescriptor,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
|
@ -128,6 +128,59 @@ impl GPUTexture {
|
||||||
pub fn id(&self) -> WebGPUTexture {
|
pub fn id(&self) -> WebGPUTexture {
|
||||||
self.texture
|
self.texture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
|
||||||
|
pub fn create(
|
||||||
|
device: &GPUDevice,
|
||||||
|
descriptor: &GPUTextureDescriptor,
|
||||||
|
) -> Fallible<DomRoot<GPUTexture>> {
|
||||||
|
let size = (&descriptor.size).try_into()?;
|
||||||
|
let desc = wgt::TextureDescriptor {
|
||||||
|
label: convert_label(&descriptor.parent),
|
||||||
|
size,
|
||||||
|
mip_level_count: descriptor.mipLevelCount,
|
||||||
|
sample_count: descriptor.sampleCount,
|
||||||
|
dimension: descriptor.dimension.into(),
|
||||||
|
format: device.validate_texture_format_required_features(&descriptor.format)?,
|
||||||
|
usage: wgt::TextureUsages::from_bits_retain(descriptor.usage),
|
||||||
|
view_formats: descriptor
|
||||||
|
.viewFormats
|
||||||
|
.iter()
|
||||||
|
.map(|tf| device.validate_texture_format_required_features(tf))
|
||||||
|
.collect::<Fallible<_>>()?,
|
||||||
|
};
|
||||||
|
|
||||||
|
let texture_id = device
|
||||||
|
.global()
|
||||||
|
.wgpu_id_hub()
|
||||||
|
.create_texture_id(device.id().0.backend());
|
||||||
|
|
||||||
|
device
|
||||||
|
.channel()
|
||||||
|
.0
|
||||||
|
.send(WebGPURequest::CreateTexture {
|
||||||
|
device_id: device.id().0,
|
||||||
|
texture_id,
|
||||||
|
descriptor: desc,
|
||||||
|
})
|
||||||
|
.expect("Failed to create WebGPU Texture");
|
||||||
|
|
||||||
|
let texture = WebGPUTexture(texture_id);
|
||||||
|
|
||||||
|
Ok(GPUTexture::new(
|
||||||
|
&device.global(),
|
||||||
|
texture,
|
||||||
|
device,
|
||||||
|
device.channel().clone(),
|
||||||
|
size,
|
||||||
|
descriptor.mipLevelCount,
|
||||||
|
descriptor.sampleCount,
|
||||||
|
descriptor.dimension,
|
||||||
|
descriptor.format,
|
||||||
|
descriptor.usage,
|
||||||
|
descriptor.parent.label.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUTextureMethods for GPUTexture {
|
impl GPUTextureMethods for GPUTexture {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue