blob: 9ec64920aa4f8828cd64adceb1a3343de896fa7a [file] [log] [blame]
// 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.
//! 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<PipelineLayout>;
/// 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<F> {
/// 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<T> From<Option<T>> for StateMode<T> {
fn from(val: Option<T>) -> Self {
match val {
Some(x) => StateMode::Fixed(x),
None => StateMode::Dynamic,
}
}
}
impl<T> From<StateMode<T>> for Option<T> {
fn from(val: StateMode<T>) -> 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<F, D> {
Fixed(F),
Dynamic(D),
}