diff --git a/Cargo.lock b/Cargo.lock index 0eadaa04d..1bbb49c7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,14 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ash" version = "0.24.4" @@ -456,6 +464,11 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "objc" version = "0.2.5" @@ -913,6 +926,7 @@ dependencies = [ name = "wgpu" version = "0.1.0" dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "wgpu-native 0.1.0", ] @@ -1025,6 +1039,7 @@ dependencies = [ [metadata] "checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum ash 0.24.4 (registry+https://github.com/rust-lang/crates.io-index)" = "11f080bc0414ee1b6b959442cb36478d56c6e6b9bb2b04079a5048d9acc91a30" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" @@ -1073,6 +1088,7 @@ dependencies = [ "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum metal 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8411e1b14691a658f4b285f980c98d1af1922dcf037ea4454288dc456ca0d1ed" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" +"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9833ab0efe5361b1e2122a0544a5d3359576911a42cb098c2e59be8650807367" "checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" "checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc" diff --git a/examples/hello_triangle_rust/main.rs b/examples/hello_triangle_rust/main.rs index 9985304b3..519e17640 100644 --- a/examples/hello_triangle_rust/main.rs +++ b/examples/hello_triangle_rust/main.rs @@ -10,9 +10,44 @@ fn main() { }, }); let vs_bytes = include_bytes!("./../data/hello_triangle.vert.spv"); - let _vs = device.create_shader_module(vs_bytes); + let vs_module = device.create_shader_module(vs_bytes); let fs_bytes = include_bytes!("./../data/hello_triangle.frag.spv"); - let _fs = device.create_shader_module(fs_bytes); + let fs_module = device.create_shader_module(fs_bytes); + + let bind_group_layout = device.create_bind_group_layout(wgpu::BindGroupLayoutDescriptor { + bindings: &[], + }); + let pipeline_layout = device.create_pipeline_layout(wgpu::PipelineLayoutDescriptor { + bind_group_layouts: &[&bind_group_layout], + }); + + let blend_state0 = device.create_blend_state(wgpu::BlendStateDescriptor::REPLACE); + let depth_stencil_state = device.create_depth_stencil_state(wgpu::DepthStencilStateDescriptor::IGNORE); + let attachment_state = device.create_attachment_state(wgpu::AttachmentStateDescriptor { + formats: &[wgpu::TextureFormat::R8g8b8a8Unorm], + }); + + let _render_pipeline = device.create_render_pipeline(wgpu::RenderPipelineDescriptor { + layout: &pipeline_layout, + stages: &[ + wgpu::PipelineStageDescriptor { + module: &vs_module, + stage: wgpu::ShaderStage::Vertex, + entry_point: "main", + }, + wgpu::PipelineStageDescriptor { + module: &fs_module, + stage: wgpu::ShaderStage::Fragment, + entry_point: "main", + }, + ], + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + blend_state: &[ + &blend_state0, + ], + depth_stencil_state: &depth_stencil_state, + attachment_state: &attachment_state, + }); let cmd_buf = device.create_command_buffer(wgpu::CommandBufferDescriptor {}); let queue = device.get_queue(); diff --git a/wgpu-native/src/pipeline.rs b/wgpu-native/src/pipeline.rs index c57175cd6..3c186471b 100644 --- a/wgpu-native/src/pipeline.rs +++ b/wgpu-native/src/pipeline.rs @@ -56,6 +56,14 @@ pub struct BlendDescriptor { pub operation: BlendOperation, } +impl BlendDescriptor { + pub const REPLACE: Self = BlendDescriptor { + src_factor: BlendFactor::One, + dst_factor: BlendFactor::Zero, + operation: BlendOperation::Add, + }; +} + #[repr(C)] pub struct BlendStateDescriptor { pub blend_enabled: bool, @@ -64,6 +72,15 @@ pub struct BlendStateDescriptor { pub write_mask: ColorWriteFlags, } +impl BlendStateDescriptor { + pub const REPLACE: Self = BlendStateDescriptor { + blend_enabled: false, + alpha: BlendDescriptor::REPLACE, + color: BlendDescriptor::REPLACE, + write_mask: ColorWriteFlags_ALL, + }; +} + pub(crate) struct BlendState { pub raw: hal::pso::ColorBlendDesc, } @@ -89,6 +106,15 @@ pub struct StencilStateFaceDescriptor { pub pass_op: StencilOperation, } +impl StencilStateFaceDescriptor { + pub const IGNORE: Self = StencilStateFaceDescriptor { + compare: resource::CompareFunction::Always, + stencil_fail_op: StencilOperation::Keep, + depth_fail_op: StencilOperation::Keep, + pass_op: StencilOperation::Keep, + }; +} + #[repr(C)] pub struct DepthStencilStateDescriptor { pub depth_write_enabled: bool, @@ -99,6 +125,17 @@ pub struct DepthStencilStateDescriptor { pub stencil_write_mask: u32, } +impl DepthStencilStateDescriptor { + pub const IGNORE: Self = DepthStencilStateDescriptor { + depth_write_enabled: false, + depth_compare: resource::CompareFunction::Always, + front: StencilStateFaceDescriptor::IGNORE, + back: StencilStateFaceDescriptor::IGNORE, + stencil_read_mask: 0xFF, + stencil_write_mask: 0xFF, + }; +} + pub(crate) struct DepthStencilState { pub raw: hal::pso::DepthStencilDesc, } diff --git a/wgpu-rs/Cargo.toml b/wgpu-rs/Cargo.toml index 4fb139f38..90880b795 100644 --- a/wgpu-rs/Cargo.toml +++ b/wgpu-rs/Cargo.toml @@ -16,3 +16,4 @@ vulkan = ["wgpu-native/gfx-backend-vulkan"] [dependencies] wgpu-native = { path = "../wgpu-native" } +arrayvec = "0.4" diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 0497e52aa..32e14cbab 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -1,10 +1,18 @@ extern crate wgpu_native as wgn; +extern crate arrayvec; + +use arrayvec::ArrayVec; + +use std::ffi::CString; pub use wgn::{ AdapterDescriptor, Color, CommandBufferDescriptor, DeviceDescriptor, Extensions, Extent3d, - Origin3d, PowerPreference, ShaderModuleDescriptor, + Origin3d, PowerPreference, ShaderModuleDescriptor, ShaderStage, + BindGroupLayoutBinding, TextureFormat, + PrimitiveTopology, BlendStateDescriptor, ColorWriteFlags, DepthStencilStateDescriptor, }; + pub struct Instance { id: wgn::InstanceId, } @@ -17,10 +25,34 @@ pub struct Device { id: wgn::DeviceId, } +pub struct BindGroupLayout { + id: wgn::BindGroupLayoutId, +} + pub struct ShaderModule { id: wgn::ShaderModuleId, } +pub struct PipelineLayout { + id: wgn::PipelineLayoutId, +} + +pub struct BlendState { + id: wgn::BlendStateId, +} + +pub struct DepthStencilState { + id: wgn::DepthStencilStateId, +} + +pub struct AttachmentState { + id: wgn::AttachmentStateId, +} + +pub struct RenderPipeline { + id: wgn::RenderPipelineId, +} + pub struct CommandBuffer { id: wgn::CommandBufferId, } @@ -29,6 +61,34 @@ pub struct Queue { id: wgn::QueueId, } +pub struct BindGroupLayoutDescriptor<'a> { + pub bindings: &'a [BindGroupLayoutBinding], +} + +pub struct PipelineLayoutDescriptor<'a> { + pub bind_group_layouts: &'a [&'a BindGroupLayout], +} + +pub struct PipelineStageDescriptor<'a> { + pub module: &'a ShaderModule, + pub stage: ShaderStage, + pub entry_point: &'a str, +} + +pub struct AttachmentStateDescriptor<'a> { + pub formats: &'a [TextureFormat], +} + +pub struct RenderPipelineDescriptor<'a> { + pub layout: &'a PipelineLayout, + pub stages: &'a [PipelineStageDescriptor<'a>], + pub primitive_topology: PrimitiveTopology, + pub blend_state: &'a [&'a BlendState], + pub depth_stencil_state: &'a DepthStencilState, + pub attachment_state: &'a AttachmentState, +} + + impl Instance { pub fn new() -> Self { Instance { @@ -75,6 +135,74 @@ impl Device { id: wgn::wgpu_device_create_command_buffer(self.id, desc), } } + + pub fn create_bind_group_layout(&self, desc: BindGroupLayoutDescriptor) -> BindGroupLayout { + BindGroupLayout { + id: wgn::wgpu_device_create_bind_group_layout(self.id, wgn::BindGroupLayoutDescriptor { + bindings: desc.bindings.as_ptr(), + bindings_length: desc.bindings.len(), + }), + } + } + + pub fn create_pipeline_layout(&self, desc: PipelineLayoutDescriptor) -> PipelineLayout { + PipelineLayout { + id: wgn::wgpu_device_create_pipeline_layout(self.id, wgn::PipelineLayoutDescriptor { + bind_group_layouts: desc.bind_group_layouts.as_ptr() as *const _, + bind_group_layouts_length: desc.bind_group_layouts.len(), + }), + } + } + + pub fn create_blend_state(&self, desc: BlendStateDescriptor) -> BlendState { + BlendState { + id: wgn::wgpu_device_create_blend_state(self.id, desc), + } + } + + pub fn create_depth_stencil_state(&self, desc: DepthStencilStateDescriptor) -> DepthStencilState { + DepthStencilState { + id: wgn::wgpu_device_create_depth_stencil_state(self.id, desc), + } + } + + pub fn create_attachment_state(&self, desc: AttachmentStateDescriptor) -> AttachmentState { + AttachmentState { + id: wgn::wgpu_device_create_attachment_state(self.id, wgn::AttachmentStateDescriptor { + formats: desc.formats.as_ptr(), + formats_length: desc.formats.len(), + }), + } + } + + pub fn create_render_pipeline(&self, desc: RenderPipelineDescriptor) -> RenderPipeline { + let entry_points = desc.stages + .iter() + .map(|ps| CString::new(ps.entry_point).unwrap()) + .collect::>(); + let stages = desc.stages + .iter() + .zip(&entry_points) + .map(|(ps, ep_name)| wgn::PipelineStageDescriptor { + module: ps.module.id, + stage: ps.stage, + entry_point: ep_name.as_ptr(), + }) + .collect::>(); + + RenderPipeline { + id: wgn::wgpu_device_create_render_pipeline(self.id, wgn::RenderPipelineDescriptor { + layout: desc.layout.id, + stages: stages.as_ptr(), + stages_length: stages.len(), + primitive_topology: desc.primitive_topology, + blend_state: desc.blend_state.as_ptr() as *const _, + blend_state_length: desc.blend_state.len(), + depth_stencil_state: desc.depth_stencil_state.id, + attachment_state: desc.attachment_state.id, + }), + } + } } impl Queue {