Register invalid resources separately

This commit is contained in:
Kunal Mohan 2020-08-06 10:48:17 +05:30
parent 01c8b24e9f
commit 072770dbc0
3 changed files with 325 additions and 206 deletions

View file

@ -293,15 +293,12 @@ 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) -> DomRoot<GPUBuffer> { fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> DomRoot<GPUBuffer> {
let wgpu_descriptor = wgt::BufferDescriptor { let desc = wgt::BufferUsage::from_bits(descriptor.usage).map(|usg| wgt::BufferDescriptor {
label: descriptor.parent.label.as_ref().map(|s| s.to_string()), label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
size: descriptor.size, size: descriptor.size,
usage: match wgt::BufferUsage::from_bits(descriptor.usage) { usage: usg,
Some(u) => u,
None => wgt::BufferUsage::empty(),
},
mapped_at_creation: descriptor.mappedAtCreation, mapped_at_creation: descriptor.mappedAtCreation,
}; });
let id = self let id = self
.global() .global()
.wgpu_id_hub() .wgpu_id_hub()
@ -309,6 +306,13 @@ impl GPUDeviceMethods for GPUDevice {
.create_buffer_id(self.device.0.backend()); .create_buffer_id(self.device.0.backend());
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
if desc.is_none() {
self.handle_server_msg(
scope_id,
WebGPUOpResult::ValidationError(String::from("Invalid GPUBufferUsage")),
);
}
self.channel self.channel
.0 .0
.send(( .send((
@ -316,7 +320,7 @@ impl GPUDeviceMethods for GPUDevice {
WebGPURequest::CreateBuffer { WebGPURequest::CreateBuffer {
device_id: self.device.0, device_id: self.device.0,
buffer_id: id, buffer_id: id,
descriptor: wgpu_descriptor, descriptor: desc,
}, },
)) ))
.expect("Failed to create WebGPU buffer"); .expect("Failed to create WebGPU buffer");
@ -357,13 +361,17 @@ impl GPUDeviceMethods for GPUDevice {
&self, &self,
descriptor: &GPUBindGroupLayoutDescriptor, descriptor: &GPUBindGroupLayoutDescriptor,
) -> DomRoot<GPUBindGroupLayout> { ) -> DomRoot<GPUBindGroupLayout> {
let mut valid = true;
let entries = descriptor let entries = descriptor
.entries .entries
.iter() .iter()
.map(|bind| { .map(|bind| {
let visibility = match wgt::ShaderStage::from_bits(bind.visibility) { let visibility = match wgt::ShaderStage::from_bits(bind.visibility) {
Some(visibility) => visibility, Some(visibility) => visibility,
None => wgt::ShaderStage::from_bits(0).unwrap(), None => {
valid = false;
wgt::ShaderStage::empty()
},
}; };
let ty = match bind.type_ { let ty = match bind.type_ {
GPUBindingType::Uniform_buffer => wgt::BindingType::UniformBuffer { GPUBindingType::Uniform_buffer => wgt::BindingType::UniformBuffer {
@ -435,13 +443,21 @@ impl GPUDeviceMethods for GPUDevice {
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
let desc = wgt::BindGroupLayoutDescriptor { let desc = if valid {
label: descriptor Some(wgt::BindGroupLayoutDescriptor {
.parent label: descriptor
.label .parent
.as_ref() .label
.map(|s| Cow::Owned(s.to_string())), .as_ref()
entries: Cow::Owned(entries), .map(|s| Cow::Owned(s.to_string())),
entries: Cow::Owned(entries),
})
} else {
self.handle_server_msg(
scope_id,
WebGPUOpResult::ValidationError(String::from("Invalid GPUShaderStage")),
);
None
}; };
let bind_group_layout_id = self let bind_group_layout_id = self
@ -695,22 +711,20 @@ impl GPUDeviceMethods for GPUDevice {
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture
fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> DomRoot<GPUTexture> { fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> DomRoot<GPUTexture> {
let size = convert_texture_size_to_dict(&descriptor.size); let size = convert_texture_size_to_dict(&descriptor.size);
let desc = wgt::TextureDescriptor { let desc =
label: descriptor.parent.label.as_ref().map(|s| s.to_string()), wgt::TextureUsage::from_bits(descriptor.usage).map(|usg| wgt::TextureDescriptor {
size: convert_texture_size_to_wgt(&size), label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
mip_level_count: descriptor.mipLevelCount, size: convert_texture_size_to_wgt(&size),
sample_count: descriptor.sampleCount, mip_level_count: descriptor.mipLevelCount,
dimension: match descriptor.dimension { sample_count: descriptor.sampleCount,
GPUTextureDimension::_1d => wgt::TextureDimension::D1, dimension: match descriptor.dimension {
GPUTextureDimension::_2d => wgt::TextureDimension::D2, GPUTextureDimension::_1d => wgt::TextureDimension::D1,
GPUTextureDimension::_3d => wgt::TextureDimension::D3, GPUTextureDimension::_2d => wgt::TextureDimension::D2,
}, GPUTextureDimension::_3d => wgt::TextureDimension::D3,
format: convert_texture_format(descriptor.format), },
usage: match wgt::TextureUsage::from_bits(descriptor.usage) { format: convert_texture_format(descriptor.format),
Some(t) => t, usage: usg,
None => wgt::TextureUsage::empty(), });
},
};
let texture_id = self let texture_id = self
.global() .global()
@ -719,7 +733,12 @@ impl GPUDeviceMethods for GPUDevice {
.create_texture_id(self.device.0.backend()); .create_texture_id(self.device.0.backend());
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
if desc.is_none() {
self.handle_server_msg(
scope_id,
WebGPUOpResult::ValidationError(String::from("Invalid GPUTextureUsage")),
);
}
self.channel self.channel
.0 .0
.send(( .send((
@ -803,110 +822,124 @@ impl GPUDeviceMethods for GPUDevice {
) -> DomRoot<GPURenderPipeline> { ) -> DomRoot<GPURenderPipeline> {
let ref rs_desc = descriptor.rasterizationState; let ref rs_desc = descriptor.rasterizationState;
let ref vs_desc = descriptor.vertexState; let ref vs_desc = descriptor.vertexState;
let scope_id = self.use_current_scope();
let desc = wgpu_pipe::RenderPipelineDescriptor { let mut valid = true;
layout: descriptor.parent.layout.id().0, let color_states = Cow::Owned(
vertex_stage: wgpu_pipe::ProgrammableStageDescriptor { descriptor
module: descriptor.vertexStage.module.id().0, .colorStates
entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()), .iter()
}, .map(|state| wgt::ColorStateDescriptor {
fragment_stage: descriptor.fragmentStage.as_ref().map(|stage| { format: convert_texture_format(state.format),
wgpu_pipe::ProgrammableStageDescriptor { alpha_blend: convert_blend_descriptor(&state.alphaBlend),
module: stage.module.id().0, color_blend: convert_blend_descriptor(&state.colorBlend),
entry_point: Cow::Owned(stage.entryPoint.to_string()), write_mask: match wgt::ColorWrite::from_bits(state.writeMask) {
} Some(mask) => mask,
}), None => {
rasterization_state: Some(wgt::RasterizationStateDescriptor { valid = false;
front_face: match rs_desc.frontFace { wgt::ColorWrite::empty()
GPUFrontFace::Ccw => wgt::FrontFace::Ccw,
GPUFrontFace::Cw => wgt::FrontFace::Cw,
},
cull_mode: match rs_desc.cullMode {
GPUCullMode::None => wgt::CullMode::None,
GPUCullMode::Front => wgt::CullMode::Front,
GPUCullMode::Back => wgt::CullMode::Back,
},
clamp_depth: rs_desc.clampDepth,
depth_bias: rs_desc.depthBias,
depth_bias_slope_scale: *rs_desc.depthBiasSlopeScale,
depth_bias_clamp: *rs_desc.depthBiasClamp,
}),
primitive_topology: match descriptor.primitiveTopology {
GPUPrimitiveTopology::Point_list => wgt::PrimitiveTopology::PointList,
GPUPrimitiveTopology::Line_list => wgt::PrimitiveTopology::LineList,
GPUPrimitiveTopology::Line_strip => wgt::PrimitiveTopology::LineStrip,
GPUPrimitiveTopology::Triangle_list => wgt::PrimitiveTopology::TriangleList,
GPUPrimitiveTopology::Triangle_strip => wgt::PrimitiveTopology::TriangleStrip,
},
color_states: Cow::Owned(
descriptor
.colorStates
.iter()
.map(|state| wgt::ColorStateDescriptor {
format: convert_texture_format(state.format),
alpha_blend: convert_blend_descriptor(&state.alphaBlend),
color_blend: convert_blend_descriptor(&state.colorBlend),
write_mask: match wgt::ColorWrite::from_bits(state.writeMask) {
Some(mask) => mask,
None => wgt::ColorWrite::empty(),
}, },
})
.collect::<Vec<_>>(),
),
depth_stencil_state: descriptor.depthStencilState.as_ref().map(|dss_desc| {
wgt::DepthStencilStateDescriptor {
format: convert_texture_format(dss_desc.format),
depth_write_enabled: dss_desc.depthWriteEnabled,
depth_compare: convert_compare_function(dss_desc.depthCompare),
stencil_front: wgt::StencilStateFaceDescriptor {
compare: convert_compare_function(dss_desc.stencilFront.compare),
fail_op: convert_stencil_op(dss_desc.stencilFront.failOp),
depth_fail_op: convert_stencil_op(dss_desc.stencilFront.depthFailOp),
pass_op: convert_stencil_op(dss_desc.stencilFront.passOp),
}, },
stencil_back: wgt::StencilStateFaceDescriptor { })
compare: convert_compare_function(dss_desc.stencilBack.compare), .collect::<Vec<_>>(),
fail_op: convert_stencil_op(dss_desc.stencilBack.failOp), );
depth_fail_op: convert_stencil_op(dss_desc.stencilBack.depthFailOp),
pass_op: convert_stencil_op(dss_desc.stencilBack.passOp), let desc = if valid {
}, Some(wgpu_pipe::RenderPipelineDescriptor {
stencil_read_mask: dss_desc.stencilReadMask, layout: descriptor.parent.layout.id().0,
stencil_write_mask: dss_desc.stencilWriteMask, vertex_stage: wgpu_pipe::ProgrammableStageDescriptor {
} module: descriptor.vertexStage.module.id().0,
}), entry_point: Cow::Owned(descriptor.vertexStage.entryPoint.to_string()),
vertex_state: wgt::VertexStateDescriptor {
index_format: match vs_desc.indexFormat {
GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16,
GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32,
}, },
vertex_buffers: Cow::Owned( fragment_stage: descriptor.fragmentStage.as_ref().map(|stage| {
vs_desc wgpu_pipe::ProgrammableStageDescriptor {
.vertexBuffers module: stage.module.id().0,
.iter() entry_point: Cow::Owned(stage.entryPoint.to_string()),
.map(|buffer| wgt::VertexBufferDescriptor { }
stride: buffer.arrayStride, }),
step_mode: match buffer.stepMode { rasterization_state: Some(wgt::RasterizationStateDescriptor {
GPUInputStepMode::Vertex => wgt::InputStepMode::Vertex, front_face: match rs_desc.frontFace {
GPUInputStepMode::Instance => wgt::InputStepMode::Instance, GPUFrontFace::Ccw => wgt::FrontFace::Ccw,
}, GPUFrontFace::Cw => wgt::FrontFace::Cw,
attributes: Cow::Owned( },
buffer cull_mode: match rs_desc.cullMode {
.attributes GPUCullMode::None => wgt::CullMode::None,
.iter() GPUCullMode::Front => wgt::CullMode::Front,
.map(|att| wgt::VertexAttributeDescriptor { GPUCullMode::Back => wgt::CullMode::Back,
format: convert_vertex_format(att.format), },
offset: att.offset, clamp_depth: rs_desc.clampDepth,
shader_location: att.shaderLocation, depth_bias: rs_desc.depthBias,
}) depth_bias_slope_scale: *rs_desc.depthBiasSlopeScale,
.collect::<Vec<_>>(), depth_bias_clamp: *rs_desc.depthBiasClamp,
), }),
}) primitive_topology: match descriptor.primitiveTopology {
.collect::<Vec<_>>(), GPUPrimitiveTopology::Point_list => wgt::PrimitiveTopology::PointList,
), GPUPrimitiveTopology::Line_list => wgt::PrimitiveTopology::LineList,
}, GPUPrimitiveTopology::Line_strip => wgt::PrimitiveTopology::LineStrip,
sample_count: descriptor.sampleCount, GPUPrimitiveTopology::Triangle_list => wgt::PrimitiveTopology::TriangleList,
sample_mask: descriptor.sampleMask, GPUPrimitiveTopology::Triangle_strip => wgt::PrimitiveTopology::TriangleStrip,
alpha_to_coverage_enabled: descriptor.alphaToCoverageEnabled, },
color_states,
depth_stencil_state: descriptor.depthStencilState.as_ref().map(|dss_desc| {
wgt::DepthStencilStateDescriptor {
format: convert_texture_format(dss_desc.format),
depth_write_enabled: dss_desc.depthWriteEnabled,
depth_compare: convert_compare_function(dss_desc.depthCompare),
stencil_front: wgt::StencilStateFaceDescriptor {
compare: convert_compare_function(dss_desc.stencilFront.compare),
fail_op: convert_stencil_op(dss_desc.stencilFront.failOp),
depth_fail_op: convert_stencil_op(dss_desc.stencilFront.depthFailOp),
pass_op: convert_stencil_op(dss_desc.stencilFront.passOp),
},
stencil_back: wgt::StencilStateFaceDescriptor {
compare: convert_compare_function(dss_desc.stencilBack.compare),
fail_op: convert_stencil_op(dss_desc.stencilBack.failOp),
depth_fail_op: convert_stencil_op(dss_desc.stencilBack.depthFailOp),
pass_op: convert_stencil_op(dss_desc.stencilBack.passOp),
},
stencil_read_mask: dss_desc.stencilReadMask,
stencil_write_mask: dss_desc.stencilWriteMask,
}
}),
vertex_state: wgt::VertexStateDescriptor {
index_format: match vs_desc.indexFormat {
GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16,
GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32,
},
vertex_buffers: Cow::Owned(
vs_desc
.vertexBuffers
.iter()
.map(|buffer| wgt::VertexBufferDescriptor {
stride: buffer.arrayStride,
step_mode: match buffer.stepMode {
GPUInputStepMode::Vertex => wgt::InputStepMode::Vertex,
GPUInputStepMode::Instance => wgt::InputStepMode::Instance,
},
attributes: Cow::Owned(
buffer
.attributes
.iter()
.map(|att| wgt::VertexAttributeDescriptor {
format: convert_vertex_format(att.format),
offset: att.offset,
shader_location: att.shaderLocation,
})
.collect::<Vec<_>>(),
),
})
.collect::<Vec<_>>(),
),
},
sample_count: descriptor.sampleCount,
sample_mask: descriptor.sampleMask,
alpha_to_coverage_enabled: descriptor.alphaToCoverageEnabled,
})
} else {
self.handle_server_msg(
scope_id,
WebGPUOpResult::ValidationError(String::from("Invalid GPUColorWriteFlags")),
);
None
}; };
let render_pipeline_id = self let render_pipeline_id = self
@ -915,8 +948,6 @@ impl GPUDeviceMethods for GPUDevice {
.lock() .lock()
.create_render_pipeline_id(self.device.0.backend()); .create_render_pipeline_id(self.device.0.backend());
let scope_id = self.use_current_scope();
self.channel self.channel
.0 .0
.send(( .send((

View file

@ -18,7 +18,9 @@ use crate::dom::gputextureview::GPUTextureView;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::string::String; use std::string::String;
use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView}; use webgpu::{
identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView,
};
#[dom_struct] #[dom_struct]
pub struct GPUTexture { pub struct GPUTexture {
@ -138,24 +140,48 @@ impl GPUTextureMethods for GPUTexture {
}; };
let format = descriptor.format.unwrap_or(self.format); let format = descriptor.format.unwrap_or(self.format);
let scope_id = self.device.use_current_scope();
let mut valid = true;
let level_count = descriptor.mipLevelCount.and_then(|count| {
if count == 0 {
valid = false;
}
NonZeroU32::new(count)
});
let array_layer_count = descriptor.arrayLayerCount.and_then(|count| {
if count == 0 {
valid = false;
}
NonZeroU32::new(count)
});
let desc = wgt::TextureViewDescriptor { let desc = if valid {
label: descriptor Some(wgt::TextureViewDescriptor {
.parent label: descriptor
.label .parent
.as_ref() .label
.map(|s| String::from(s.as_ref())), .as_ref()
format: convert_texture_format(format), .map(|s| String::from(s.as_ref())),
dimension: convert_texture_view_dimension(dimension), format: convert_texture_format(format),
aspect: match descriptor.aspect { dimension: convert_texture_view_dimension(dimension),
GPUTextureAspect::All => wgt::TextureAspect::All, aspect: match descriptor.aspect {
GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly, GPUTextureAspect::All => wgt::TextureAspect::All,
GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly, GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
}, GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly,
base_mip_level: descriptor.baseMipLevel, },
level_count: descriptor.mipLevelCount.and_then(NonZeroU32::new), base_mip_level: descriptor.baseMipLevel,
base_array_layer: descriptor.baseArrayLayer, level_count,
array_layer_count: descriptor.arrayLayerCount.and_then(NonZeroU32::new), base_array_layer: descriptor.baseArrayLayer,
array_layer_count,
})
} else {
self.device.handle_server_msg(
scope_id,
WebGPUOpResult::ValidationError(String::from(
"arrayLayerCount and mipLevelCount cannot be 0",
)),
);
None
}; };
let texture_view_id = self let texture_view_id = self
@ -164,8 +190,6 @@ impl GPUTextureMethods for GPUTexture {
.lock() .lock()
.create_texture_view_id(self.device.id().0.backend()); .create_texture_view_id(self.device.id().0.backend());
let scope_id = self.device.use_current_scope();
self.channel self.channel
.0 .0
.send(( .send((

View file

@ -118,12 +118,12 @@ pub enum WebGPURequest {
CreateBindGroupLayout { CreateBindGroupLayout {
device_id: id::DeviceId, device_id: id::DeviceId,
bind_group_layout_id: id::BindGroupLayoutId, bind_group_layout_id: id::BindGroupLayoutId,
descriptor: wgt::BindGroupLayoutDescriptor<'static>, descriptor: Option<wgt::BindGroupLayoutDescriptor<'static>>,
}, },
CreateBuffer { CreateBuffer {
device_id: id::DeviceId, device_id: id::DeviceId,
buffer_id: id::BufferId, buffer_id: id::BufferId,
descriptor: wgt::BufferDescriptor<Option<String>>, descriptor: Option<wgt::BufferDescriptor<Option<String>>>,
}, },
CreateCommandEncoder { CreateCommandEncoder {
device_id: id::DeviceId, device_id: id::DeviceId,
@ -146,7 +146,7 @@ pub enum WebGPURequest {
CreateRenderPipeline { CreateRenderPipeline {
device_id: id::DeviceId, device_id: id::DeviceId,
render_pipeline_id: id::RenderPipelineId, render_pipeline_id: id::RenderPipelineId,
descriptor: RenderPipelineDescriptor<'static>, descriptor: Option<RenderPipelineDescriptor<'static>>,
}, },
CreateSampler { CreateSampler {
device_id: id::DeviceId, device_id: id::DeviceId,
@ -169,13 +169,13 @@ pub enum WebGPURequest {
CreateTexture { CreateTexture {
device_id: id::DeviceId, device_id: id::DeviceId,
texture_id: id::TextureId, texture_id: id::TextureId,
descriptor: wgt::TextureDescriptor<Option<String>>, descriptor: Option<wgt::TextureDescriptor<Option<String>>>,
}, },
CreateTextureView { CreateTextureView {
texture_id: id::TextureId, texture_id: id::TextureId,
texture_view_id: id::TextureViewId, texture_view_id: id::TextureViewId,
device_id: id::DeviceId, device_id: id::DeviceId,
descriptor: wgt::TextureViewDescriptor<Option<String>>, descriptor: Option<wgt::TextureViewDescriptor<Option<String>>>,
}, },
DestroyBuffer(id::BufferId), DestroyBuffer(id::BufferId),
DestroySwapChain { DestroySwapChain {
@ -456,6 +456,9 @@ impl<'a> WGPU<'a> {
command_encoder_id, command_encoder_id,
&wgt::CommandBufferDescriptor::default() &wgt::CommandBufferDescriptor::default()
)); ));
if result.is_err() {
let _ = gfx_select!(command_encoder_id => global.command_buffer_error(command_encoder_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CopyBufferToBuffer { WebGPURequest::CopyBufferToBuffer {
@ -534,6 +537,9 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(bind_group_id => let result = gfx_select!(bind_group_id =>
global.device_create_bind_group(device_id, &descriptor, bind_group_id)); global.device_create_bind_group(device_id, &descriptor, bind_group_id));
if result.is_err() {
let _ = gfx_select!(bind_group_id => global.bind_group_error(bind_group_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateBindGroupLayout { WebGPURequest::CreateBindGroupLayout {
@ -542,9 +548,18 @@ impl<'a> WGPU<'a> {
descriptor, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
let result = gfx_select!(bind_group_layout_id => if let Some(desc) = descriptor {
global.device_create_bind_group_layout(device_id, &descriptor, bind_group_layout_id)); let result = gfx_select!(bind_group_layout_id =>
self.send_result(device_id, scope_id, result); global.device_create_bind_group_layout(device_id, &desc, bind_group_layout_id));
if result.is_err() {
let _ = gfx_select!(bind_group_layout_id =>
global.bind_group_layout_error(bind_group_layout_id));
}
self.send_result(device_id, scope_id, result);
} else {
let _ = gfx_select!(bind_group_layout_id =>
global.bind_group_layout_error(bind_group_layout_id));
}
}, },
WebGPURequest::CreateBuffer { WebGPURequest::CreateBuffer {
device_id, device_id,
@ -552,17 +567,24 @@ impl<'a> WGPU<'a> {
descriptor, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
let st; if let Some(desc) = descriptor {
let label = match descriptor.label { let st;
Some(ref s) => { let label = match desc.label {
st = CString::new(s.as_bytes()).unwrap(); Some(ref s) => {
st.as_ptr() st = CString::new(s.as_bytes()).unwrap();
}, st.as_ptr()
None => ptr::null(), },
}; None => ptr::null(),
let result = gfx_select!(buffer_id => };
global.device_create_buffer(device_id, &descriptor.map_label(|_| label), buffer_id)); let result = gfx_select!(buffer_id =>
self.send_result(device_id, scope_id, result); global.device_create_buffer(device_id, &desc.map_label(|_| label), buffer_id));
if result.is_err() {
let _ = gfx_select!(buffer_id => global.buffer_error(buffer_id));
}
self.send_result(device_id, scope_id, result);
} else {
let _ = gfx_select!(buffer_id => global.buffer_error(buffer_id));
}
}, },
WebGPURequest::CreateCommandEncoder { WebGPURequest::CreateCommandEncoder {
device_id, device_id,
@ -581,6 +603,9 @@ impl<'a> WGPU<'a> {
let desc = wgt::CommandEncoderDescriptor { label }; let desc = wgt::CommandEncoderDescriptor { label };
let result = gfx_select!(command_encoder_id => let result = gfx_select!(command_encoder_id =>
global.device_create_command_encoder(device_id, &desc, command_encoder_id)); global.device_create_command_encoder(device_id, &desc, command_encoder_id));
if result.is_err() {
let _ = gfx_select!(command_encoder_id => global.command_encoder_error(command_encoder_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateComputePipeline { WebGPURequest::CreateComputePipeline {
@ -591,6 +616,10 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(compute_pipeline_id => let result = gfx_select!(compute_pipeline_id =>
global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id)); global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id));
if result.is_err() {
let _ = gfx_select!(compute_pipeline_id =>
global.compute_pipeline_error(compute_pipeline_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateContext(sender) => { WebGPURequest::CreateContext(sender) => {
@ -611,18 +640,28 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(pipeline_layout_id => let result = gfx_select!(pipeline_layout_id =>
global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id)); global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id));
if result.is_err() {
let _ = gfx_select!(pipeline_layout_id => global.pipeline_layout_error(pipeline_layout_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
//TODO: consider https://github.com/gfx-rs/wgpu/issues/684
WebGPURequest::CreateRenderPipeline { WebGPURequest::CreateRenderPipeline {
device_id, device_id,
render_pipeline_id, render_pipeline_id,
descriptor, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
let result = gfx_select!(render_pipeline_id => if let Some(desc) = descriptor {
global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id)); let result = gfx_select!(render_pipeline_id =>
self.send_result(device_id, scope_id, result); global.device_create_render_pipeline(device_id, &desc, render_pipeline_id));
if result.is_err() {
let _ = gfx_select!(render_pipeline_id =>
global.render_pipeline_error(render_pipeline_id));
}
self.send_result(device_id, scope_id, result);
} else {
let _ = gfx_select!(render_pipeline_id => global.render_pipeline_error(render_pipeline_id));
}
}, },
WebGPURequest::CreateSampler { WebGPURequest::CreateSampler {
device_id, device_id,
@ -643,6 +682,9 @@ impl<'a> WGPU<'a> {
&descriptor.map_label(|_| label), &descriptor.map_label(|_| label),
sampler_id sampler_id
)); ));
if result.is_err() {
let _ = gfx_select!(sampler_id => global.sampler_error(sampler_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateShaderModule { WebGPURequest::CreateShaderModule {
@ -655,6 +697,10 @@ impl<'a> WGPU<'a> {
wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Owned(program)); wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Owned(program));
let result = gfx_select!(program_id => let result = gfx_select!(program_id =>
global.device_create_shader_module(device_id, source, program_id)); global.device_create_shader_module(device_id, source, program_id));
if result.is_err() {
let _ =
gfx_select!(program_id => global.shader_module_error(program_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateSwapChain { WebGPURequest::CreateSwapChain {
@ -705,20 +751,27 @@ impl<'a> WGPU<'a> {
descriptor, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
let st; if let Some(desc) = descriptor {
let label = match descriptor.label { let st;
Some(ref s) => { let label = match desc.label {
st = CString::new(s.as_bytes()).unwrap(); Some(ref s) => {
st.as_ptr() st = CString::new(s.as_bytes()).unwrap();
}, st.as_ptr()
None => ptr::null(), },
}; None => ptr::null(),
let result = gfx_select!(texture_id => global.device_create_texture( };
device_id, let result = gfx_select!(texture_id => global.device_create_texture(
&descriptor.map_label(|_| label), device_id,
texture_id &desc.map_label(|_| label),
)); texture_id
self.send_result(device_id, scope_id, result); ));
if result.is_err() {
let _ = gfx_select!(texture_id => global.texture_error(texture_id));
}
self.send_result(device_id, scope_id, result);
} else {
let _ = gfx_select!(texture_id => global.texture_error(texture_id));
}
}, },
WebGPURequest::CreateTextureView { WebGPURequest::CreateTextureView {
texture_id, texture_id,
@ -727,20 +780,27 @@ impl<'a> WGPU<'a> {
descriptor, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
let st; if let Some(desc) = descriptor {
let label = match descriptor.label { let st;
Some(ref s) => { let label = match desc.label {
st = CString::new(s.as_bytes()).unwrap(); Some(ref s) => {
st.as_ptr() st = CString::new(s.as_bytes()).unwrap();
}, st.as_ptr()
None => ptr::null(), },
}; None => ptr::null(),
let result = gfx_select!(texture_view_id => global.texture_create_view( };
texture_id, let result = gfx_select!(texture_view_id => global.texture_create_view(
Some(&descriptor.map_label(|_| label)), texture_id,
texture_view_id Some(&desc.map_label(|_| label)),
)); texture_view_id
self.send_result(device_id, scope_id, result); ));
if result.is_err() {
let _ = gfx_select!(texture_view_id => global.texture_view_error(texture_view_id));
}
self.send_result(device_id, scope_id, result);
} else {
let _ = gfx_select!(texture_view_id => global.texture_view_error(texture_view_id));
}
}, },
WebGPURequest::DestroyBuffer(buffer) => { WebGPURequest::DestroyBuffer(buffer) => {
let global = &self.global; let global = &self.global;
@ -816,6 +876,9 @@ impl<'a> WGPU<'a> {
&descriptor.map_label(|_| label), &descriptor.map_label(|_| label),
render_bundle_id render_bundle_id
)); ));
if result.is_err() {
let _ = gfx_select!(render_bundle_id => global.render_bundle_error(render_bundle_id));
}
self.send_result(device_id, scope_id, result); self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::RequestAdapter { WebGPURequest::RequestAdapter {
@ -871,6 +934,7 @@ impl<'a> WGPU<'a> {
)) { )) {
Ok(id) => id, Ok(id) => id,
Err(e) => { Err(e) => {
let _ = gfx_select!(device_id => global.device_error(device_id));
if let Err(w) = sender.send(Err(format!("{:?}", e))) { if let Err(w) = sender.send(Err(format!("{:?}", e))) {
warn!( warn!(
"Failed to send response to WebGPURequest::RequestDevice ({})", "Failed to send response to WebGPURequest::RequestDevice ({})",