summaryrefslogtreecommitdiff
path: root/ext/webgpu/pipeline.rs
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2021-08-24 20:32:25 +0200
committerGitHub <noreply@github.com>2021-08-24 20:32:25 +0200
commit4853be20f2d649842ebc97124d8479c7aad7cc9b (patch)
tree1be4dcc96c72166b3e1e4f19ee70eb791e1304aa /ext/webgpu/pipeline.rs
parente10d30c8eaf41ad68b48f21c8d563d192b82afe8 (diff)
refactor(webgpu): use op interface idiomatically (#11835)
Diffstat (limited to 'ext/webgpu/pipeline.rs')
-rw-r--r--ext/webgpu/pipeline.rs645
1 files changed, 380 insertions, 265 deletions
diff --git a/ext/webgpu/pipeline.rs b/ext/webgpu/pipeline.rs
index 877143f94..77edcadfb 100644
--- a/ext/webgpu/pipeline.rs
+++ b/ext/webgpu/pipeline.rs
@@ -6,6 +6,10 @@ use deno_core::{OpState, Resource};
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
+use std::convert::{TryFrom, TryInto};
+
+use crate::sampler::GpuCompareFunction;
+use crate::texture::GpuTextureFormat;
use super::error::{WebGpuError, WebGpuResult};
@@ -38,121 +42,196 @@ impl Resource for WebGpuRenderPipeline {
}
}
-pub fn serialize_index_format(format: String) -> wgpu_types::IndexFormat {
- match format.as_str() {
- "uint16" => wgpu_types::IndexFormat::Uint16,
- "uint32" => wgpu_types::IndexFormat::Uint32,
- _ => unreachable!(),
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuIndexFormat {
+ Uint16,
+ Uint32,
+}
+
+impl From<GpuIndexFormat> for wgpu_types::IndexFormat {
+ fn from(value: GpuIndexFormat) -> wgpu_types::IndexFormat {
+ match value {
+ GpuIndexFormat::Uint16 => wgpu_types::IndexFormat::Uint16,
+ GpuIndexFormat::Uint32 => wgpu_types::IndexFormat::Uint32,
+ }
}
}
-fn serialize_stencil_operation(
- operation: &str,
-) -> wgpu_types::StencilOperation {
- match operation {
- "keep" => wgpu_types::StencilOperation::Keep,
- "zero" => wgpu_types::StencilOperation::Zero,
- "replace" => wgpu_types::StencilOperation::Replace,
- "invert" => wgpu_types::StencilOperation::Invert,
- "increment-clamp" => wgpu_types::StencilOperation::IncrementClamp,
- "decrement-clamp" => wgpu_types::StencilOperation::DecrementClamp,
- "increment-wrap" => wgpu_types::StencilOperation::IncrementWrap,
- "decrement-wrap" => wgpu_types::StencilOperation::DecrementWrap,
- _ => unreachable!(),
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GPUStencilOperation {
+ Keep,
+ Zero,
+ Replace,
+ Invert,
+ IncrementClamp,
+ DecrementClamp,
+ IncrementWrap,
+ DecrementWrap,
+}
+
+impl From<GPUStencilOperation> for wgpu_types::StencilOperation {
+ fn from(value: GPUStencilOperation) -> wgpu_types::StencilOperation {
+ match value {
+ GPUStencilOperation::Keep => wgpu_types::StencilOperation::Keep,
+ GPUStencilOperation::Zero => wgpu_types::StencilOperation::Zero,
+ GPUStencilOperation::Replace => wgpu_types::StencilOperation::Replace,
+ GPUStencilOperation::Invert => wgpu_types::StencilOperation::Invert,
+ GPUStencilOperation::IncrementClamp => {
+ wgpu_types::StencilOperation::IncrementClamp
+ }
+ GPUStencilOperation::DecrementClamp => {
+ wgpu_types::StencilOperation::DecrementClamp
+ }
+ GPUStencilOperation::IncrementWrap => {
+ wgpu_types::StencilOperation::IncrementWrap
+ }
+ GPUStencilOperation::DecrementWrap => {
+ wgpu_types::StencilOperation::DecrementWrap
+ }
+ }
}
}
-fn serialize_stencil_face_state(
- state: GpuStencilFaceState,
-) -> wgpu_types::StencilFaceState {
- wgpu_types::StencilFaceState {
- compare: state
- .compare
- .as_ref()
- .map_or(wgpu_types::CompareFunction::Always, |op| {
- super::sampler::serialize_compare_function(op)
- }),
- fail_op: state
- .fail_op
- .as_ref()
- .map_or(wgpu_types::StencilOperation::Keep, |op| {
- serialize_stencil_operation(op)
- }),
- depth_fail_op: state
- .depth_fail_op
- .as_ref()
- .map_or(wgpu_types::StencilOperation::Keep, |op| {
- serialize_stencil_operation(op)
- }),
- pass_op: state
- .pass_op
- .as_ref()
- .map_or(wgpu_types::StencilOperation::Keep, |op| {
- serialize_stencil_operation(op)
- }),
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuBlendFactor {
+ Zero,
+ One,
+ Src,
+ OneMinusSrc,
+ SrcAlpha,
+ OneMinusSrcAlpha,
+ Dst,
+ OneMinusDst,
+ DstAlpha,
+ OneMinusDstAlpha,
+ SrcAlphaSaturated,
+ Constant,
+ OneMinusConstant,
+}
+
+impl From<GpuBlendFactor> for wgpu_types::BlendFactor {
+ fn from(value: GpuBlendFactor) -> wgpu_types::BlendFactor {
+ match value {
+ GpuBlendFactor::Zero => wgpu_types::BlendFactor::Zero,
+ GpuBlendFactor::One => wgpu_types::BlendFactor::One,
+ GpuBlendFactor::Src => wgpu_types::BlendFactor::Src,
+ GpuBlendFactor::OneMinusSrc => wgpu_types::BlendFactor::OneMinusSrc,
+ GpuBlendFactor::SrcAlpha => wgpu_types::BlendFactor::SrcAlpha,
+ GpuBlendFactor::OneMinusSrcAlpha => {
+ wgpu_types::BlendFactor::OneMinusSrcAlpha
+ }
+ GpuBlendFactor::Dst => wgpu_types::BlendFactor::Dst,
+ GpuBlendFactor::OneMinusDst => wgpu_types::BlendFactor::OneMinusDst,
+ GpuBlendFactor::DstAlpha => wgpu_types::BlendFactor::DstAlpha,
+ GpuBlendFactor::OneMinusDstAlpha => {
+ wgpu_types::BlendFactor::OneMinusDstAlpha
+ }
+ GpuBlendFactor::SrcAlphaSaturated => {
+ wgpu_types::BlendFactor::SrcAlphaSaturated
+ }
+ GpuBlendFactor::Constant => wgpu_types::BlendFactor::Constant,
+ GpuBlendFactor::OneMinusConstant => {
+ wgpu_types::BlendFactor::OneMinusConstant
+ }
+ }
}
}
-fn serialize_blend_factor(blend_factor: &str) -> wgpu_types::BlendFactor {
- match blend_factor {
- "zero" => wgpu_types::BlendFactor::Zero,
- "one" => wgpu_types::BlendFactor::One,
- "src" => wgpu_types::BlendFactor::Src,
- "one-minus-src" => wgpu_types::BlendFactor::OneMinusSrc,
- "src-alpha" => wgpu_types::BlendFactor::SrcAlpha,
- "one-minus-src-alpha" => wgpu_types::BlendFactor::OneMinusSrcAlpha,
- "dst" => wgpu_types::BlendFactor::Dst,
- "one-minus-dst" => wgpu_types::BlendFactor::OneMinusDst,
- "dst-alpha" => wgpu_types::BlendFactor::DstAlpha,
- "one-minus-dst-alpha" => wgpu_types::BlendFactor::OneMinusDstAlpha,
- "src-alpha-saturated" => wgpu_types::BlendFactor::SrcAlphaSaturated,
- "constant" => wgpu_types::BlendFactor::Constant,
- "one-minus-constant" => wgpu_types::BlendFactor::OneMinusConstant,
- _ => unreachable!(),
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuBlendOperation {
+ Add,
+ Subtract,
+ ReverseSubtract,
+ Min,
+ Max,
+}
+
+impl From<GpuBlendOperation> for wgpu_types::BlendOperation {
+ fn from(value: GpuBlendOperation) -> wgpu_types::BlendOperation {
+ match value {
+ GpuBlendOperation::Add => wgpu_types::BlendOperation::Add,
+ GpuBlendOperation::Subtract => wgpu_types::BlendOperation::Subtract,
+ GpuBlendOperation::ReverseSubtract => {
+ wgpu_types::BlendOperation::ReverseSubtract
+ }
+ GpuBlendOperation::Min => wgpu_types::BlendOperation::Min,
+ GpuBlendOperation::Max => wgpu_types::BlendOperation::Max,
+ }
}
}
-fn serialize_blend_state(state: GpuBlendState) -> wgpu_types::BlendState {
- wgpu_types::BlendState {
- alpha: serialize_blend_component(state.alpha),
- color: serialize_blend_component(state.color),
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuPrimitiveTopology {
+ PointList,
+ LineList,
+ LineStrip,
+ TriangleList,
+ TriangleStrip,
+}
+
+impl From<GpuPrimitiveTopology> for wgpu_types::PrimitiveTopology {
+ fn from(value: GpuPrimitiveTopology) -> wgpu_types::PrimitiveTopology {
+ match value {
+ GpuPrimitiveTopology::PointList => {
+ wgpu_types::PrimitiveTopology::PointList
+ }
+ GpuPrimitiveTopology::LineList => wgpu_types::PrimitiveTopology::LineList,
+ GpuPrimitiveTopology::LineStrip => {
+ wgpu_types::PrimitiveTopology::LineStrip
+ }
+ GpuPrimitiveTopology::TriangleList => {
+ wgpu_types::PrimitiveTopology::TriangleList
+ }
+ GpuPrimitiveTopology::TriangleStrip => {
+ wgpu_types::PrimitiveTopology::TriangleStrip
+ }
+ }
}
}
-fn serialize_blend_component(
- blend: GpuBlendComponent,
-) -> wgpu_types::BlendComponent {
- wgpu_types::BlendComponent {
- src_factor: blend
- .src_factor
- .as_ref()
- .map_or(wgpu_types::BlendFactor::One, |factor| {
- serialize_blend_factor(factor)
- }),
- dst_factor: blend
- .dst_factor
- .as_ref()
- .map_or(wgpu_types::BlendFactor::Zero, |factor| {
- serialize_blend_factor(factor)
- }),
- operation: match &blend.operation {
- Some(operation) => match operation.as_str() {
- "add" => wgpu_types::BlendOperation::Add,
- "subtract" => wgpu_types::BlendOperation::Subtract,
- "reverse-subtract" => wgpu_types::BlendOperation::ReverseSubtract,
- "min" => wgpu_types::BlendOperation::Min,
- "max" => wgpu_types::BlendOperation::Max,
- _ => unreachable!(),
- },
- None => wgpu_types::BlendOperation::Add,
- },
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuFrontFace {
+ Ccw,
+ Cw,
+}
+
+impl From<GpuFrontFace> for wgpu_types::FrontFace {
+ fn from(value: GpuFrontFace) -> wgpu_types::FrontFace {
+ match value {
+ GpuFrontFace::Ccw => wgpu_types::FrontFace::Ccw,
+ GpuFrontFace::Cw => wgpu_types::FrontFace::Cw,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum GpuCullMode {
+ None,
+ Front,
+ Back,
+}
+
+impl From<GpuCullMode> for Option<wgpu_types::Face> {
+ fn from(value: GpuCullMode) -> Option<wgpu_types::Face> {
+ match value {
+ GpuCullMode::None => None,
+ GpuCullMode::Front => Some(wgpu_types::Face::Front),
+ GpuCullMode::Back => Some(wgpu_types::Face::Back),
+ }
}
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuProgrammableStage {
- module: u32,
+ module: ResourceId,
entry_point: String,
// constants: HashMap<String, GPUPipelineConstantValue>
}
@@ -162,7 +241,7 @@ struct GpuProgrammableStage {
pub struct CreateComputePipelineArgs {
device_rid: ResourceId,
label: Option<String>,
- layout: Option<u32>,
+ layout: Option<ResourceId>,
compute: GpuProgrammableStage,
}
@@ -264,58 +343,138 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuPrimitiveState {
- topology: Option<String>,
- strip_index_format: Option<String>,
- front_face: Option<String>,
- cull_mode: Option<String>,
+ topology: GpuPrimitiveTopology,
+ strip_index_format: Option<GpuIndexFormat>,
+ front_face: GpuFrontFace,
+ cull_mode: GpuCullMode,
clamp_depth: bool,
}
-#[derive(Deserialize, Clone)]
+impl From<GpuPrimitiveState> for wgpu_types::PrimitiveState {
+ fn from(value: GpuPrimitiveState) -> wgpu_types::PrimitiveState {
+ wgpu_types::PrimitiveState {
+ topology: value.topology.into(),
+ strip_index_format: value.strip_index_format.map(Into::into),
+ front_face: value.front_face.into(),
+ cull_mode: value.cull_mode.into(),
+ clamp_depth: value.clamp_depth,
+ polygon_mode: Default::default(), // native-only
+ conservative: false, // native-only
+ }
+ }
+}
+#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuBlendComponent {
- src_factor: Option<String>,
- dst_factor: Option<String>,
- operation: Option<String>,
+ src_factor: GpuBlendFactor,
+ dst_factor: GpuBlendFactor,
+ operation: GpuBlendOperation,
+}
+
+impl From<GpuBlendComponent> for wgpu_types::BlendComponent {
+ fn from(component: GpuBlendComponent) -> Self {
+ wgpu_types::BlendComponent {
+ src_factor: component.src_factor.into(),
+ dst_factor: component.dst_factor.into(),
+ operation: component.operation.into(),
+ }
+ }
}
-#[derive(Deserialize, Clone)]
+#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuBlendState {
color: GpuBlendComponent,
alpha: GpuBlendComponent,
}
+impl From<GpuBlendState> for wgpu_types::BlendState {
+ fn from(state: GpuBlendState) -> wgpu_types::BlendState {
+ wgpu_types::BlendState {
+ color: state.color.into(),
+ alpha: state.alpha.into(),
+ }
+ }
+}
+
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuColorTargetState {
- format: String,
+ format: GpuTextureFormat,
blend: Option<GpuBlendState>,
- write_mask: Option<u32>,
+ write_mask: u32,
+}
+
+impl TryFrom<GpuColorTargetState> for wgpu_types::ColorTargetState {
+ type Error = AnyError;
+ fn try_from(
+ state: GpuColorTargetState,
+ ) -> Result<wgpu_types::ColorTargetState, AnyError> {
+ Ok(wgpu_types::ColorTargetState {
+ format: state.format.try_into()?,
+ blend: state.blend.map(Into::into),
+ write_mask: wgpu_types::ColorWrites::from_bits_truncate(state.write_mask),
+ })
+ }
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuStencilFaceState {
- compare: Option<String>,
- fail_op: Option<String>,
- depth_fail_op: Option<String>,
- pass_op: Option<String>,
+ compare: GpuCompareFunction,
+ fail_op: GPUStencilOperation,
+ depth_fail_op: GPUStencilOperation,
+ pass_op: GPUStencilOperation,
+}
+
+impl From<GpuStencilFaceState> for wgpu_types::StencilFaceState {
+ fn from(state: GpuStencilFaceState) -> Self {
+ wgpu_types::StencilFaceState {
+ compare: state.compare.into(),
+ fail_op: state.fail_op.into(),
+ depth_fail_op: state.depth_fail_op.into(),
+ pass_op: state.pass_op.into(),
+ }
+ }
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuDepthStencilState {
- format: String,
- depth_write_enabled: Option<bool>,
- depth_compare: Option<String>,
- stencil_front: Option<GpuStencilFaceState>,
- stencil_back: Option<GpuStencilFaceState>,
- stencil_read_mask: Option<u32>,
- stencil_write_mask: Option<u32>,
- depth_bias: Option<i32>,
- depth_bias_slope_scale: Option<f32>,
- depth_bias_clamp: Option<f32>,
+ format: GpuTextureFormat,
+ depth_write_enabled: bool,
+ depth_compare: GpuCompareFunction,
+ stencil_front: GpuStencilFaceState,
+ stencil_back: GpuStencilFaceState,
+ stencil_read_mask: u32,
+ stencil_write_mask: u32,
+ depth_bias: i32,
+ depth_bias_slope_scale: f32,
+ depth_bias_clamp: f32,
+}
+
+impl TryFrom<GpuDepthStencilState> for wgpu_types::DepthStencilState {
+ type Error = AnyError;
+ fn try_from(
+ state: GpuDepthStencilState,
+ ) -> Result<wgpu_types::DepthStencilState, AnyError> {
+ Ok(wgpu_types::DepthStencilState {
+ format: state.format.try_into()?,
+ depth_write_enabled: state.depth_write_enabled,
+ depth_compare: state.depth_compare.into(),
+ stencil: wgpu_types::StencilState {
+ front: state.stencil_front.into(),
+ back: state.stencil_back.into(),
+ read_mask: state.stencil_read_mask,
+ write_mask: state.stencil_write_mask,
+ },
+ bias: wgpu_types::DepthBiasState {
+ constant: state.depth_bias,
+ slope_scale: state.depth_bias_slope_scale,
+ clamp: state.depth_bias_clamp,
+ },
+ })
+ }
}
#[derive(Deserialize)]
@@ -326,6 +485,16 @@ struct GpuVertexAttribute {
shader_location: u32,
}
+impl From<GpuVertexAttribute> for wgpu_types::VertexAttribute {
+ fn from(attribute: GpuVertexAttribute) -> Self {
+ wgpu_types::VertexAttribute {
+ format: attribute.format.into(),
+ offset: attribute.offset,
+ shader_location: attribute.shader_location,
+ }
+ }
+}
+
#[derive(Deserialize)]
#[serde(rename_all = "lowercase")]
enum GpuVertexFormat {
@@ -409,26 +578,69 @@ impl From<GpuVertexFormat> for wgpu_types::VertexFormat {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
+enum GpuVertexStepMode {
+ Vertex,
+ Instance,
+}
+
+impl From<GpuVertexStepMode> for wgpu_types::VertexStepMode {
+ fn from(vsm: GpuVertexStepMode) -> wgpu_types::VertexStepMode {
+ use wgpu_types::VertexStepMode;
+ match vsm {
+ GpuVertexStepMode::Vertex => VertexStepMode::Vertex,
+ GpuVertexStepMode::Instance => VertexStepMode::Instance,
+ }
+ }
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
struct GpuVertexBufferLayout {
array_stride: u64,
- step_mode: Option<String>,
+ step_mode: GpuVertexStepMode,
attributes: Vec<GpuVertexAttribute>,
}
+impl<'a> From<GpuVertexBufferLayout>
+ for wgpu_core::pipeline::VertexBufferLayout<'a>
+{
+ fn from(
+ layout: GpuVertexBufferLayout,
+ ) -> wgpu_core::pipeline::VertexBufferLayout<'a> {
+ wgpu_core::pipeline::VertexBufferLayout {
+ array_stride: layout.array_stride,
+ step_mode: layout.step_mode.into(),
+ attributes: Cow::Owned(
+ layout.attributes.into_iter().map(Into::into).collect(),
+ ),
+ }
+ }
+}
+
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuVertexState {
- module: u32,
+ module: ResourceId,
entry_point: String,
- buffers: Option<Vec<Option<GpuVertexBufferLayout>>>,
+ buffers: Vec<Option<GpuVertexBufferLayout>>,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct GpuMultisampleState {
- count: Option<u32>,
- mask: Option<u64>, // against spec, but future proof
- alpha_to_coverage_enabled: Option<bool>,
+ count: u32,
+ mask: u64,
+ alpha_to_coverage_enabled: bool,
+}
+
+impl From<GpuMultisampleState> for wgpu_types::MultisampleState {
+ fn from(gms: GpuMultisampleState) -> wgpu_types::MultisampleState {
+ wgpu_types::MultisampleState {
+ count: gms.count,
+ mask: gms.mask,
+ alpha_to_coverage_enabled: gms.alpha_to_coverage_enabled,
+ }
+ }
}
#[derive(Deserialize)]
@@ -437,6 +649,7 @@ struct GpuFragmentState {
targets: Vec<GpuColorTargetState>,
module: u32,
entry_point: String,
+ // TODO(lucacasonato): constants
}
#[derive(Deserialize)]
@@ -444,11 +657,11 @@ struct GpuFragmentState {
pub struct CreateRenderPipelineArgs {
device_rid: ResourceId,
label: Option<String>,
- layout: Option<u32>,
+ layout: Option<ResourceId>,
vertex: GpuVertexState,
- primitive: Option<GpuPrimitiveState>,
+ primitive: GpuPrimitiveState,
depth_stencil: Option<GpuDepthStencilState>,
- multisample: Option<GpuMultisampleState>,
+ multisample: GpuMultisampleState,
fragment: Option<GpuFragmentState>,
}
@@ -476,149 +689,51 @@ pub fn op_webgpu_create_render_pipeline(
.resource_table
.get::<super::shader::WebGpuShaderModule>(args.vertex.module)?;
+ let fragment = if let Some(fragment) = args.fragment {
+ let fragment_shader_module_resource =
+ state
+ .resource_table
+ .get::<super::shader::WebGpuShaderModule>(fragment.module)?;
+
+ let mut targets = Vec::with_capacity(fragment.targets.len());
+
+ for target in fragment.targets {
+ targets.push(target.try_into()?);
+ }
+
+ Some(wgpu_core::pipeline::FragmentState {
+ stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
+ module: fragment_shader_module_resource.0,
+ entry_point: Cow::from(fragment.entry_point),
+ },
+ targets: Cow::from(targets),
+ })
+ } else {
+ None
+ };
+
+ let vertex_buffers = args
+ .vertex
+ .buffers
+ .into_iter()
+ .flatten()
+ .map(Into::into)
+ .collect();
+
let descriptor = wgpu_core::pipeline::RenderPipelineDescriptor {
- label: args.label.map(Cow::from),
+ label: args.label.map(Cow::Owned),
layout,
vertex: wgpu_core::pipeline::VertexState {
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: vertex_shader_module_resource.0,
- entry_point: Cow::from(args.vertex.entry_point),
+ entry_point: Cow::Owned(args.vertex.entry_point),
},
- buffers: Cow::from(if let Some(buffers) = args.vertex.buffers {
- let mut return_buffers = vec![];
- for buffer in buffers.into_iter().flatten() {
- return_buffers.push(wgpu_core::pipeline::VertexBufferLayout {
- array_stride: buffer.array_stride,
- step_mode: match buffer.step_mode {
- Some(step_mode) => match step_mode.as_str() {
- "vertex" => wgpu_types::VertexStepMode::Vertex,
- "instance" => wgpu_types::VertexStepMode::Instance,
- _ => unreachable!(),
- },
- None => wgpu_types::VertexStepMode::Vertex,
- },
- attributes: Cow::from(
- buffer
- .attributes
- .into_iter()
- .map(|attribute| wgpu_types::VertexAttribute {
- format: attribute.format.into(),
- offset: attribute.offset,
- shader_location: attribute.shader_location,
- })
- .collect::<Vec<wgpu_types::VertexAttribute>>(),
- ),
- });
- }
- return_buffers
- } else {
- vec![]
- }),
+ buffers: Cow::Owned(vertex_buffers),
},
- primitive: args.primitive.map_or(Default::default(), |primitive| {
- wgpu_types::PrimitiveState {
- topology: match primitive.topology {
- Some(topology) => match topology.as_str() {
- "point-list" => wgpu_types::PrimitiveTopology::PointList,
- "line-list" => wgpu_types::PrimitiveTopology::LineList,
- "line-strip" => wgpu_types::PrimitiveTopology::LineStrip,
- "triangle-list" => wgpu_types::PrimitiveTopology::TriangleList,
- "triangle-strip" => wgpu_types::PrimitiveTopology::TriangleStrip,
- _ => unreachable!(),
- },
- None => wgpu_types::PrimitiveTopology::TriangleList,
- },
- strip_index_format: primitive
- .strip_index_format
- .map(serialize_index_format),
- front_face: match primitive.front_face {
- Some(front_face) => match front_face.as_str() {
- "ccw" => wgpu_types::FrontFace::Ccw,
- "cw" => wgpu_types::FrontFace::Cw,
- _ => unreachable!(),
- },
- None => wgpu_types::FrontFace::Ccw,
- },
- cull_mode: match primitive.cull_mode {
- Some(cull_mode) => match cull_mode.as_str() {
- "none" => None,
- "front" => Some(wgpu_types::Face::Front),
- "back" => Some(wgpu_types::Face::Back),
- _ => unreachable!(),
- },
- None => None,
- },
- polygon_mode: Default::default(), // native-only
- conservative: false, // native-only
- clamp_depth: primitive.clamp_depth,
- }
- }),
- depth_stencil: args.depth_stencil.map(|depth_stencil| {
- wgpu_types::DepthStencilState {
- format: super::texture::serialize_texture_format(&depth_stencil.format)
- .unwrap(),
- depth_write_enabled: depth_stencil.depth_write_enabled.unwrap_or(false),
- depth_compare: match depth_stencil.depth_compare {
- Some(depth_compare) => {
- super::sampler::serialize_compare_function(&depth_compare)
- }
- None => wgpu_types::CompareFunction::Always,
- },
- stencil: wgpu_types::StencilState {
- front: depth_stencil
- .stencil_front
- .map_or(Default::default(), serialize_stencil_face_state),
- back: depth_stencil
- .stencil_back
- .map_or(Default::default(), serialize_stencil_face_state),
- read_mask: depth_stencil.stencil_read_mask.unwrap_or(0xFFFFFFFF),
- write_mask: depth_stencil.stencil_write_mask.unwrap_or(0xFFFFFFFF),
- },
- bias: wgpu_types::DepthBiasState {
- constant: depth_stencil.depth_bias.unwrap_or(0),
- slope_scale: depth_stencil.depth_bias_slope_scale.unwrap_or(0.0),
- clamp: depth_stencil.depth_bias_clamp.unwrap_or(0.0),
- },
- }
- }),
- multisample: args.multisample.map_or(Default::default(), |multisample| {
- wgpu_types::MultisampleState {
- count: multisample.count.unwrap_or(1),
- mask: multisample.mask.unwrap_or(0xFFFFFFFF),
- alpha_to_coverage_enabled: multisample
- .alpha_to_coverage_enabled
- .unwrap_or(false),
- }
- }),
- fragment: args.fragment.map(|fragment| {
- let fragment_shader_module_resource = state
- .resource_table
- .get::<super::shader::WebGpuShaderModule>(fragment.module)
- .unwrap();
-
- wgpu_core::pipeline::FragmentState {
- stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
- module: fragment_shader_module_resource.0,
- entry_point: Cow::from(fragment.entry_point),
- },
- targets: Cow::from(
- fragment
- .targets
- .into_iter()
- .map(|target| wgpu_types::ColorTargetState {
- format: super::texture::serialize_texture_format(&target.format)
- .unwrap(),
- blend: target.blend.map(serialize_blend_state),
- write_mask: target
- .write_mask
- .map_or(Default::default(), |mask| {
- wgpu_types::ColorWrites::from_bits(mask).unwrap()
- }),
- })
- .collect::<Vec<wgpu_types::ColorTargetState>>(),
- ),
- }
- }),
+ primitive: args.primitive.into(),
+ depth_stencil: args.depth_stencil.map(TryInto::try_into).transpose()?,
+ multisample: args.multisample.into(),
+ fragment,
};
let implicit_pipelines = match args.layout {