// Copyright (c) 2016 The vulkano developers // Licensed under the Apache License, Version 2.0 // or the MIT // license , // at your option. All files in the project carrying such // notice may not be copied, modified, or distributed except // according to those terms. //! Describes a processing operation that will execute on the Vulkan device. //! //! In Vulkan, before you can add a draw or a compute command to a command buffer you have to //! create a *pipeline object* that describes this command. //! //! When you create a pipeline object, the implementation will usually generate some GPU machine //! code that will execute the operation (similar to a compiler that generates an executable for //! the CPU). Consequently it is a CPU-intensive operation that should be performed at //! initialization or during a loading screen. pub use self::{compute::ComputePipeline, graphics::GraphicsPipeline, layout::PipelineLayout}; use crate::{device::DeviceOwned, macros::vulkan_enum, shader::DescriptorBindingRequirements}; use ahash::HashMap; use std::sync::Arc; pub mod cache; pub mod compute; pub mod graphics; pub mod layout; /// A trait for operations shared between pipeline types. pub trait Pipeline: DeviceOwned { /// Returns the bind point of this pipeline. fn bind_point(&self) -> PipelineBindPoint; /// Returns the pipeline layout used in this pipeline. fn layout(&self) -> &Arc; /// Returns the number of descriptor sets actually accessed by this pipeline. This may be less /// than the number of sets in the pipeline layout. fn num_used_descriptor_sets(&self) -> u32; /// Returns a reference to the descriptor binding requirements for this pipeline. fn descriptor_binding_requirements( &self, ) -> &HashMap<(u32, u32), DescriptorBindingRequirements>; } vulkan_enum! { #[non_exhaustive] /// The type of a pipeline. /// /// When binding a pipeline or descriptor sets in a command buffer, the state for each bind point /// is independent from the others. This means that it is possible, for example, to bind a graphics /// pipeline without disturbing any bound compute pipeline. Likewise, binding descriptor sets for /// the `Compute` bind point does not affect sets that were bound to the `Graphics` bind point. PipelineBindPoint = PipelineBindPoint(i32); // TODO: document Compute = COMPUTE, // TODO: document Graphics = GRAPHICS, /* TODO: enable // TODO: document RayTracing = RAY_TRACING_KHR { device_extensions: [khr_ray_tracing_pipeline, nv_ray_tracing], },*/ /* TODO: enable // TODO: document SubpassShading = SUBPASS_SHADING_HUAWEI { device_extensions: [huawei_subpass_shading], },*/ } vulkan_enum! { #[non_exhaustive] /// A particular state value within a graphics pipeline that can be dynamically set by a command /// buffer. DynamicState = DynamicState(i32); // TODO: document Viewport = VIEWPORT, // TODO: document Scissor = SCISSOR, // TODO: document LineWidth = LINE_WIDTH, // TODO: document DepthBias = DEPTH_BIAS, // TODO: document BlendConstants = BLEND_CONSTANTS, // TODO: document DepthBounds = DEPTH_BOUNDS, // TODO: document StencilCompareMask = STENCIL_COMPARE_MASK, // TODO: document StencilWriteMask = STENCIL_WRITE_MASK, // TODO: document StencilReference = STENCIL_REFERENCE, // TODO: document CullMode = CULL_MODE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document FrontFace = FRONT_FACE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document PrimitiveTopology = PRIMITIVE_TOPOLOGY { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document ViewportWithCount = VIEWPORT_WITH_COUNT { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document ScissorWithCount = SCISSOR_WITH_COUNT { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document VertexInputBindingStride = VERTEX_INPUT_BINDING_STRIDE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document DepthTestEnable = DEPTH_TEST_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document DepthWriteEnable = DEPTH_WRITE_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document DepthCompareOp = DEPTH_COMPARE_OP { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document DepthBoundsTestEnable = DEPTH_BOUNDS_TEST_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document StencilTestEnable = STENCIL_TEST_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document StencilOp = STENCIL_OP { api_version: V1_3, device_extensions: [ext_extended_dynamic_state], }, // TODO: document RasterizerDiscardEnable = RASTERIZER_DISCARD_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state2], }, // TODO: document DepthBiasEnable = DEPTH_BIAS_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state2], }, // TODO: document PrimitiveRestartEnable = PRIMITIVE_RESTART_ENABLE { api_version: V1_3, device_extensions: [ext_extended_dynamic_state2], }, // TODO: document ViewportWScaling = VIEWPORT_W_SCALING_NV { device_extensions: [nv_clip_space_w_scaling], }, // TODO: document DiscardRectangle = DISCARD_RECTANGLE_EXT { device_extensions: [ext_discard_rectangles], }, // TODO: document SampleLocations = SAMPLE_LOCATIONS_EXT { device_extensions: [ext_sample_locations], }, // TODO: document RayTracingPipelineStackSize = RAY_TRACING_PIPELINE_STACK_SIZE_KHR { device_extensions: [khr_ray_tracing_pipeline], }, // TODO: document ViewportShadingRatePalette = VIEWPORT_SHADING_RATE_PALETTE_NV { device_extensions: [nv_shading_rate_image], }, // TODO: document ViewportCoarseSampleOrder = VIEWPORT_COARSE_SAMPLE_ORDER_NV { device_extensions: [nv_shading_rate_image], }, // TODO: document ExclusiveScissor = EXCLUSIVE_SCISSOR_NV { device_extensions: [nv_scissor_exclusive], }, // TODO: document FragmentShadingRate = FRAGMENT_SHADING_RATE_KHR { device_extensions: [khr_fragment_shading_rate], }, // TODO: document LineStipple = LINE_STIPPLE_EXT { device_extensions: [ext_line_rasterization], }, // TODO: document VertexInput = VERTEX_INPUT_EXT { device_extensions: [ext_vertex_input_dynamic_state], }, // TODO: document PatchControlPoints = PATCH_CONTROL_POINTS_EXT { device_extensions: [ext_extended_dynamic_state2], }, // TODO: document LogicOp = LOGIC_OP_EXT { device_extensions: [ext_extended_dynamic_state2], }, // TODO: document ColorWriteEnable = COLOR_WRITE_ENABLE_EXT { device_extensions: [ext_color_write_enable], }, // TODO: document TessellationDomainOrigin = TESSELLATION_DOMAIN_ORIGIN_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document DepthClampEnable = DEPTH_CLAMP_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document PolygonMode = POLYGON_MODE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document RasterizationSamples = RASTERIZATION_SAMPLES_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document SampleMask = SAMPLE_MASK_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document AlphaToCoverageEnable = ALPHA_TO_COVERAGE_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document AlphaToOneEnable = ALPHA_TO_ONE_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document LogicOpEnable = LOGIC_OP_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ColorBlendEnable = COLOR_BLEND_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ColorBlendEquation = COLOR_BLEND_EQUATION_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ColorWriteMask = COLOR_WRITE_MASK_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document RasterizationStream = RASTERIZATION_STREAM_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ConservativeRasterizationMode = CONSERVATIVE_RASTERIZATION_MODE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ExtraPrimitiveOverestimationSize = EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document DepthClipEnable = DEPTH_CLIP_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document SampleLocationsEnable = SAMPLE_LOCATIONS_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ColorBlendAdvanced = COLOR_BLEND_ADVANCED_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ProvokingVertexMode = PROVOKING_VERTEX_MODE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document LineRasterizationMode = LINE_RASTERIZATION_MODE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document LineStippleEnable = LINE_STIPPLE_ENABLE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document DepthClipNegativeOneToOne = DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ViewportWScalingEnable = VIEWPORT_W_SCALING_ENABLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ViewportSwizzle = VIEWPORT_SWIZZLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document CoverageToColorEnable = COVERAGE_TO_COLOR_ENABLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document CoverageToColorLocation = COVERAGE_TO_COLOR_LOCATION_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document CoverageModulationMode = COVERAGE_MODULATION_MODE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document CoverageModulationTableEnable = COVERAGE_MODULATION_TABLE_ENABLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document CoverageModulationTable = COVERAGE_MODULATION_TABLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document ShadingRateImageEnable = SHADING_RATE_IMAGE_ENABLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document RepresentativeFragmentTestEnable = REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV { device_extensions: [ext_extended_dynamic_state3], }, // TODO: document CoverageReductionMode = COVERAGE_REDUCTION_MODE_NV { device_extensions: [ext_extended_dynamic_state3], }, } /// Specifies how a dynamic state is handled by a graphics pipeline. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum StateMode { /// The pipeline has a fixed value for this state. Previously set dynamic state will be lost /// when binding it, and will have to be re-set after binding a pipeline that uses it. Fixed(F), /// The pipeline expects a dynamic value to be set by a command buffer. Previously set dynamic /// state is not disturbed when binding it. Dynamic, } impl From> for StateMode { fn from(val: Option) -> Self { match val { Some(x) => StateMode::Fixed(x), None => StateMode::Dynamic, } } } impl From> for Option { fn from(val: StateMode) -> Self { match val { StateMode::Fixed(x) => Some(x), StateMode::Dynamic => None, } } } /// A variant of `StateMode` that is used for cases where some value is still needed when the state /// is dynamic. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum PartialStateMode { Fixed(F), Dynamic(D), }