mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Record errors in GPUCommandEncoder.BeginPass() and EncoderPass.endPass()
This commit is contained in:
parent
78c9466fdb
commit
1d80f57aab
4 changed files with 230 additions and 168 deletions
|
@ -125,14 +125,32 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPUComputePassDescriptor,
|
descriptor: &GPUComputePassDescriptor,
|
||||||
) -> DomRoot<GPUComputePassEncoder> {
|
) -> DomRoot<GPUComputePassEncoder> {
|
||||||
|
let scope_id = self.device.use_current_scope();
|
||||||
self.set_state(
|
self.set_state(
|
||||||
GPUCommandEncoderState::EncodingComputePass,
|
GPUCommandEncoderState::EncodingComputePass,
|
||||||
GPUCommandEncoderState::Open,
|
GPUCommandEncoderState::Open,
|
||||||
);
|
);
|
||||||
|
let (compute_pass, res) = if !self.valid.get() {
|
||||||
|
(
|
||||||
|
None,
|
||||||
|
WebGPUOpResult::ValidationError(String::from(
|
||||||
|
"CommandEncoder is not in Open State",
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
Some(wgpu_com::ComputePass::new(self.encoder.0)),
|
||||||
|
WebGPUOpResult::Success,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.device.handle_server_msg(scope_id, res);
|
||||||
|
|
||||||
GPUComputePassEncoder::new(
|
GPUComputePassEncoder::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
self.channel.clone(),
|
self.channel.clone(),
|
||||||
&self,
|
&self,
|
||||||
|
compute_pass,
|
||||||
descriptor.parent.label.as_ref().cloned(),
|
descriptor.parent.label.as_ref().cloned(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -142,102 +160,118 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
&self,
|
&self,
|
||||||
descriptor: &GPURenderPassDescriptor,
|
descriptor: &GPURenderPassDescriptor,
|
||||||
) -> DomRoot<GPURenderPassEncoder> {
|
) -> DomRoot<GPURenderPassEncoder> {
|
||||||
|
let scope_id = self.device.use_current_scope();
|
||||||
self.set_state(
|
self.set_state(
|
||||||
GPUCommandEncoderState::EncodingRenderPass,
|
GPUCommandEncoderState::EncodingRenderPass,
|
||||||
GPUCommandEncoderState::Open,
|
GPUCommandEncoderState::Open,
|
||||||
);
|
);
|
||||||
|
|
||||||
let depth_stencil = descriptor.depthStencilAttachment.as_ref().map(|depth| {
|
let (render_pass, res) = if !self.valid.get() {
|
||||||
let (depth_load_op, clear_depth) = match depth.depthLoadValue {
|
(
|
||||||
GPULoadOpOrFloat::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0.0f32),
|
None,
|
||||||
GPULoadOpOrFloat::Float(f) => (wgpu_com::LoadOp::Clear, *f),
|
WebGPUOpResult::ValidationError(String::from(
|
||||||
};
|
"CommandEncoder is not in Open State",
|
||||||
let (stencil_load_op, clear_stencil) = match depth.stencilLoadValue {
|
)),
|
||||||
GPUStencilLoadValue::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0u32),
|
)
|
||||||
GPUStencilLoadValue::RangeEnforcedUnsignedLong(l) => (wgpu_com::LoadOp::Clear, l),
|
} else {
|
||||||
};
|
let depth_stencil = descriptor.depthStencilAttachment.as_ref().map(|depth| {
|
||||||
let depth_channel = wgpu_com::PassChannel {
|
let (depth_load_op, clear_depth) = match depth.depthLoadValue {
|
||||||
load_op: depth_load_op,
|
GPULoadOpOrFloat::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0.0f32),
|
||||||
store_op: match depth.depthStoreOp {
|
GPULoadOpOrFloat::Float(f) => (wgpu_com::LoadOp::Clear, *f),
|
||||||
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
};
|
||||||
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
let (stencil_load_op, clear_stencil) = match depth.stencilLoadValue {
|
||||||
},
|
GPUStencilLoadValue::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0u32),
|
||||||
clear_value: clear_depth,
|
GPUStencilLoadValue::RangeEnforcedUnsignedLong(l) => {
|
||||||
read_only: depth.depthReadOnly,
|
(wgpu_com::LoadOp::Clear, l)
|
||||||
};
|
},
|
||||||
let stencil_channel = wgpu_com::PassChannel {
|
};
|
||||||
load_op: stencil_load_op,
|
let depth_channel = wgpu_com::PassChannel {
|
||||||
store_op: match depth.stencilStoreOp {
|
load_op: depth_load_op,
|
||||||
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
store_op: match depth.depthStoreOp {
|
||||||
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
||||||
},
|
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
||||||
clear_value: clear_stencil,
|
},
|
||||||
read_only: depth.stencilReadOnly,
|
clear_value: clear_depth,
|
||||||
};
|
read_only: depth.depthReadOnly,
|
||||||
wgpu_com::DepthStencilAttachmentDescriptor {
|
};
|
||||||
attachment: depth.attachment.id().0,
|
let stencil_channel = wgpu_com::PassChannel {
|
||||||
depth: depth_channel,
|
load_op: stencil_load_op,
|
||||||
stencil: stencil_channel,
|
store_op: match depth.stencilStoreOp {
|
||||||
}
|
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
||||||
});
|
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
||||||
|
},
|
||||||
|
clear_value: clear_stencil,
|
||||||
|
read_only: depth.stencilReadOnly,
|
||||||
|
};
|
||||||
|
wgpu_com::DepthStencilAttachmentDescriptor {
|
||||||
|
attachment: depth.attachment.id().0,
|
||||||
|
depth: depth_channel,
|
||||||
|
stencil: stencil_channel,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let desc = wgpu_com::RenderPassDescriptor {
|
let desc = wgpu_com::RenderPassDescriptor {
|
||||||
color_attachments: Cow::Owned(
|
color_attachments: Cow::Owned(
|
||||||
descriptor
|
descriptor
|
||||||
.colorAttachments
|
.colorAttachments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|color| {
|
.map(|color| {
|
||||||
let (load_op, clear_value) = match color.loadValue {
|
let (load_op, clear_value) = match color.loadValue {
|
||||||
GPUColorLoad::GPULoadOp(_) => {
|
GPUColorLoad::GPULoadOp(_) => {
|
||||||
(wgpu_com::LoadOp::Load, wgt::Color::TRANSPARENT)
|
(wgpu_com::LoadOp::Load, wgt::Color::TRANSPARENT)
|
||||||
},
|
},
|
||||||
GPUColorLoad::DoubleSequence(ref s) => {
|
GPUColorLoad::DoubleSequence(ref s) => {
|
||||||
let mut w = s.clone();
|
let mut w = s.clone();
|
||||||
if w.len() < 3 {
|
if w.len() < 3 {
|
||||||
w.resize(3, Finite::wrap(0.0f64));
|
w.resize(3, Finite::wrap(0.0f64));
|
||||||
}
|
}
|
||||||
w.resize(4, Finite::wrap(1.0f64));
|
w.resize(4, Finite::wrap(1.0f64));
|
||||||
(
|
(
|
||||||
|
wgpu_com::LoadOp::Clear,
|
||||||
|
wgt::Color {
|
||||||
|
r: *w[0],
|
||||||
|
g: *w[1],
|
||||||
|
b: *w[2],
|
||||||
|
a: *w[3],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
GPUColorLoad::GPUColorDict(ref d) => (
|
||||||
wgpu_com::LoadOp::Clear,
|
wgpu_com::LoadOp::Clear,
|
||||||
wgt::Color {
|
wgt::Color {
|
||||||
r: *w[0],
|
r: *d.r,
|
||||||
g: *w[1],
|
g: *d.g,
|
||||||
b: *w[2],
|
b: *d.b,
|
||||||
a: *w[3],
|
a: *d.a,
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
},
|
};
|
||||||
GPUColorLoad::GPUColorDict(ref d) => (
|
let channel = wgpu_com::PassChannel {
|
||||||
wgpu_com::LoadOp::Clear,
|
load_op,
|
||||||
wgt::Color {
|
store_op: match color.storeOp {
|
||||||
r: *d.r,
|
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
||||||
g: *d.g,
|
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
||||||
b: *d.b,
|
|
||||||
a: *d.a,
|
|
||||||
},
|
},
|
||||||
),
|
clear_value,
|
||||||
};
|
read_only: false,
|
||||||
let channel = wgpu_com::PassChannel {
|
};
|
||||||
load_op,
|
wgpu_com::ColorAttachmentDescriptor {
|
||||||
store_op: match color.storeOp {
|
attachment: color.attachment.id().0,
|
||||||
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
resolve_target: color.resolveTarget.as_ref().map(|t| t.id().0),
|
||||||
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
channel,
|
||||||
},
|
}
|
||||||
clear_value,
|
})
|
||||||
read_only: false,
|
.collect::<Vec<_>>(),
|
||||||
};
|
),
|
||||||
wgpu_com::ColorAttachmentDescriptor {
|
depth_stencil_attachment: depth_stencil.as_ref(),
|
||||||
attachment: color.attachment.id().0,
|
};
|
||||||
resolve_target: color.resolveTarget.as_ref().map(|t| t.id().0),
|
(
|
||||||
channel,
|
Some(wgpu_com::RenderPass::new(self.encoder.0, desc)),
|
||||||
}
|
WebGPUOpResult::Success,
|
||||||
})
|
)
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
),
|
|
||||||
depth_stencil_attachment: depth_stencil.as_ref(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let render_pass = wgpu_com::RenderPass::new(self.encoder.0, desc);
|
self.device.handle_server_msg(scope_id, res);
|
||||||
|
|
||||||
GPURenderPassEncoder::new(
|
GPURenderPassEncoder::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
|
@ -257,10 +291,9 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
destination_offset: GPUSize64,
|
destination_offset: GPUSize64,
|
||||||
size: GPUSize64,
|
size: GPUSize64,
|
||||||
) {
|
) {
|
||||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
|
||||||
let scope_id = self.device.use_current_scope();
|
let scope_id = self.device.use_current_scope();
|
||||||
|
|
||||||
if !valid {
|
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||||
self.device.handle_server_msg(
|
self.device.handle_server_msg(
|
||||||
scope_id,
|
scope_id,
|
||||||
WebGPUOpResult::ValidationError(String::from(
|
WebGPUOpResult::ValidationError(String::from(
|
||||||
|
@ -299,10 +332,9 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
destination: &GPUTextureCopyView,
|
destination: &GPUTextureCopyView,
|
||||||
copy_size: GPUExtent3D,
|
copy_size: GPUExtent3D,
|
||||||
) {
|
) {
|
||||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
|
||||||
let scope_id = self.device.use_current_scope();
|
let scope_id = self.device.use_current_scope();
|
||||||
|
|
||||||
if !valid {
|
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||||
self.device.handle_server_msg(
|
self.device.handle_server_msg(
|
||||||
scope_id,
|
scope_id,
|
||||||
WebGPUOpResult::ValidationError(String::from(
|
WebGPUOpResult::ValidationError(String::from(
|
||||||
|
@ -341,10 +373,9 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
destination: &GPUBufferCopyView,
|
destination: &GPUBufferCopyView,
|
||||||
copy_size: GPUExtent3D,
|
copy_size: GPUExtent3D,
|
||||||
) {
|
) {
|
||||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
|
||||||
let scope_id = self.device.use_current_scope();
|
let scope_id = self.device.use_current_scope();
|
||||||
|
|
||||||
if !valid {
|
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||||
self.device.handle_server_msg(
|
self.device.handle_server_msg(
|
||||||
scope_id,
|
scope_id,
|
||||||
WebGPUOpResult::ValidationError(String::from(
|
WebGPUOpResult::ValidationError(String::from(
|
||||||
|
@ -383,10 +414,9 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
destination: &GPUTextureCopyView,
|
destination: &GPUTextureCopyView,
|
||||||
copy_size: GPUExtent3D,
|
copy_size: GPUExtent3D,
|
||||||
) {
|
) {
|
||||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
|
||||||
let scope_id = self.device.use_current_scope();
|
let scope_id = self.device.use_current_scope();
|
||||||
|
|
||||||
if !valid {
|
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||||
self.device.handle_server_msg(
|
self.device.handle_server_msg(
|
||||||
scope_id,
|
scope_id,
|
||||||
WebGPUOpResult::ValidationError(String::from(
|
WebGPUOpResult::ValidationError(String::from(
|
||||||
|
@ -423,6 +453,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||||
WebGPURequest::CommandEncoderFinish {
|
WebGPURequest::CommandEncoderFinish {
|
||||||
command_encoder_id: self.encoder.0,
|
command_encoder_id: self.encoder.0,
|
||||||
device_id: self.device.id().0,
|
device_id: self.device.id().0,
|
||||||
|
is_error: !self.valid.get(),
|
||||||
// TODO(zakorgy): We should use `_descriptor` here after it's not empty
|
// TODO(zakorgy): We should use `_descriptor` here after it's not empty
|
||||||
// and the underlying wgpu-core struct is serializable
|
// and the underlying wgpu-core struct is serializable
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,13 +33,14 @@ impl GPUComputePassEncoder {
|
||||||
fn new_inherited(
|
fn new_inherited(
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
parent: &GPUCommandEncoder,
|
parent: &GPUCommandEncoder,
|
||||||
|
compute_pass: Option<ComputePass>,
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
channel,
|
channel,
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
label: DomRefCell::new(label),
|
label: DomRefCell::new(label),
|
||||||
compute_pass: DomRefCell::new(Some(ComputePass::new(parent.id().0))),
|
compute_pass: DomRefCell::new(compute_pass),
|
||||||
command_encoder: Dom::from_ref(parent),
|
command_encoder: Dom::from_ref(parent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,10 +49,16 @@ impl GPUComputePassEncoder {
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
parent: &GPUCommandEncoder,
|
parent: &GPUCommandEncoder,
|
||||||
|
compute_pass: Option<ComputePass>,
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(GPUComputePassEncoder::new_inherited(channel, parent, label)),
|
Box::new(GPUComputePassEncoder::new_inherited(
|
||||||
|
channel,
|
||||||
|
parent,
|
||||||
|
compute_pass,
|
||||||
|
label,
|
||||||
|
)),
|
||||||
global,
|
global,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -88,24 +95,23 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
|
||||||
|
|
||||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass
|
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass
|
||||||
fn EndPass(&self) {
|
fn EndPass(&self) {
|
||||||
if let Some(compute_pass) = self.compute_pass.borrow_mut().take() {
|
let compute_pass = self.compute_pass.borrow_mut().take();
|
||||||
self.channel
|
self.channel
|
||||||
.0
|
.0
|
||||||
.send((
|
.send((
|
||||||
self.command_encoder.device().use_current_scope(),
|
self.command_encoder.device().use_current_scope(),
|
||||||
WebGPURequest::RunComputePass {
|
WebGPURequest::RunComputePass {
|
||||||
command_encoder_id: self.command_encoder.id().0,
|
command_encoder_id: self.command_encoder.id().0,
|
||||||
device_id: self.command_encoder.device().id().0,
|
device_id: self.command_encoder.device().id().0,
|
||||||
compute_pass,
|
compute_pass,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.expect("Failed to send RunComputePass");
|
.expect("Failed to send RunComputePass");
|
||||||
|
|
||||||
self.command_encoder.set_state(
|
self.command_encoder.set_state(
|
||||||
GPUCommandEncoderState::Open,
|
GPUCommandEncoderState::Open,
|
||||||
GPUCommandEncoderState::EncodingComputePass,
|
GPUCommandEncoderState::EncodingComputePass,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuprogrammablepassencoder-setbindgroup
|
/// https://gpuweb.github.io/gpuweb/#dom-gpuprogrammablepassencoder-setbindgroup
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub struct GPURenderPassEncoder {
|
||||||
impl GPURenderPassEncoder {
|
impl GPURenderPassEncoder {
|
||||||
fn new_inherited(
|
fn new_inherited(
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
render_pass: RenderPass,
|
render_pass: Option<RenderPass>,
|
||||||
parent: &GPUCommandEncoder,
|
parent: &GPUCommandEncoder,
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -43,7 +43,7 @@ impl GPURenderPassEncoder {
|
||||||
channel,
|
channel,
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
label: DomRefCell::new(label),
|
label: DomRefCell::new(label),
|
||||||
render_pass: DomRefCell::new(Some(render_pass)),
|
render_pass: DomRefCell::new(render_pass),
|
||||||
command_encoder: Dom::from_ref(parent),
|
command_encoder: Dom::from_ref(parent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ impl GPURenderPassEncoder {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
channel: WebGPU,
|
channel: WebGPU,
|
||||||
render_pass: RenderPass,
|
render_pass: Option<RenderPass>,
|
||||||
parent: &GPUCommandEncoder,
|
parent: &GPUCommandEncoder,
|
||||||
label: Option<USVString>,
|
label: Option<USVString>,
|
||||||
) -> DomRoot<Self> {
|
) -> DomRoot<Self> {
|
||||||
|
@ -126,27 +126,27 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
||||||
|
|
||||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-setblendcolor
|
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-setblendcolor
|
||||||
fn SetBlendColor(&self, color: GPUColor) {
|
fn SetBlendColor(&self, color: GPUColor) {
|
||||||
let colors = match color {
|
|
||||||
GPUColor::GPUColorDict(d) => wgt::Color {
|
|
||||||
r: *d.r,
|
|
||||||
g: *d.g,
|
|
||||||
b: *d.b,
|
|
||||||
a: *d.a,
|
|
||||||
},
|
|
||||||
GPUColor::DoubleSequence(mut s) => {
|
|
||||||
if s.len() < 3 {
|
|
||||||
s.resize(3, Finite::wrap(0.0f64));
|
|
||||||
}
|
|
||||||
s.resize(4, Finite::wrap(1.0f64));
|
|
||||||
wgt::Color {
|
|
||||||
r: *s[0],
|
|
||||||
g: *s[1],
|
|
||||||
b: *s[2],
|
|
||||||
a: *s[3],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if let Some(render_pass) = self.render_pass.borrow_mut().as_mut() {
|
if let Some(render_pass) = self.render_pass.borrow_mut().as_mut() {
|
||||||
|
let colors = match color {
|
||||||
|
GPUColor::GPUColorDict(d) => wgt::Color {
|
||||||
|
r: *d.r,
|
||||||
|
g: *d.g,
|
||||||
|
b: *d.b,
|
||||||
|
a: *d.a,
|
||||||
|
},
|
||||||
|
GPUColor::DoubleSequence(mut s) => {
|
||||||
|
if s.len() < 3 {
|
||||||
|
s.resize(3, Finite::wrap(0.0f64));
|
||||||
|
}
|
||||||
|
s.resize(4, Finite::wrap(1.0f64));
|
||||||
|
wgt::Color {
|
||||||
|
r: *s[0],
|
||||||
|
g: *s[1],
|
||||||
|
b: *s[2],
|
||||||
|
a: *s[3],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
wgpu_render::wgpu_render_pass_set_blend_color(render_pass, &colors);
|
wgpu_render::wgpu_render_pass_set_blend_color(render_pass, &colors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,24 +160,23 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
||||||
|
|
||||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass
|
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass
|
||||||
fn EndPass(&self) {
|
fn EndPass(&self) {
|
||||||
if let Some(render_pass) = self.render_pass.borrow_mut().take() {
|
let render_pass = self.render_pass.borrow_mut().take();
|
||||||
self.channel
|
self.channel
|
||||||
.0
|
.0
|
||||||
.send((
|
.send((
|
||||||
self.command_encoder.device().use_current_scope(),
|
self.command_encoder.device().use_current_scope(),
|
||||||
WebGPURequest::RunRenderPass {
|
WebGPURequest::RunRenderPass {
|
||||||
command_encoder_id: self.command_encoder.id().0,
|
command_encoder_id: self.command_encoder.id().0,
|
||||||
device_id: self.command_encoder.device().id().0,
|
device_id: self.command_encoder.device().id().0,
|
||||||
render_pass,
|
render_pass,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.expect("Failed to send RunRenderPass");
|
.expect("Failed to send RunRenderPass");
|
||||||
|
|
||||||
self.command_encoder.set_state(
|
self.command_encoder.set_state(
|
||||||
GPUCommandEncoderState::Open,
|
GPUCommandEncoderState::Open,
|
||||||
GPUCommandEncoderState::EncodingRenderPass,
|
GPUCommandEncoderState::EncodingRenderPass,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderencoderbase-setpipeline
|
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderencoderbase-setpipeline
|
||||||
|
|
|
@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -77,6 +77,7 @@ pub enum WebGPURequest {
|
||||||
CommandEncoderFinish {
|
CommandEncoderFinish {
|
||||||
command_encoder_id: id::CommandEncoderId,
|
command_encoder_id: id::CommandEncoderId,
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
|
is_error: bool,
|
||||||
// TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core
|
// TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core
|
||||||
// wgpu::command::CommandBufferDescriptor,
|
// wgpu::command::CommandBufferDescriptor,
|
||||||
},
|
},
|
||||||
|
@ -207,12 +208,12 @@ pub enum WebGPURequest {
|
||||||
RunComputePass {
|
RunComputePass {
|
||||||
command_encoder_id: id::CommandEncoderId,
|
command_encoder_id: id::CommandEncoderId,
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
compute_pass: ComputePass,
|
compute_pass: Option<ComputePass>,
|
||||||
},
|
},
|
||||||
RunRenderPass {
|
RunRenderPass {
|
||||||
command_encoder_id: id::CommandEncoderId,
|
command_encoder_id: id::CommandEncoderId,
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
render_pass: RenderPass,
|
render_pass: Option<RenderPass>,
|
||||||
},
|
},
|
||||||
Submit {
|
Submit {
|
||||||
queue_id: id::QueueId,
|
queue_id: id::QueueId,
|
||||||
|
@ -337,6 +338,8 @@ struct WGPU<'a> {
|
||||||
// Presentation Buffers with pending mapping
|
// Presentation Buffers with pending mapping
|
||||||
present_buffer_maps:
|
present_buffer_maps:
|
||||||
HashMap<id::BufferId, Rc<BufferMapInfo<'a, (Option<ErrorScopeId>, WebGPURequest)>>>,
|
HashMap<id::BufferId, Rc<BufferMapInfo<'a, (Option<ErrorScopeId>, WebGPURequest)>>>,
|
||||||
|
//TODO: Remove this (https://github.com/gfx-rs/wgpu/issues/867)
|
||||||
|
error_command_buffers: HashSet<id::CommandBufferId>,
|
||||||
webrender_api: webrender_api::RenderApi,
|
webrender_api: webrender_api::RenderApi,
|
||||||
webrender_document: webrender_api::DocumentId,
|
webrender_document: webrender_api::DocumentId,
|
||||||
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||||
|
@ -368,6 +371,7 @@ impl<'a> WGPU<'a> {
|
||||||
_invalid_adapters: Vec::new(),
|
_invalid_adapters: Vec::new(),
|
||||||
buffer_maps: HashMap::new(),
|
buffer_maps: HashMap::new(),
|
||||||
present_buffer_maps: HashMap::new(),
|
present_buffer_maps: HashMap::new(),
|
||||||
|
error_command_buffers: HashSet::new(),
|
||||||
webrender_api: webrender_api_sender.create_api(),
|
webrender_api: webrender_api_sender.create_api(),
|
||||||
webrender_document,
|
webrender_document,
|
||||||
external_images,
|
external_images,
|
||||||
|
@ -450,14 +454,20 @@ impl<'a> WGPU<'a> {
|
||||||
WebGPURequest::CommandEncoderFinish {
|
WebGPURequest::CommandEncoderFinish {
|
||||||
command_encoder_id,
|
command_encoder_id,
|
||||||
device_id,
|
device_id,
|
||||||
|
is_error,
|
||||||
} => {
|
} => {
|
||||||
let global = &self.global;
|
let global = &self.global;
|
||||||
let result = gfx_select!(command_encoder_id => global.command_encoder_finish(
|
let result = if is_error {
|
||||||
command_encoder_id,
|
Err(String::from("Invalid GPUCommandEncoder"))
|
||||||
&wgt::CommandBufferDescriptor::default()
|
} else {
|
||||||
));
|
gfx_select!(command_encoder_id => global.command_encoder_finish(
|
||||||
|
command_encoder_id,
|
||||||
|
&wgt::CommandBufferDescriptor::default()
|
||||||
|
))
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
};
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
let _ = gfx_select!(command_encoder_id => global.command_buffer_error(command_encoder_id));
|
self.error_command_buffers.insert(command_encoder_id);
|
||||||
}
|
}
|
||||||
self.send_result(device_id, scope_id, result);
|
self.send_result(device_id, scope_id, result);
|
||||||
},
|
},
|
||||||
|
@ -967,10 +977,14 @@ impl<'a> WGPU<'a> {
|
||||||
compute_pass,
|
compute_pass,
|
||||||
} => {
|
} => {
|
||||||
let global = &self.global;
|
let global = &self.global;
|
||||||
let result = gfx_select!(command_encoder_id => global.command_encoder_run_compute_pass(
|
let result = if let Some(pass) = compute_pass {
|
||||||
command_encoder_id,
|
gfx_select!(command_encoder_id => global.command_encoder_run_compute_pass(
|
||||||
&compute_pass
|
command_encoder_id,
|
||||||
));
|
&pass
|
||||||
|
)).map_err(|e| format!("{:?}", e))
|
||||||
|
} else {
|
||||||
|
Err(String::from("Invalid ComputePass"))
|
||||||
|
};
|
||||||
self.send_result(device_id, scope_id, result);
|
self.send_result(device_id, scope_id, result);
|
||||||
},
|
},
|
||||||
WebGPURequest::RunRenderPass {
|
WebGPURequest::RunRenderPass {
|
||||||
|
@ -979,10 +993,14 @@ impl<'a> WGPU<'a> {
|
||||||
render_pass,
|
render_pass,
|
||||||
} => {
|
} => {
|
||||||
let global = &self.global;
|
let global = &self.global;
|
||||||
let result = gfx_select!(command_encoder_id => global.command_encoder_run_render_pass(
|
let result = if let Some(pass) = render_pass {
|
||||||
command_encoder_id,
|
gfx_select!(command_encoder_id => global.command_encoder_run_render_pass(
|
||||||
&render_pass
|
command_encoder_id,
|
||||||
));
|
&pass
|
||||||
|
)).map_err(|e| format!("{:?}", e))
|
||||||
|
} else {
|
||||||
|
Err(String::from("Invalid RenderPass"))
|
||||||
|
};
|
||||||
self.send_result(device_id, scope_id, result);
|
self.send_result(device_id, scope_id, result);
|
||||||
},
|
},
|
||||||
WebGPURequest::Submit {
|
WebGPURequest::Submit {
|
||||||
|
@ -990,7 +1008,15 @@ impl<'a> WGPU<'a> {
|
||||||
command_buffers,
|
command_buffers,
|
||||||
} => {
|
} => {
|
||||||
let global = &self.global;
|
let global = &self.global;
|
||||||
let result = gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers));
|
let cmd_id = command_buffers
|
||||||
|
.iter()
|
||||||
|
.find(|id| self.error_command_buffers.contains(id));
|
||||||
|
let result = if cmd_id.is_some() {
|
||||||
|
Err(String::from("Invalid command buffer submitted"))
|
||||||
|
} else {
|
||||||
|
gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers))
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
};
|
||||||
self.send_result(queue_id, scope_id, result);
|
self.send_result(queue_id, scope_id, result);
|
||||||
},
|
},
|
||||||
WebGPURequest::SwapChainPresent {
|
WebGPURequest::SwapChainPresent {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue