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 {
label,
entries: &hal_bindings,

View File

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

View File

@ -1,6 +1,6 @@
use super::{DeviceResult, Resource}; //TEMP
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 {
unsafe fn exit(self) {
@ -46,6 +46,7 @@ impl crate::Device<super::Api> for super::Device {
Ok(super::Buffer {
raw,
target,
size: desc.size,
map_flags,
})
}
@ -269,24 +270,122 @@ impl crate::Device<super::Api> for super::Device {
unsafe fn create_bind_group_layout(
&self,
desc: &crate::BindGroupLayoutDescriptor,
) -> DeviceResult<Resource> {
Ok(Resource)
) -> Result<super::BindGroupLayout, crate::DeviceError> {
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(
&self,
desc: &crate::PipelineLayoutDescriptor<super::Api>,
) -> DeviceResult<Resource> {
Ok(Resource)
) -> Result<super::PipelineLayout, crate::DeviceError> {
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
}
unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {}
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: super::PipelineLayout) {}
unsafe fn create_bind_group(
&self,
desc: &crate::BindGroupDescriptor<super::Api>,
) -> DeviceResult<Resource> {
Ok(Resource)
) -> Result<super::BindGroup, crate::DeviceError> {
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
}
unsafe fn destroy_bind_group(&self, group: Resource) {}
};
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: super::BindGroup) {}
unsafe fn create_shader_module(
&self,

View File

@ -41,9 +41,9 @@ impl crate::Api for Api {
type QuerySet = Resource;
type Fence = Resource;
type BindGroupLayout = Resource;
type BindGroup = Resource;
type PipelineLayout = Resource;
type BindGroupLayout = BindGroupLayout;
type BindGroup = BindGroup;
type PipelineLayout = PipelineLayout;
type ShaderModule = Resource;
type RenderPipeline = Resource;
type ComputePipeline = Resource;
@ -190,6 +190,7 @@ pub struct Queue {
pub struct Buffer {
raw: glow::Buffer,
target: BindTarget,
size: wgt::BufferAddress,
map_flags: u32,
}
@ -239,6 +240,53 @@ pub struct 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)]
struct TextureCopyInfo {
external_format: u32,

View File

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

View File

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

View File

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

View File

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

View File

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