// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Gather information about rendering, held in query pools.
//!
//! In Vulkan, queries are not created individually. Instead you manipulate **query pools**, which
//! represent a collection of queries. Whenever you use a query, you have to specify both the query
//! pool and the slot id within that query pool.

use crate::check_errors;
use crate::device::Device;
use crate::device::DeviceOwned;
use crate::DeviceSize;
use crate::Error;
use crate::OomError;
use crate::Success;
use crate::VulkanObject;
use std::error;
use std::ffi::c_void;
use std::fmt;
use std::mem::MaybeUninit;
use std::ops::Range;
use std::ptr;
use std::sync::Arc;

/// A collection of one or more queries of a particular type.
#[derive(Debug)]
pub struct QueryPool {
    pool: ash::vk::QueryPool,
    device: Arc<Device>,
    num_slots: u32,
    ty: QueryType,
}

impl QueryPool {
    /// Builds a new query pool.
    pub fn new(
        device: Arc<Device>,
        ty: QueryType,
        num_slots: u32,
    ) -> Result<QueryPool, QueryPoolCreationError> {
        let statistics = match ty {
            QueryType::PipelineStatistics(flags) => {
                if !device.enabled_features().pipeline_statistics_query {
                    return Err(QueryPoolCreationError::PipelineStatisticsQueryFeatureNotEnabled);
                }

                flags.into()
            }
            QueryType::Occlusion | QueryType::Timestamp => {
                ash::vk::QueryPipelineStatisticFlags::empty()
            }
        };

        let pool = unsafe {
            let infos = ash::vk::QueryPoolCreateInfo {
                flags: ash::vk::QueryPoolCreateFlags::empty(),
                query_type: ty.into(),
                query_count: num_slots,
                pipeline_statistics: statistics,
                ..Default::default()
            };

            let mut output = MaybeUninit::uninit();
            let fns = device.fns();
            check_errors(fns.v1_0.create_query_pool(
                device.internal_object(),
                &infos,
                ptr::null(),
                output.as_mut_ptr(),
            ))?;
            output.assume_init()
        };

        Ok(QueryPool {
            pool,
            device,
            num_slots,
            ty,
        })
    }

    /// Returns the [`QueryType`] that this query pool was created with.
    #[inline]
    pub fn ty(&self) -> QueryType {
        self.ty
    }

    /// Returns the number of query slots of this query pool.
    #[inline]
    pub fn num_slots(&self) -> u32 {
        self.num_slots
    }

    /// Returns a reference to a single query slot, or `None` if the index is out of range.
    #[inline]
    pub fn query(&self, index: u32) -> Option<Query> {
        if index < self.num_slots() {
            Some(Query { pool: self, index })
        } else {
            None
        }
    }

    /// Returns a reference to a range of queries, or `None` if out of range.
    ///
    /// # Panic
    ///
    /// Panics if the range is empty.
    #[inline]
    pub fn queries_range(&self, range: Range<u32>) -> Option<QueriesRange> {
        assert!(!range.is_empty());

        if range.end <= self.num_slots() {
            Some(QueriesRange { pool: self, range })
        } else {
            None
        }
    }
}

unsafe impl VulkanObject for QueryPool {
    type Object = ash::vk::QueryPool;

    #[inline]
    fn internal_object(&self) -> ash::vk::QueryPool {
        self.pool
    }
}

unsafe impl DeviceOwned for QueryPool {
    #[inline]
    fn device(&self) -> &Arc<Device> {
        &self.device
    }
}

impl Drop for QueryPool {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let fns = self.device.fns();
            fns.v1_0
                .destroy_query_pool(self.device.internal_object(), self.pool, ptr::null());
        }
    }
}

/// Error that can happen when creating a query pool.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum QueryPoolCreationError {
    /// Not enough memory.
    OomError(OomError),
    /// A pipeline statistics pool was requested but the corresponding feature wasn't enabled.
    PipelineStatisticsQueryFeatureNotEnabled,
}

impl error::Error for QueryPoolCreationError {
    #[inline]
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match *self {
            QueryPoolCreationError::OomError(ref err) => Some(err),
            _ => None,
        }
    }
}

