rusticl: use stream uploader for cb0 if prefered

Using the same buffer without a barrier actually can lead to data races as
drivers might not properly synchronize the content. Using the stream
uploader is a neat fix which prevents us from having to use a barrier but
still keep high throughput when launching kernels back-to-back.

Fixes: 5ff33f9905 ("rusticl: use real buffer for cb0 for drivers prefering")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27666>
This commit is contained in:
Karol Herbst 2024-05-07 22:33:10 +02:00 committed by Marge Bot
parent 56f7b0297e
commit 8da8c6c2d8
3 changed files with 40 additions and 21 deletions

View file

@ -6,8 +6,6 @@ use crate::core::platform::*;
use crate::impl_cl_type_trait;
use mesa_rust::pipe::context::PipeContext;
use mesa_rust::pipe::resource::PipeResource;
use mesa_rust::pipe::screen::ResourceType;
use mesa_rust_util::properties::*;
use rusticl_opencl_gen::*;
@ -25,7 +23,7 @@ use std::thread::JoinHandle;
/// Used for tracking bound GPU state to lower CPU overhead and centralize state tracking
pub struct QueueContext {
ctx: PipeContext,
cb0: Option<PipeResource>,
use_stream: bool,
}
impl QueueContext {
@ -34,30 +32,18 @@ impl QueueContext {
.screen()
.create_context()
.ok_or(CL_OUT_OF_HOST_MEMORY)?;
let size = device.param_max_size() as u32;
let cb0 = if device.prefers_real_buffer_in_cb0() {
device
.screen()
.resource_create_buffer(size, ResourceType::Cb0, 0)
} else {
None
};
if let Some(cb0) = &cb0 {
ctx.bind_constant_buffer(0, cb0);
}
Ok(Self { ctx: ctx, cb0: cb0 })
Ok(Self {
ctx: ctx,
use_stream: device.prefers_real_buffer_in_cb0(),
})
}
pub fn update_cb0(&self, data: &[u8]) {
// only update if we actually bind data
if !data.is_empty() {
// if we have a real buffer, update that, otherwise just set the data directly
if let Some(cb) = &self.cb0 {
debug_assert!(data.len() <= cb.width() as usize);
self.ctx
.buffer_subdata(cb, 0, data.as_ptr().cast(), data.len() as u32);
if self.use_stream {
self.ctx.set_constant_buffer_stream(0, data);
} else {
self.ctx.set_constant_buffer(0, data);
}

View file

@ -8,6 +8,7 @@ use mesa_rust_gen::pipe_fd_type::*;
use mesa_rust_gen::*;
use mesa_rust_util::has_required_feature;
use std::mem::size_of;
use std::os::raw::*;
use std::ptr;
use std::ptr::*;
@ -417,6 +418,37 @@ impl PipeContext {
}
}
pub fn set_constant_buffer_stream(&self, idx: u32, data: &[u8]) {
let mut cb = pipe_constant_buffer {
buffer: ptr::null_mut(),
buffer_offset: 0,
buffer_size: data.len() as u32,
user_buffer: ptr::null_mut(),
};
unsafe {
let stream = self.pipe.as_ref().stream_uploader;
u_upload_data(
stream,
0,
data.len() as u32,
size_of::<[u64; 16]>() as u32,
data.as_ptr().cast(),
&mut cb.buffer_offset,
&mut cb.buffer,
);
u_upload_unmap(stream);
self.pipe.as_ref().set_constant_buffer.unwrap()(
self.pipe.as_ptr(),
pipe_shader_type::PIPE_SHADER_COMPUTE,
idx,
false,
&cb,
);
}
}
pub fn launch_grid(
&self,
work_dim: u32,

View file

@ -19,6 +19,7 @@
#include "util/disk_cache.h"
#include "util/os_time.h"
#include "util/sha1/sha1.h"
#include "util/u_upload_mgr.h"
#include "util/u_printf.h"
#include "util/u_sampler.h"
#include "util/u_surface.h"