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',

Reply via email to