impl fmt::Display for QueryPoolCreationError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(
            fmt,
            "{}",
            match *self {
                QueryPoolCreationError::OomError(_) => "not enough memory available",
                QueryPoolCreationError::PipelineStatisticsQueryFeatureNotEnabled => {
                    "a pipeline statistics pool was requested but the corresponding feature \
                 wasn't enabled"
                }
            }
        )
    }
}

impl From<OomError> for QueryPoolCreationError {
    #[inline]
    fn from(err: OomError) -> QueryPoolCreationError {
        QueryPoolCreationError::OomError(err)
    }
}

impl From<Error> for QueryPoolCreationError {
    #[inline]
    fn from(err: Error) -> QueryPoolCreationError {
        match err {
            err @ Error::OutOfHostMemory => QueryPoolCreationError::OomError(OomError::from(err)),
            err @ Error::OutOfDeviceMemory => QueryPoolCreationError::OomError(OomError::from(err)),
            _ => panic!("unexpected error: {:?}", err),
        }
    }
}

/// A reference to a single query slot.
///
/// This is created through [`QueryPool::query`].
#[derive(Clone, Debug)]
pub struct Query<'a> {
    pool: &'a QueryPool,
    index: u32,
}

impl<'a> Query<'a> {
    /// Returns a reference to the query pool.
    #[inline]
    pub fn pool(&self) -> &'a QueryPool {
        &self.pool
    }

    /// Returns the index of the query represented.
    #[inline]
    pub fn index(&self) -> u32 {
        self.index
    }
}

/// A reference to a range of queries.
///
/// This is created through [`QueryPool::queries_range`].
#[derive(Clone, Debug)]
pub struct QueriesRange<'a> {
    pool: &'a QueryPool,
    range: Range<u32>,
}

impl<'a> QueriesRange<'a> {
    /// Returns a reference to the query pool.
    #[inline]
    pub fn pool(&self) -> &'a QueryPool {
        &self.pool
    }

    /// Returns the range of queries represented.
    #[inline]
    pub fn range(&self) -> Range<u32> {
        self.range.clone()
    }

    /// Copies the results of this range of queries to a buffer on the CPU.
    ///
    /// [`self.pool().ty().result_size()`](QueryType::result_size) elements
    /// will be written for each query in the range, plus 1 extra element per query if
    /// [`QueryResultFlags::with_availability`] is enabled.
    /// The provided buffer must be large enough to hold the data.
    ///
    /// `true` is returned if every result was available and written to the buffer. `false`
    /// is returned if some results were not yet available; these will not be written to the buffer.
    ///
    /// See also [`copy_query_pool_results`](crate::command_buffer::AutoCommandBufferBuilder::copy_query_pool_results).
    pub fn get_results<T>(
        &self,
        destination: &mut [T],
        flags: QueryResultFlags,
    ) -> Result<bool, GetResultsError>
    where
        T: QueryResultElement,
    {
        let stride = self.check_query_pool_results::<T>(
            destination.as_ptr() as DeviceSize,
            destination.len() as DeviceSize,
            flags,
        )?;

        let result = unsafe {
            let fns = self.pool.device.fns();
            check_errors(fns.v1_0.get_query_pool_results(
                self.pool.device.internal_object(),
                self.pool.internal_object(),
                self.range.start,
                self.range.end - self.range.start,
                std::mem::size_of_val(destination),
                destination.as_mut_ptr() as *mut c_void,
                stride,
                ash::vk::QueryResultFlags::from(flags) | T::FLAG,
            ))?
        };

        Ok(match result {
            Success::Success => true,
            Success::NotReady => false,
            s => panic!("unexpected success value: {:?}", s),
        })
    }

    pub(crate) fn check_query_pool_results<T>(
        &self,
        buffer_start: DeviceSize,
        buffer_len: DeviceSize,
        flags: QueryResultFlags,
    ) -> Result<DeviceSize, GetResultsError>
    where
        T: QueryResultElement,
    {
        assert!(buffer_len > 0);
        debug_assert!(buffer_start % std::mem::size_of::<T>() as DeviceSize == 0);

        let count = self.range.end - self.range.start;
        let per_query_len = self.pool.ty.result_size() + flags.with_availability as DeviceSize;
        let required_len = per_query_len * count as DeviceSize;

        if buffer_len < required_len {
            return Err(GetResultsError::BufferTooSmall {
                required_len: required_len as DeviceSize,
                actual_len: buffer_len as DeviceSize,
            });
        }

        match self.pool.ty {
            QueryType::Occlusion => (),
            QueryType::PipelineStatistics(_) => (),
            QueryType::Timestamp => {
                if flags.partial {
                    return Err(GetResultsError::InvalidFlags);
                }
            }
        }

        Ok(per_query_len * std::mem::size_of::<T>() as DeviceSize)
    }
}

