diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index ff5151a13..029defd44 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -14,6 +14,20 @@ typedef enum { WGPUPowerPreference_HighPerformance = 2, } WGPUPowerPreference; +typedef enum { + WGPUPrimitiveTopology_PointList = 0, + WGPUPrimitiveTopology_LineList = 1, + WGPUPrimitiveTopology_LineStrip = 2, + WGPUPrimitiveTopology_TriangleList = 3, + WGPUPrimitiveTopology_TriangleStrip = 4, +} WGPUPrimitiveTopology; + +typedef enum { + WGPUShaderStage_Vertex = 0, + WGPUShaderStage_Fragment = 1, + WGPUShaderStage_Compute = 2, +} WGPUShaderStage; + typedef WGPUId WGPUDeviceId; typedef WGPUId WGPUAdapterId; @@ -38,8 +52,33 @@ typedef struct { } WGPUCommandBufferDescriptor; +typedef WGPUId WGPUPipelineLayoutId; + typedef WGPUId WGPUShaderModuleId; +typedef struct { + WGPUShaderModuleId module; + WGPUShaderStage stage; + const char *entry_point; +} WGPUPipelineStageDescriptor; + +typedef WGPUId WGPUBlendStateId; + +typedef WGPUId WGPUDepthStencilStateId; + +typedef WGPUId WGPUAttachmentStateId; + +typedef struct { + WGPUPipelineLayoutId layout; + const WGPUPipelineStageDescriptor *stages; + uintptr_t stages_length; + WGPUPrimitiveTopology primitive_topology; + const WGPUBlendStateId *blend_state; + uintptr_t blend_state_length; + WGPUDepthStencilStateId depth_stencil_state; + WGPUAttachmentStateId attachment_state; +} WGPURenderPipelineDescriptor; + typedef struct { const uint8_t *bytes; uintptr_t length; @@ -66,6 +105,9 @@ WGPUInstanceId wgpu_create_instance(void); WGPUCommandBufferId wgpu_device_create_command_buffer(WGPUDeviceId device_id, WGPUCommandBufferDescriptor desc); +WGPURenderPipelineId wgpu_device_create_render_pipeline(WGPUDeviceId device_id, + WGPURenderPipelineDescriptor desc); + WGPUShaderModuleId wgpu_device_create_shader_module(WGPUDeviceId device_id, WGPUShaderModuleDescriptor desc); diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 3e881a793..b0c642eae 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -92,4 +92,59 @@ pub extern "C" fn wgpu_queue_submit( } device.com_allocator.submit(cmd_buf); } +pub extern "C" fn wgpu_device_create_render_pipeline( + device_id: DeviceId, + desc: pipeline::RenderPipelineDescriptor, +) -> RenderPipelineId { + let device = registry::DEVICE_REGISTRY.get_mut(device_id); + // TODO: layout, primitive_topology, blend_state, depth_stencil_state, attachment_state + let pipeline_stages = unsafe { slice::from_raw_parts(desc.stages, desc.stages_length) }; + + // TODO: avoid allocation + let shaders_owned = pipeline_stages + .iter() + .map(|ps| registry::SHADER_MODULE_REGISTRY.get_mut(ps.module)) + .collect::>(); + let shaders = { + let mut vertex = None; + let mut fragment = None; + for (i, pipeline_stage) in pipeline_stages.iter().enumerate() { + let entry = hal::pso::EntryPoint:: { + entry: unsafe { ffi::CStr::from_ptr(pipeline_stage.entry_point) } + .to_str() + .to_owned() + .unwrap(), // TODO + module: &shaders_owned[i].raw, + specialization: hal::pso::Specialization { + // TODO + constants: &[], + data: &[], + }, + }; + match pipeline_stage.stage { + pipeline::ShaderStage::Vertex => { + vertex = Some(entry); + } + pipeline::ShaderStage::Fragment => { + fragment = Some(entry); + } + pipeline::ShaderStage::Compute => unimplemented!(), // TODO + } + } + + hal::pso::GraphicsShaderSet { + vertex: vertex.unwrap(), // TODO + hull: None, + domain: None, + geometry: None, + fragment, + } + }; + + /* + let pipeline = device + .device + .create_graphics_pipeline(pipeline_desc); + */ + unimplemented!(); } diff --git a/wgpu-native/src/pipeline.rs b/wgpu-native/src/pipeline.rs index 0d94aa2ac..955a1bbb8 100644 --- a/wgpu-native/src/pipeline.rs +++ b/wgpu-native/src/pipeline.rs @@ -1,7 +1,10 @@ use hal; use resource; -use {BlendStateId, ByteArray, DepthStencilStateId, PipelineLayoutId}; +use { + AttachmentStateId, BlendStateId, ByteArray, DepthStencilStateId, PipelineLayoutId, + ShaderModuleId, +}; #[repr(C)] pub enum BlendFactor { @@ -146,8 +149,9 @@ pub struct ShaderModuleDescriptor { } #[repr(C)] -pub struct AttachmentStateDescriptor<'a> { - pub formats: &'a [resource::TextureFormat], +pub struct AttachmentStateDescriptor { + pub formats: *const resource::TextureFormat, + pub formats_length: usize, } pub struct AttachmentState { @@ -163,15 +167,15 @@ pub enum ShaderStage { #[repr(C)] pub struct PipelineStageDescriptor { - pub module: ShaderModuleDescriptor, + pub module: ShaderModuleId, pub stage: ShaderStage, pub entry_point: *const ::std::os::raw::c_char, } #[repr(C)] -pub struct ComputePipelineDescriptor<'a> { +pub struct ComputePipelineDescriptor { pub layout: PipelineLayoutId, - pub stages: &'a [PipelineStageDescriptor], + pub stages: *const PipelineStageDescriptor, } pub struct ComputePipeline { @@ -188,13 +192,15 @@ pub enum PrimitiveTopology { } #[repr(C)] -pub struct RenderPipelineDescriptor<'a> { +pub struct RenderPipelineDescriptor { pub layout: PipelineLayoutId, - pub stages: &'a [PipelineStageDescriptor], + pub stages: *const PipelineStageDescriptor, + pub stages_length: usize, pub primitive_topology: PrimitiveTopology, - pub blend_state: &'a [BlendStateId], + pub blend_state: *const BlendStateId, + pub blend_state_length: usize, pub depth_stencil_state: DepthStencilStateId, - pub attachment_state: AttachmentState, + pub attachment_state: AttachmentStateId, } pub struct RenderPipeline { diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index a57bb6f08..3343cbef9 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -4,9 +4,7 @@ use std::marker::PhantomData; use std::os::raw::c_void; #[cfg(feature = "remote")] -use std::sync::Arc; -#[cfg(feature = "remote")] -use parking_lot::{Mutex, MutexGuard, MappedMutexGuard}; +use parking_lot::{MappedMutexGuard, Mutex, MutexGuard}; #[cfg(feature = "remote")] use hal::backend::FastHashMap; @@ -104,7 +102,9 @@ impl Registry for RemoteRegistry { } fn get_mut(&self, id: Id) -> RegistryItem { - MutexGuard::map(self.registrations.lock(), |r| r.tracked.get_mut(&id).unwrap()) + MutexGuard::map(self.registrations.lock(), |r| { + r.tracked.get_mut(&id).unwrap() + }) } fn take(&self, id: Id) -> T { @@ -120,7 +120,8 @@ type ConcreteRegistry = LocalRegistry; type ConcreteRegistry = RemoteRegistry; lazy_static! { - pub(crate) static ref ADAPTER_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref ADAPTER_REGISTRY: ConcreteRegistry = + ConcreteRegistry::new(); pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); pub(crate) static ref INSTANCE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new();