diff --git a/Cargo.lock b/Cargo.lock index 74884819c5e..43aaa613674 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1039,7 +1039,7 @@ dependencies = [ [[package]] name = "naga" version = "0.8.0" -source = "git+https://github.com/gfx-rs/naga?rev=c0b7ac7#c0b7ac7f542cc42ccac6f2ec3fc1fb01309cf4d7" +source = "git+https://github.com/gfx-rs/naga?rev=a1840be#a1840beb1a96c9a49980fe3efa8e2f3dcd88abe6" dependencies = [ "bit-set", "bitflags", diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index 4460086e262..45977a517b5 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -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"] diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 045aded7873..9f69af5098e 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -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"] diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index e4bb5b60c94..b8f81620461 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -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"), @@ -363,6 +364,9 @@ impl super::Adapter { 0 }; + let max_uniform_buffer_binding_size = + gl.get_parameter_i32(glow::MAX_UNIFORM_BLOCK_SIZE) as u32; + let limits = wgt::Limits { max_texture_dimension_1d: max_texture_size, max_texture_dimension_2d: max_texture_size, @@ -376,8 +380,7 @@ impl super::Adapter { max_storage_buffers_per_shader_stage, max_storage_textures_per_shader_stage, max_uniform_buffers_per_shader_stage, - max_uniform_buffer_binding_size: gl.get_parameter_i32(glow::MAX_UNIFORM_BLOCK_SIZE) - as u32, + max_uniform_buffer_binding_size, max_storage_buffer_binding_size: if ver >= (3, 1) { gl.get_parameter_i32(glow::MAX_SHADER_STORAGE_BLOCK_SIZE) } else { @@ -399,7 +402,7 @@ impl super::Adapter { } else { !0 }, - max_push_constant_size: 0, + max_push_constant_size: max_uniform_buffer_binding_size, min_uniform_buffer_offset_alignment, min_storage_buffer_offset_alignment, max_inter_stage_shader_components: gl.get_parameter_i32(glow::MAX_VARYING_COMPONENTS) @@ -522,7 +525,7 @@ impl crate::Adapter for super::Adapter { unsafe fn open( &self, features: wgt::Features, - _limits: &wgt::Limits, + limits: &wgt::Limits, ) -> Result, crate::DeviceError> { let gl = &self.shared.context.lock(); gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1); @@ -539,6 +542,22 @@ impl crate::Adapter for super::Adapter { let zeroes = vec![0u8; super::ZERO_BUFFER_SIZE]; gl.buffer_data_u8_slice(glow::COPY_READ_BUFFER, &zeroes, glow::STATIC_DRAW); + let push_constants_buffer = if features.contains(wgt::Features::PUSH_CONSTANTS) { + let size = limits.max_push_constant_size.max(256) as i32; + let buffer = gl + .create_buffer() + .map_err(|_| crate::DeviceError::OutOfMemory)?; + gl.bind_buffer(glow::UNIFORM_BUFFER, Some(buffer)); + gl.buffer_data_size(glow::UNIFORM_BUFFER, size, glow::DYNAMIC_READ); + let ptr = gl.map_buffer_range(glow::UNIFORM_BUFFER, 0, size, glow::MAP_WRITE_BIT); + // TODO: this should always be 4 byte aligned but maybe add some checks + let slice = std::slice::from_raw_parts_mut(ptr as *mut u32, size as usize); + gl.bind_buffer(glow::UNIFORM_BUFFER, None); + Some((buffer, slice)) + } else { + None + }; + // Compile the shader program we use for doing manual clears to work around Mesa fastclear // bug. let (shader_clear_program, shader_clear_program_color_uniform_location) = @@ -566,6 +585,7 @@ impl crate::Adapter for super::Adapter { temp_query_results: Vec::new(), draw_buffer_count: 1, current_index_buffer: None, + push_constants_buffer, }, }) } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index a2e80e0f6c8..3f043257ec9 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -603,10 +603,13 @@ impl crate::CommandEncoder for super::CommandEncoder { &mut self, _layout: &super::PipelineLayout, _stages: wgt::ShaderStages, - _offset: u32, - _data: &[u32], + offset: u32, + data: &[u32], ) { - unimplemented!() + self.cmd_buffer.commands.push(C::SetPushConstants { + offset, + data: data.into(), + }); } unsafe fn insert_debug_marker(&mut self, label: &str) { diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index a85301fa2c0..bd91aa56cf8 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -29,6 +29,11 @@ impl CompilationContext<'_> { ep_info: &naga::valid::FunctionInfo, reflection_info: naga::back::glsl::ReflectionInfo, ) { + if let Some(name) = reflection_info.push_constant { + self.name_binding_map + .insert(name, (super::BindingRegister::UniformBuffers, 0)); + } + for (handle, var) in module.global_variables.iter() { if ep_info[handle].is_empty() { continue; @@ -809,6 +814,12 @@ impl crate::Device for super::Device { ); let mut binding_map = glsl::BindingMap::default(); + // If push constants are used by the pipeline, reserve the first slot + // for the uniform buffer used to emulate push constants. + if !desc.push_constant_ranges.is_empty() { + num_uniform_buffers += 1; + } + for (group_index, bg_layout) in desc.bind_group_layouts.iter().enumerate() { // create a vector with the size enough to hold all the bindings, filled with `!0` let mut binding_to_slot = vec![ @@ -856,6 +867,7 @@ impl crate::Device for super::Device { version: self.shared.shading_language_version, writer_flags, binding_map, + push_constant_binding: 0, }, }) } diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index d5e1980b212..d0ce917af99 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -208,6 +208,7 @@ pub struct Queue { temp_query_results: Vec, draw_buffer_count: u8, current_index_buffer: Option, + push_constants_buffer: Option<(glow::Buffer, &'static mut [u32])>, } #[derive(Clone, Debug)] @@ -716,6 +717,10 @@ enum Command { InsertDebugMarker(Range), PushDebugGroup(Range), PopDebugGroup, + SetPushConstants { + offset: u32, + data: Vec, + }, } #[derive(Default)] diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index b3acddc9f85..13f53efffd7 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -1067,6 +1067,19 @@ impl super::Queue { #[cfg(not(target_arch = "wasm32"))] gl.pop_debug_group(); } + C::SetPushConstants { offset, ref data } => { + let &mut (buffer, ref mut buffer_data) = + self.push_constants_buffer.as_mut().unwrap(); + buffer_data[offset as usize..(offset as usize + data.len())] + .copy_from_slice(&data[..]); + gl.bind_buffer_range( + glow::UNIFORM_BUFFER, + 0, + Some(buffer), + offset as i32, + data.len() as i32, + ); + } } } } diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index cc6dc6ab938..f2d09912757 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -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); } diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 5110322b833..dc6f4eb455a 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -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"]