/// Error that can happen when calling [`QueriesRange::get_results`].
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GetResultsError {
    /// The buffer is too small for the operation.
    BufferTooSmall {
        /// Required number of elements in the buffer.
        required_len: DeviceSize,
        /// Actual number of elements in the buffer.
        actual_len: DeviceSize,
    },
    /// The connection to the device has been lost.
    DeviceLost,
    /// The provided flags are not allowed for this type of query.
    InvalidFlags,
    /// Not enough memory.
    OomError(OomError),
}

impl From<Error> for GetResultsError {
    #[inline]
    fn from(err: Error) -> Self {
        match err {
            Error::OutOfHostMemory | Error::OutOfDeviceMemory => {
                Self::OomError(OomError::from(err))
            }
            Error::DeviceLost => Self::DeviceLost,
            _ => panic!("unexpected error: {:?}", err),
        }
    }
}

impl From<OomError> for GetResultsError {
    #[inline]
    fn from(err: OomError) -> Self {
        Self::OomError(err)
    }
}

impl fmt::Display for GetResultsError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(
            fmt,
            "{}",
            match *self {
                Self::BufferTooSmall { .. } => {
                    "the buffer is too small for the operation"
                }
                Self::DeviceLost => "the connection to the device has been lost",
                Self::InvalidFlags => {
                    "the provided flags are not allowed for this type of query"
                }
                Self::OomError(_) => "not enough memory available",
            }
        )
    }
}

impl error::Error for GetResultsError {
    #[inline]
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match *self {
            Self::OomError(ref err) => Some(err),
            _ => None,
        }
    }
}

/// A trait for elements of buffers that can be used as a destination for query results.
///
/// # Safety
/// This is implemented for `u32` and `u64`. Unless you really know what you're doing, you should
/// not implement this trait for any other type.
pub unsafe trait QueryResultElement {
    const FLAG: ash::vk::QueryResultFlags;
}

unsafe impl QueryResultElement for u32 {
    const FLAG: ash::vk::QueryResultFlags = ash::vk::QueryResultFlags::empty();
}

unsafe impl QueryResultElement for u64 {
    const FLAG: ash::vk::QueryResultFlags = ash::vk::QueryResultFlags::TYPE_64;
}

/// The type of query that a query pool should perform.
#[derive(Debug, Copy, Clone)]
pub enum QueryType {
    /// Tracks the number of samples that pass per-fragment tests (e.g. the depth test).
    Occlusion,
    /// Tracks statistics on pipeline invocations and their input data.
    PipelineStatistics(QueryPipelineStatisticFlags),
    /// Writes timestamps at chosen points in a command buffer.
    Timestamp,
}

impl QueryType {
    /// Returns the number of [`QueryResultElement`]s that are needed to hold the result of a
    /// single query of this type.
    ///
    /// - For `Occlusion` and `Timestamp` queries, this returns 1.
    /// - For `PipelineStatistics` queries, this returns the number of statistics flags enabled.
    ///
    /// If the results are retrieved with [`QueryResultFlags::with_availability`] enabled, then
    /// an additional element is required per query.
    #[inline]
    pub const fn result_size(&self) -> DeviceSize {
        match self {
            Self::Occlusion | Self::Timestamp => 1,
            Self::PipelineStatistics(flags) => flags.count(),
        }
    }
}

impl From<QueryType> for ash::vk::QueryType {
    #[inline]
    fn from(value: QueryType) -> Self {
        match value {
            QueryType::Occlusion => ash::vk::QueryType::OCCLUSION,
            QueryType::PipelineStatistics(_) => ash::vk::QueryType::PIPELINE_STATISTICS,
            QueryType::Timestamp => ash::vk::QueryType::TIMESTAMP,
        }
    }
}

