Add bind group layout

This commit is contained in:
Joshua Groves 2018-09-26 12:37:24 -06:00
parent 551d944214
commit 9ef70b8246
6 changed files with 140 additions and 28 deletions

View File

@ -8,6 +8,21 @@
#include <stdlib.h>
#include <stdbool.h>
#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);

View File

@ -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<B: hal::Backend> {
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<B: hal::Backend> {
@ -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 {

View File

@ -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
}

View File

@ -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<B: hal::Backend> Device<B> {
}
}
pub struct ShaderModule<B: hal::Backend> {
pub(crate) struct ShaderModule<B: hal::Backend> {
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,

View File

@ -85,6 +85,7 @@ pub type SamplerId = Id;
// Binding model
pub type BindGroupLayoutId = Id;
pub(crate) type BindGroupLayoutHandle = BindGroupLayout<B>;
pub type PipelineLayoutId = Id;
// Pipeline

View File

@ -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<T> = RemoteRegistry<T>;
lazy_static! {
pub(crate) static ref ADAPTER_REGISTRY: ConcreteRegistry<AdapterHandle> =
ConcreteRegistry::new();
pub(crate) static ref BIND_GROUP_LAYOUT_REGISTRY: ConcreteRegistry<BindGroupLayoutHandle> =
ConcreteRegistry::new();
pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry<DeviceHandle> = ConcreteRegistry::new();
pub(crate) static ref INSTANCE_REGISTRY: ConcreteRegistry<InstanceHandle> = ConcreteRegistry::new();
pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry<ShaderModuleHandle> = ConcreteRegistry::new();