From 9ef70b82463ea7e7191cae9af60a78678ed236d7 Mon Sep 17 00:00:00 2001 From: Joshua Groves Date: Wed, 26 Sep 2018 12:37:24 -0600 Subject: [PATCH] Add bind group layout --- wgpu-bindings/wgpu.h | 41 ++++++++++++++++++++++++++++++++ wgpu-native/src/binding_model.rs | 40 +++++++++++++++++-------------- wgpu-native/src/conv.rs | 35 ++++++++++++++++++++++++++- wgpu-native/src/device.rs | 39 ++++++++++++++++++++++++++---- wgpu-native/src/lib.rs | 1 + wgpu-native/src/registry.rs | 12 ++++++---- 6 files changed, 140 insertions(+), 28 deletions(-) diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index 029defd44..e01267d11 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -8,6 +8,21 @@ #include #include +#define WGPUShaderStageFlags_COMPUTE 4 + +#define WGPUShaderStageFlags_FRAGMENT 2 + +#define WGPUShaderStageFlags_NONE 0 + +#define WGPUShaderStageFlags_VERTEX 1 + +typedef enum { + WGPUBindingType_UniformBuffer = 0, + WGPUBindingType_Sampler = 1, + WGPUBindingType_SampledTexture = 2, + WGPUBindingType_StorageBuffer = 3, +} WGPUBindingType; + typedef enum { WGPUPowerPreference_Default = 0, WGPUPowerPreference_LowPower = 1, @@ -51,9 +66,30 @@ typedef WGPUId WGPUInstanceId; typedef struct { } WGPUCommandBufferDescriptor; +typedef WGPUId WGPUBindGroupLayoutId; + +typedef uint32_t WGPUShaderStageFlags; + +typedef struct { + uint32_t binding; + WGPUShaderStageFlags visibility; + WGPUBindingType ty; +} WGPUBindGroupLayoutBinding; + +typedef struct { + const WGPUBindGroupLayoutBinding *bindings; + uintptr_t bindings_length; +} WGPUBindGroupLayoutDescriptor; typedef WGPUId WGPUPipelineLayoutId; +typedef struct { + const WGPUBindGroupLayoutId *bind_group_layouts; + uintptr_t bind_group_layouts_length; +} WGPUPipelineLayoutDescriptor; + +typedef WGPUId WGPURenderPipelineId; + typedef WGPUId WGPUShaderModuleId; typedef struct { @@ -104,6 +140,11 @@ WGPUInstanceId wgpu_create_instance(void); WGPUCommandBufferId wgpu_device_create_command_buffer(WGPUDeviceId device_id, WGPUCommandBufferDescriptor desc); +WGPUBindGroupLayoutId wgpu_device_create_bind_group_layout(WGPUDeviceId device_id, + WGPUBindGroupLayoutDescriptor desc); + +WGPUPipelineLayoutId wgpu_device_create_pipeline_layout(WGPUDeviceId device_id, + WGPUPipelineLayoutDescriptor desc); WGPURenderPipelineId wgpu_device_create_render_pipeline(WGPUDeviceId device_id, WGPURenderPipelineDescriptor desc); diff --git a/wgpu-native/src/binding_model.rs b/wgpu-native/src/binding_model.rs index ca8df9052..3e1a4d8d0 100644 --- a/wgpu-native/src/binding_model.rs +++ b/wgpu-native/src/binding_model.rs @@ -2,15 +2,16 @@ use hal; use {BindGroupLayoutId, BufferId, SamplerId, TextureViewId}; -bitflags! { - #[repr(transparent)] - pub struct ShaderStageFlags: u32 { - const NONE = 0; - const VERTEX = 1; - const FRAGMENT = 2; - const COMPUTE = 4; - } -} +// TODO: bitflags +pub type ShaderStageFlags = u32; +#[allow(non_upper_case_globals)] +pub const ShaderStageFlags_NONE: u32 = 0; +#[allow(non_upper_case_globals)] +pub const ShaderStageFlags_VERTEX: u32 = 1; +#[allow(non_upper_case_globals)] +pub const ShaderStageFlags_FRAGMENT: u32 = 2; +#[allow(non_upper_case_globals)] +pub const ShaderStageFlags_COMPUTE: u32 = 4; #[repr(C)] pub enum BindingType { @@ -28,17 +29,19 @@ pub struct BindGroupLayoutBinding { } #[repr(C)] -pub struct BindGroupLayoutDescriptor<'a> { - pub bindings: &'a [BindGroupLayoutBinding], +pub struct BindGroupLayoutDescriptor { + pub bindings: *const BindGroupLayoutBinding, + pub bindings_length: usize, } -pub struct BindGroupLayout { - // TODO +pub(crate) struct BindGroupLayout { + pub raw: B::DescriptorSetLayout, } #[repr(C)] -pub struct PipelineLayoutDescriptor<'a> { - pub bind_group_layouts: &'a [BindGroupLayoutId], +pub struct PipelineLayoutDescriptor { + pub bind_group_layouts: *const BindGroupLayoutId, + pub bind_group_layouts_length: usize, } pub struct PipelineLayout { @@ -66,9 +69,10 @@ pub struct Binding { } #[repr(C)] -pub struct BindGroupDescriptor<'a> { - pub layout: BindGroupLayout, - pub bindings: &'a [Binding], +pub struct BindGroupDescriptor { + pub layout: BindGroupLayoutId, + pub bindings: *const Binding, + pub bindings_length: usize, } pub struct BindGroup { diff --git a/wgpu-native/src/conv.rs b/wgpu-native/src/conv.rs index 238d6a8f0..e5e0f0962 100644 --- a/wgpu-native/src/conv.rs +++ b/wgpu-native/src/conv.rs @@ -1,6 +1,6 @@ use hal; -use resource; +use {binding_model, resource}; pub(crate) fn map_buffer_usage( usage: resource::BufferUsageFlags, @@ -39,3 +39,36 @@ pub(crate) fn map_buffer_usage( (hal_usage, hal_memory) } + +pub(crate) fn map_binding_type( + binding_ty: &binding_model::BindingType, +) -> hal::pso::DescriptorType { + use binding_model::BindingType::*; + use hal::pso::DescriptorType as H; + match binding_ty { + UniformBuffer => H::UniformBuffer, + Sampler => H::Sampler, + SampledTexture => H::SampledImage, + StorageBuffer => H::StorageBuffer, + } +} + +pub(crate) fn map_shader_stage_flags( + shader_stage_flags: binding_model::ShaderStageFlags, +) -> hal::pso::ShaderStageFlags { + use binding_model::{ + ShaderStageFlags_COMPUTE, ShaderStageFlags_FRAGMENT, ShaderStageFlags_VERTEX, + }; + use hal::pso::ShaderStageFlags as H; + let mut value = H::empty(); + if 0 != shader_stage_flags & ShaderStageFlags_VERTEX { + value |= H::VERTEX; + } + if 0 != shader_stage_flags & ShaderStageFlags_FRAGMENT { + value |= H::FRAGMENT; + } + if 0 != shader_stage_flags & ShaderStageFlags_COMPUTE { + value |= H::COMPUTE; + } + value +} diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index b0c642eae..c7ee4d5a5 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1,10 +1,9 @@ use hal::{self, Device as _Device}; use hal::queue::RawCommandQueue; -use {command, conv, memory, pipeline, resource}; +use {binding_model, command, conv, memory, pipeline, resource}; use registry::{self, Registry}; -use {BufferId, CommandBufferId, DeviceId, QueueId, ShaderModuleId}; - +use {BindGroupLayoutId, DeviceId, PipelineLayoutId, RenderPipelineId, , BufferId, CommandBufferId, DeviceId, QueueId, ShaderModuleId}; use std::{iter, slice}; @@ -30,10 +29,42 @@ impl Device { } } -pub struct ShaderModule { +pub(crate) struct ShaderModule { pub raw: B::ShaderModule, } +#[no_mangle] +pub extern "C" fn wgpu_device_create_bind_group_layout( + device_id: DeviceId, + desc: binding_model::BindGroupLayoutDescriptor, +) -> BindGroupLayoutId { + let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; + let device = registry::DEVICE_REGISTRY.get_mut(device_id); + let descriptor_set_layout = device.device.create_descriptor_set_layout( + bindings.iter().map(|binding| { + hal::pso::DescriptorSetLayoutBinding { + binding: binding.binding, + ty: conv::map_binding_type(&binding.ty), + count: bindings.len(), + stage_flags: conv::map_shader_stage_flags(binding.visibility), + immutable_samplers: false, // TODO + } + }), + &[], + ); + registry::BIND_GROUP_LAYOUT_REGISTRY.register(binding_model::BindGroupLayout { + raw: descriptor_set_layout, + }) +} + +#[no_mangle] +pub extern "C" fn wgpu_device_create_pipeline_layout( + device_id: DeviceId, + desc: binding_model::PipelineLayoutDescriptor, +) -> PipelineLayoutId { + unimplemented!() +} + #[no_mangle] pub extern "C" fn wgpu_device_create_shader_module( device_id: DeviceId, diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index bbae752c2..e53126a3f 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -85,6 +85,7 @@ pub type SamplerId = Id; // Binding model pub type BindGroupLayoutId = Id; +pub(crate) type BindGroupLayoutHandle = BindGroupLayout; pub type PipelineLayoutId = Id; // Pipeline diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index 8a3a88caa..6ed5056d7 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -1,17 +1,17 @@ +#[cfg(feature = "remote")] +use hal::backend::FastHashMap; +#[cfg(feature = "remote")] +use parking_lot::{MappedMutexGuard, Mutex, MutexGuard}; #[cfg(not(feature = "remote"))] use std::marker::PhantomData; #[cfg(not(feature = "remote"))] use std::os::raw::c_void; #[cfg(feature = "remote")] -use parking_lot::{MappedMutexGuard, Mutex, MutexGuard}; -#[cfg(feature = "remote")] use std::sync::Arc; - #[cfg(feature = "remote")] use hal::backend::FastHashMap; -use {AdapterHandle, CommandBufferHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle}; - +use {AdapterHandle, BindGroupLayoutHandle, CommandBufferHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle}; #[cfg(not(feature = "remote"))] pub(crate) type Id = *mut c_void; @@ -123,6 +123,8 @@ type ConcreteRegistry = RemoteRegistry; lazy_static! { pub(crate) static ref ADAPTER_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref BIND_GROUP_LAYOUT_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();