/// Flags that control how a query is to be executed.
#[derive(Clone, Copy, Debug, Default)]
pub struct QueryControlFlags {
    /// For occlusion queries, specifies that the result must reflect the exact number of
    /// tests passed. If not enabled, the query may return a result of 1 even if more fragments
    /// passed the test.
    pub precise: bool,
}

impl From<QueryControlFlags> for ash::vk::QueryControlFlags {
    #[inline]
    fn from(value: QueryControlFlags) -> Self {
        let mut result = ash::vk::QueryControlFlags::empty();
        if value.precise {
            result |= ash::vk::QueryControlFlags::PRECISE;
        }
        result
    }
}

/// For pipeline statistics queries, the statistics that should be gathered.
#[derive(Clone, Copy, Debug, Default)]
pub struct QueryPipelineStatisticFlags {
    /// Count the number of vertices processed by the input assembly.
    pub input_assembly_vertices: bool,
    /// Count the number of primitives processed by the input assembly.
    pub input_assembly_primitives: bool,
    /// Count the number of times a vertex shader is invoked.
    pub vertex_shader_invocations: bool,
    /// Count the number of times a geometry shader is invoked.
    pub geometry_shader_invocations: bool,
    /// Count the number of primitives generated by geometry shaders.
    pub geometry_shader_primitives: bool,
    /// Count the number of times the clipping stage is invoked on a primitive.
    pub clipping_invocations: bool,
    /// Count the number of primitives that are output by the clipping stage.
    pub clipping_primitives: bool,
    /// Count the number of times a fragment shader is invoked.
    pub fragment_shader_invocations: bool,
    /// Count the number of patches processed by a tessellation control shader.
    pub tessellation_control_shader_patches: bool,
    /// Count the number of times a tessellation evaluation shader is invoked.
    pub tessellation_evaluation_shader_invocations: bool,
    /// Count the number of times a compute shader is invoked.
    pub compute_shader_invocations: bool,
}

impl QueryPipelineStatisticFlags {
    #[inline]
    pub fn none() -> QueryPipelineStatisticFlags {
        QueryPipelineStatisticFlags {
            input_assembly_vertices: false,
            input_assembly_primitives: false,
            vertex_shader_invocations: false,
            geometry_shader_invocations: false,
            geometry_shader_primitives: false,
            clipping_invocations: false,
            clipping_primitives: false,
            fragment_shader_invocations: false,
            tessellation_control_shader_patches: false,
            tessellation_evaluation_shader_invocations: false,
            compute_shader_invocations: false,
        }
    }

    /// Returns the number of flags that are set to `true`.
    #[inline]
    pub const fn count(&self) -> DeviceSize {
        let &Self {
            input_assembly_vertices,
            input_assembly_primitives,
            vertex_shader_invocations,
            geometry_shader_invocations,
            geometry_shader_primitives,
            clipping_invocations,
            clipping_primitives,
            fragment_shader_invocations,
            tessellation_control_shader_patches,
            tessellation_evaluation_shader_invocations,
            compute_shader_invocations,
        } = self;
        input_assembly_vertices as DeviceSize
            + input_assembly_primitives as DeviceSize
            + vertex_shader_invocations as DeviceSize
            + geometry_shader_invocations as DeviceSize
            + geometry_shader_primitives as DeviceSize
            + clipping_invocations as DeviceSize
            + clipping_primitives as DeviceSize
            + fragment_shader_invocations as DeviceSize
            + tessellation_control_shader_patches as DeviceSize
            + tessellation_evaluation_shader_invocations as DeviceSize
            + compute_shader_invocations as DeviceSize
    }

    /// Returns `true` if any flags referring to compute operations are set to `true`.
    #[inline]
    pub const fn is_compute(&self) -> bool {
        let &Self {
            compute_shader_invocations,
            ..
        } = self;
        compute_shader_invocations
    }

    /// Returns `true` if any flags referring to graphics operations are set to `true`.
    #[inline]
    pub const fn is_graphics(&self) -> bool {
        let &Self {
            input_assembly_vertices,
            input_assembly_primitives,
            vertex_shader_invocations,
            geometry_shader_invocations,
            geometry_shader_primitives,
            clipping_invocations,
            clipping_primitives,
            fragment_shader_invocations,
            tessellation_control_shader_patches,
            tessellation_evaluation_shader_invocations,
            ..
        } = self;
        input_assembly_vertices
            || input_assembly_primitives
            || vertex_shader_invocations
            || geometry_shader_invocations
            || geometry_shader_primitives
            || clipping_invocations
            || clipping_primitives
            || fragment_shader_invocations
            || tessellation_control_shader_patches
            || tessellation_evaluation_shader_invocations
    }
}

impl From<QueryPipelineStatisticFlags> for ash::vk::QueryPipelineStatisticFlags {
    fn from(value: QueryPipelineStatisticFlags) -> ash::vk::QueryPipelineStatisticFlags {
        let mut result = ash::vk::QueryPipelineStatisticFlags::empty();
        if value.input_assembly_vertices {
            result |= ash::vk::QueryPipelineStatisticFlags::INPUT_ASSEMBLY_VERTICES;
        }
        if value.input_assembly_primitives {
            result |= ash::vk::QueryPipelineStatisticFlags::INPUT_ASSEMBLY_PRIMITIVES;
        }
        if value.vertex_shader_invocations {
            result |= ash::vk::QueryPipelineStatisticFlags::VERTEX_SHADER_INVOCATIONS;
        }
        if value.geometry_shader_invocations {
            result |= ash::vk::QueryPipelineStatisticFlags::GEOMETRY_SHADER_INVOCATIONS;
        }
        if value.geometry_shader_primitives {
            result |= ash::vk::QueryPipelineStatisticFlags::GEOMETRY_SHADER_PRIMITIVES;
        }
        if value.clipping_invocations {
            result |= ash::vk::QueryPipelineStatisticFlags::CLIPPING_INVOCATIONS;
        }
        if value.clipping_primitives {
            result |= ash::vk::QueryPipelineStatisticFlags::CLIPPING_PRIMITIVES;
        }
        if value.fragment_shader_invocations {
            result |= ash::vk::QueryPipelineStatisticFlags::FRAGMENT_SHADER_INVOCATIONS;
        }
        if value.tessellation_control_shader_patches {
            result |= ash::vk::QueryPipelineStatisticFlags::TESSELLATION_CONTROL_SHADER_PATCHES;
        }
        if value.tessellation_evaluation_shader_invocations {
            result |=
                ash::vk::QueryPipelineStatisticFlags::TESSELLATION_EVALUATION_SHADER_INVOCATIONS;
        }
        if value.compute_shader_invocations {
            result |= ash::vk::QueryPipelineStatisticFlags::COMPUTE_SHADER_INVOCATIONS;
        }
        result
    }
}

/// Flags to control how the results of a query should be retrieved.
///
/// `VK_QUERY_RESULT_64_BIT` is not included, as it is determined automatically via the
/// [`QueryResultElement`] trait.
#[derive(Clone, Copy, Debug, Default)]
pub struct QueryResultFlags {
    /// Wait for the results to become available before writing the results.
    pub wait: bool,
    /// Write an additional element to the end of each query's results, indicating the availability
    /// of the results:
    /// - Nonzero: The results are available, and have been written to the element(s) preceding.
    /// - Zero: The results are not yet available, and have not been written.
    pub with_availability: bool,
    /// Allow writing partial results to the buffer, instead of waiting until they are fully
    /// available.
    pub partial: bool,
}

impl From<QueryResultFlags> for ash::vk::QueryResultFlags {
    #[inline]
    fn from(value: QueryResultFlags) -> Self {
        let mut result = ash::vk::QueryResultFlags::empty();
        if value.wait {
            result |= ash::vk::QueryResultFlags::WAIT;
        }
        if value.with_availability {
            result |= ash::vk::QueryResultFlags::WITH_AVAILABILITY;
        }
        if value.partial {
            result |= ash::vk::QueryResultFlags::PARTIAL;
        }
        result
    }
}

#[cfg(test)]
mod tests {
    use crate::query::QueryPipelineStatisticFlags;
    use crate::query::QueryPool;
    use crate::query::QueryPoolCreationError;
    use crate::query::QueryType;

    #[test]
    fn pipeline_statistics_feature() {
        let (device, _) = gfx_dev_and_queue!();

        let ty = QueryType::PipelineStatistics(QueryPipelineStatisticFlags::none());
        match QueryPool::new(device, ty, 256) {
            Err(QueryPoolCreationError::PipelineStatisticsQueryFeatureNotEnabled) => (),
            _ => panic!(),
        };
    }
}
