Module: Mesa Branch: main Commit: 52e53938c3775c0844f80a27a0c68150eeb5261d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=52e53938c3775c0844f80a27a0c68150eeb5261d
Author: Dr. David Alan Gilbert <[email protected]> Date: Mon Jul 10 15:05:53 2023 +0100 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 <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24101> --- src/gallium/frontends/rusticl/mesa/pipe.rs | 1 + src/gallium/frontends/rusticl/mesa/pipe/context.rs | 15 +++++ src/gallium/frontends/rusticl/mesa/pipe/query.rs | 65 ++++++++++++++++++++++ src/gallium/frontends/rusticl/meson.build | 2 + 4 files changed, 83 insertions(+) diff --git a/src/gallium/frontends/rusticl/mesa/pipe.rs b/src/gallium/frontends/rusticl/mesa/pipe.rs index 38846ca8eac..13636995265 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe.rs @@ -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; diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index e65f3447c60..404bf210de7 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -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) diff --git a/src/gallium/frontends/rusticl/mesa/pipe/query.rs b/src/gallium/frontends/rusticl/mesa/pipe/query.rs new file mode 100644 index 00000000000..f58c43fc9c1 --- /dev/null +++ b/src/gallium/frontends/rusticl/mesa/pipe/query.rs @@ -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); + } +} diff --git a/src/gallium/frontends/rusticl/meson.build b/src/gallium/frontends/rusticl/meson.build index 4bde074d32e..5479a6f4538 100644 --- a/src/gallium/frontends/rusticl/meson.build +++ b/src/gallium/frontends/rusticl/meson.build @@ -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',
