mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 17:30:12 +01:00
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:
parent
56f7b0297e
commit
8da8c6c2d8
3 changed files with 40 additions and 21 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue