aboutsummaryrefslogtreecommitdiff
path: root/src/pipeline/graphics_pipeline/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/pipeline/graphics_pipeline/mod.rs')
-rw-r--r--src/pipeline/graphics_pipeline/mod.rs448
1 files changed, 448 insertions, 0 deletions
diff --git a/src/pipeline/graphics_pipeline/mod.rs b/src/pipeline/graphics_pipeline/mod.rs
new file mode 100644
index 0000000..2082830
--- /dev/null
+++ b/src/pipeline/graphics_pipeline/mod.rs
@@ -0,0 +1,448 @@
+// Copyright (c) 2017 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.
+
+pub use self::builder::GraphicsPipelineBuilder;
+pub use self::creation_error::GraphicsPipelineCreationError;
+use crate::buffer::BufferAccess;
+use crate::device::Device;
+use crate::device::DeviceOwned;
+use crate::pipeline::layout::PipelineLayout;
+use crate::pipeline::shader::ShaderInterface;
+use crate::pipeline::vertex::BufferlessDefinition;
+use crate::pipeline::vertex::IncompatibleVertexDefinitionError;
+use crate::pipeline::vertex::VertexDefinition;
+use crate::pipeline::vertex::VertexInput;
+use crate::pipeline::vertex::VertexSource;
+use crate::render_pass::RenderPass;
+use crate::render_pass::Subpass;
+use crate::SafeDeref;
+use crate::VulkanObject;
+use std::fmt;
+use std::hash::Hash;
+use std::hash::Hasher;
+use std::marker::PhantomData;
+use std::ptr;
+use std::sync::Arc;
+use std::u32;
+
+mod builder;
+mod creation_error;
+// FIXME: restore
+//mod tests;
+
+/// Defines how the implementation should perform a draw operation.
+///
+/// This object contains the shaders and the various fixed states that describe how the
+/// implementation should perform the various operations needed by a draw command.
+pub struct GraphicsPipeline<VertexDefinition> {
+ inner: Inner,
+ layout: Arc<PipelineLayout>,
+ subpass: Subpass,
+ vertex_definition: VertexDefinition,
+ vertex_input: VertexInput,
+
+ dynamic_line_width: bool,
+ dynamic_viewport: bool,
+ dynamic_scissor: bool,
+ dynamic_depth_bias: bool,
+ dynamic_depth_bounds: bool,
+ dynamic_stencil_compare_mask: bool,
+ dynamic_stencil_write_mask: bool,
+ dynamic_stencil_reference: bool,
+ dynamic_blend_constants: bool,
+
+ num_viewports: u32,
+}
+
+#[derive(PartialEq, Eq, Hash)]
+struct Inner {
+ pipeline: ash::vk::Pipeline,
+ device: Arc<Device>,
+}
+
+impl GraphicsPipeline<()> {
+ /// Starts the building process of a graphics pipeline. Returns a builder object that you can
+ /// fill with the various parameters.
+ pub fn start<'a>() -> GraphicsPipelineBuilder<
+ 'static,
+ 'static,
+ 'static,
+ 'static,
+ 'static,
+ BufferlessDefinition,
+ (),
+ (),
+ (),
+ (),
+ (),
+ > {
+ GraphicsPipelineBuilder::new()
+ }
+}
+
+impl<Mv> GraphicsPipeline<Mv> {
+ /// Returns the vertex definition used in the constructor.
+ #[inline]
+ pub fn vertex_definition(&self) -> &Mv {
+ &self.vertex_definition
+ }
+
+ /// Returns the device used to create this pipeline.
+ #[inline]
+ pub fn device(&self) -> &Arc<Device> {
+ &self.inner.device
+ }
+
+ /// Returns the pass used in the constructor.
+ #[inline]
+ pub fn subpass(&self) -> Subpass {
+ self.subpass.clone()
+ }
+
+ /// Returns the render pass used in the constructor.
+ #[inline]
+ pub fn render_pass(&self) -> &Arc<RenderPass> {
+ self.subpass.render_pass()
+ }
+
+ /// Returns true if the line width used by this pipeline is dynamic.
+ #[inline]
+ pub fn has_dynamic_line_width(&self) -> bool {
+ self.dynamic_line_width
+ }
+
+ /// Returns the number of viewports and scissors of this pipeline.
+ #[inline]
+ pub fn num_viewports(&self) -> u32 {
+ self.num_viewports
+ }
+
+ /// Returns true if the viewports used by this pipeline are dynamic.
+ #[inline]
+ pub fn has_dynamic_viewports(&self) -> bool {
+ self.dynamic_viewport
+ }
+
+ /// Returns true if the scissors used by this pipeline are dynamic.
+ #[inline]
+ pub fn has_dynamic_scissors(&self) -> bool {
+ self.dynamic_scissor
+ }
+
+ /// Returns true if the depth bounds used by this pipeline are dynamic.
+ #[inline]
+ pub fn has_dynamic_depth_bounds(&self) -> bool {
+ self.dynamic_depth_bounds
+ }
+
+ /// Returns true if the stencil compare masks used by this pipeline are dynamic.
+ #[inline]
+ pub fn has_dynamic_stencil_compare_mask(&self) -> bool {
+ self.dynamic_stencil_compare_mask
+ }
+
+ /// Returns true if the stencil write masks used by this pipeline are dynamic.
+ #[inline]
+ pub fn has_dynamic_stencil_write_mask(&self) -> bool {
+ self.dynamic_stencil_write_mask
+ }
+
+ /// Returns true if the stencil references used by this pipeline are dynamic.
+ #[inline]
+ pub fn has_dynamic_stencil_reference(&self) -> bool {
+ self.dynamic_stencil_reference
+ }
+}
+
+unsafe impl<Mv> DeviceOwned for GraphicsPipeline<Mv> {
+ #[inline]
+ fn device(&self) -> &Arc<Device> {
+ &self.inner.device
+ }
+}
+
+impl<Mv> fmt::Debug for GraphicsPipeline<Mv> {
+ #[inline]
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(fmt, "<Vulkan graphics pipeline {:?}>", self.inner.pipeline)
+ }
+}
+
+unsafe impl<Mv> VulkanObject for GraphicsPipeline<Mv> {
+ type Object = ash::vk::Pipeline;
+
+ #[inline]
+ fn internal_object(&self) -> ash::vk::Pipeline {
+ self.inner.pipeline
+ }
+}
+
+impl Drop for Inner {
+ #[inline]
+ fn drop(&mut self) {
+ unsafe {
+ let fns = self.device.fns();
+ fns.v1_0
+ .destroy_pipeline(self.device.internal_object(), self.pipeline, ptr::null());
+ }
+ }
+}
+
+/// Trait implemented on objects that reference a graphics pipeline. Can be made into a trait
+/// object.
+/// When using this trait `AutoCommandBufferBuilder::draw*` calls will need the buffers to be
+/// wrapped in a `vec!()`.
+pub unsafe trait GraphicsPipelineAbstract:
+ VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>> + DeviceOwned
+{
+ /// Returns an opaque object that represents the inside of the graphics pipeline.
+ fn inner(&self) -> GraphicsPipelineSys;
+
+ /// Returns the pipeline layout used in the constructor.
+ fn layout(&self) -> &Arc<PipelineLayout>;
+
+ /// Returns the subpass this graphics pipeline is rendering to.
+ fn subpass(&self) -> &Subpass;
+
+ /// Returns the vertex input description of the graphics pipeline.
+ fn vertex_input(&self) -> &VertexInput;
+
+ /// Returns true if the line width used by this pipeline is dynamic.
+ fn has_dynamic_line_width(&self) -> bool;
+
+ /// Returns the number of viewports and scissors of this pipeline.
+ fn num_viewports(&self) -> u32;
+
+ /// Returns true if the viewports used by this pipeline are dynamic.
+ fn has_dynamic_viewports(&self) -> bool;
+
+ /// Returns true if the scissors used by this pipeline are dynamic.
+ fn has_dynamic_scissors(&self) -> bool;
+
+ /// Returns true if the depth bounds used by this pipeline are dynamic.
+ fn has_dynamic_depth_bounds(&self) -> bool;
+
+ /// Returns true if the stencil compare masks used by this pipeline are dynamic.
+ fn has_dynamic_stencil_compare_mask(&self) -> bool;
+
+ /// Returns true if the stencil write masks used by this pipeline are dynamic.
+ fn has_dynamic_stencil_write_mask(&self) -> bool;
+
+ /// Returns true if the stencil references used by this pipeline are dynamic.
+ fn has_dynamic_stencil_reference(&self) -> bool;
+}
+
+unsafe impl<Mv> GraphicsPipelineAbstract for GraphicsPipeline<Mv>
+where
+ Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>,
+{
+ #[inline]
+ fn inner(&self) -> GraphicsPipelineSys {
+ GraphicsPipelineSys(self.inner.pipeline, PhantomData)
+ }
+
+ /// Returns the pipeline layout used in the constructor.
+ #[inline]
+ fn layout(&self) -> &Arc<PipelineLayout> {
+ &self.layout
+ }
+
+ #[inline]
+ fn subpass(&self) -> &Subpass {
+ &self.subpass
+ }
+
+ #[inline]
+ fn vertex_input(&self) -> &VertexInput {
+ &self.vertex_input
+ }
+
+ #[inline]
+ fn has_dynamic_line_width(&self) -> bool {
+ self.dynamic_line_width
+ }
+
+ #[inline]
+ fn num_viewports(&self) -> u32 {
+ self.num_viewports
+ }
+
+ #[inline]
+ fn has_dynamic_viewports(&self) -> bool {
+ self.dynamic_viewport
+ }
+
+ #[inline]
+ fn has_dynamic_scissors(&self) -> bool {
+ self.dynamic_scissor
+ }
+
+ #[inline]
+ fn has_dynamic_depth_bounds(&self) -> bool {
+ self.dynamic_depth_bounds
+ }
+
+ #[inline]
+ fn has_dynamic_stencil_compare_mask(&self) -> bool {
+ self.dynamic_stencil_compare_mask
+ }
+
+ #[inline]
+ fn has_dynamic_stencil_write_mask(&self) -> bool {
+ self.dynamic_stencil_write_mask
+ }
+
+ #[inline]
+ fn has_dynamic_stencil_reference(&self) -> bool {
+ self.dynamic_stencil_reference
+ }
+}
+
+unsafe impl<T> GraphicsPipelineAbstract for T
+where
+ T: SafeDeref,
+ T::Target: GraphicsPipelineAbstract,
+{
+ #[inline]
+ fn inner(&self) -> GraphicsPipelineSys {
+ GraphicsPipelineAbstract::inner(&**self)
+ }
+
+ #[inline]
+ fn layout(&self) -> &Arc<PipelineLayout> {
+ (**self).layout()
+ }
+
+ #[inline]
+ fn subpass(&self) -> &Subpass {
+ (**self).subpass()
+ }
+
+ #[inline]
+ fn vertex_input(&self) -> &VertexInput {
+ (**self).vertex_input()
+ }
+
+ #[inline]
+ fn has_dynamic_line_width(&self) -> bool {
+ (**self).has_dynamic_line_width()
+ }
+
+ #[inline]
+ fn num_viewports(&self) -> u32 {
+ (**self).num_viewports()
+ }
+
+ #[inline]
+ fn has_dynamic_viewports(&self) -> bool {
+ (**self).has_dynamic_viewports()
+ }
+
+ #[inline]
+ fn has_dynamic_scissors(&self) -> bool {
+ (**self).has_dynamic_scissors()
+ }
+
+ #[inline]
+ fn has_dynamic_depth_bounds(&self) -> bool {
+ (**self).has_dynamic_depth_bounds()
+ }
+
+ #[inline]
+ fn has_dynamic_stencil_compare_mask(&self) -> bool {
+ (**self).has_dynamic_stencil_compare_mask()
+ }
+
+ #[inline]
+ fn has_dynamic_stencil_write_mask(&self) -> bool {
+ (**self).has_dynamic_stencil_write_mask()
+ }
+
+ #[inline]
+ fn has_dynamic_stencil_reference(&self) -> bool {
+ (**self).has_dynamic_stencil_reference()
+ }
+}
+
+impl<Mv> PartialEq for GraphicsPipeline<Mv>
+where
+ Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>,
+{
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ self.inner == other.inner
+ }
+}
+
+impl<Mv> Eq for GraphicsPipeline<Mv> where Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>
+{}
+
+impl<Mv> Hash for GraphicsPipeline<Mv>
+where
+ Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>,
+{
+ #[inline]
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.inner.hash(state);
+ }
+}
+
+impl PartialEq for dyn GraphicsPipelineAbstract + Send + Sync {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ GraphicsPipelineAbstract::inner(self).0 == GraphicsPipelineAbstract::inner(other).0
+ && DeviceOwned::device(self) == DeviceOwned::device(other)
+ }
+}
+
+impl Eq for dyn GraphicsPipelineAbstract + Send + Sync {}
+
+impl Hash for dyn GraphicsPipelineAbstract + Send + Sync {
+ #[inline]
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ GraphicsPipelineAbstract::inner(self).0.hash(state);
+ DeviceOwned::device(self).hash(state);
+ }
+}
+
+/// Opaque object that represents the inside of the graphics pipeline.
+#[derive(Debug, Copy, Clone)]
+pub struct GraphicsPipelineSys<'a>(ash::vk::Pipeline, PhantomData<&'a ()>);
+
+unsafe impl<'a> VulkanObject for GraphicsPipelineSys<'a> {
+ type Object = ash::vk::Pipeline;
+
+ #[inline]
+ fn internal_object(&self) -> ash::vk::Pipeline {
+ self.0
+ }
+}
+
+unsafe impl<Mv> VertexDefinition for GraphicsPipeline<Mv>
+where
+ Mv: VertexDefinition,
+{
+ #[inline]
+ fn definition(
+ &self,
+ interface: &ShaderInterface,
+ ) -> Result<VertexInput, IncompatibleVertexDefinitionError> {
+ self.vertex_definition.definition(interface)
+ }
+}
+
+unsafe impl<Mv, S> VertexSource<S> for GraphicsPipeline<Mv>
+where
+ Mv: VertexSource<S>,
+{
+ #[inline]
+ fn decode(&self, s: S) -> (Vec<Box<dyn BufferAccess + Send + Sync>>, usize, usize) {
+ self.vertex_definition.decode(s)
+ }
+}