From c2c74ea55bb9ad4a62a749a1a077c6c6cba89126 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 18 Nov 2023 18:54:45 -0500 Subject: [PATCH 1/6] Implement base instance in shaders on GL --- naga/src/back/glsl/mod.rs | 7 ++++++- naga/tests/in/push-constants.wgsl | 3 ++- naga/tests/out/glsl/access.foo_vert.Vertex.glsl | 2 ++ ...t_size_vertex_shader_webgl.vs_main.Vertex.glsl | 2 ++ naga/tests/out/glsl/image.queries.Vertex.glsl | 2 ++ .../out/glsl/interpolate.vert_main.Vertex.glsl | 2 ++ naga/tests/out/glsl/invariant.vs.Vertex.glsl | 2 ++ naga/tests/out/glsl/padding.vertex.Vertex.glsl | 2 ++ .../out/glsl/push-constants.vert_main.Vertex.glsl | 7 +++++-- naga/tests/out/glsl/quad-vert.main.Vertex.glsl | 2 ++ naga/tests/out/glsl/quad.vert_main.Vertex.glsl | 2 ++ naga/tests/out/glsl/shadow.vs_main.Vertex.glsl | 2 ++ naga/tests/out/glsl/skybox.vs_main.Vertex.glsl | 2 ++ naga/tests/out/hlsl/push-constants.hlsl | 6 +++--- wgpu-hal/src/gles/command.rs | 15 +++++++++++---- wgpu-hal/src/gles/device.rs | 8 ++++++++ wgpu-hal/src/gles/mod.rs | 5 +++++ wgpu-hal/src/gles/queue.rs | 8 ++++++++ 18 files changed, 68 insertions(+), 11 deletions(-) diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index 2ecb421d4db..e2a650552f2 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -652,6 +652,11 @@ impl<'a, W: Write> Writer<'a, W> { writeln!(self.out)?; } + if self.entry_point.stage == ShaderStage::Vertex { + writeln!(self.out, "uniform uint _naga_vs_base_instance;")?; + writeln!(self.out)?; + } + // Enable early depth tests if needed if let Some(depth_test) = self.entry_point.early_depth_test { // If early depth test is supported for this version of GLSL @@ -4330,7 +4335,7 @@ const fn glsl_built_in( Bi::BaseVertex => "uint(gl_BaseVertex)", Bi::ClipDistance => "gl_ClipDistance", Bi::CullDistance => "gl_CullDistance", - Bi::InstanceIndex => "uint(gl_InstanceID)", + Bi::InstanceIndex => "(uint(gl_InstanceID) + _naga_vs_base_instance)", Bi::PointSize => "gl_PointSize", Bi::VertexIndex => "uint(gl_VertexID)", // fragment diff --git a/naga/tests/in/push-constants.wgsl b/naga/tests/in/push-constants.wgsl index b3dc5152303..dbe81a02958 100644 --- a/naga/tests/in/push-constants.wgsl +++ b/naga/tests/in/push-constants.wgsl @@ -10,9 +10,10 @@ struct FragmentIn { @vertex fn vert_main( @location(0) pos : vec2, + @builtin(instance_index) ii: u32, @builtin(vertex_index) vi: u32, ) -> @builtin(position) vec4 { - return vec4(f32(vi) * pc.multiplier * pos, 0.0, 1.0); + return vec4(f32(ii) * f32(vi) * pc.multiplier * pos, 0.0, 1.0); } @fragment diff --git a/naga/tests/out/glsl/access.foo_vert.Vertex.glsl b/naga/tests/out/glsl/access.foo_vert.Vertex.glsl index edc7ce1e6b4..e2d70c24e35 100644 --- a/naga/tests/out/glsl/access.foo_vert.Vertex.glsl +++ b/naga/tests/out/glsl/access.foo_vert.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct GlobalConst { uint a; uvec3 b; diff --git a/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl b/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl index 069595bc81d..d48bd1d58cf 100644 --- a/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl +++ b/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + void main() { uint in_vertex_index = uint(gl_VertexID); diff --git a/naga/tests/out/glsl/image.queries.Vertex.glsl b/naga/tests/out/glsl/image.queries.Vertex.glsl index 932a0a3bc33..730ce949c5c 100644 --- a/naga/tests/out/glsl/image.queries.Vertex.glsl +++ b/naga/tests/out/glsl/image.queries.Vertex.glsl @@ -4,6 +4,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + uniform highp sampler2D _group_0_binding_0_vs; uniform highp sampler2D _group_0_binding_1_vs; diff --git a/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl b/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl index f423a3dc187..2a195d3ae17 100644 --- a/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl @@ -1,4 +1,6 @@ #version 400 core +uniform uint _naga_vs_base_instance; + struct FragmentInput { vec4 position; uint _flat; diff --git a/naga/tests/out/glsl/invariant.vs.Vertex.glsl b/naga/tests/out/glsl/invariant.vs.Vertex.glsl index a34eab34790..e5ba4e4b515 100644 --- a/naga/tests/out/glsl/invariant.vs.Vertex.glsl +++ b/naga/tests/out/glsl/invariant.vs.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + invariant gl_Position; void main() { diff --git a/naga/tests/out/glsl/padding.vertex.Vertex.glsl b/naga/tests/out/glsl/padding.vertex.Vertex.glsl index 82d8d31fa9f..2411957ce52 100644 --- a/naga/tests/out/glsl/padding.vertex.Vertex.glsl +++ b/naga/tests/out/glsl/padding.vertex.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct S { vec3 a; }; diff --git a/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl b/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl index 4519dc4c6c2..083a2c614db 100644 --- a/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct PushConstants { float multiplier; }; @@ -15,9 +17,10 @@ layout(location = 0) in vec2 _p2vs_location0; void main() { vec2 pos = _p2vs_location0; + uint ii = (uint(gl_InstanceID) + _naga_vs_base_instance); uint vi = uint(gl_VertexID); - float _e5 = _push_constant_binding_vs.multiplier; - gl_Position = vec4(((float(vi) * _e5) * pos), 0.0, 1.0); + float _e8 = _push_constant_binding_vs.multiplier; + gl_Position = vec4((((float(ii) * float(vi)) * _e8) * pos), 0.0, 1.0); return; } diff --git a/naga/tests/out/glsl/quad-vert.main.Vertex.glsl b/naga/tests/out/glsl/quad-vert.main.Vertex.glsl index db5089c2dfb..5efbf8d5db7 100644 --- a/naga/tests/out/glsl/quad-vert.main.Vertex.glsl +++ b/naga/tests/out/glsl/quad-vert.main.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct gen_gl_PerVertex { vec4 gen_gl_Position; float gen_gl_PointSize; diff --git a/naga/tests/out/glsl/quad.vert_main.Vertex.glsl b/naga/tests/out/glsl/quad.vert_main.Vertex.glsl index c5bca7f6669..07f23e6f248 100644 --- a/naga/tests/out/glsl/quad.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/quad.vert_main.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct VertexOutput { vec2 uv; vec4 position; diff --git a/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl b/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl index 631c412f2a3..b72789ff219 100644 --- a/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl +++ b/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct Globals { mat4x4 view_proj; uvec4 num_lights; diff --git a/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl b/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl index e40addaa2fc..7a7006d42bc 100644 --- a/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl +++ b/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl @@ -3,6 +3,8 @@ precision highp float; precision highp int; +uniform uint _naga_vs_base_instance; + struct VertexOutput { vec4 position; vec3 uv; diff --git a/naga/tests/out/hlsl/push-constants.hlsl b/naga/tests/out/hlsl/push-constants.hlsl index 22b4b6acdf6..501bc7f90de 100644 --- a/naga/tests/out/hlsl/push-constants.hlsl +++ b/naga/tests/out/hlsl/push-constants.hlsl @@ -19,10 +19,10 @@ struct FragmentInput_main { float4 color : LOC0; }; -float4 vert_main(float2 pos : LOC0, uint vi : SV_VertexID) : SV_Position +float4 vert_main(float2 pos : LOC0, uint ii : SV_InstanceID, uint vi : SV_VertexID) : SV_Position { - float _expr5 = pc.multiplier; - return float4(((float((_NagaConstants.base_vertex + vi)) * _expr5) * pos), 0.0, 1.0); + float _expr8 = pc.multiplier; + return float4((((float((_NagaConstants.base_instance + ii)) * float((_NagaConstants.base_vertex + vi))) * _expr8) * pos), 0.0, 1.0); } float4 main(FragmentInput_main fragmentinput_main) : SV_Target0 diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index abbbe8d4274..7eedf08d9ce 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -29,6 +29,7 @@ pub(super) struct State { instance_vbuf_mask: usize, dirty_vbuf_mask: usize, active_first_instance: u32, + base_instance_location: Option, push_constant_descs: ArrayVec, // The current state of the push constant data block. current_push_constant_data: [u32; super::MAX_PUSH_CONSTANTS], @@ -57,6 +58,7 @@ impl Default for State { instance_vbuf_mask: Default::default(), dirty_vbuf_mask: Default::default(), active_first_instance: Default::default(), + base_instance_location: Default::default(), push_constant_descs: Default::default(), current_push_constant_data: [0; super::MAX_PUSH_CONSTANTS], end_of_pass_timestamp: Default::default(), @@ -206,6 +208,7 @@ impl super::CommandEncoder { fn set_pipeline_inner(&mut self, inner: &super::PipelineInner) { self.cmd_buffer.commands.push(C::SetProgram(inner.program)); + self.state.base_instance_location = inner.base_instance_location.clone(); self.state.push_constant_descs = inner.push_constant_descs.clone(); // rebind textures, if needed @@ -1004,15 +1007,17 @@ impl crate::CommandEncoder for super::CommandEncoder { &mut self, start_vertex: u32, vertex_count: u32, - start_instance: u32, + base_instance: u32, instance_count: u32, ) { - self.prepare_draw(start_instance); + self.prepare_draw(base_instance); self.cmd_buffer.commands.push(C::Draw { topology: self.state.topology, start_vertex, vertex_count, + base_instance, instance_count, + base_instance_location: self.state.base_instance_location.clone(), }); } unsafe fn draw_indexed( @@ -1020,10 +1025,10 @@ impl crate::CommandEncoder for super::CommandEncoder { start_index: u32, index_count: u32, base_vertex: i32, - start_instance: u32, + base_instance: u32, instance_count: u32, ) { - self.prepare_draw(start_instance); + self.prepare_draw(base_instance); let (index_size, index_type) = match self.state.index_format { wgt::IndexFormat::Uint16 => (2, glow::UNSIGNED_SHORT), wgt::IndexFormat::Uint32 => (4, glow::UNSIGNED_INT), @@ -1035,7 +1040,9 @@ impl crate::CommandEncoder for super::CommandEncoder { index_offset, index_count, base_vertex, + base_instance, instance_count, + base_instance_location: self.state.base_instance_location.clone(), }); } unsafe fn draw_indirect( diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 7934c4be01a..fceca1f7e01 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -467,9 +467,17 @@ impl super::Device { } } + let base_instance_location = if has_stages.contains(wgt::ShaderStages::VERTEX) { + // If this returns none (the uniform isn't active), that's fine, we just won't set it. + unsafe { gl.get_uniform_location(program, "_naga_vs_base_instance") } + } else { + None + }; + Ok(Arc::new(super::PipelineInner { program, sampler_map, + base_instance_location, push_constant_descs: uniforms, })) } diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 0af5ad4a6ed..ed7c0fdb71c 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -513,6 +513,7 @@ type SamplerBindMap = [Option; MAX_TEXTURE_SLOTS]; struct PipelineInner { program: glow::Program, sampler_map: SamplerBindMap, + base_instance_location: Option, push_constant_descs: ArrayVec, } @@ -712,7 +713,9 @@ enum Command { topology: u32, start_vertex: u32, vertex_count: u32, + base_instance: u32, instance_count: u32, + base_instance_location: Option, }, DrawIndexed { topology: u32, @@ -720,7 +723,9 @@ enum Command { index_count: u32, index_offset: wgt::BufferAddress, base_vertex: i32, + base_instance: u32, instance_count: u32, + base_instance_location: Option, }, DrawIndirect { topology: u32, diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 3b87ae7b729..a0dc3e95079 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -158,11 +158,15 @@ impl super::Queue { start_vertex, vertex_count, instance_count, + base_instance, + base_instance_location, } => { // Don't use `gl.draw_arrays` for `instance_count == 1`. // Angle has a bug where it doesn't consider the instance divisor when `DYNAMIC_DRAW` is used in `draw_arrays`. // See https://github.com/gfx-rs/wgpu/issues/3578 unsafe { + gl.uniform_1_u32(base_instance_location.as_ref(), base_instance); + gl.draw_arrays_instanced( topology, start_vertex as i32, @@ -177,8 +181,12 @@ impl super::Queue { index_count, index_offset, base_vertex, + base_instance, instance_count, + base_instance_location, } => { + unsafe { gl.uniform_1_u32(base_instance_location.as_ref(), base_instance) }; + match base_vertex { // Don't use `gl.draw_elements`/`gl.draw_elements_base_vertex` for `instance_count == 1`. // Angle has a bug where it doesn't consider the instance divisor when `DYNAMIC_DRAW` is used in `gl.draw_elements`/`gl.draw_elements_base_vertex`. From bec87bb6b9ab5cb83dc1d17d78b843fd230a4256 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 18 Nov 2023 19:03:31 -0500 Subject: [PATCH 2/6] Iterate --- naga/src/back/glsl/keywords.rs | 1 + naga/src/back/glsl/mod.rs | 10 ++++++++-- naga/tests/out/glsl/access.foo_vert.Vertex.glsl | 2 +- ..._point_size_vertex_shader_webgl.vs_main.Vertex.glsl | 2 +- naga/tests/out/glsl/image.queries.Vertex.glsl | 2 +- naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl | 2 +- naga/tests/out/glsl/invariant.vs.Vertex.glsl | 2 +- naga/tests/out/glsl/padding.vertex.Vertex.glsl | 2 +- .../out/glsl/push-constants.vert_main.Vertex.glsl | 2 +- naga/tests/out/glsl/quad-vert.main.Vertex.glsl | 2 +- naga/tests/out/glsl/quad.vert_main.Vertex.glsl | 2 +- naga/tests/out/glsl/shadow.vs_main.Vertex.glsl | 2 +- naga/tests/out/glsl/skybox.vs_main.Vertex.glsl | 2 +- wgpu-hal/src/gles/device.rs | 2 +- 14 files changed, 21 insertions(+), 14 deletions(-) diff --git a/naga/src/back/glsl/keywords.rs b/naga/src/back/glsl/keywords.rs index afadd6e7f1a..f980319fa21 100644 --- a/naga/src/back/glsl/keywords.rs +++ b/naga/src/back/glsl/keywords.rs @@ -480,4 +480,5 @@ pub const RESERVED_KEYWORDS: &[&str] = &[ // Naga utilities: super::MODF_FUNCTION, super::FREXP_FUNCTION, + super::BASE_INSTANCE_BINDING, ]; diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index e2a650552f2..e1966596368 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -76,6 +76,8 @@ const CLAMPED_LOD_SUFFIX: &str = "_clamped_lod"; pub(crate) const MODF_FUNCTION: &str = "naga_modf"; pub(crate) const FREXP_FUNCTION: &str = "naga_frexp"; +pub const BASE_INSTANCE_BINDING: &str = "naga_vs_base_instance"; + /// Mapping between resources and bindings. pub type BindingMap = std::collections::BTreeMap; @@ -569,7 +571,11 @@ impl<'a, W: Write> Writer<'a, W> { keywords::RESERVED_KEYWORDS, &[], &[], - &["gl_"], + &[ + "gl_", // all GL built-in variables + "_group", // all normal bindings + "_push_constant_binding_", // all push constant bindings + ], &mut names, ); @@ -653,7 +659,7 @@ impl<'a, W: Write> Writer<'a, W> { } if self.entry_point.stage == ShaderStage::Vertex { - writeln!(self.out, "uniform uint _naga_vs_base_instance;")?; + writeln!(self.out, "uniform uint {BASE_INSTANCE_BINDING};")?; writeln!(self.out)?; } diff --git a/naga/tests/out/glsl/access.foo_vert.Vertex.glsl b/naga/tests/out/glsl/access.foo_vert.Vertex.glsl index e2d70c24e35..fee83ae5090 100644 --- a/naga/tests/out/glsl/access.foo_vert.Vertex.glsl +++ b/naga/tests/out/glsl/access.foo_vert.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct GlobalConst { uint a; diff --git a/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl b/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl index d48bd1d58cf..605dc833519 100644 --- a/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl +++ b/naga/tests/out/glsl/force_point_size_vertex_shader_webgl.vs_main.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; void main() { diff --git a/naga/tests/out/glsl/image.queries.Vertex.glsl b/naga/tests/out/glsl/image.queries.Vertex.glsl index 730ce949c5c..ad1dd437df8 100644 --- a/naga/tests/out/glsl/image.queries.Vertex.glsl +++ b/naga/tests/out/glsl/image.queries.Vertex.glsl @@ -4,7 +4,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; uniform highp sampler2D _group_0_binding_0_vs; diff --git a/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl b/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl index 2a195d3ae17..85bac684c4f 100644 --- a/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/interpolate.vert_main.Vertex.glsl @@ -1,5 +1,5 @@ #version 400 core -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct FragmentInput { vec4 position; diff --git a/naga/tests/out/glsl/invariant.vs.Vertex.glsl b/naga/tests/out/glsl/invariant.vs.Vertex.glsl index e5ba4e4b515..4b1d8ac3e8f 100644 --- a/naga/tests/out/glsl/invariant.vs.Vertex.glsl +++ b/naga/tests/out/glsl/invariant.vs.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; invariant gl_Position; diff --git a/naga/tests/out/glsl/padding.vertex.Vertex.glsl b/naga/tests/out/glsl/padding.vertex.Vertex.glsl index 2411957ce52..53e0d9d71df 100644 --- a/naga/tests/out/glsl/padding.vertex.Vertex.glsl +++ b/naga/tests/out/glsl/padding.vertex.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct S { vec3 a; diff --git a/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl b/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl index 083a2c614db..9b1252626c1 100644 --- a/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct PushConstants { float multiplier; diff --git a/naga/tests/out/glsl/quad-vert.main.Vertex.glsl b/naga/tests/out/glsl/quad-vert.main.Vertex.glsl index 5efbf8d5db7..8262d2199fa 100644 --- a/naga/tests/out/glsl/quad-vert.main.Vertex.glsl +++ b/naga/tests/out/glsl/quad-vert.main.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct gen_gl_PerVertex { vec4 gen_gl_Position; diff --git a/naga/tests/out/glsl/quad.vert_main.Vertex.glsl b/naga/tests/out/glsl/quad.vert_main.Vertex.glsl index 07f23e6f248..9c39de218e4 100644 --- a/naga/tests/out/glsl/quad.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/quad.vert_main.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct VertexOutput { vec2 uv; diff --git a/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl b/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl index b72789ff219..e5ef5e50ca4 100644 --- a/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl +++ b/naga/tests/out/glsl/shadow.vs_main.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct Globals { mat4x4 view_proj; diff --git a/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl b/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl index 7a7006d42bc..384894b781a 100644 --- a/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl +++ b/naga/tests/out/glsl/skybox.vs_main.Vertex.glsl @@ -3,7 +3,7 @@ precision highp float; precision highp int; -uniform uint _naga_vs_base_instance; +uniform uint naga_vs_base_instance; struct VertexOutput { vec4 position; diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index fceca1f7e01..c1f1619a436 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -469,7 +469,7 @@ impl super::Device { let base_instance_location = if has_stages.contains(wgt::ShaderStages::VERTEX) { // If this returns none (the uniform isn't active), that's fine, we just won't set it. - unsafe { gl.get_uniform_location(program, "_naga_vs_base_instance") } + unsafe { gl.get_uniform_location(program, naga::back::glsl::BASE_INSTANCE_BINDING) } } else { None }; From bb3e3957dfba719f64653c2010b2efadb851523c Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 18 Nov 2023 19:20:08 -0500 Subject: [PATCH 3/6] CI --- naga/src/back/glsl/mod.rs | 8 +++++--- wgpu-hal/src/gles/command.rs | 3 +++ wgpu-hal/src/gles/mod.rs | 26 ++++++++++++++++++++++++++ wgpu-hal/src/gles/queue.rs | 4 ++-- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index e1966596368..fadb61fb8ab 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -76,6 +76,7 @@ const CLAMPED_LOD_SUFFIX: &str = "_clamped_lod"; pub(crate) const MODF_FUNCTION: &str = "naga_modf"; pub(crate) const FREXP_FUNCTION: &str = "naga_frexp"; +// Must match code in glsl_built_in pub const BASE_INSTANCE_BINDING: &str = "naga_vs_base_instance"; /// Mapping between resources and bindings. @@ -572,8 +573,8 @@ impl<'a, W: Write> Writer<'a, W> { &[], &[], &[ - "gl_", // all GL built-in variables - "_group", // all normal bindings + "gl_", // all GL built-in variables + "_group", // all normal bindings "_push_constant_binding_", // all push constant bindings ], &mut names, @@ -4341,7 +4342,8 @@ const fn glsl_built_in( Bi::BaseVertex => "uint(gl_BaseVertex)", Bi::ClipDistance => "gl_ClipDistance", Bi::CullDistance => "gl_CullDistance", - Bi::InstanceIndex => "(uint(gl_InstanceID) + _naga_vs_base_instance)", + // Must match BASE_INSTANCE_BINDING + Bi::InstanceIndex => "(uint(gl_InstanceID) + naga_vs_base_instance)", Bi::PointSize => "gl_PointSize", Bi::VertexIndex => "uint(gl_VertexID)", // fragment diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 7eedf08d9ce..4bbcb6ffb68 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -205,6 +205,7 @@ impl super::CommandEncoder { } } + #[allow(clippy::clone_on_copy)] // False positive when cloning glow::UniformLocation fn set_pipeline_inner(&mut self, inner: &super::PipelineInner) { self.cmd_buffer.commands.push(C::SetProgram(inner.program)); @@ -1011,6 +1012,7 @@ impl crate::CommandEncoder for super::CommandEncoder { instance_count: u32, ) { self.prepare_draw(base_instance); + #[allow(clippy::clone_on_copy)] // False positive when cloning glow::UniformLocation self.cmd_buffer.commands.push(C::Draw { topology: self.state.topology, start_vertex, @@ -1034,6 +1036,7 @@ impl crate::CommandEncoder for super::CommandEncoder { wgt::IndexFormat::Uint32 => (4, glow::UNSIGNED_INT), }; let index_offset = self.state.index_offset + index_size * start_index as wgt::BufferAddress; + #[allow(clippy::clone_on_copy)] // False positive when cloning glow::UniformLocation self.cmd_buffer.commands.push(C::DrawIndexed { topology: self.state.topology, index_type, diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index ed7c0fdb71c..114f6677073 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -914,6 +914,19 @@ impl fmt::Debug for CommandBuffer { } } +#[cfg(all( + target_arch = "wasm32", + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") +))] +unsafe impl Sync for CommandBuffer {} +#[cfg(all( + target_arch = "wasm32", + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") +))] +unsafe impl Send for CommandBuffer {} + //TODO: we would have something like `Arc` // here and in the command buffers. So that everything grows // inside the encoder and stays there until `reset_all`. @@ -932,6 +945,19 @@ impl fmt::Debug for CommandEncoder { } } +#[cfg(all( + target_arch = "wasm32", + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") +))] +unsafe impl Sync for CommandEncoder {} +#[cfg(all( + target_arch = "wasm32", + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") +))] +unsafe impl Send for CommandEncoder {} + #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] fn gl_debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, message: &str) { let source_str = match source { diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index a0dc3e95079..ad3a7781c51 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -159,7 +159,7 @@ impl super::Queue { vertex_count, instance_count, base_instance, - base_instance_location, + ref base_instance_location, } => { // Don't use `gl.draw_arrays` for `instance_count == 1`. // Angle has a bug where it doesn't consider the instance divisor when `DYNAMIC_DRAW` is used in `draw_arrays`. @@ -183,7 +183,7 @@ impl super::Queue { base_vertex, base_instance, instance_count, - base_instance_location, + ref base_instance_location, } => { unsafe { gl.uniform_1_u32(base_instance_location.as_ref(), base_instance) }; From 95b404f6a7ac018e6f9f7723ed876d2cb93f10f4 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 18 Nov 2023 19:27:09 -0500 Subject: [PATCH 4/6] Woot --- naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl | 2 +- tests/tests/vertex_indices/mod.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl b/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl index 9b1252626c1..eadb7370fe6 100644 --- a/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl +++ b/naga/tests/out/glsl/push-constants.vert_main.Vertex.glsl @@ -17,7 +17,7 @@ layout(location = 0) in vec2 _p2vs_location0; void main() { vec2 pos = _p2vs_location0; - uint ii = (uint(gl_InstanceID) + _naga_vs_base_instance); + uint ii = (uint(gl_InstanceID) + naga_vs_base_instance); uint vi = uint(gl_VertexID); float _e8 = _push_constant_binding_vs.multiplier; gl_Position = vec4((((float(ii) * float(vi)) * _e8) * pos), 0.0, 1.0); diff --git a/tests/tests/vertex_indices/mod.rs b/tests/tests/vertex_indices/mod.rs index 4fe8395eaa0..a4d242abec9 100644 --- a/tests/tests/vertex_indices/mod.rs +++ b/tests/tests/vertex_indices/mod.rs @@ -186,9 +186,7 @@ static DRAW_INSTANCED_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( TestParameters::default() .test_features_limits() - .features(wgpu::Features::VERTEX_WRITABLE_STORAGE) - // https://github.com/gfx-rs/wgpu/issues/4276 - .expect_fail(FailureCase::backend(wgpu::Backends::GL)), + .features(wgpu::Features::VERTEX_WRITABLE_STORAGE), ) .run_sync(|ctx| { pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| { From 59c67627120d901ad92805e3cad2754bde527f06 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 18 Nov 2023 19:34:38 -0500 Subject: [PATCH 5/6] Clippy --- tests/tests/vertex_indices/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests/vertex_indices/mod.rs b/tests/tests/vertex_indices/mod.rs index a4d242abec9..d321996089f 100644 --- a/tests/tests/vertex_indices/mod.rs +++ b/tests/tests/vertex_indices/mod.rs @@ -2,7 +2,7 @@ use std::num::NonZeroU64; use wgpu::util::DeviceExt; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; fn pulling_common( ctx: TestingContext, From ba2a06db0efff8639b99c3796a09782655eccf0b Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 18 Nov 2023 19:58:07 -0500 Subject: [PATCH 6/6] Changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 539aee7ef86..2131807337b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,11 @@ Bottom level categories: ## Unreleased +### New Features + +#### OpenGL +- `@builtin(instance_index)` now properly reflects the range provided in the draw call instead of always counting from 0. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722). + ### Changes #### General