hal/gles: bind group creation

This commit is contained in:
Dzmitry Malyshau 2021-06-22 23:50:39 -04:00 committed by Dzmitry Malyshau
parent 85e59c3d7f
commit d29c450ec3
9 changed files with 174 additions and 24 deletions

View File

@ -1035,7 +1035,8 @@ impl<A: HalApi> Device<A> {
})?; })?;
} }
let hal_bindings = entry_map.values().cloned().collect::<Vec<_>>(); let mut hal_bindings = entry_map.values().cloned().collect::<Vec<_>>();
hal_bindings.sort_by_key(|b| b.binding);
let hal_desc = hal::BindGroupLayoutDescriptor { let hal_desc = hal::BindGroupLayoutDescriptor {
label, label,
entries: &hal_bindings, entries: &hal_bindings,

View File

@ -173,15 +173,15 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn set_bind_group( unsafe fn set_bind_group(
&mut self, &mut self,
layout: &Resource, layout: &super::PipelineLayout,
index: u32, index: u32,
group: &Resource, group: &super::BindGroup,
dynamic_offsets: &[wgt::DynamicOffset], dynamic_offsets: &[wgt::DynamicOffset],
) { ) {
} }
unsafe fn set_push_constants( unsafe fn set_push_constants(
&mut self, &mut self,
layout: &Resource, layout: &super::PipelineLayout,
stages: wgt::ShaderStage, stages: wgt::ShaderStage,
offset: u32, offset: u32,
data: &[u32], data: &[u32],

View File

@ -1,6 +1,6 @@
use super::{DeviceResult, Resource}; //TEMP use super::{DeviceResult, Resource}; //TEMP
use glow::HasContext; use glow::HasContext;
use std::{convert::TryInto, ptr::NonNull}; use std::{convert::TryInto, ptr::NonNull, sync::Arc};
impl crate::Device<super::Api> for super::Device { impl crate::Device<super::Api> for super::Device {
unsafe fn exit(self) { unsafe fn exit(self) {
@ -46,6 +46,7 @@ impl crate::Device<super::Api> for super::Device {
Ok(super::Buffer { Ok(super::Buffer {
raw, raw,
target, target,
size: desc.size,
map_flags, map_flags,
}) })
} }
@ -269,24 +270,122 @@ impl crate::Device<super::Api> for super::Device {
unsafe fn create_bind_group_layout( unsafe fn create_bind_group_layout(
&self, &self,
desc: &crate::BindGroupLayoutDescriptor, desc: &crate::BindGroupLayoutDescriptor,
) -> DeviceResult<Resource> { ) -> Result<super::BindGroupLayout, crate::DeviceError> {
Ok(Resource) Ok(super::BindGroupLayout {
entries: Arc::from(desc.entries),
})
} }
unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {} unsafe fn destroy_bind_group_layout(&self, _bg_layout: super::BindGroupLayout) {}
unsafe fn create_pipeline_layout( unsafe fn create_pipeline_layout(
&self, &self,
desc: &crate::PipelineLayoutDescriptor<super::Api>, desc: &crate::PipelineLayoutDescriptor<super::Api>,
) -> DeviceResult<Resource> { ) -> Result<super::PipelineLayout, crate::DeviceError> {
Ok(Resource) let mut group_infos = Vec::with_capacity(desc.bind_group_layouts.len());
let mut num_samplers = 0u8;
let mut num_textures = 0u8;
let mut num_uniform_buffers = 0u8;
let mut num_storage_buffers = 0u8;
for bg_layout in desc.bind_group_layouts {
// create a vector with the size enough to hold all the bindings, filled with `!0`
let mut binding_to_slot = vec![
!0;
bg_layout
.entries
.last()
.map_or(0, |b| b.binding as usize + 1)
]
.into_boxed_slice();
for entry in bg_layout.entries.iter() {
let counter = match entry.ty {
wgt::BindingType::Sampler { .. } => &mut num_samplers,
wgt::BindingType::Texture { .. } | wgt::BindingType::StorageTexture { .. } => {
&mut num_textures
}
wgt::BindingType::Buffer {
ty: wgt::BufferBindingType::Uniform,
..
} => &mut num_uniform_buffers,
wgt::BindingType::Buffer {
ty: wgt::BufferBindingType::Storage { .. },
..
} => &mut num_storage_buffers,
};
binding_to_slot[entry.binding as usize] = *counter;
*counter += entry.count.map_or(1, |c| c.get() as u8);
}
group_infos.push(super::BindGroupLayoutInfo {
entries: Arc::clone(&bg_layout.entries),
binding_to_slot,
});
}
Ok(super::PipelineLayout {
group_infos: group_infos.into_boxed_slice(),
})
} }
unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {} unsafe fn destroy_pipeline_layout(&self, pipeline_layout: super::PipelineLayout) {}
unsafe fn create_bind_group( unsafe fn create_bind_group(
&self, &self,
desc: &crate::BindGroupDescriptor<super::Api>, desc: &crate::BindGroupDescriptor<super::Api>,
) -> DeviceResult<Resource> { ) -> Result<super::BindGroup, crate::DeviceError> {
Ok(Resource) let mut contents = Vec::new();
for (entry, layout) in desc.entries.iter().zip(desc.layout.entries.iter()) {
let binding = match layout.ty {
wgt::BindingType::Buffer { ty, .. } => {
let bb = &desc.buffers[entry.resource_index as usize];
let register = match ty {
wgt::BufferBindingType::Uniform => super::BindingRegister::UniformBuffers,
wgt::BufferBindingType::Storage { .. } => {
super::BindingRegister::StorageBuffers
}
};
super::RawBinding::Buffer {
register,
raw: bb.buffer.raw,
offset: bb.offset as i32,
size: match bb.size {
Some(s) => s.get() as i32,
None => (bb.buffer.size - bb.offset) as i32,
},
}
}
wgt::BindingType::Sampler { .. } => {
let sampler = desc.samplers[entry.resource_index as usize];
super::RawBinding::Sampler(sampler.raw)
}
wgt::BindingType::Texture { .. } | wgt::BindingType::StorageTexture { .. } => {
match *desc.textures[entry.resource_index as usize].view {
super::TextureView::Renderbuffer { .. } => {
panic!("Unable to use a renderbuffer in a group")
}
super::TextureView::Texture {
raw,
target,
ref range,
} => super::RawBinding::Texture {
raw,
target,
range: range.clone(),
},
}
}
};
contents.push(binding);
}
Ok(super::BindGroup {
layout_entries: Arc::clone(&desc.layout.entries),
contents: contents.into_boxed_slice(),
})
} }
unsafe fn destroy_bind_group(&self, group: Resource) {} unsafe fn destroy_bind_group(&self, _group: super::BindGroup) {}
unsafe fn create_shader_module( unsafe fn create_shader_module(
&self, &self,

View File

@ -41,9 +41,9 @@ impl crate::Api for Api {
type QuerySet = Resource; type QuerySet = Resource;
type Fence = Resource; type Fence = Resource;
type BindGroupLayout = Resource; type BindGroupLayout = BindGroupLayout;
type BindGroup = Resource; type BindGroup = BindGroup;
type PipelineLayout = Resource; type PipelineLayout = PipelineLayout;
type ShaderModule = Resource; type ShaderModule = Resource;
type RenderPipeline = Resource; type RenderPipeline = Resource;
type ComputePipeline = Resource; type ComputePipeline = Resource;
@ -190,6 +190,7 @@ pub struct Queue {
pub struct Buffer { pub struct Buffer {
raw: glow::Buffer, raw: glow::Buffer,
target: BindTarget, target: BindTarget,
size: wgt::BufferAddress,
map_flags: u32, map_flags: u32,
} }
@ -239,6 +240,53 @@ pub struct Sampler {
raw: glow::Sampler, raw: glow::Sampler,
} }
pub struct BindGroupLayout {
entries: Arc<[wgt::BindGroupLayoutEntry]>,
}
struct BindGroupLayoutInfo {
entries: Arc<[wgt::BindGroupLayoutEntry]>,
/// Mapping of resources, indexed by `binding`, into the whole layout space.
/// For texture resources, the value is the texture slot index.
/// For sampler resources, the value is the index of the sampler in the whole layout.
/// For buffers, the value is the uniform or storage slot index.
/// For unused bindings, the value is `!0`
binding_to_slot: Box<[u8]>,
}
pub struct PipelineLayout {
group_infos: Box<[BindGroupLayoutInfo]>,
}
#[derive(Debug)]
enum BindingRegister {
Textures,
UniformBuffers,
StorageBuffers,
}
#[derive(Debug)]
enum RawBinding {
Buffer {
register: BindingRegister,
raw: glow::Buffer,
offset: i32,
size: i32,
},
Texture {
raw: glow::Texture,
target: BindTarget,
range: wgt::ImageSubresourceRange,
},
Sampler(glow::Sampler),
}
#[derive(Debug)]
pub struct BindGroup {
layout_entries: Arc<[wgt::BindGroupLayoutEntry]>,
contents: Box<[RawBinding]>,
}
#[derive(Debug)] #[derive(Debug)]
struct TextureCopyInfo { struct TextureCopyInfo {
external_format: u32, external_format: u32,

View File

@ -238,6 +238,7 @@ pub trait Device<A: Api>: Send + Sync {
) -> Result<A::CommandEncoder, DeviceError>; ) -> Result<A::CommandEncoder, DeviceError>;
unsafe fn destroy_command_encoder(&self, pool: A::CommandEncoder); unsafe fn destroy_command_encoder(&self, pool: A::CommandEncoder);
/// Creates a bind group layout.
unsafe fn create_bind_group_layout( unsafe fn create_bind_group_layout(
&self, &self,
desc: &BindGroupLayoutDescriptor, desc: &BindGroupLayoutDescriptor,
@ -753,6 +754,10 @@ pub struct SamplerDescriptor<'a> {
pub border_color: Option<wgt::SamplerBorderColor>, pub border_color: Option<wgt::SamplerBorderColor>,
} }
/// BindGroupLayout descriptor.
///
/// Valid usage:
/// - `entries` are sorted by ascending `wgt::BindGroupLayoutEntry::binding`
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct BindGroupLayoutDescriptor<'a> { pub struct BindGroupLayoutDescriptor<'a> {
pub label: Label<'a>, pub label: Label<'a>,

View File

@ -363,11 +363,8 @@ impl crate::Device<super::Api> for super::Device {
&self, &self,
desc: &crate::BindGroupLayoutDescriptor, desc: &crate::BindGroupLayoutDescriptor,
) -> DeviceResult<super::BindGroupLayout> { ) -> DeviceResult<super::BindGroupLayout> {
let mut map = desc.entries.to_vec();
map.sort_by_key(|e| e.binding);
Ok(super::BindGroupLayout { Ok(super::BindGroupLayout {
entries: Arc::new(map), entries: Arc::from(desc.entries),
}) })
} }
unsafe fn destroy_bind_group_layout(&self, _bg_layout: super::BindGroupLayout) {} unsafe fn destroy_bind_group_layout(&self, _bg_layout: super::BindGroupLayout) {}

View File

@ -412,7 +412,7 @@ impl Sampler {
#[derive(Debug)] #[derive(Debug)]
pub struct BindGroupLayout { pub struct BindGroupLayout {
/// Sorted list of BGL entries. /// Sorted list of BGL entries.
entries: Arc<Vec<wgt::BindGroupLayoutEntry>>, entries: Arc<[wgt::BindGroupLayoutEntry]>,
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]

View File

@ -937,7 +937,7 @@ impl crate::Device<super::Api> for super::Device {
Ok(super::BindGroupLayout { Ok(super::BindGroupLayout {
raw, raw,
desc_count, desc_count,
types, types: types.into_boxed_slice(),
}) })
} }
unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) { unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) {

View File

@ -271,7 +271,7 @@ pub struct Sampler {
pub struct BindGroupLayout { pub struct BindGroupLayout {
raw: vk::DescriptorSetLayout, raw: vk::DescriptorSetLayout,
desc_count: gpu_descriptor::DescriptorTotalCount, desc_count: gpu_descriptor::DescriptorTotalCount,
types: Vec<(vk::DescriptorType, u32)>, types: Box<[(vk::DescriptorType, u32)]>,
} }
#[derive(Debug)] #[derive(Debug)]