diff --git a/src/gallium/frontends/rusticl/core/kernel.rs b/src/gallium/frontends/rusticl/core/kernel.rs index c75968164a8..f22aaa77dac 100644 --- a/src/gallium/frontends/rusticl/core/kernel.rs +++ b/src/gallium/frontends/rusticl/core/kernel.rs @@ -1651,7 +1651,7 @@ impl Kernel { ctx.bind_kernel(&nir_kernel_builds, variant)?; ctx.bind_sampler_states(samplers); ctx.bind_sampler_views(sviews); - ctx.set_shader_images(&iviews); + ctx.bind_shader_images(&iviews); ctx.set_global_binding(resources.as_slice(), &mut globals); for z in 0..grid[2].div_ceil(hw_max_grid[2]) { diff --git a/src/gallium/frontends/rusticl/core/queue.rs b/src/gallium/frontends/rusticl/core/queue.rs index d85f5e7560c..ec78a0f06d5 100644 --- a/src/gallium/frontends/rusticl/core/queue.rs +++ b/src/gallium/frontends/rusticl/core/queue.rs @@ -11,6 +11,7 @@ use mesa_rust::compiler::nir::NirShader; use mesa_rust::pipe::context::PipeContext; use mesa_rust::pipe::context::PipeContextPrio; use mesa_rust::pipe::fence::PipeFence; +use mesa_rust::pipe::resource::PipeImageView; use mesa_rust::pipe::resource::PipeSamplerView; use mesa_rust_gen::*; use mesa_rust_util::properties::*; @@ -74,6 +75,7 @@ impl<'a> QueueContext<'a> { cso: None, use_stream: self.dev.prefers_real_buffer_in_cb0(), bound_sampler_views: 0, + bound_shader_images: 0, samplers: HashMap::new(), } } @@ -89,6 +91,7 @@ pub struct QueueContextWithState<'a> { variant: NirKernelVariant, cso: Option>, bound_sampler_views: u32, + bound_shader_images: u32, samplers: HashMap, } @@ -152,6 +155,13 @@ impl QueueContextWithState<'_> { self.bound_sampler_views = cnt; } + pub fn bind_shader_images(&mut self, images: &[PipeImageView]) { + let cnt = images.len() as u32; + let unbind_cnt = self.bound_shader_images.saturating_sub(cnt); + self.ctx.set_shader_images(images, unbind_cnt); + self.bound_shader_images = cnt; + } + pub fn update_cb0(&self, data: &[u8]) -> CLResult<()> { // only update if we actually bind data if !data.is_empty() { @@ -180,11 +190,12 @@ impl Drop for QueueContextWithState<'_> { self.set_constant_buffer(0, &[]); self.ctx.clear_sampler_views(self.bound_sampler_views); self.ctx.clear_sampler_states(self.dev.max_samplers()); + self.ctx.clear_shader_images(self.bound_shader_images); + self.samplers .values() .for_each(|&sampler| self.ctx.delete_sampler_state(sampler)); - self.ctx.clear_shader_images(self.dev.caps.max_write_images); if self.builds.is_some() { // SAFETY: We simply unbind here. The bound cso will only be dropped at the end of this // drop handler. diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index dadaac4577f..781ed5fe8dc 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -568,7 +568,7 @@ impl PipeContext { } } - pub fn set_shader_images(&self, images: &[PipeImageView]) { + pub fn set_shader_images(&self, images: &[PipeImageView], unbind_trailing: u32) { let images = PipeImageView::slice_to_pipe(images); unsafe { self.pipe.as_ref().set_shader_images.unwrap()( @@ -576,7 +576,7 @@ impl PipeContext { pipe_shader_type::PIPE_SHADER_COMPUTE, 0, images.len() as u32, - 0, + unbind_trailing, images.as_ptr(), ) }