Skip to content

Commit

Permalink
hal/gl: Allow push constants trough emulation
Browse files Browse the repository at this point in the history
Uses freestanding uniforms for push constants
  • Loading branch information
JCapucho committed Jan 18, 2022
1 parent 5b2b6f5 commit 3795042
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ default-members = ["wgpu", "wgpu-hal", "wgpu-info"]

[patch."https://github.com/gfx-rs/naga"]
#naga = { path = "../naga" }
naga = { git = "https://github.com/JCapucho/naga", branch = "glsl-out-push-constants-v2" }

[patch."https://github.com/zakarumych/gpu-descriptor"]
#gpu-descriptor = { path = "../gpu-descriptor/gpu-descriptor" }
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ thiserror = "1"

[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "c0b7ac7"
rev = "a1840be"
#version = "0.8"
features = ["span", "validate", "wgsl-in"]

Expand Down
4 changes: 2 additions & 2 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ js-sys = { version = "0.3" }

[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "c0b7ac7"
rev = "a1840be"
#version = "0.8"

# DEV dependencies

[dev-dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "c0b7ac7"
rev = "a1840be"
#version = "0.8"
features = ["wgsl-in"]

Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ impl super::Adapter {

let mut features = wgt::Features::empty()
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
| wgt::Features::CLEAR_TEXTURE;
| wgt::Features::CLEAR_TEXTURE
| wgt::Features::PUSH_CONSTANTS;
features.set(
wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
extensions.contains("GL_EXT_texture_border_clamp"),
Expand Down Expand Up @@ -399,7 +400,7 @@ impl super::Adapter {
} else {
!0
},
max_push_constant_size: 0,
max_push_constant_size: 64,
min_uniform_buffer_offset_alignment,
min_storage_buffer_offset_alignment,
max_inter_stage_shader_components: gl.get_parameter_i32(glow::MAX_VARYING_COMPONENTS)
Expand Down
46 changes: 41 additions & 5 deletions wgpu-hal/src/gles/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(super) struct State {
has_pass_label: bool,
instance_vbuf_mask: usize,
dirty_vbuf_mask: usize,
uniforms: Box<[super::UniformDesc]>,
}

impl super::CommandBuffer {
Expand All @@ -43,6 +44,21 @@ impl super::CommandBuffer {
self.data_bytes.extend(marker.as_bytes());
start..self.data_bytes.len() as u32
}

fn add_push_constant_data(&mut self, data: &[u32]) -> Range<u32> {
let data_raw = unsafe {
std::slice::from_raw_parts(
data.as_ptr() as *const _,
data.len() * mem::size_of::<u32>(),
)
};
let start = self.data_bytes.len();
assert!(start < u32::MAX as usize);
self.data_bytes.extend_from_slice(data_raw);
let end = self.data_bytes.len();
assert!(end < u32::MAX as usize);
(start as u32)..(end as u32)
}
}

impl super::CommandEncoder {
Expand Down Expand Up @@ -148,8 +164,7 @@ impl super::CommandEncoder {
fn set_pipeline_inner(&mut self, inner: &super::PipelineInner) {
self.cmd_buffer.commands.push(C::SetProgram(inner.program));

//TODO: push constants
let _ = &inner.uniforms;
self.state.uniforms = inner.uniforms.clone();

// rebind textures, if needed
let mut dirty_textures = 0u32;
Expand Down Expand Up @@ -603,10 +618,31 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
&mut self,
_layout: &super::PipelineLayout,
_stages: wgt::ShaderStages,
_offset: u32,
_data: &[u32],
offset: u32,
data: &[u32],
) {
unimplemented!()
let range = self.cmd_buffer.add_push_constant_data(data);

let uniforms = &self.state.uniforms;
if uniforms.is_empty() {
unimplemented!()
}

let uniform = if offset == 0 {
// If offset is zero, we can just return the first item
// in our uniform list
uniforms.get(0).unwrap()
} else {
match uniforms.binary_search_by(|uniform| uniform.offset.cmp(&offset)) {
Ok(index) => uniforms.get(index).unwrap(),
Err(_) => panic!("No uniform found at offset: {}", offset),
}
}
.clone();

self.cmd_buffer
.commands
.push(C::SetPushConstants { uniform, range });
}

unsafe fn insert_debug_marker(&mut self, label: &str) {
Expand Down
43 changes: 41 additions & 2 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,48 @@ impl super::Device {
let glow::ActiveUniform { size, utype, name } =
gl.get_active_uniform(program, uniform).unwrap();

match utype {
glow::INT_SAMPLER_1D
| glow::INT_SAMPLER_1D_ARRAY
| glow::INT_SAMPLER_2D
| glow::INT_SAMPLER_2D_ARRAY
| glow::INT_SAMPLER_2D_MULTISAMPLE
| glow::INT_SAMPLER_2D_MULTISAMPLE_ARRAY
| glow::INT_SAMPLER_2D_RECT
| glow::INT_SAMPLER_3D
| glow::INT_SAMPLER_CUBE
| glow::INT_SAMPLER_CUBE_MAP_ARRAY
| glow::UNSIGNED_INT_SAMPLER_1D
| glow::UNSIGNED_INT_SAMPLER_1D_ARRAY
| glow::UNSIGNED_INT_SAMPLER_2D
| glow::UNSIGNED_INT_SAMPLER_2D_ARRAY
| glow::UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE
| glow::UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
| glow::UNSIGNED_INT_SAMPLER_2D_RECT
| glow::UNSIGNED_INT_SAMPLER_3D
| glow::UNSIGNED_INT_SAMPLER_CUBE
| glow::UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY
| glow::SAMPLER_1D
| glow::SAMPLER_1D_SHADOW
| glow::SAMPLER_1D_ARRAY
| glow::SAMPLER_1D_ARRAY_SHADOW
| glow::SAMPLER_2D
| glow::SAMPLER_2D_SHADOW
| glow::SAMPLER_2D_ARRAY
| glow::SAMPLER_2D_ARRAY_SHADOW
| glow::SAMPLER_2D_MULTISAMPLE
| glow::SAMPLER_2D_MULTISAMPLE_ARRAY
| glow::SAMPLER_2D_RECT
| glow::SAMPLER_2D_RECT_SHADOW
| glow::SAMPLER_3D
| glow::SAMPLER_CUBE
| glow::SAMPLER_CUBE_MAP_ARRAY
| glow::SAMPLER_CUBE_MAP_ARRAY_SHADOW
| glow::SAMPLER_CUBE_SHADOW => continue,
_ => {}
}

if let Some(location) = gl.get_uniform_location(program, &name) {
// Sampler2D won't show up in UniformLocation and the only other uniforms
// should be push constants
uniforms.push(super::UniformDesc {
location,
offset,
Expand Down
7 changes: 6 additions & 1 deletion wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ struct VertexBufferDesc {
}

#[allow(unused)]
#[derive(Clone)]
#[derive(Clone, Debug)]
struct UniformDesc {
location: glow::UniformLocation,
offset: u32,
Expand Down Expand Up @@ -716,6 +716,11 @@ enum Command {
InsertDebugMarker(Range<u32>),
PushDebugGroup(Range<u32>),
PopDebugGroup,
SetPushConstants {
uniform: UniformDesc,
/// Offset from the start of the `data_bytes`
range: Range<u32>,
},
}

#[derive(Default)]
Expand Down
69 changes: 69 additions & 0 deletions wgpu-hal/src/gles/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,75 @@ impl super::Queue {
#[cfg(not(target_arch = "wasm32"))]
gl.pop_debug_group();
}
C::SetPushConstants {
ref uniform,
ref range,
} => {
let range = range.clone();
fn get_data<T>(data: &[u8], range: std::ops::Range<u32>) -> &[T] {
let range_size = range.end - range.start;
assert_eq!(range_size as usize % mem::size_of::<T>(), 0);
assert!(data.len() >= range.end as usize);
let raw = &data[(range.start as usize)..(range.end as usize)];
unsafe {
slice::from_raw_parts(
raw.as_ptr() as *const _,
raw.len() / mem::size_of::<T>(),
)
}
}

let uniform_location = uniform.location.clone();
let location = Some(&uniform_location);

match uniform.utype {
glow::FLOAT => {
let data = get_data::<f32>(data_bytes, range)[0];
gl.uniform_1_f32(location, data);
}
glow::FLOAT_VEC2 => {
let data = get_data::<[f32; 2]>(data_bytes, range)[0];
gl.uniform_2_f32_slice(location, &data);
}
glow::FLOAT_VEC3 => {
let data = get_data::<[f32; 3]>(data_bytes, range)[0];
gl.uniform_3_f32_slice(location, &data);
}
glow::FLOAT_VEC4 => {
let data = get_data::<[f32; 4]>(data_bytes, range)[0];
gl.uniform_4_f32_slice(location, &data);
}
glow::INT => {
let data = get_data::<i32>(data_bytes, range)[0];
gl.uniform_1_i32(location, data);
}
glow::INT_VEC2 => {
let data = get_data::<[i32; 2]>(data_bytes, range)[0];
gl.uniform_2_i32_slice(location, &data);
}
glow::INT_VEC3 => {
let data = get_data::<[i32; 3]>(data_bytes, range)[0];
gl.uniform_3_i32_slice(location, &data);
}
glow::INT_VEC4 => {
let data = get_data::<[i32; 4]>(data_bytes, range)[0];
gl.uniform_4_i32_slice(location, &data);
}
glow::FLOAT_MAT2 => {
let data = get_data::<[f32; 4]>(data_bytes, range)[0];
gl.uniform_matrix_2_f32_slice(location, false, &data);
}
glow::FLOAT_MAT3 => {
let data = get_data::<[f32; 9]>(data_bytes, range)[0];
gl.uniform_matrix_3_f32_slice(location, false, &data);
}
glow::FLOAT_MAT4 => {
let data = get_data::<[f32; 16]>(data_bytes, range)[0];
gl.uniform_matrix_4_f32_slice(location, false, &data);
}
_ => panic!("Unsupported uniform datatype!"),
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/metal/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl super::Device {
let mut immutable_buffer_mask = 0;
for (var_handle, var) in module.global_variables.iter() {
if var.class == naga::StorageClass::WorkGroup {
let size = module.types[var.ty].inner.span(&module.constants);
let size = module.types[var.ty].inner.size(&module.constants);
wg_memory_sizes.push(size);
}

Expand Down
6 changes: 3 additions & 3 deletions wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,20 @@ env_logger = "0.8"

[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "c0b7ac7"
rev = "a1840be"
#version = "0.8"
optional = true

# used to test all the example shaders
[dev-dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "c0b7ac7"
rev = "a1840be"
#version = "0.8"
features = ["wgsl-in"]

[target.'cfg(target_arch = "wasm32")'.dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "c0b7ac7"
rev = "a1840be"
#version = "0.8"
features = ["wgsl-out"]

Expand Down

0 comments on commit 3795042

Please sign in to comment.