mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Update wgpu-core and wgpu-types
This commit is contained in:
parent
00b3f785c4
commit
48ef306bd3
13 changed files with 244 additions and 366 deletions
|
@ -164,10 +164,10 @@ use tendril::{StrTendril, TendrilSink};
|
|||
use time::{Duration, Timespec, Tm};
|
||||
use uuid::Uuid;
|
||||
use webgpu::{
|
||||
wgpu::command::RawPass, WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout,
|
||||
WebGPUBuffer, WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice,
|
||||
WebGPUPipelineLayout, WebGPUQueue, WebGPURenderPipeline, WebGPUSampler, WebGPUShaderModule,
|
||||
WebGPUTexture, WebGPUTextureView,
|
||||
wgpu::command::RawPass, wgpu::id, WebGPU, WebGPUAdapter, WebGPUBindGroup,
|
||||
WebGPUBindGroupLayout, WebGPUBuffer, WebGPUCommandBuffer, WebGPUCommandEncoder,
|
||||
WebGPUComputePipeline, WebGPUDevice, WebGPUPipelineLayout, WebGPUQueue, WebGPURenderPipeline,
|
||||
WebGPUSampler, WebGPUShaderModule, WebGPUTexture, WebGPUTextureView,
|
||||
};
|
||||
use webrender_api::{DocumentId, ExternalImageId, ImageKey};
|
||||
use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||
|
@ -578,7 +578,7 @@ unsafe_no_jsmanaged_fields!(WebGPUContextId);
|
|||
unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer);
|
||||
unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder);
|
||||
unsafe_no_jsmanaged_fields!(WebGPUDevice);
|
||||
unsafe_no_jsmanaged_fields!(Option<RawPass>);
|
||||
unsafe_no_jsmanaged_fields!(Option<RawPass<id::CommandEncoderId>>);
|
||||
unsafe_no_jsmanaged_fields!(GPUBufferState);
|
||||
unsafe_no_jsmanaged_fields!(GPUCommandEncoderState);
|
||||
unsafe_no_jsmanaged_fields!(WebXRSwapChainId);
|
||||
|
|
|
@ -84,7 +84,9 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
extensions: wgt::Extensions::empty(),
|
||||
limits: wgt::Limits {
|
||||
max_bind_groups: descriptor.limits.maxBindGroups,
|
||||
..Default::default()
|
||||
},
|
||||
shader_validation: true,
|
||||
};
|
||||
let id = self
|
||||
.global()
|
||||
|
|
|
@ -3,19 +3,14 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::{
|
||||
GPUBindGroupEntry, GPUBindGroupMethods,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::GPUBindGroupMethods;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||
use crate::dom::gpubuffer::GPUBuffer;
|
||||
use crate::dom::gputextureview::TextureSubresource;
|
||||
use dom_struct::dom_struct;
|
||||
use std::cell::Cell;
|
||||
use std::collections::HashMap;
|
||||
use webgpu::{WebGPUBindGroup, WebGPUDevice};
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -25,10 +20,6 @@ pub struct GPUBindGroup {
|
|||
bind_group: WebGPUBindGroup,
|
||||
device: WebGPUDevice,
|
||||
layout: Dom<GPUBindGroupLayout>,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
entries: Vec<GPUBindGroupEntry>,
|
||||
used_buffers: HashMap<Dom<GPUBuffer>, u32>,
|
||||
used_textures: HashMap<TextureSubresource, u32>,
|
||||
valid: Cell<bool>,
|
||||
}
|
||||
|
||||
|
@ -37,10 +28,7 @@ impl GPUBindGroup {
|
|||
bind_group: WebGPUBindGroup,
|
||||
device: WebGPUDevice,
|
||||
valid: bool,
|
||||
entries: Vec<GPUBindGroupEntry>,
|
||||
layout: &GPUBindGroupLayout,
|
||||
used_buffers: HashMap<DomRoot<GPUBuffer>, u32>,
|
||||
used_textures: HashMap<TextureSubresource, u32>,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -49,12 +37,6 @@ impl GPUBindGroup {
|
|||
device,
|
||||
valid: Cell::new(valid),
|
||||
layout: Dom::from_ref(layout),
|
||||
entries,
|
||||
used_buffers: used_buffers
|
||||
.into_iter()
|
||||
.map(|(key, value)| (Dom::from_ref(&*key), value))
|
||||
.collect(),
|
||||
used_textures,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,20 +45,11 @@ impl GPUBindGroup {
|
|||
bind_group: WebGPUBindGroup,
|
||||
device: WebGPUDevice,
|
||||
valid: bool,
|
||||
entries: Vec<GPUBindGroupEntry>,
|
||||
layout: &GPUBindGroupLayout,
|
||||
used_buffers: HashMap<DomRoot<GPUBuffer>, u32>,
|
||||
used_textures: HashMap<TextureSubresource, u32>,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUBindGroup::new_inherited(
|
||||
bind_group,
|
||||
device,
|
||||
valid,
|
||||
entries,
|
||||
layout,
|
||||
used_buffers,
|
||||
used_textures,
|
||||
bind_group, device, valid, layout,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
|
|
|
@ -22,6 +22,7 @@ use webgpu::{
|
|||
},
|
||||
RawPass,
|
||||
},
|
||||
wgpu::id,
|
||||
WebGPU, WebGPURequest,
|
||||
};
|
||||
|
||||
|
@ -32,7 +33,7 @@ pub struct GPUComputePassEncoder {
|
|||
channel: WebGPU,
|
||||
label: DomRefCell<Option<DOMString>>,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-core"]
|
||||
raw_pass: DomRefCell<Option<RawPass>>,
|
||||
raw_pass: DomRefCell<Option<RawPass<id::CommandEncoderId>>>,
|
||||
command_encoder: Dom<GPUCommandEncoder>,
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,12 @@
|
|||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::{
|
||||
GPUBindGroupDescriptor, GPUBindGroupEntry, GPUBindingResource, GPUBufferBindings,
|
||||
GPUBindGroupDescriptor, GPUBindingResource, GPUBufferBindings,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBindGroupLayoutBinding::{
|
||||
GPUBindGroupLayoutDescriptor, GPUBindGroupLayoutEntry, GPUBindingType,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUBufferDescriptor;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBufferUsageBinding::GPUBufferUsageConstants;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUComputePipelineBinding::GPUComputePipelineDescriptor;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{
|
||||
GPUCommandEncoderDescriptor, GPUDeviceMethods,
|
||||
|
@ -32,7 +31,6 @@ use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::{
|
|||
GPUExtent3D, GPUExtent3DDict, GPUTextureComponentType, GPUTextureDescriptor,
|
||||
GPUTextureDimension, GPUTextureFormat,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureUsageBinding::GPUTextureUsageConstants;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::GPUTextureViewDimension;
|
||||
use crate::dom::bindings::codegen::UnionTypes::Uint32ArrayOrString::{String, Uint32Array};
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||
|
@ -53,19 +51,18 @@ use crate::dom::gpurenderpipeline::GPURenderPipeline;
|
|||
use crate::dom::gpusampler::GPUSampler;
|
||||
use crate::dom::gpushadermodule::GPUShaderModule;
|
||||
use crate::dom::gputexture::GPUTexture;
|
||||
use crate::dom::gputextureview::{GPUTextureView, TextureSubresource};
|
||||
use crate::dom::gputextureview::GPUTextureView;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use arrayvec::ArrayVec;
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use js::jsval::{JSVal, ObjectValue};
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
use std::collections::{hash_map::Entry, HashMap, HashSet};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::num::NonZeroU64;
|
||||
use std::ptr::{self, NonNull};
|
||||
use webgpu::wgpu::binding_model::{
|
||||
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, BufferBinding,
|
||||
};
|
||||
use webgpu::{self, wgpu, wgt, WebGPU, WebGPURequest};
|
||||
use webgpu::wgpu::binding_model::BufferBinding;
|
||||
use webgpu::{self, wgpu, wgt, WebGPU, WebGPUBindings, WebGPURequest};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUDevice {
|
||||
|
@ -165,11 +162,11 @@ impl GPUDevice {
|
|||
binding: &GPUBindGroupLayoutEntry,
|
||||
) -> bool {
|
||||
let mut valid = if let Some(d) = binding.viewDimension {
|
||||
texture_view.descriptor().dimension.unwrap() == d
|
||||
texture_view.dimension() == d
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let view_component = get_component_from_format(texture_view.descriptor().format.unwrap());
|
||||
let view_component = get_component_from_format(texture_view.format());
|
||||
valid &= if let Some(c) = binding.textureComponentType {
|
||||
view_component == c
|
||||
} else {
|
||||
|
@ -189,10 +186,11 @@ impl GPUDevice {
|
|||
},
|
||||
GPUBindingType::Readonly_storage_texture |
|
||||
GPUBindingType::Writeonly_storage_texture => {
|
||||
match wgt::TextureUsage::from_bits(texture_view.texture().usage()) {
|
||||
let v = match wgt::TextureUsage::from_bits(texture_view.texture().usage()) {
|
||||
Some(u) => u.contains(wgt::TextureUsage::STORAGE),
|
||||
None => false,
|
||||
}
|
||||
};
|
||||
v && Some(texture_view.format()) == binding.storageTextureFormat
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
@ -227,9 +225,13 @@ impl GPUDevice {
|
|||
_ => false,
|
||||
};
|
||||
valid &= if let Some(s) = buffer_bind.size {
|
||||
buffer_bind.offset + s <= buffer_bind.buffer.size() && buffer_bind.offset > 0
|
||||
buffer_bind.offset + s <= buffer_bind.buffer.size() &&
|
||||
buffer_bind.offset + s >= binding.minBufferBindingSize &&
|
||||
buffer_bind.offset > 0 &&
|
||||
buffer_bind.offset.checked_add(s).is_some()
|
||||
} else {
|
||||
buffer_bind.offset > 0 && buffer_bind.offset < buffer_bind.buffer.size()
|
||||
buffer_bind.offset < buffer_bind.buffer.size() &&
|
||||
buffer_bind.buffer.size() - buffer_bind.offset >= binding.minBufferBindingSize
|
||||
};
|
||||
valid
|
||||
}
|
||||
|
@ -407,7 +409,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled &&
|
||||
bind.storageTextureFormat.is_none();
|
||||
BindingType::UniformBuffer
|
||||
wgt::BindingType::UniformBuffer {
|
||||
dynamic: bind.hasDynamicOffset,
|
||||
min_binding_size: if bind.minBufferBindingSize == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(NonZeroU64::new(bind.minBufferBindingSize).unwrap())
|
||||
},
|
||||
}
|
||||
},
|
||||
GPUBindingType::Storage_buffer => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
|
@ -421,7 +430,15 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled &&
|
||||
bind.storageTextureFormat.is_none();
|
||||
BindingType::StorageBuffer
|
||||
wgt::BindingType::StorageBuffer {
|
||||
dynamic: bind.hasDynamicOffset,
|
||||
min_binding_size: if bind.minBufferBindingSize == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(NonZeroU64::new(bind.minBufferBindingSize).unwrap())
|
||||
},
|
||||
readonly: false,
|
||||
}
|
||||
},
|
||||
GPUBindingType::Readonly_storage_buffer => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
|
@ -434,14 +451,46 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled &&
|
||||
bind.storageTextureFormat.is_none();
|
||||
BindingType::ReadonlyStorageBuffer
|
||||
wgt::BindingType::StorageBuffer {
|
||||
dynamic: bind.hasDynamicOffset,
|
||||
min_binding_size: if bind.minBufferBindingSize == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(NonZeroU64::new(bind.minBufferBindingSize).unwrap())
|
||||
},
|
||||
readonly: true,
|
||||
}
|
||||
},
|
||||
GPUBindingType::Sampled_texture => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_sampled_textures_per_shader_stage -= 1;
|
||||
}
|
||||
valid &= !bind.hasDynamicOffset && bind.storageTextureFormat.is_none();
|
||||
BindingType::SampledTexture
|
||||
valid &= !bind.hasDynamicOffset &&
|
||||
bind.storageTextureFormat.is_none() &&
|
||||
bind.minBufferBindingSize == 0;
|
||||
wgt::BindingType::SampledTexture {
|
||||
dimension: bind
|
||||
.viewDimension
|
||||
.map_or(wgt::TextureViewDimension::D2, |v| {
|
||||
convert_texture_view_dimension(v)
|
||||
}),
|
||||
component_type: if let Some(c) = bind.textureComponentType {
|
||||
match c {
|
||||
GPUTextureComponentType::Float => {
|
||||
wgt::TextureComponentType::Float
|
||||
},
|
||||
GPUTextureComponentType::Sint => {
|
||||
wgt::TextureComponentType::Sint
|
||||
},
|
||||
GPUTextureComponentType::Uint => {
|
||||
wgt::TextureComponentType::Uint
|
||||
},
|
||||
}
|
||||
} else {
|
||||
wgt::TextureComponentType::Float
|
||||
},
|
||||
multisampled: bind.multisampled,
|
||||
}
|
||||
},
|
||||
GPUBindingType::Readonly_storage_texture => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
|
@ -449,8 +498,22 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
}
|
||||
valid &= !bind.hasDynamicOffset &&
|
||||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled;
|
||||
BindingType::ReadonlyStorageTexture
|
||||
!bind.multisampled &&
|
||||
bind.minBufferBindingSize == 0 &&
|
||||
bind.storageTextureFormat.is_some();
|
||||
wgt::BindingType::StorageTexture {
|
||||
dimension: bind
|
||||
.viewDimension
|
||||
.map_or(wgt::TextureViewDimension::D2, |v| {
|
||||
convert_texture_view_dimension(v)
|
||||
}),
|
||||
format: bind
|
||||
.storageTextureFormat
|
||||
.map_or(wgt::TextureFormat::Bgra8UnormSrgb, |f| {
|
||||
convert_texture_format(f)
|
||||
}),
|
||||
readonly: true,
|
||||
}
|
||||
},
|
||||
GPUBindingType::Writeonly_storage_texture => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
|
@ -458,8 +521,22 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
}
|
||||
valid &= !bind.hasDynamicOffset &&
|
||||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled;
|
||||
BindingType::WriteonlyStorageTexture
|
||||
!bind.multisampled &&
|
||||
bind.minBufferBindingSize == 0 &&
|
||||
bind.storageTextureFormat.is_some();
|
||||
wgt::BindingType::StorageTexture {
|
||||
dimension: bind
|
||||
.viewDimension
|
||||
.map_or(wgt::TextureViewDimension::D2, |v| {
|
||||
convert_texture_view_dimension(v)
|
||||
}),
|
||||
format: bind
|
||||
.storageTextureFormat
|
||||
.map_or(wgt::TextureFormat::Bgra8UnormSrgb, |f| {
|
||||
convert_texture_format(f)
|
||||
}),
|
||||
readonly: true,
|
||||
}
|
||||
},
|
||||
GPUBindingType::Sampler => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
|
@ -469,8 +546,9 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
bind.viewDimension.is_none() &&
|
||||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled &&
|
||||
bind.storageTextureFormat.is_none();
|
||||
BindingType::Sampler
|
||||
bind.storageTextureFormat.is_none() &&
|
||||
bind.minBufferBindingSize == 0;
|
||||
wgt::BindingType::Sampler { comparison: false }
|
||||
},
|
||||
GPUBindingType::Comparison_sampler => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
|
@ -480,38 +558,15 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
bind.viewDimension.is_none() &&
|
||||
bind.textureComponentType.is_none() &&
|
||||
!bind.multisampled &&
|
||||
bind.storageTextureFormat.is_none();
|
||||
BindingType::ComparisonSampler
|
||||
bind.storageTextureFormat.is_none() &&
|
||||
bind.minBufferBindingSize == 0;
|
||||
wgt::BindingType::Sampler { comparison: true }
|
||||
},
|
||||
};
|
||||
|
||||
BindGroupLayoutEntry {
|
||||
binding: bind.binding,
|
||||
visibility,
|
||||
ty,
|
||||
has_dynamic_offset: bind.hasDynamicOffset,
|
||||
multisampled: bind.multisampled,
|
||||
texture_component_type: if let Some(c) = bind.textureComponentType {
|
||||
match c {
|
||||
GPUTextureComponentType::Float => wgt::TextureComponentType::Float,
|
||||
GPUTextureComponentType::Sint => wgt::TextureComponentType::Sint,
|
||||
GPUTextureComponentType::Uint => wgt::TextureComponentType::Uint,
|
||||
}
|
||||
} else {
|
||||
wgt::TextureComponentType::Float
|
||||
},
|
||||
storage_texture_format: match bind.storageTextureFormat {
|
||||
Some(s) => convert_texture_format(s),
|
||||
None => wgt::TextureFormat::Bgra8UnormSrgb,
|
||||
},
|
||||
view_dimension: bind
|
||||
.viewDimension
|
||||
.map_or(wgt::TextureViewDimension::D2, |v| {
|
||||
convert_texture_view_dimension(v)
|
||||
}),
|
||||
}
|
||||
wgt::BindGroupLayoutEntry::new(bind.binding, visibility, ty)
|
||||
})
|
||||
.collect::<Vec<BindGroupLayoutEntry>>();
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// bindings are unique
|
||||
valid &= storeBindings.len() == entries.len();
|
||||
|
@ -539,7 +594,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
.send(WebGPURequest::CreateBindGroupLayout {
|
||||
device_id: self.device.0,
|
||||
bind_group_layout_id,
|
||||
entries: entries.clone(),
|
||||
entries,
|
||||
})
|
||||
.expect("Failed to create WebGPU BindGroupLayout");
|
||||
|
||||
|
@ -558,6 +613,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
viewDimension: bind.viewDimension,
|
||||
textureComponentType: bind.textureComponentType,
|
||||
storageTextureFormat: bind.storageTextureFormat,
|
||||
minBufferBindingSize: bind.minBufferBindingSize,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -631,43 +687,13 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup
|
||||
fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> {
|
||||
//let alignment: u64 = 256;
|
||||
let mut valid = descriptor.layout.is_valid() &&
|
||||
descriptor.layout.entries().len() == descriptor.entries.len();
|
||||
|
||||
/*valid &= descriptor.entries.iter().all(|bind| {
|
||||
let buffer_size = bind.resource.buffer.size();
|
||||
let resource_size = bind.resource.size.unwrap_or(buffer_size);
|
||||
let length = bind.resource.offset.checked_add(resource_size);
|
||||
let usage = wgt::BufferUsage::from_bits(bind.resource.buffer.usage()).unwrap();
|
||||
|
||||
length.is_some() &&
|
||||
buffer_size >= length.unwrap() && // check buffer OOB
|
||||
bind.resource.offset % alignment == 0 && // check alignment
|
||||
bind.resource.offset < buffer_size && // on Vulkan offset must be less than size of buffer
|
||||
descriptor.layout.entries().iter().any(|layout_bind| {
|
||||
match layout_bind.type_ {
|
||||
GPUBindingType::Storage_buffer => usage.contains(wgt::BufferUsage::STORAGE),
|
||||
// GPUBindingType::Readonly_storage_buffer => BufferUsage::STORAGE_READ,
|
||||
GPUBindingType::Uniform_buffer => usage.contains(wgt::BufferUsage::UNIFORM),
|
||||
GPUBindingType::Sampler => bind.resource
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
// binding must be present in layout
|
||||
layout_bind.binding == bind.binding
|
||||
})
|
||||
});*/
|
||||
let mut bindings = HashSet::new();
|
||||
let mut used_buffers = HashMap::new();
|
||||
let mut used_textures = HashMap::new();
|
||||
valid &= descriptor.entries.iter().all(|bind| {
|
||||
bindings.insert(bind.binding);
|
||||
if let Some(layout_bind) = descriptor
|
||||
.layout
|
||||
.entries()
|
||||
.values()
|
||||
.find(|lb| lb.binding == bind.binding)
|
||||
{
|
||||
if let Some(layout_bind) = descriptor.layout.entries().get(&bind.binding) {
|
||||
match layout_bind.type_ {
|
||||
GPUBindingType::Sampler => match bind.resource {
|
||||
GPUBindingResource::GPUSampler(ref s) => s.is_valid() && !s.compare(),
|
||||
|
@ -677,87 +703,22 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
GPUBindingResource::GPUSampler(ref s) => s.is_valid() && s.compare(),
|
||||
_ => false,
|
||||
},
|
||||
GPUBindingType::Sampled_texture => match bind.resource {
|
||||
GPUBindingType::Sampled_texture |
|
||||
GPUBindingType::Readonly_storage_texture |
|
||||
GPUBindingType::Writeonly_storage_texture => match bind.resource {
|
||||
GPUBindingResource::GPUTextureView(ref t) => {
|
||||
let desc = t.descriptor();
|
||||
for i in desc.baseMipLevel..desc.mipLevelCount {
|
||||
for j in desc.baseArrayLayer..desc.arrayLayerCount {
|
||||
let subresource = TextureSubresource {
|
||||
texture: DomRoot::from_ref(t.texture()),
|
||||
mipmap_level: i,
|
||||
array_layer: j,
|
||||
};
|
||||
match used_textures.entry(subresource) {
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(GPUTextureUsageConstants::SAMPLED);
|
||||
},
|
||||
Entry::Occupied(mut o) => {
|
||||
*o.get_mut() += GPUTextureUsageConstants::SAMPLED;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
t.is_valid() && self.validate_texture_view_binding(t, layout_bind)
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
GPUBindingType::Readonly_storage_texture |
|
||||
GPUBindingType::Writeonly_storage_texture => match bind.resource {
|
||||
GPUBindingResource::GPUTextureView(ref t) => {
|
||||
let desc = t.descriptor();
|
||||
for i in desc.baseMipLevel..desc.mipLevelCount {
|
||||
for j in desc.baseArrayLayer..desc.arrayLayerCount {
|
||||
let subresource = TextureSubresource {
|
||||
texture: DomRoot::from_ref(t.texture()),
|
||||
mipmap_level: i,
|
||||
array_layer: j,
|
||||
};
|
||||
match used_textures.entry(subresource) {
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(GPUTextureUsageConstants::STORAGE);
|
||||
},
|
||||
Entry::Occupied(mut o) => {
|
||||
*o.get_mut() += GPUTextureUsageConstants::STORAGE;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
t.is_valid() &&
|
||||
self.validate_texture_view_binding(t, layout_bind) &&
|
||||
t.descriptor().format == layout_bind.storageTextureFormat
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
GPUBindingType::Uniform_buffer => match bind.resource {
|
||||
GPUBindingType::Uniform_buffer |
|
||||
GPUBindingType::Storage_buffer |
|
||||
GPUBindingType::Readonly_storage_buffer => match bind.resource {
|
||||
GPUBindingResource::GPUBufferBindings(ref b) => {
|
||||
match used_buffers.entry(DomRoot::from_ref(&*b.buffer)) {
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(GPUBufferUsageConstants::UNIFORM);
|
||||
},
|
||||
Entry::Occupied(mut o) => {
|
||||
*o.get_mut() += GPUBufferUsageConstants::UNIFORM;
|
||||
},
|
||||
}
|
||||
b.buffer.is_valid() && self.validate_buffer_binding(b, layout_bind)
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
GPUBindingType::Storage_buffer | GPUBindingType::Readonly_storage_buffer => {
|
||||
match bind.resource {
|
||||
GPUBindingResource::GPUBufferBindings(ref b) => {
|
||||
match used_buffers.entry(DomRoot::from_ref(&*b.buffer)) {
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(GPUBufferUsageConstants::STORAGE);
|
||||
},
|
||||
Entry::Occupied(mut o) => {
|
||||
*o.get_mut() += GPUBufferUsageConstants::STORAGE;
|
||||
},
|
||||
}
|
||||
b.buffer.is_valid() && self.validate_buffer_binding(b, layout_bind)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
@ -769,25 +730,27 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
let entries = descriptor
|
||||
.entries
|
||||
.iter()
|
||||
.map(|bind| BindGroupEntry {
|
||||
binding: bind.binding,
|
||||
resource: match bind.resource {
|
||||
GPUBindingResource::GPUSampler(ref s) => BindingResource::Sampler(s.id().0),
|
||||
GPUBindingResource::GPUTextureView(ref t) => {
|
||||
BindingResource::TextureView(t.id().0)
|
||||
.map(|bind| {
|
||||
(
|
||||
bind.binding,
|
||||
match bind.resource {
|
||||
GPUBindingResource::GPUSampler(ref s) => WebGPUBindings::Sampler(s.id().0),
|
||||
GPUBindingResource::GPUTextureView(ref t) => {
|
||||
WebGPUBindings::TextureView(t.id().0)
|
||||
},
|
||||
GPUBindingResource::GPUBufferBindings(ref b) => {
|
||||
WebGPUBindings::Buffer(BufferBinding {
|
||||
buffer_id: b.buffer.id().0,
|
||||
offset: b.offset,
|
||||
size: if let Some(s) = b.size {
|
||||
wgt::BufferSize(s)
|
||||
} else {
|
||||
wgt::BufferSize::WHOLE
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
GPUBindingResource::GPUBufferBindings(ref b) => {
|
||||
BindingResource::Buffer(BufferBinding {
|
||||
buffer: b.buffer.id().0,
|
||||
offset: b.offset,
|
||||
size: if let Some(s) = b.size {
|
||||
wgt::BufferSize(s)
|
||||
} else {
|
||||
wgt::BufferSize::WHOLE
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -806,39 +769,13 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
})
|
||||
.expect("Failed to create WebGPU BindGroup");
|
||||
|
||||
let desc_entries = descriptor
|
||||
.entries
|
||||
.iter()
|
||||
.map(|bind| GPUBindGroupEntry {
|
||||
binding: bind.binding,
|
||||
resource: match bind.resource {
|
||||
GPUBindingResource::GPUSampler(ref s) => {
|
||||
GPUBindingResource::GPUSampler(DomRoot::from_ref(&*s))
|
||||
},
|
||||
GPUBindingResource::GPUTextureView(ref t) => {
|
||||
GPUBindingResource::GPUTextureView(DomRoot::from_ref(&*t))
|
||||
},
|
||||
GPUBindingResource::GPUBufferBindings(ref b) => {
|
||||
GPUBindingResource::GPUBufferBindings(GPUBufferBindings {
|
||||
buffer: DomRoot::from_ref(&*b.buffer),
|
||||
offset: b.offset,
|
||||
size: b.size,
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let bind_group = webgpu::WebGPUBindGroup(bind_group_id);
|
||||
GPUBindGroup::new(
|
||||
&self.global(),
|
||||
bind_group,
|
||||
self.device,
|
||||
valid,
|
||||
desc_entries,
|
||||
&*descriptor.layout,
|
||||
used_buffers,
|
||||
used_textures,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1003,6 +940,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
lod_max_clamp: *descriptor.lodMaxClamp,
|
||||
compare: descriptor.compare.map(|c| convert_compare_function(c)),
|
||||
anisotropy_clamp: None,
|
||||
..Default::default()
|
||||
};
|
||||
self.channel
|
||||
.0
|
||||
|
@ -1015,14 +953,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
let sampler = webgpu::WebGPUSampler(sampler_id);
|
||||
|
||||
GPUSampler::new(
|
||||
&self.global(),
|
||||
self.channel.clone(),
|
||||
self.device,
|
||||
compare_enable,
|
||||
sampler,
|
||||
true,
|
||||
)
|
||||
GPUSampler::new(&self.global(), self.device, compare_enable, sampler, true)
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline
|
||||
|
|
|
@ -19,6 +19,7 @@ use crate::dom::gpurenderpipeline::GPURenderPipeline;
|
|||
use dom_struct::dom_struct;
|
||||
use webgpu::{
|
||||
wgpu::command::{render_ffi as wgpu_render, RawPass},
|
||||
wgpu::id,
|
||||
wgt, WebGPU, WebGPURequest,
|
||||
};
|
||||
|
||||
|
@ -29,12 +30,16 @@ pub struct GPURenderPassEncoder {
|
|||
channel: WebGPU,
|
||||
label: DomRefCell<Option<DOMString>>,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-core"]
|
||||
raw_pass: DomRefCell<Option<RawPass>>,
|
||||
raw_pass: DomRefCell<Option<RawPass<id::CommandEncoderId>>>,
|
||||
command_encoder: Dom<GPUCommandEncoder>,
|
||||
}
|
||||
|
||||
impl GPURenderPassEncoder {
|
||||
fn new_inherited(channel: WebGPU, raw_pass: RawPass, parent: &GPUCommandEncoder) -> Self {
|
||||
fn new_inherited(
|
||||
channel: WebGPU,
|
||||
raw_pass: RawPass<id::CommandEncoderId>,
|
||||
parent: &GPUCommandEncoder,
|
||||
) -> Self {
|
||||
Self {
|
||||
channel,
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -47,7 +52,7 @@ impl GPURenderPassEncoder {
|
|||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
channel: WebGPU,
|
||||
raw_pass: RawPass,
|
||||
raw_pass: RawPass<id::CommandEncoderId>,
|
||||
parent: &GPUCommandEncoder,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
|
|
|
@ -10,13 +10,11 @@ use crate::dom::bindings::str::DOMString;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use dom_struct::dom_struct;
|
||||
use std::cell::Cell;
|
||||
use webgpu::{WebGPU, WebGPUDevice, WebGPUSampler};
|
||||
use webgpu::{WebGPUDevice, WebGPUSampler};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUSampler {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "channels are hard"]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<DOMString>>,
|
||||
device: WebGPUDevice,
|
||||
compare_enable: bool,
|
||||
|
@ -26,7 +24,6 @@ pub struct GPUSampler {
|
|||
|
||||
impl GPUSampler {
|
||||
fn new_inherited(
|
||||
channel: WebGPU,
|
||||
device: WebGPUDevice,
|
||||
compare_enable: bool,
|
||||
sampler: WebGPUSampler,
|
||||
|
@ -34,7 +31,6 @@ impl GPUSampler {
|
|||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
channel,
|
||||
label: DomRefCell::new(None),
|
||||
valid: Cell::new(valid),
|
||||
device,
|
||||
|
@ -45,7 +41,6 @@ impl GPUSampler {
|
|||
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
channel: WebGPU,
|
||||
device: WebGPUDevice,
|
||||
compare_enable: bool,
|
||||
sampler: WebGPUSampler,
|
||||
|
@ -53,7 +48,6 @@ impl GPUSampler {
|
|||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUSampler::new_inherited(
|
||||
channel,
|
||||
device,
|
||||
compare_enable,
|
||||
sampler,
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUObjectBaseBinding::GPUObjectDescriptorBase;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::{
|
||||
GPUExtent3DDict, GPUTextureDimension, GPUTextureFormat, GPUTextureMethods,
|
||||
};
|
||||
|
@ -189,32 +188,7 @@ impl GPUTextureMethods for GPUTexture {
|
|||
|
||||
let texture_view = WebGPUTextureView(texture_view_id);
|
||||
|
||||
let desc = GPUTextureViewDescriptor {
|
||||
parent: GPUObjectDescriptorBase {
|
||||
label: descriptor
|
||||
.parent
|
||||
.label
|
||||
.as_ref()
|
||||
.map(|l| l.as_ref().map(|u| u.clone())),
|
||||
},
|
||||
arrayLayerCount: if descriptor.arrayLayerCount == 0 {
|
||||
self.texture_size.depth - descriptor.baseArrayLayer
|
||||
} else {
|
||||
descriptor.arrayLayerCount
|
||||
},
|
||||
aspect: descriptor.aspect,
|
||||
baseArrayLayer: descriptor.baseArrayLayer,
|
||||
baseMipLevel: descriptor.baseMipLevel,
|
||||
dimension: Some(dimension),
|
||||
format: Some(descriptor.format.unwrap_or(self.format)),
|
||||
mipLevelCount: if descriptor.mipLevelCount == 0 {
|
||||
self.mip_level_count - descriptor.baseMipLevel
|
||||
} else {
|
||||
descriptor.mipLevelCount
|
||||
},
|
||||
};
|
||||
|
||||
GPUTextureView::new(&self.global(), texture_view, &self, true, desc)
|
||||
GPUTextureView::new(&self.global(), texture_view, &self, true, dimension, format)
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gputexture-destroy
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::GPUTextureViewDescriptor;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::GPUTextureViewMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::GPUTextureFormat;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::{
|
||||
GPUTextureViewDimension, GPUTextureViewMethods,
|
||||
};
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
|
@ -12,34 +14,8 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::gputexture::GPUTexture;
|
||||
use dom_struct::dom_struct;
|
||||
use std::cell::Cell;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use webgpu::WebGPUTextureView;
|
||||
|
||||
#[derive(MallocSizeOf, JSTraceable)]
|
||||
pub struct TextureSubresource {
|
||||
pub texture: DomRoot<GPUTexture>,
|
||||
pub mipmap_level: u32,
|
||||
pub array_layer: u32,
|
||||
}
|
||||
|
||||
impl PartialEq for TextureSubresource {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.texture.id().0 == other.texture.id().0 &&
|
||||
self.mipmap_level == other.mipmap_level &&
|
||||
self.array_layer == other.array_layer
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for TextureSubresource {}
|
||||
|
||||
impl Hash for TextureSubresource {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.texture.id().0.hash(state);
|
||||
self.mipmap_level.hash(state);
|
||||
self.array_layer.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUTextureView {
|
||||
reflector_: Reflector,
|
||||
|
@ -47,8 +23,8 @@ pub struct GPUTextureView {
|
|||
texture_view: WebGPUTextureView,
|
||||
texture: Dom<GPUTexture>,
|
||||
valid: Cell<bool>,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
descriptor: GPUTextureViewDescriptor,
|
||||
dimension: GPUTextureViewDimension,
|
||||
format: GPUTextureFormat,
|
||||
}
|
||||
|
||||
impl GPUTextureView {
|
||||
|
@ -56,7 +32,8 @@ impl GPUTextureView {
|
|||
texture_view: WebGPUTextureView,
|
||||
texture: &GPUTexture,
|
||||
valid: bool,
|
||||
descriptor: GPUTextureViewDescriptor,
|
||||
dimension: GPUTextureViewDimension,
|
||||
format: GPUTextureFormat,
|
||||
) -> GPUTextureView {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -64,7 +41,8 @@ impl GPUTextureView {
|
|||
label: DomRefCell::new(None),
|
||||
texture_view,
|
||||
valid: Cell::new(valid),
|
||||
descriptor,
|
||||
dimension,
|
||||
format,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,14 +51,16 @@ impl GPUTextureView {
|
|||
texture_view: WebGPUTextureView,
|
||||
texture: &GPUTexture,
|
||||
valid: bool,
|
||||
descriptor: GPUTextureViewDescriptor,
|
||||
dimension: GPUTextureViewDimension,
|
||||
format: GPUTextureFormat,
|
||||
) -> DomRoot<GPUTextureView> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUTextureView::new_inherited(
|
||||
texture_view,
|
||||
texture,
|
||||
valid,
|
||||
descriptor,
|
||||
dimension,
|
||||
format,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
|
@ -96,8 +76,12 @@ impl GPUTextureView {
|
|||
self.valid.get()
|
||||
}
|
||||
|
||||
pub fn descriptor(&self) -> &GPUTextureViewDescriptor {
|
||||
&self.descriptor
|
||||
pub fn dimension(&self) -> GPUTextureViewDimension {
|
||||
self.dimension
|
||||
}
|
||||
|
||||
pub fn format(&self) -> GPUTextureFormat {
|
||||
self.format
|
||||
}
|
||||
|
||||
pub fn texture(&self) -> &GPUTexture {
|
||||
|
|
|
@ -16,18 +16,11 @@ dictionary GPUBindGroupLayoutEntry {
|
|||
required GPUIndex32 binding;
|
||||
required GPUShaderStageFlags visibility;
|
||||
required GPUBindingType type;
|
||||
|
||||
// Used for uniform buffer and storage buffer bindings.
|
||||
boolean hasDynamicOffset = false;
|
||||
|
||||
// Used for sampled texture and storage texture bindings.
|
||||
GPUSize64 minBufferBindingSize = 0;
|
||||
GPUTextureViewDimension viewDimension;
|
||||
|
||||
// Used for sampled texture bindings.
|
||||
GPUTextureComponentType textureComponentType;
|
||||
boolean multisampled = false;
|
||||
|
||||
// Used for storage texture bindings.
|
||||
GPUTextureFormat storageTextureFormat;
|
||||
};
|
||||
|
||||
|
@ -36,8 +29,8 @@ enum GPUBindingType {
|
|||
"storage-buffer",
|
||||
"readonly-storage-buffer",
|
||||
"sampler",
|
||||
"comparison-sampler",
|
||||
"sampled-texture",
|
||||
"readonly-storage-texture",
|
||||
"writeonly-storage-texture",
|
||||
"comparison-sampler",
|
||||
"writeonly-storage-texture"
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue