rusticl: Wrap pipe queries

Pipe queries are asynchronous state reads, you create a query
and sometime later retrieve the result.

Wrap the underlying basic calls and types and provide a type
(PipeQuery) to handle the lifetype of the query.  Note the pipe context
used for the query must live at last as long as the query.

Queries are created by calls to the PipeQueryGen, a wrapper
that figures out the return type and wraps that in the intermediate
that's returned.   A typical use is:

  query_start = PipeQueryGen::<{pipe_query_type::PIPE_QUERY_TIMESTAMP}>::new(ctx);

Signed-off-by: Dr. David Alan Gilbert <dave@treblig.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24101>
This commit is contained in:
Dr. David Alan Gilbert 2023-07-10 15:05:53 +01:00 committed by Marge Bot
parent c893fa1fcd
commit 52e53938c3
4 changed files with 83 additions and 0 deletions

View file

@ -1,6 +1,7 @@
pub mod context;
pub mod device;
pub mod fence;
pub mod query;
pub mod resource;
pub mod screen;
pub mod transfer;

View file

@ -521,6 +521,18 @@ impl PipeContext {
}
}
pub fn create_query(&self, query_type: c_uint, index: c_uint) -> *mut pipe_query {
unsafe { self.pipe.as_ref().create_query.unwrap()(self.pipe.as_ptr(), query_type, index) }
}
pub fn end_query(&self, pq: *mut pipe_query) -> bool {
unsafe { self.pipe.as_ref().end_query.unwrap()(self.pipe.as_ptr(), pq) }
}
pub fn destroy_query(&self, pq: *mut pipe_query) {
unsafe { self.pipe.as_ref().destroy_query.unwrap()(self.pipe.as_ptr(), pq) }
}
pub fn memory_barrier(&self, barriers: u32) {
unsafe { self.pipe.as_ref().memory_barrier.unwrap()(self.pipe.as_ptr(), barriers) }
}
@ -577,8 +589,11 @@ fn has_required_cbs(context: &pipe_context) -> bool {
& has_required_feature!(context, buffer_unmap)
& has_required_feature!(context, clear_buffer)
& has_required_feature!(context, create_compute_state)
& has_required_feature!(context, create_query)
& has_required_feature!(context, delete_compute_state)
& has_required_feature!(context, delete_sampler_state)
& has_required_feature!(context, destroy_query)
& has_required_feature!(context, end_query)
& has_required_feature!(context, flush)
& has_required_feature!(context, get_compute_state_info)
& has_required_feature!(context, launch_grid)

View file

@ -0,0 +1,65 @@
use crate::pipe::context::*;
use mesa_rust_gen::*;
use std::marker::*;
// Callers create new queries using PipeQueryGen<QueryType>::new(...)
pub struct PipeQueryGen<const Q: pipe_query_type::Type> {}
// We record the type that the given Query type will return into
// a trait we associate with a PipeQuery object we return
// QueryResultTrait is the type we'd like our PipeQueryGen to return
// for a given query
pub trait QueryResultTrait {
type ResType;
}
// Define this set of PipeQueryGen's for these queries
impl QueryResultTrait for PipeQueryGen<{ pipe_query_type::PIPE_QUERY_TIMESTAMP }> {
type ResType = u64;
}
impl<const Q: pipe_query_type::Type> PipeQueryGen<Q>
where
PipeQueryGen<Q>: QueryResultTrait,
{
// The external interface to create a new query
pub fn new(ctx: &PipeContext) -> Option<PipeQuery<<Self as QueryResultTrait>::ResType>> {
PipeQuery::<<Self as QueryResultTrait>::ResType>::new(ctx, Q)
}
}
// Our higher level view of a 'pipe_query', created by a call to the
// 'create_query' method on the pipe context
pub struct PipeQuery<'a, R> {
query: *mut pipe_query,
ctx: &'a PipeContext,
_result_marker: PhantomData<R>,
}
impl<'a, R> PipeQuery<'a, R> {
fn new(ctx: &'a PipeContext, query_type: u32) -> Option<Self> {
let pq = ctx.create_query(query_type, 0);
if pq.is_null() {
return None;
}
let res = Some(Self {
query: pq,
ctx: ctx,
_result_marker: Default::default(),
});
if !ctx.end_query(pq) {
ctx.destroy_query(pq);
return None;
}
res
}
}
impl<'a, R> Drop for PipeQuery<'a, R> {
fn drop(&mut self) {
self.ctx.destroy_query(self.query);
}
}

View file

@ -277,6 +277,8 @@ rusticl_mesa_bindings_rs = rust.bindgen(
'--allowlist-var', 'PIPE_.*',
'--allowlist-type', 'pipe_endian',
'--bitfield-enum', 'pipe_map_flags',
'--allowlist-type', 'pipe_query_type',
'--constified-enum-module', 'pipe_query_type',
'--allowlist-type', 'pipe_resource_usage',
'--bitfield-enum', 'pipe_resource_usage',
'--allowlist-type', 'pipe_tex_filter',