Skip to content

Commit

Permalink
Binding changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Neo-Zhixing committed Jan 25, 2021
1 parent 7b388b0 commit 0955a22
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 42 deletions.
26 changes: 18 additions & 8 deletions crates/bevy_render/src/pipeline/binding.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::UniformProperty;
use crate::texture::{TextureComponentType, TextureFormat, TextureViewDimension};
use crate::texture::{TextureSampleType, TextureFormat, TextureViewDimension, StorageTextureAccess};

bitflags::bitflags! {
pub struct BindingShaderStage: u32 {
Expand All @@ -20,25 +20,35 @@ pub struct BindingDescriptor {
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum BindType {
Uniform {
dynamic: bool,
has_dynamic_offset: bool,
property: UniformProperty,
},
StorageBuffer {
dynamic: bool,
has_dynamic_offset: bool,
readonly: bool,
},
Sampler {
/// The sampling result is produced based on more than a single color sample from a texture,
/// e.g. when bilinear interpolation is enabled.
///
/// A filtering sampler can only be used with a filterable texture.
filtering: bool,
/// Use as a comparison sampler instead of a normal sampler.
/// For more info take a look at the analogous functionality in OpenGL: https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode.
comparison: bool,
},
SampledTexture {
Texture {
multisampled: bool,
dimension: TextureViewDimension,
component_type: TextureComponentType,
view_dimension: TextureViewDimension,
sample_type: TextureSampleType,
},
StorageTexture {
dimension: TextureViewDimension,
/// Allowed access to this texture.
access: StorageTextureAccess,
/// Format of the texture.
format: TextureFormat,
readonly: bool,
/// Dimension of the texture view that is going to be sampled.
view_dimension: TextureViewDimension,
},
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/pipeline/pipeline_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,10 @@ impl PipelineCompiler {
.any(|b| b == &binding.name)
{
if let BindType::Uniform {
ref mut dynamic, ..
ref mut has_dynamic_offset, ..
} = binding.bind_type
{
*dynamic = true;
*has_dynamic_offset = true;
binding_changed = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/render_graph/nodes/pass_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl<Q: WorldQuery> PassNode<Q> {
name: "Camera".to_string(),
index: 0,
bind_type: BindType::Uniform {
dynamic: false,
has_dynamic_offset: false,
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
},
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
Expand Down
21 changes: 14 additions & 7 deletions crates/bevy_render/src/shader/shader_reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
UniformProperty, VertexAttributeDescriptor, VertexBufferDescriptor, VertexFormat,
},
shader::{ShaderLayout, GL_INSTANCE_INDEX, GL_VERTEX_INDEX},
texture::{TextureComponentType, TextureViewDimension},
texture::{TextureSampleType, TextureViewDimension},
};
use bevy_core::AsBytes;
use spirv_reflect::{
Expand Down Expand Up @@ -123,27 +123,34 @@ fn reflect_binding(
ReflectDescriptorType::UniformBuffer => (
&type_description.type_name,
BindType::Uniform {
dynamic: false,
has_dynamic_offset: false,
property: reflect_uniform(type_description),
},
),
ReflectDescriptorType::SampledImage => (
&binding.name,
BindType::SampledTexture {
dimension: reflect_dimension(type_description),
component_type: TextureComponentType::Float,
BindType::Texture {
view_dimension: reflect_dimension(type_description),
sample_type: TextureSampleType::Float { filterable: false },
multisampled: false,
},
),
ReflectDescriptorType::StorageBuffer => (
&type_description.type_name,
BindType::StorageBuffer {
dynamic: false,
has_dynamic_offset: false,
readonly: true,
},
),
// TODO: detect comparison "true" case: https:/gpuweb/gpuweb/issues/552
ReflectDescriptorType::Sampler => (&binding.name, BindType::Sampler { comparison: false }),
// TODO: detect filtering "true" case
ReflectDescriptorType::Sampler => (
&binding.name,
BindType::Sampler {
comparison: false,
filtering: false,
}
),
_ => panic!("Unsupported bind type {:?}.", binding.descriptor_type),
};

Expand Down
27 changes: 27 additions & 0 deletions crates/bevy_render/src/texture/texture_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,30 @@ impl Default for TextureDescriptor {
}
}
}

#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum StorageTextureAccess {
/// The texture can only be read in the shader and it must be annotated with `readonly`.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(set=0, binding=0, r32f) readonly uniform image2D myStorageImage;
/// ```
ReadOnly,
/// The texture can only be written in the shader and it must be annotated with `writeonly`.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(set=0, binding=0, r32f) writeonly uniform image2D myStorageImage;
/// ```
WriteOnly,
/// The texture can be both read and written in the shader.
/// [`Features::STORAGE_TEXTURE_ACCESS_READ_WRITE`] must be enabled to use this access mode.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(set=0, binding=0, r32f) uniform image2D myStorageImage;
/// ```
ReadWrite,
}

36 changes: 34 additions & 2 deletions crates/bevy_render/src/texture/texture_dimension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,41 @@ impl Extent3d {

/// Type of data shaders will read from a texture.
#[derive(Copy, Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum TextureComponentType {
Float,
pub enum TextureSampleType {
/// Sampling returns floats.
///
/// If `filterable` is false, the texture can't be sampled with
/// a filtering sampler.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(binding = 0)
/// uniform texture2D t;
/// ```
Float { filterable: bool },
/// Sampling does the depth reference comparison.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(binding = 0)
/// uniform texture2DShadow t;
/// ```
Depth,
/// Sampling returns signed integers.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(binding = 0)
/// uniform itexture2D t;
/// ```
Sint,
/// Sampling returns unsigned integers.
///
/// Example GLSL syntax:
/// ```cpp,ignore
/// layout(binding = 0)
/// uniform utexture2D t;
/// ```
Uint,
}

Expand Down
61 changes: 39 additions & 22 deletions crates/bevy_wgpu/src/wgpu_type_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ use bevy_render::{
},
renderer::BufferUsage,
texture::{
AddressMode, Extent3d, FilterMode, SamplerDescriptor, TextureComponentType,
AddressMode, Extent3d, FilterMode, SamplerDescriptor, TextureSampleType,
TextureDescriptor, TextureDimension, TextureFormat, TextureUsage, TextureViewDimension,
},
};
use bevy_window::Window;
use wgpu::BufferBindingType;
use bevy_render::texture::StorageTextureAccess;

pub trait WgpuFrom<T> {
fn from(val: T) -> Self;
Expand Down Expand Up @@ -181,46 +183,61 @@ where
impl WgpuFrom<&BindType> for wgpu::BindingType {
fn from(bind_type: &BindType) -> Self {
match bind_type {
BindType::Uniform { dynamic, .. } => wgpu::BindingType::UniformBuffer {
dynamic: *dynamic,
BindType::Uniform { has_dynamic_offset, .. } => wgpu::BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: *has_dynamic_offset,
min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
},
BindType::StorageBuffer { dynamic, readonly } => wgpu::BindingType::StorageBuffer {
dynamic: *dynamic,
readonly: *readonly,
BindType::StorageBuffer { has_dynamic_offset, readonly } => wgpu::BindingType::Buffer {
ty: BufferBindingType::Storage {
read_only: *readonly
},
has_dynamic_offset: *has_dynamic_offset,
min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
},
BindType::SampledTexture {
dimension,
BindType::Texture {
view_dimension,
multisampled,
component_type,
} => wgpu::BindingType::SampledTexture {
dimension: (*dimension).wgpu_into(),
sample_type,
} => wgpu::BindingType::Texture {
view_dimension: (*view_dimension).wgpu_into(),
multisampled: *multisampled,
component_type: (*component_type).wgpu_into(),
sample_type: (*sample_type).wgpu_into(),
},
BindType::Sampler { comparison } => wgpu::BindingType::Sampler {
BindType::Sampler { comparison, filtering } => wgpu::BindingType::Sampler {
filtering: *filtering,
comparison: *comparison,
},
BindType::StorageTexture {
dimension,
view_dimension,
format,
readonly,
access,
} => wgpu::BindingType::StorageTexture {
dimension: (*dimension).wgpu_into(),
access: (*access).wgpu_into(),
view_dimension: (*view_dimension).wgpu_into(),
format: (*format).wgpu_into(),
readonly: *readonly,
},
}
}
}

impl WgpuFrom<TextureComponentType> for wgpu::TextureComponentType {
fn from(texture_component_type: TextureComponentType) -> Self {
impl WgpuFrom<TextureSampleType> for wgpu::TextureSampleType {
fn from(texture_component_type: TextureSampleType) -> Self {
match texture_component_type {
TextureComponentType::Float => wgpu::TextureComponentType::Float,
TextureComponentType::Sint => wgpu::TextureComponentType::Sint,
TextureComponentType::Uint => wgpu::TextureComponentType::Uint,
TextureSampleType::Float { filterable } => wgpu::TextureSampleType::Float { filterable },
TextureSampleType::Sint => wgpu::TextureSampleType::Sint,
TextureSampleType::Uint => wgpu::TextureSampleType::Uint,
TextureSampleType::Depth => wgpu::TextureSampleType::Depth,
}
}
}

impl WgpuFrom<StorageTextureAccess> for wgpu::StorageTextureAccess {
fn from(storage_texture_access: StorageTextureAccess) -> Self {
match storage_texture_access {
StorageTextureAccess::ReadOnly => wgpu::StorageTextureAccess::ReadOnly,
StorageTextureAccess::WriteOnly => wgpu::StorageTextureAccess::WriteOnly,
StorageTextureAccess::ReadWrite => wgpu::StorageTextureAccess::ReadWrite,
}
}
}
Expand Down

0 comments on commit 0955a22

Please sign in to comment.