1 // Copyright (c) 2016 The vulkano developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT 5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, 6 // at your option. All files in the project carrying such 7 // notice may not be copied, modified, or distributed except 8 // according to those terms. 9 10 //! Describes a processing operation that will execute on the Vulkan device. 11 //! 12 //! In Vulkan, before you can add a draw or a compute command to a command buffer you have to 13 //! create a *pipeline object* that describes this command. 14 //! 15 //! When you create a pipeline object, the implementation will usually generate some GPU machine 16 //! code that will execute the operation (similar to a compiler that generates an executable for 17 //! the CPU). Consequently it is a CPU-intensive operation that should be performed at 18 //! initialization or during a loading screen. 19 20 pub use self::{compute::ComputePipeline, graphics::GraphicsPipeline, layout::PipelineLayout}; 21 use crate::{device::DeviceOwned, macros::vulkan_enum, shader::DescriptorBindingRequirements}; 22 use ahash::HashMap; 23 use std::sync::Arc; 24 25 pub mod cache; 26 pub mod compute; 27 pub mod graphics; 28 pub mod layout; 29 30 /// A trait for operations shared between pipeline types. 31 pub trait Pipeline: DeviceOwned { 32 /// Returns the bind point of this pipeline. bind_point(&self) -> PipelineBindPoint33 fn bind_point(&self) -> PipelineBindPoint; 34 35 /// Returns the pipeline layout used in this pipeline. layout(&self) -> &Arc<PipelineLayout>36 fn layout(&self) -> &Arc<PipelineLayout>; 37 38 /// Returns the number of descriptor sets actually accessed by this pipeline. This may be less 39 /// than the number of sets in the pipeline layout. num_used_descriptor_sets(&self) -> u3240 fn num_used_descriptor_sets(&self) -> u32; 41 42 /// Returns a reference to the descriptor binding requirements for this pipeline. descriptor_binding_requirements( &self, ) -> &HashMap<(u32, u32), DescriptorBindingRequirements>43 fn descriptor_binding_requirements( 44 &self, 45 ) -> &HashMap<(u32, u32), DescriptorBindingRequirements>; 46 } 47 48 vulkan_enum! { 49 #[non_exhaustive] 50 51 /// The type of a pipeline. 52 /// 53 /// When binding a pipeline or descriptor sets in a command buffer, the state for each bind point 54 /// is independent from the others. This means that it is possible, for example, to bind a graphics 55 /// pipeline without disturbing any bound compute pipeline. Likewise, binding descriptor sets for 56 /// the `Compute` bind point does not affect sets that were bound to the `Graphics` bind point. 57 PipelineBindPoint = PipelineBindPoint(i32); 58 59 // TODO: document 60 Compute = COMPUTE, 61 62 // TODO: document 63 Graphics = GRAPHICS, 64 65 /* TODO: enable 66 // TODO: document 67 RayTracing = RAY_TRACING_KHR { 68 device_extensions: [khr_ray_tracing_pipeline, nv_ray_tracing], 69 },*/ 70 71 /* TODO: enable 72 // TODO: document 73 SubpassShading = SUBPASS_SHADING_HUAWEI { 74 device_extensions: [huawei_subpass_shading], 75 },*/ 76 } 77 78 vulkan_enum! { 79 #[non_exhaustive] 80 81 /// A particular state value within a graphics pipeline that can be dynamically set by a command 82 /// buffer. 83 DynamicState = DynamicState(i32); 84 85 // TODO: document 86 Viewport = VIEWPORT, 87 88 // TODO: document 89 Scissor = SCISSOR, 90 91 // TODO: document 92 LineWidth = LINE_WIDTH, 93 94 // TODO: document 95 DepthBias = DEPTH_BIAS, 96 97 // TODO: document 98 BlendConstants = BLEND_CONSTANTS, 99 100 // TODO: document 101 DepthBounds = DEPTH_BOUNDS, 102 103 // TODO: document 104 StencilCompareMask = STENCIL_COMPARE_MASK, 105 106 // TODO: document 107 StencilWriteMask = STENCIL_WRITE_MASK, 108 109 // TODO: document 110 StencilReference = STENCIL_REFERENCE, 111 112 // TODO: document 113 CullMode = CULL_MODE { 114 api_version: V1_3, 115 device_extensions: [ext_extended_dynamic_state], 116 }, 117 118 // TODO: document 119 FrontFace = FRONT_FACE { 120 api_version: V1_3, 121 device_extensions: [ext_extended_dynamic_state], 122 }, 123 124 // TODO: document 125 PrimitiveTopology = PRIMITIVE_TOPOLOGY { 126 api_version: V1_3, 127 device_extensions: [ext_extended_dynamic_state], 128 }, 129 130 // TODO: document 131 ViewportWithCount = VIEWPORT_WITH_COUNT { 132 api_version: V1_3, 133 device_extensions: [ext_extended_dynamic_state], 134 }, 135 136 // TODO: document 137 ScissorWithCount = SCISSOR_WITH_COUNT { 138 api_version: V1_3, 139 device_extensions: [ext_extended_dynamic_state], 140 }, 141 142 // TODO: document 143 VertexInputBindingStride = VERTEX_INPUT_BINDING_STRIDE { 144 api_version: V1_3, 145 device_extensions: [ext_extended_dynamic_state], 146 }, 147 148 // TODO: document 149 DepthTestEnable = DEPTH_TEST_ENABLE { 150 api_version: V1_3, 151 device_extensions: [ext_extended_dynamic_state], 152 }, 153 154 // TODO: document 155 DepthWriteEnable = DEPTH_WRITE_ENABLE { 156 api_version: V1_3, 157 device_extensions: [ext_extended_dynamic_state], 158 }, 159 160 // TODO: document 161 DepthCompareOp = DEPTH_COMPARE_OP { 162 api_version: V1_3, 163 device_extensions: [ext_extended_dynamic_state], 164 }, 165 166 // TODO: document 167 DepthBoundsTestEnable = DEPTH_BOUNDS_TEST_ENABLE { 168 api_version: V1_3, 169 device_extensions: [ext_extended_dynamic_state], 170 }, 171 172 // TODO: document 173 StencilTestEnable = STENCIL_TEST_ENABLE { 174 api_version: V1_3, 175 device_extensions: [ext_extended_dynamic_state], 176 }, 177 178 // TODO: document 179 StencilOp = STENCIL_OP { 180 api_version: V1_3, 181 device_extensions: [ext_extended_dynamic_state], 182 }, 183 184 // TODO: document 185 RasterizerDiscardEnable = RASTERIZER_DISCARD_ENABLE { 186 api_version: V1_3, 187 device_extensions: [ext_extended_dynamic_state2], 188 }, 189 190 // TODO: document 191 DepthBiasEnable = DEPTH_BIAS_ENABLE { 192 api_version: V1_3, 193 device_extensions: [ext_extended_dynamic_state2], 194 }, 195 196 // TODO: document 197 PrimitiveRestartEnable = PRIMITIVE_RESTART_ENABLE { 198 api_version: V1_3, 199 device_extensions: [ext_extended_dynamic_state2], 200 }, 201 202 // TODO: document 203 ViewportWScaling = VIEWPORT_W_SCALING_NV { 204 device_extensions: [nv_clip_space_w_scaling], 205 }, 206 207 // TODO: document 208 DiscardRectangle = DISCARD_RECTANGLE_EXT { 209 device_extensions: [ext_discard_rectangles], 210 }, 211 212 // TODO: document 213 SampleLocations = SAMPLE_LOCATIONS_EXT { 214 device_extensions: [ext_sample_locations], 215 }, 216 217 // TODO: document 218 RayTracingPipelineStackSize = RAY_TRACING_PIPELINE_STACK_SIZE_KHR { 219 device_extensions: [khr_ray_tracing_pipeline], 220 }, 221 222 // TODO: document 223 ViewportShadingRatePalette = VIEWPORT_SHADING_RATE_PALETTE_NV { 224 device_extensions: [nv_shading_rate_image], 225 }, 226 227 // TODO: document 228 ViewportCoarseSampleOrder = VIEWPORT_COARSE_SAMPLE_ORDER_NV { 229 device_extensions: [nv_shading_rate_image], 230 }, 231 232 // TODO: document 233 ExclusiveScissor = EXCLUSIVE_SCISSOR_NV { 234 device_extensions: [nv_scissor_exclusive], 235 }, 236 237 // TODO: document 238 FragmentShadingRate = FRAGMENT_SHADING_RATE_KHR { 239 device_extensions: [khr_fragment_shading_rate], 240 }, 241 242 // TODO: document 243 LineStipple = LINE_STIPPLE_EXT { 244 device_extensions: [ext_line_rasterization], 245 }, 246 247 // TODO: document 248 VertexInput = VERTEX_INPUT_EXT { 249 device_extensions: [ext_vertex_input_dynamic_state], 250 }, 251 252 // TODO: document 253 PatchControlPoints = PATCH_CONTROL_POINTS_EXT { 254 device_extensions: [ext_extended_dynamic_state2], 255 }, 256 257 // TODO: document 258 LogicOp = LOGIC_OP_EXT { 259 device_extensions: [ext_extended_dynamic_state2], 260 }, 261 262 // TODO: document 263 ColorWriteEnable = COLOR_WRITE_ENABLE_EXT { 264 device_extensions: [ext_color_write_enable], 265 }, 266 267 // TODO: document 268 TessellationDomainOrigin = TESSELLATION_DOMAIN_ORIGIN_EXT { 269 device_extensions: [ext_extended_dynamic_state3], 270 }, 271 272 // TODO: document 273 DepthClampEnable = DEPTH_CLAMP_ENABLE_EXT { 274 device_extensions: [ext_extended_dynamic_state3], 275 }, 276 277 // TODO: document 278 PolygonMode = POLYGON_MODE_EXT { 279 device_extensions: [ext_extended_dynamic_state3], 280 }, 281 282 // TODO: document 283 RasterizationSamples = RASTERIZATION_SAMPLES_EXT { 284 device_extensions: [ext_extended_dynamic_state3], 285 }, 286 287 // TODO: document 288 SampleMask = SAMPLE_MASK_EXT { 289 device_extensions: [ext_extended_dynamic_state3], 290 }, 291 292 // TODO: document 293 AlphaToCoverageEnable = ALPHA_TO_COVERAGE_ENABLE_EXT { 294 device_extensions: [ext_extended_dynamic_state3], 295 }, 296 297 // TODO: document 298 AlphaToOneEnable = ALPHA_TO_ONE_ENABLE_EXT { 299 device_extensions: [ext_extended_dynamic_state3], 300 }, 301 302 // TODO: document 303 LogicOpEnable = LOGIC_OP_ENABLE_EXT { 304 device_extensions: [ext_extended_dynamic_state3], 305 }, 306 307 // TODO: document 308 ColorBlendEnable = COLOR_BLEND_ENABLE_EXT { 309 device_extensions: [ext_extended_dynamic_state3], 310 }, 311 312 // TODO: document 313 ColorBlendEquation = COLOR_BLEND_EQUATION_EXT { 314 device_extensions: [ext_extended_dynamic_state3], 315 }, 316 317 // TODO: document 318 ColorWriteMask = COLOR_WRITE_MASK_EXT { 319 device_extensions: [ext_extended_dynamic_state3], 320 }, 321 322 // TODO: document 323 RasterizationStream = RASTERIZATION_STREAM_EXT { 324 device_extensions: [ext_extended_dynamic_state3], 325 }, 326 327 // TODO: document 328 ConservativeRasterizationMode = CONSERVATIVE_RASTERIZATION_MODE_EXT { 329 device_extensions: [ext_extended_dynamic_state3], 330 }, 331 332 // TODO: document 333 ExtraPrimitiveOverestimationSize = EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT { 334 device_extensions: [ext_extended_dynamic_state3], 335 }, 336 337 // TODO: document 338 DepthClipEnable = DEPTH_CLIP_ENABLE_EXT { 339 device_extensions: [ext_extended_dynamic_state3], 340 }, 341 342 // TODO: document 343 SampleLocationsEnable = SAMPLE_LOCATIONS_ENABLE_EXT { 344 device_extensions: [ext_extended_dynamic_state3], 345 }, 346 347 // TODO: document 348 ColorBlendAdvanced = COLOR_BLEND_ADVANCED_EXT { 349 device_extensions: [ext_extended_dynamic_state3], 350 }, 351 352 // TODO: document 353 ProvokingVertexMode = PROVOKING_VERTEX_MODE_EXT { 354 device_extensions: [ext_extended_dynamic_state3], 355 }, 356 357 // TODO: document 358 LineRasterizationMode = LINE_RASTERIZATION_MODE_EXT { 359 device_extensions: [ext_extended_dynamic_state3], 360 }, 361 362 // TODO: document 363 LineStippleEnable = LINE_STIPPLE_ENABLE_EXT { 364 device_extensions: [ext_extended_dynamic_state3], 365 }, 366 367 // TODO: document 368 DepthClipNegativeOneToOne = DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT { 369 device_extensions: [ext_extended_dynamic_state3], 370 }, 371 372 // TODO: document 373 ViewportWScalingEnable = VIEWPORT_W_SCALING_ENABLE_NV { 374 device_extensions: [ext_extended_dynamic_state3], 375 }, 376 377 // TODO: document 378 ViewportSwizzle = VIEWPORT_SWIZZLE_NV { 379 device_extensions: [ext_extended_dynamic_state3], 380 }, 381 382 // TODO: document 383 CoverageToColorEnable = COVERAGE_TO_COLOR_ENABLE_NV { 384 device_extensions: [ext_extended_dynamic_state3], 385 }, 386 387 // TODO: document 388 CoverageToColorLocation = COVERAGE_TO_COLOR_LOCATION_NV { 389 device_extensions: [ext_extended_dynamic_state3], 390 }, 391 392 // TODO: document 393 CoverageModulationMode = COVERAGE_MODULATION_MODE_NV { 394 device_extensions: [ext_extended_dynamic_state3], 395 }, 396 397 // TODO: document 398 CoverageModulationTableEnable = COVERAGE_MODULATION_TABLE_ENABLE_NV { 399 device_extensions: [ext_extended_dynamic_state3], 400 }, 401 402 // TODO: document 403 CoverageModulationTable = COVERAGE_MODULATION_TABLE_NV { 404 device_extensions: [ext_extended_dynamic_state3], 405 }, 406 407 // TODO: document 408 ShadingRateImageEnable = SHADING_RATE_IMAGE_ENABLE_NV { 409 device_extensions: [ext_extended_dynamic_state3], 410 }, 411 412 // TODO: document 413 RepresentativeFragmentTestEnable = REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV { 414 device_extensions: [ext_extended_dynamic_state3], 415 }, 416 417 // TODO: document 418 CoverageReductionMode = COVERAGE_REDUCTION_MODE_NV { 419 device_extensions: [ext_extended_dynamic_state3], 420 }, 421 } 422 423 /// Specifies how a dynamic state is handled by a graphics pipeline. 424 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 425 pub enum StateMode<F> { 426 /// The pipeline has a fixed value for this state. Previously set dynamic state will be lost 427 /// when binding it, and will have to be re-set after binding a pipeline that uses it. 428 Fixed(F), 429 430 /// The pipeline expects a dynamic value to be set by a command buffer. Previously set dynamic 431 /// state is not disturbed when binding it. 432 Dynamic, 433 } 434 435 impl<T> From<Option<T>> for StateMode<T> { from(val: Option<T>) -> Self436 fn from(val: Option<T>) -> Self { 437 match val { 438 Some(x) => StateMode::Fixed(x), 439 None => StateMode::Dynamic, 440 } 441 } 442 } 443 444 impl<T> From<StateMode<T>> for Option<T> { from(val: StateMode<T>) -> Self445 fn from(val: StateMode<T>) -> Self { 446 match val { 447 StateMode::Fixed(x) => Some(x), 448 StateMode::Dynamic => None, 449 } 450 } 451 } 452 453 /// A variant of `StateMode` that is used for cases where some value is still needed when the state 454 /// is dynamic. 455 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 456 pub enum PartialStateMode<F, D> { 457 Fixed(F), 458 Dynamic(D), 459 } 460