diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-01-19 13:38:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-19 13:38:51 +0100 |
commit | 2ab21dafa768b3bb89f9a7f6550648263bc065d1 (patch) | |
tree | 584fbe7660d84a1cd85072412d65dd99610a94da /ext/webgpu/pipeline.rs | |
parent | 1259a3f48c00e95a8bb0964e4dabfa769a20bcde (diff) |
experiment: wgpu sync (#13402)
Diffstat (limited to 'ext/webgpu/pipeline.rs')
-rw-r--r-- | ext/webgpu/pipeline.rs | 791 |
1 files changed, 0 insertions, 791 deletions
diff --git a/ext/webgpu/pipeline.rs b/ext/webgpu/pipeline.rs deleted file mode 100644 index 1d22bdba0..000000000 --- a/ext/webgpu/pipeline.rs +++ /dev/null @@ -1,791 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use serde::Serialize; -use std::borrow::Cow; - -use crate::sampler::GpuCompareFunction; -use crate::texture::GpuTextureFormat; - -use super::error::{WebGpuError, WebGpuResult}; - -const MAX_BIND_GROUPS: usize = 8; - -pub(crate) struct WebGpuPipelineLayout( - pub(crate) wgpu_core::id::PipelineLayoutId, -); -impl Resource for WebGpuPipelineLayout { - fn name(&self) -> Cow<str> { - "webGPUPipelineLayout".into() - } -} - -pub(crate) struct WebGpuComputePipeline( - pub(crate) wgpu_core::id::ComputePipelineId, -); -impl Resource for WebGpuComputePipeline { - fn name(&self) -> Cow<str> { - "webGPUComputePipeline".into() - } -} - -pub(crate) struct WebGpuRenderPipeline( - pub(crate) wgpu_core::id::RenderPipelineId, -); -impl Resource for WebGpuRenderPipeline { - fn name(&self) -> Cow<str> { - "webGPURenderPipeline".into() - } -} - -#[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, - } - } -} - -#[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 - } - } - } -} - -#[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 - } - } - } -} - -#[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, - } - } -} - -#[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 - } - } - } -} - -#[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: ResourceId, - entry_point: String, - // constants: HashMap<String, GPUPipelineConstantValue> -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateComputePipelineArgs { - device_rid: ResourceId, - label: Option<String>, - layout: Option<ResourceId>, - compute: GpuProgrammableStage, -} - -pub fn op_webgpu_create_compute_pipeline( - state: &mut OpState, - args: CreateComputePipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let pipeline_layout = if let Some(rid) = args.layout { - let id = state.resource_table.get::<WebGpuPipelineLayout>(rid)?; - Some(id.0) - } else { - None - }; - - let compute_shader_module_resource = - state - .resource_table - .get::<super::shader::WebGpuShaderModule>(args.compute.module)?; - - let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { - label: args.label.map(Cow::from), - layout: pipeline_layout, - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: compute_shader_module_resource.0, - entry_point: Cow::from(args.compute.entry_point), - // TODO(lucacasonato): support args.compute.constants - }, - }; - let implicit_pipelines = match args.layout { - Some(_) => None, - None => Some(wgpu_core::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS], - }), - }; - - let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline( - device, - &descriptor, - std::marker::PhantomData, - implicit_pipelines - )); - - let rid = state - .resource_table - .add(WebGpuComputePipeline(compute_pipeline)); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePipelineGetBindGroupLayoutArgs { - compute_pipeline_rid: ResourceId, - index: u32, -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct PipelineLayout { - rid: ResourceId, - label: String, - err: Option<WebGpuError>, -} - -pub fn op_webgpu_compute_pipeline_get_bind_group_layout( - state: &mut OpState, - args: ComputePipelineGetBindGroupLayoutArgs, - _: (), -) -> Result<PipelineLayout, AnyError> { - let instance = state.borrow::<super::Instance>(); - let compute_pipeline_resource = state - .resource_table - .get::<WebGpuComputePipeline>(args.compute_pipeline_rid)?; - let compute_pipeline = compute_pipeline_resource.0; - - let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, args.index, std::marker::PhantomData)); - - let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); - - let rid = state - .resource_table - .add(super::binding::WebGpuBindGroupLayout(bind_group_layout)); - - Ok(PipelineLayout { - rid, - label, - err: maybe_err.map(WebGpuError::from), - }) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuPrimitiveState { - topology: GpuPrimitiveTopology, - strip_index_format: Option<GpuIndexFormat>, - front_face: GpuFrontFace, - cull_mode: GpuCullMode, - clamp_depth: bool, -} - -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: 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)] -#[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: GpuTextureFormat, - blend: Option<GpuBlendState>, - 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: 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: 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)] -#[serde(rename_all = "camelCase")] -struct GpuVertexAttribute { - format: GpuVertexFormat, - offset: u64, - 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 { - Uint8x2, - Uint8x4, - Sint8x2, - Sint8x4, - Unorm8x2, - Unorm8x4, - Snorm8x2, - Snorm8x4, - Uint16x2, - Uint16x4, - Sint16x2, - Sint16x4, - Unorm16x2, - Unorm16x4, - Snorm16x2, - Snorm16x4, - Float16x2, - Float16x4, - Float32, - Float32x2, - Float32x3, - Float32x4, - Uint32, - Uint32x2, - Uint32x3, - Uint32x4, - Sint32, - Sint32x2, - Sint32x3, - Sint32x4, - Float64, - Float64x2, - Float64x3, - Float64x4, -} - -impl From<GpuVertexFormat> for wgpu_types::VertexFormat { - fn from(vf: GpuVertexFormat) -> wgpu_types::VertexFormat { - use wgpu_types::VertexFormat; - match vf { - GpuVertexFormat::Uint8x2 => VertexFormat::Uint8x2, - GpuVertexFormat::Uint8x4 => VertexFormat::Uint8x4, - GpuVertexFormat::Sint8x2 => VertexFormat::Sint8x2, - GpuVertexFormat::Sint8x4 => VertexFormat::Sint8x4, - GpuVertexFormat::Unorm8x2 => VertexFormat::Unorm8x2, - GpuVertexFormat::Unorm8x4 => VertexFormat::Unorm8x4, - GpuVertexFormat::Snorm8x2 => VertexFormat::Snorm8x2, - GpuVertexFormat::Snorm8x4 => VertexFormat::Snorm8x4, - GpuVertexFormat::Uint16x2 => VertexFormat::Uint16x2, - GpuVertexFormat::Uint16x4 => VertexFormat::Uint16x4, - GpuVertexFormat::Sint16x2 => VertexFormat::Sint16x2, - GpuVertexFormat::Sint16x4 => VertexFormat::Sint16x4, - GpuVertexFormat::Unorm16x2 => VertexFormat::Unorm16x2, - GpuVertexFormat::Unorm16x4 => VertexFormat::Unorm16x4, - GpuVertexFormat::Snorm16x2 => VertexFormat::Snorm16x2, - GpuVertexFormat::Snorm16x4 => VertexFormat::Snorm16x4, - GpuVertexFormat::Float16x2 => VertexFormat::Float16x2, - GpuVertexFormat::Float16x4 => VertexFormat::Float16x4, - GpuVertexFormat::Float32 => VertexFormat::Float32, - GpuVertexFormat::Float32x2 => VertexFormat::Float32x2, - GpuVertexFormat::Float32x3 => VertexFormat::Float32x3, - GpuVertexFormat::Float32x4 => VertexFormat::Float32x4, - GpuVertexFormat::Uint32 => VertexFormat::Uint32, - GpuVertexFormat::Uint32x2 => VertexFormat::Uint32x2, - GpuVertexFormat::Uint32x3 => VertexFormat::Uint32x3, - GpuVertexFormat::Uint32x4 => VertexFormat::Uint32x4, - GpuVertexFormat::Sint32 => VertexFormat::Sint32, - GpuVertexFormat::Sint32x2 => VertexFormat::Sint32x2, - GpuVertexFormat::Sint32x3 => VertexFormat::Sint32x3, - GpuVertexFormat::Sint32x4 => VertexFormat::Sint32x4, - GpuVertexFormat::Float64 => VertexFormat::Float64, - GpuVertexFormat::Float64x2 => VertexFormat::Float64x2, - GpuVertexFormat::Float64x3 => VertexFormat::Float64x3, - GpuVertexFormat::Float64x4 => VertexFormat::Float64x4, - } - } -} - -#[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: 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: ResourceId, - entry_point: String, - buffers: Vec<Option<GpuVertexBufferLayout>>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuMultisampleState { - 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)] -#[serde(rename_all = "camelCase")] -struct GpuFragmentState { - targets: Vec<GpuColorTargetState>, - module: u32, - entry_point: String, - // TODO(lucacasonato): constants -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateRenderPipelineArgs { - device_rid: ResourceId, - label: Option<String>, - layout: Option<ResourceId>, - vertex: GpuVertexState, - primitive: GpuPrimitiveState, - depth_stencil: Option<GpuDepthStencilState>, - multisample: GpuMultisampleState, - fragment: Option<GpuFragmentState>, -} - -pub fn op_webgpu_create_render_pipeline( - state: &mut OpState, - args: CreateRenderPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let layout = if let Some(rid) = args.layout { - let pipeline_layout_resource = - state.resource_table.get::<WebGpuPipelineLayout>(rid)?; - Some(pipeline_layout_resource.0) - } else { - None - }; - - let vertex_shader_module_resource = - state - .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::Owned), - layout, - vertex: wgpu_core::pipeline::VertexState { - stage: wgpu_core::pipeline::ProgrammableStageDescriptor { - module: vertex_shader_module_resource.0, - entry_point: Cow::Owned(args.vertex.entry_point), - }, - buffers: Cow::Owned(vertex_buffers), - }, - 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 { - Some(_) => None, - None => Some(wgpu_core::device::ImplicitPipelineIds { - root_id: std::marker::PhantomData, - group_ids: &[std::marker::PhantomData; MAX_BIND_GROUPS], - }), - }; - - let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline( - device, - &descriptor, - std::marker::PhantomData, - implicit_pipelines - )); - - let rid = state - .resource_table - .add(WebGpuRenderPipeline(render_pipeline)); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPipelineGetBindGroupLayoutArgs { - render_pipeline_rid: ResourceId, - index: u32, -} - -pub fn op_webgpu_render_pipeline_get_bind_group_layout( - state: &mut OpState, - args: RenderPipelineGetBindGroupLayoutArgs, - _: (), -) -> Result<PipelineLayout, AnyError> { - let instance = state.borrow::<super::Instance>(); - let render_pipeline_resource = state - .resource_table - .get::<WebGpuRenderPipeline>(args.render_pipeline_rid)?; - let render_pipeline = render_pipeline_resource.0; - - let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, args.index, std::marker::PhantomData)); - - let label = gfx_select!(bind_group_layout => instance.bind_group_layout_label(bind_group_layout)); - - let rid = state - .resource_table - .add(super::binding::WebGpuBindGroupLayout(bind_group_layout)); - - Ok(PipelineLayout { - rid, - label, - err: maybe_err.map(WebGpuError::from), - }) -} |