mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Work on support for queries (#718)
* Move query.rs to query/mod.rs * Remove genericity over Device * Replace device() with DeviceOwned impls * Add unsafe query methods to UnsafeCommandBufferBuilder
This commit is contained in:
parent
9e65c250e1
commit
83e643c234
@ -46,6 +46,8 @@ use pipeline::input_assembly::IndexType;
|
||||
use pipeline::viewport::Scissor;
|
||||
use pipeline::viewport::Viewport;
|
||||
use query::QueryPipelineStatisticFlags;
|
||||
use query::UnsafeQueriesRange;
|
||||
use query::UnsafeQuery;
|
||||
use sampler::Filter;
|
||||
use sync::AccessFlagBits;
|
||||
use sync::Event;
|
||||
@ -343,6 +345,19 @@ impl<P> UnsafeCommandBufferBuilder<P> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls `vkCmdBeginQuery` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn begin_query(&mut self, query: UnsafeQuery, precise: bool) {
|
||||
let vk = self.device().pointers();
|
||||
let cmd = self.internal_object();
|
||||
let flags = if precise {
|
||||
vk::QUERY_CONTROL_PRECISE_BIT
|
||||
} else {
|
||||
0
|
||||
};
|
||||
vk.CmdBeginQuery(cmd, query.pool().internal_object(), query.index(), flags);
|
||||
}
|
||||
|
||||
/// Calls `vkCmdBeginRenderPass` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn begin_render_pass<F, I>(&mut self, framebuffer: &F,
|
||||
@ -893,6 +908,25 @@ impl<P> UnsafeCommandBufferBuilder<P> {
|
||||
regions.as_ptr());
|
||||
}
|
||||
|
||||
/// Calls `vkCmdCopyQueryPoolResults` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn copy_query_pool_results(&mut self, queries: UnsafeQueriesRange,
|
||||
destination: &BufferAccess, stride: usize)
|
||||
{
|
||||
let destination = destination.inner();
|
||||
debug_assert!(destination.offset < destination.buffer.size());
|
||||
debug_assert!(destination.buffer.usage_transfer_destination());
|
||||
|
||||
let flags = 0; // FIXME:
|
||||
|
||||
let vk = self.device().pointers();
|
||||
let cmd = self.internal_object();
|
||||
vk.CmdCopyQueryPoolResults(cmd, queries.pool().internal_object(), queries.first_index(),
|
||||
queries.count(), destination.buffer.internal_object(),
|
||||
destination.offset as vk::DeviceSize,
|
||||
stride as vk::DeviceSize, flags);
|
||||
}
|
||||
|
||||
/// Calls `vkCmdDispatch` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn dispatch(&mut self, dimensions: [u32; 3]) {
|
||||
@ -997,6 +1031,14 @@ impl<P> UnsafeCommandBufferBuilder<P> {
|
||||
stride);
|
||||
}
|
||||
|
||||
/// Calls `vkCmdEndQuery` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn end_query(&mut self, query: UnsafeQuery) {
|
||||
let vk = self.device().pointers();
|
||||
let cmd = self.internal_object();
|
||||
vk.CmdEndQuery(cmd, query.pool().internal_object(), query.index());
|
||||
}
|
||||
|
||||
/// Calls `vkCmdEndRenderPass` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn end_render_pass(&mut self) {
|
||||
@ -1120,6 +1162,15 @@ impl<P> UnsafeCommandBufferBuilder<P> {
|
||||
vk.CmdResetEvent(cmd, event.internal_object(), stages.into_vulkan_bits());
|
||||
}
|
||||
|
||||
/// Calls `vkCmdResetQueryPool` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn reset_query_pool(&mut self, queries: UnsafeQueriesRange) {
|
||||
let vk = self.device().pointers();
|
||||
let cmd = self.internal_object();
|
||||
vk.CmdResetQueryPool(cmd, queries.pool().internal_object(), queries.first_index(),
|
||||
queries.count());
|
||||
}
|
||||
|
||||
/// Calls `vkCmdSetBlendConstants` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn set_blend_constants(&mut self, constants: [f32; 4]) {
|
||||
@ -1281,6 +1332,15 @@ impl<P> UnsafeCommandBufferBuilder<P> {
|
||||
size as vk::DeviceSize,
|
||||
data as *const D as *const _);
|
||||
}
|
||||
|
||||
/// Calls `vkCmdWriteTimestamp` on the builder.
|
||||
#[inline]
|
||||
pub unsafe fn write_timestamp(&mut self, query: UnsafeQuery, stages: PipelineStages) {
|
||||
let vk = self.device().pointers();
|
||||
let cmd = self.internal_object();
|
||||
vk.CmdWriteTimestamp(cmd, stages.into_vulkan_bits(), query.pool().internal_object(),
|
||||
query.index());
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<P> DeviceOwned for UnsafeCommandBufferBuilder<P> {
|
||||
|
@ -20,28 +20,24 @@ use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use device::Device;
|
||||
use device::DeviceOwned;
|
||||
|
||||
use Error;
|
||||
use OomError;
|
||||
use SafeDeref;
|
||||
use VulkanObject;
|
||||
use check_errors;
|
||||
use vk;
|
||||
|
||||
pub struct UnsafeQueryPool<P = Arc<Device>>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
pub struct UnsafeQueryPool {
|
||||
pool: vk::QueryPool,
|
||||
device: P,
|
||||
device: Arc<Device>,
|
||||
num_slots: u32,
|
||||
}
|
||||
|
||||
impl<P> UnsafeQueryPool<P>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
impl UnsafeQueryPool {
|
||||
/// Builds a new query pool.
|
||||
pub fn new(device: P, ty: QueryType, num_slots: u32)
|
||||
-> Result<UnsafeQueryPool<P>, QueryPoolCreationError> {
|
||||
pub fn new(device: Arc<Device>, ty: QueryType, num_slots: u32)
|
||||
-> Result<UnsafeQueryPool, QueryPoolCreationError> {
|
||||
let (vk_ty, statistics) = match ty {
|
||||
QueryType::Occlusion => (vk::QUERY_TYPE_OCCLUSION, 0),
|
||||
QueryType::Timestamp => (vk::QUERY_TYPE_TIMESTAMP, 0),
|
||||
@ -86,13 +82,94 @@ impl<P> UnsafeQueryPool<P>
|
||||
self.num_slots
|
||||
}
|
||||
|
||||
/// Returns the device used to create the pool.
|
||||
#[inline]
|
||||
pub fn device(&self) -> &P {
|
||||
pub fn query(&self, index: u32) -> Option<UnsafeQuery> {
|
||||
if index < self.num_slots() {
|
||||
Some(UnsafeQuery {
|
||||
pool: self,
|
||||
index,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// # Panic
|
||||
///
|
||||
/// Panicks if `count` is 0.
|
||||
#[inline]
|
||||
pub fn queries_range(&self, first_index: u32, count: u32) -> Option<UnsafeQueriesRange> {
|
||||
assert!(count >= 1);
|
||||
|
||||
if first_index + count < self.num_slots() {
|
||||
Some(UnsafeQueriesRange {
|
||||
pool: self,
|
||||
first: first_index,
|
||||
count,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VulkanObject for UnsafeQueryPool {
|
||||
type Object = vk::QueryPool;
|
||||
|
||||
#[inline]
|
||||
fn internal_object(&self) -> vk::QueryPool {
|
||||
self.pool
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl DeviceOwned for UnsafeQueryPool {
|
||||
#[inline]
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnsafeQuery<'a> {
|
||||
pool: &'a UnsafeQueryPool,
|
||||
index: u32,
|
||||
}
|
||||
|
||||
impl<'a> UnsafeQuery<'a> {
|
||||
#[inline]
|
||||
pub fn pool(&self) -> &'a UnsafeQueryPool {
|
||||
&self.pool
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnsafeQueriesRange<'a> {
|
||||
pool: &'a UnsafeQueryPool,
|
||||
first: u32,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> UnsafeQueriesRange<'a> {
|
||||
#[inline]
|
||||
pub fn pool(&self) -> &'a UnsafeQueryPool {
|
||||
&self.pool
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn first_index(&self) -> u32 {
|
||||
self.first
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum QueryType {
|
||||
Occlusion,
|
||||
@ -174,9 +251,7 @@ impl Into<vk::QueryPipelineStatisticFlags> for QueryPipelineStatisticFlags {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Drop for UnsafeQueryPool<P>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
impl Drop for UnsafeQueryPool {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
@ -275,10 +350,11 @@ impl OcclusionQueriesPool {
|
||||
pub fn num_slots(&self) -> u32 {
|
||||
self.inner.num_slots()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the device that was used to create this pool.
|
||||
unsafe impl DeviceOwned for OcclusionQueriesPool {
|
||||
#[inline]
|
||||
pub fn device(&self) -> &Arc<Device> {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
self.inner.device()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user