1/* 2 * Copyright © 2022 Collabora, Ltd 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifndef VK_GRAPHICS_STATE_H 25#define VK_GRAPHICS_STATE_H 26 27#include "vulkan/vulkan_core.h" 28 29#include "vk_limits.h" 30 31#include "util/bitset.h" 32 33#ifdef __cplusplus 34extern "C" { 35#endif 36 37struct vk_command_buffer; 38struct vk_device; 39 40/** Enumeration of all Vulkan dynamic graphics states 41 * 42 * Enumerants are named with both the abreviation of the state group to which 43 * the state belongs as well as the name of the state itself. These are 44 * intended to pretty closely match the VkDynamicState enum but may not match 45 * perfectly all the time. 46 */ 47enum mesa_vk_dynamic_graphics_state { 48 MESA_VK_DYNAMIC_VI, 49 MESA_VK_DYNAMIC_VI_BINDING_STRIDES, 50 MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY, 51 MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE, 52 MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS, 53 MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT, 54 MESA_VK_DYNAMIC_VP_VIEWPORTS, 55 MESA_VK_DYNAMIC_VP_SCISSOR_COUNT, 56 MESA_VK_DYNAMIC_VP_SCISSORS, 57 MESA_VK_DYNAMIC_DR_RECTANGLES, 58 MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE, 59 MESA_VK_DYNAMIC_RS_CULL_MODE, 60 MESA_VK_DYNAMIC_RS_FRONT_FACE, 61 MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE, 62 MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS, 63 MESA_VK_DYNAMIC_RS_LINE_WIDTH, 64 MESA_VK_DYNAMIC_RS_LINE_STIPPLE, 65 MESA_VK_DYNAMIC_FSR, 66 MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS, 67 MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE, 68 MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE, 69 MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP, 70 MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE, 71 MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS, 72 MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE, 73 MESA_VK_DYNAMIC_DS_STENCIL_OP, 74 MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK, 75 MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK, 76 MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE, 77 MESA_VK_DYNAMIC_CB_LOGIC_OP, 78 MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES, 79 MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS, 80 81 /* Must be left at the end */ 82 MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX, 83}; 84 85/** Populate a bitset with dynamic states 86 * 87 * This function maps a VkPipelineDynamicStateCreateInfo to a bitset indexed 88 * by mesa_vk_dynamic_graphics_state enumerants. 89 * 90 * @param[out] dynamic Bitset to populate 91 * @param[in] info VkPipelineDynamicStateCreateInfo or NULL 92 */ 93void 94vk_get_dynamic_graphics_states(BITSET_WORD *dynamic, 95 const VkPipelineDynamicStateCreateInfo *info); 96 97struct vk_vertex_binding_state { 98 /** VkVertexInputBindingDescription::stride */ 99 uint16_t stride; 100 101 /** VkVertexInputBindingDescription::inputRate */ 102 uint16_t input_rate; 103 104 /** VkVertexInputBindingDivisorDescriptionEXT::divisor or 1 */ 105 uint32_t divisor; 106}; 107 108struct vk_vertex_attribute_state { 109 /** VkVertexInputAttributeDescription::binding */ 110 uint32_t binding; 111 112 /** VkVertexInputAttributeDescription::format */ 113 VkFormat format; 114 115 /** VkVertexInputAttributeDescription::offset */ 116 uint32_t offset; 117}; 118 119struct vk_vertex_input_state { 120 /** Bitset of which bindings are valid, indexed by binding */ 121 uint32_t bindings_valid; 122 struct vk_vertex_binding_state bindings[MESA_VK_MAX_VERTEX_BINDINGS]; 123 124 /** Bitset of which attributes are valid, indexed by location */ 125 uint32_t attributes_valid; 126 struct vk_vertex_attribute_state attributes[MESA_VK_MAX_VERTEX_ATTRIBUTES]; 127}; 128 129struct vk_input_assembly_state { 130 /** VkPipelineInputAssemblyStateCreateInfo::topology 131 * 132 * MESA_VK_DYNAMIC_GRAPHICS_STATE_IA_PRIMITIVE_TOPOLOGY 133 */ 134 uint8_t primitive_topology; 135 136 /** VkPipelineInputAssemblyStateCreateInfo::primitiveRestartEnable 137 * 138 * MESA_VK_DYNAMIC_GRAPHICS_STATE_IA_PRIMITIVE_RESTART_ENABLE 139 */ 140 bool primitive_restart_enable; 141}; 142 143struct vk_tessellation_state { 144 /** VkPipelineTessellationStateCreateInfo::patchControlPoints */ 145 uint8_t patch_control_points; 146 147 /** VkPipelineTessellationDomainOriginStateCreateInfo::domainOrigin */ 148 uint8_t domain_origin; 149}; 150 151struct vk_viewport_state { 152 /** VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOne */ 153 bool negative_one_to_one; 154 155 /** VkPipelineViewportStateCreateInfo::viewportCount */ 156 uint8_t viewport_count; 157 158 /** VkPipelineViewportStateCreateInfo::scissorCount */ 159 uint8_t scissor_count; 160 161 /** VkPipelineViewportStateCreateInfo::pViewports */ 162 VkRect2D scissors[MESA_VK_MAX_SCISSORS]; 163 164 /** VkPipelineViewportStateCreateInfo::pScissors */ 165 VkViewport viewports[MESA_VK_MAX_VIEWPORTS]; 166}; 167 168struct vk_discard_rectangles_state { 169 /** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode */ 170 VkDiscardRectangleModeEXT mode; 171 172 /** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount */ 173 uint32_t rectangle_count; 174 175 /** VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles */ 176 VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES]; 177}; 178 179struct vk_rasterization_state { 180 /** VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable 181 * 182 * This will be false if rasterizer discard is dynamic 183 */ 184 bool rasterizer_discard_enable; 185 186 /** VkPipelineRasterizationStateCreateInfo::depthClampEnable */ 187 bool depth_clamp_enable; 188 189 /** VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable */ 190 bool depth_clip_enable; 191 192 /** VkPipelineRasterizationStateCreateInfo::polygonMode */ 193 VkPolygonMode polygon_mode; 194 195 /** VkPipelineRasterizationStateCreateInfo::cullMode */ 196 VkCullModeFlags cull_mode; 197 198 /** VkPipelineRasterizationStateCreateInfo::frontFace */ 199 VkFrontFace front_face; 200 201 /** VkPipelineRasterizationConservativeStateCreateInfoEXT::conservativeRasterizationMode */ 202 VkConservativeRasterizationModeEXT conservative_mode; 203 204 /** VkPipelineRasterizationStateRasterizationOrderAMD::rasterizationOrder */ 205 VkRasterizationOrderAMD rasterization_order_amd; 206 207 /** VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::provokingVertexMode */ 208 VkProvokingVertexModeEXT provoking_vertex; 209 210 /** VkPipelineRasterizationStateStreamCreateInfoEXT::rasterizationStream */ 211 uint32_t rasterization_stream; 212 213 struct { 214 /** VkPipelineRasterizationStateCreateInfo::depthBiasEnable */ 215 bool enable; 216 217 /** VkPipelineRasterizationStateCreateInfo::depthBiasConstantFactor */ 218 float constant; 219 220 /** VkPipelineRasterizationStateCreateInfo::depthBiasClamp */ 221 float clamp; 222 223 /** VkPipelineRasterizationStateCreateInfo::depthBiasSlopeFactor */ 224 float slope; 225 } depth_bias; 226 227 struct { 228 /** VkPipelineRasterizationStateCreateInfo::lineWidth */ 229 float width; 230 231 /** VkPipelineRasterizationLineStateCreateInfoEXT::lineRasterizationMode 232 * 233 * Will be set to VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT if 234 * VkPipelineRasterizationLineStateCreateInfoEXT is not provided. 235 */ 236 VkLineRasterizationModeEXT mode; 237 238 struct { 239 /** VkPipelineRasterizationLineStateCreateInfoEXT::stippledLineEnable */ 240 bool enable; 241 242 /** VkPipelineRasterizationLineStateCreateInfoEXT::lineStippleFactor */ 243 uint32_t factor; 244 245 /** VkPipelineRasterizationLineStateCreateInfoEXT::lineStipplePattern */ 246 uint16_t pattern; 247 } stipple; 248 } line; 249}; 250 251struct vk_fragment_shading_rate_state { 252 /** VkPipelineFragmentShadingRateStateCreateInfoKHR::fragmentSize 253 * 254 * MESA_VK_DYNAMIC_GRAPHICS_STATE_FSR 255 */ 256 VkExtent2D fragment_size; 257 258 /** VkPipelineFragmentShadingRateStateCreateInfoKHR::combinerOps 259 * 260 * MESA_VK_DYNAMIC_GRAPHICS_STATE_FSR 261 */ 262 VkFragmentShadingRateCombinerOpKHR combiner_ops[2]; 263}; 264 265struct vk_sample_locations_state { 266 /** VkSampleLocationsInfoEXT::sampleLocationsPerPixel */ 267 VkSampleCountFlagBits per_pixel; 268 269 /** VkSampleLocationsInfoEXT::sampleLocationGridSize */ 270 VkExtent2D grid_size; 271 272 /** VkSampleLocationsInfoEXT::sampleLocations */ 273 VkSampleLocationEXT locations[MESA_VK_MAX_SAMPLE_LOCATIONS]; 274}; 275 276struct vk_multisample_state { 277 /** VkPipelineMultisampleStateCreateInfo::rasterizationSamples */ 278 VkSampleCountFlagBits rasterization_samples; 279 280 /** VkPipelineMultisampleStateCreateInfo::sampleShadingEnable */ 281 bool sample_shading_enable; 282 283 /** VkPipelineMultisampleStateCreateInfo::minSampleShading */ 284 float min_sample_shading; 285 286 /** VkPipelineMultisampleStateCreateInfo::pSampleMask */ 287 uint16_t sample_mask; 288 289 /** VkPipelineMultisampleStateCreateInfo::alphaToCoverageEnable */ 290 bool alpha_to_coverage_enable; 291 292 /** VkPipelineMultisampleStateCreateInfo::alphaToOneEnable */ 293 bool alpha_to_one_enable; 294 295 /** VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable */ 296 bool sample_locations_enable; 297 298 /** VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsInfo 299 * 300 * May be NULL for dynamic sample locations. 301 */ 302 const struct vk_sample_locations_state *sample_locations; 303}; 304 305/** Represents the stencil test state for a face */ 306struct vk_stencil_test_face_state { 307 /* 308 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_OP 309 */ 310 struct { 311 /** VkStencilOpState::failOp */ 312 uint8_t fail; 313 314 /** VkStencilOpState::passOp */ 315 uint8_t pass; 316 317 /** VkStencilOpState::depthFailOp */ 318 uint8_t depth_fail; 319 320 /** VkStencilOpState::compareOp */ 321 uint8_t compare; 322 } op; 323 324 /** VkStencilOpState::compareMask 325 * 326 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_COMPARE_MASK 327 */ 328 uint8_t compare_mask; 329 330 /** VkStencilOpState::writeMask 331 * 332 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_WRITE_MASK 333 */ 334 uint8_t write_mask; 335 336 /** VkStencilOpState::reference 337 * 338 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_REFERENCE 339 */ 340 uint8_t reference; 341}; 342 343struct vk_depth_stencil_state { 344 struct { 345 /** VkPipelineDepthStencilStateCreateInfo::depthTestEnable 346 * 347 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_TEST_ENABLE 348 */ 349 bool test_enable; 350 351 /** VkPipelineDepthStencilStateCreateInfo::depthWriteEnable 352 * 353 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_WRITE_ENABLE 354 */ 355 bool write_enable; 356 357 /** VkPipelineDepthStencilStateCreateInfo::depthCompareOp 358 * 359 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_COMPARE_OP 360 */ 361 VkCompareOp compare_op; 362 363 struct { 364 /** VkPipelineDepthStencilStateCreateInfo::depthBoundsTestEnable 365 * 366 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_BOUNDS_TEST_ENABLE 367 */ 368 bool enable; 369 370 /** VkPipelineDepthStencilStateCreateInfo::min/maxDepthBounds 371 * 372 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_BOUNDS_TEST_BOUNDS 373 */ 374 float min, max; 375 } bounds_test; 376 } depth; 377 378 struct { 379 /** VkPipelineDepthStencilStateCreateInfo::stencilTestEnable 380 * 381 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_TEST_ENABLE 382 */ 383 bool test_enable; 384 385 /** Whether or not stencil is should be written 386 * 387 * This does not map directly to any particular Vulkan API state and is 388 * initialized to true. If independent stencil disable ever becomes a 389 * thing, it will use this state. vk_optimize_depth_stencil_state() may 390 * set this to false if it can prove that the stencil test will never 391 * alter the stencil value. 392 */ 393 bool write_enable; 394 395 /** VkPipelineDepthStencilStateCreateInfo::front */ 396 struct vk_stencil_test_face_state front; 397 398 /** VkPipelineDepthStencilStateCreateInfo::back */ 399 struct vk_stencil_test_face_state back; 400 } stencil; 401}; 402 403/** Optimize a depth/stencil state 404 * 405 * The way depth and stencil testing is specified, there are many case where, 406 * regardless of depth/stencil writes being enabled, nothing actually gets 407 * written due to some other bit of state being set. In the presence of 408 * discards, it's fairly easy to get into cases where early depth/stencil 409 * testing is disabled on some hardware, leading to a fairly big performance 410 * hit. This function attempts to optimize the depth stencil state and 411 * disable writes and sometimes even testing whenever possible. 412 * 413 * @param[inout] ds The depth stencil state to optimize 414 * @param[in] ds_aspects Which image aspects are present in the 415 * render pass. 416 * @param[in] consider_write_mask If true, the write mask will be taken 417 * into account when optimizing. If 418 * false, it will be ignored. 419 */ 420void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds, 421 VkImageAspectFlags ds_aspects, 422 bool consider_write_mask); 423 424struct vk_color_blend_attachment_state { 425 /** VkPipelineColorBlendAttachmentState::blendEnable */ 426 bool blend_enable; 427 428 /** VkPipelineColorBlendAttachmentState::srcColorBlendFactor */ 429 uint8_t src_color_blend_factor; 430 431 /** VkPipelineColorBlendAttachmentState::dstColorBlendFactor */ 432 uint8_t dst_color_blend_factor; 433 434 /** VkPipelineColorBlendAttachmentState::srcAlphaBlendFactor */ 435 uint8_t src_alpha_blend_factor; 436 437 /** VkPipelineColorBlendAttachmentState::dstAlphaBlendFactor */ 438 uint8_t dst_alpha_blend_factor; 439 440 /** VkPipelineColorBlendAttachmentState::colorWriteMask */ 441 uint8_t write_mask; 442 443 /** VkPipelineColorBlendAttachmentState::colorBlendOp */ 444 VkBlendOp color_blend_op; 445 446 /** VkPipelineColorBlendAttachmentState::alphaBlendOp */ 447 VkBlendOp alpha_blend_op; 448}; 449 450struct vk_color_blend_state { 451 /** VkPipelineColorBlendStateCreateInfo::logicOpEnable */ 452 bool logic_op_enable; 453 454 /** VkPipelineColorBlendStateCreateInfo::logicOp */ 455 uint8_t logic_op; 456 457 /** VkPipelineColorWriteCreateInfoEXT::pColorWriteEnables */ 458 uint8_t color_write_enables; 459 460 /** VkPipelineColorBlendStateCreateInfo::attachmentCount */ 461 uint8_t attachment_count; 462 463 /** VkPipelineColorBlendStateCreateInfo::pAttachments */ 464 struct vk_color_blend_attachment_state attachments[MESA_VK_MAX_COLOR_ATTACHMENTS]; 465 466 /** VkPipelineColorBlendStateCreateInfo::blendConstants */ 467 float blend_constants[4]; 468}; 469 470struct vk_render_pass_state { 471 /** Set of image aspects bound as color/depth/stencil attachments 472 * 473 * Set to VK_IMAGE_ASPECT_METADATA_BIT to indicate that attachment info 474 * is invalid. 475 */ 476 VkImageAspectFlags attachment_aspects; 477 478 /** VkGraphicsPipelineCreateInfo::renderPass */ 479 VkRenderPass render_pass; 480 481 /** VkGraphicsPipelineCreateInfo::subpass */ 482 uint32_t subpass; 483 484 /** VkPipelineRenderingCreateInfo::viewMask */ 485 uint32_t view_mask; 486 487 /** VkRenderingSelfDependencyInfoMESA::colorSelfDependencies */ 488 uint8_t color_self_dependencies; 489 490 /** VkRenderingSelfDependencyInfoMESA::depthSelfDependency */ 491 bool depth_self_dependency; 492 493 /** VkRenderingSelfDependencyInfoMESA::stencilSelfDependency */ 494 bool stencil_self_dependency; 495 496 /** VkPipelineRenderingCreateInfo::colorAttachmentCount */ 497 uint8_t color_attachment_count; 498 499 /** VkPipelineRenderingCreateInfo::pColorAttachmentFormats */ 500 VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS]; 501 502 /** VkPipelineRenderingCreateInfo::depthAttachmentFormat */ 503 VkFormat depth_attachment_format; 504 505 /** VkPipelineRenderingCreateInfo::stencilAttachmentFormat */ 506 VkFormat stencil_attachment_format; 507}; 508 509/** Struct representing all dynamic graphics state 510 * 511 * Before invoking any core functions, the driver must properly populate 512 * initialize this struct: 513 * 514 * - Initialize using vk_default_dynamic_graphics_state, if desired 515 * - Set vi to a driver-allocated vk_vertex_input_state struct 516 * - Set ms.sample_locations to a driver-allocated 517 * vk_sample_locations_state struct 518 */ 519struct vk_dynamic_graphics_state { 520 /** Vertex input state 521 * 522 * Must be provided by the driver if VK_EXT_vertex_input_dynamic_state is 523 * supported. 524 * 525 * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI 526 */ 527 struct vk_vertex_input_state *vi; 528 529 /** Vertex binding strides 530 * 531 * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI_BINDING_STRIDES 532 */ 533 uint16_t vi_binding_strides[MESA_VK_MAX_VERTEX_BINDINGS]; 534 535 struct vk_input_assembly_state ia; 536 537 struct { 538 uint32_t patch_control_points; 539 } ts; 540 541 /** Viewport state */ 542 struct { 543 /** Viewport count 544 * 545 * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORT_COUNT 546 */ 547 uint32_t viewport_count; 548 549 /** Viewports 550 * 551 * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORTS 552 */ 553 VkViewport viewports[MESA_VK_MAX_VIEWPORTS]; 554 555 /** Scissor count 556 * 557 * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSOR_COUNT 558 */ 559 uint32_t scissor_count; 560 561 /** Scissor rects 562 * 563 * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSORS 564 */ 565 VkRect2D scissors[MESA_VK_MAX_SCISSORS]; 566 } vp; 567 568 /** Discard rectangles 569 * 570 * MESA_VK_DYNAMIC_GRAPHICS_STATE_DR_RECTANGLES 571 */ 572 struct { 573 uint32_t rectangle_count; 574 VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES]; 575 } dr; 576 577 /** Rasterization state */ 578 struct { 579 /** Rasterizer discard 580 * 581 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_RASTERIZER_DISCARD_ENABLE 582 */ 583 bool rasterizer_discard_enable; 584 585 /** Cull mode 586 * 587 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_CULL_MODE 588 */ 589 VkCullModeFlags cull_mode; 590 591 /** Front face 592 * 593 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_FRONT_FACE 594 */ 595 VkFrontFace front_face; 596 597 struct { 598 /** Depth bias enable 599 * 600 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_ENABLE 601 */ 602 bool enable; 603 604 /** Depth bias constant factor 605 * 606 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_FACTORS 607 */ 608 float constant; 609 610 /** Depth bias clamp 611 * 612 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_FACTORS 613 */ 614 float clamp; 615 616 /** Depth bias slope 617 * 618 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_FACTORS 619 */ 620 float slope; 621 } depth_bias; 622 623 struct { 624 /** Line width 625 * 626 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_LINE_WIDTH 627 */ 628 float width; 629 630 /** Line stipple 631 * 632 * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_LINE_STIPPLE 633 */ 634 struct { 635 uint32_t factor; 636 uint16_t pattern; 637 } stipple; 638 } line; 639 } rs; 640 641 struct vk_fragment_shading_rate_state fsr; 642 643 /** Multisample state */ 644 struct { 645 /** Sample locations 646 * 647 * Must be provided by the driver if VK_EXT_sample_locations is 648 * supported. 649 * 650 * MESA_VK_DYNAMIC_GRAPHICS_STATE_MS_SAMPLE_LOCATIONS 651 */ 652 struct vk_sample_locations_state *sample_locations; 653 } ms; 654 655 struct vk_depth_stencil_state ds; 656 657 /** Color blend state */ 658 struct { 659 /** Integer color logic op 660 * 661 * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_LOGIC_OP, 662 */ 663 VkLogicOp logic_op; 664 665 /** Color write enables 666 * 667 * Bitmask of color write enables, indexed by color attachment index. 668 * 669 * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_COLOR_WRITE_ENABLES, 670 */ 671 uint32_t color_write_enables; 672 673 /** Blend constants 674 * 675 * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_BLEND_CONSTANTS, 676 */ 677 float blend_constants[4]; 678 } cb; 679 680 /** For pipelines, which bits of dynamic state are set */ 681 BITSET_DECLARE(set, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 682 683 /** For command buffers, which bits of dynamic state have changed */ 684 BITSET_DECLARE(dirty, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 685}; 686 687struct vk_graphics_pipeline_all_state { 688 struct vk_vertex_input_state vi; 689 struct vk_input_assembly_state ia; 690 struct vk_tessellation_state ts; 691 struct vk_viewport_state vp; 692 struct vk_discard_rectangles_state dr; 693 struct vk_rasterization_state rs; 694 struct vk_fragment_shading_rate_state fsr; 695 struct vk_multisample_state ms; 696 struct vk_sample_locations_state ms_sample_locations; 697 struct vk_depth_stencil_state ds; 698 struct vk_color_blend_state cb; 699 struct vk_render_pass_state rp; 700}; 701 702struct vk_graphics_pipeline_state { 703 /** Bitset of which states are dynamic */ 704 BITSET_DECLARE(dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 705 706 VkShaderStageFlags shader_stages; 707 708 /** Vertex input state */ 709 const struct vk_vertex_input_state *vi; 710 711 /** Input assembly state */ 712 const struct vk_input_assembly_state *ia; 713 714 /** Tessellation state */ 715 const struct vk_tessellation_state *ts; 716 717 /** Viewport state */ 718 const struct vk_viewport_state *vp; 719 720 /** Discard Rectangles state */ 721 const struct vk_discard_rectangles_state *dr; 722 723 /** Rasterization state */ 724 const struct vk_rasterization_state *rs; 725 726 /** Fragment shading rate state */ 727 const struct vk_fragment_shading_rate_state *fsr; 728 729 /** Multiesample state */ 730 const struct vk_multisample_state *ms; 731 732 /** Depth stencil state */ 733 const struct vk_depth_stencil_state *ds; 734 735 /** Color blend state */ 736 const struct vk_color_blend_state *cb; 737 738 /** Render pass state */ 739 const struct vk_render_pass_state *rp; 740}; 741 742/** Struct for extra information that we need from the subpass. 743 * 744 * This struct need only be provided if the driver has its own render pass 745 * implementation. If the driver uses the common render pass implementation, 746 * we can get this information ourselves. 747 */ 748struct vk_subpass_info { 749 /** VkSubpassDescription2::viewMask */ 750 uint32_t view_mask; 751 752 /** 753 * Aspects of all attachments used as color or depth/stencil attachments 754 * in the subpass. Input and resolve attachments should not be considered 755 * when computing the attachments aspect mask. This is used to determine 756 * whether or not depth/stencil and color blend state are required for a 757 * pipeline. 758 */ 759 VkImageAspectFlags attachment_aspects; 760}; 761 762/** Populate a vk_graphics_pipeline_state from VkGraphicsPipelineCreateInfo 763 * 764 * This function crawls the provided VkGraphicsPipelineCreateInfo and uses it 765 * to populate the vk_graphics_pipeline_state. Upon returning from this 766 * function, all pointers in `state` will either be `NULL` or point to a valid 767 * sub-state structure. Whenever an extension struct is missing, a reasonable 768 * default value is provided whenever possible. Some states may be left NULL 769 * if the state does not exist (such as when rasterizer discard is enabled) or 770 * if all of the corresponding states are dynamic. 771 * 772 * This function assumes that the vk_graphics_pipeline_state is already valid 773 * (i.e., all pointers are NULL or point to valid states). Any states already 774 * present are assumed to be identical to how we would populate them from 775 * VkGraphicsPipelineCreateInfo. 776 * 777 * This function can operate in one of two modes with respect to how the 778 * memory for states is allocated. If a `vk_graphics_pipeline_all_state` 779 * struct is provided, any newly populated states will point to the relevant 780 * field in `all`. If `all == NULL`, it attempts to dynamically allocate any 781 * newly required states using the provided allocator and scope. The pointer 782 * to this new blob of memory is returned via `alloc_ptr_out` and must 783 * eventually be freed by the driver. 784 * 785 * @param[in] device The Vulkan device 786 * @param[out] state The graphics pipeline state to populate 787 * @param[in] info The pCreateInfo from vkCreateGraphicsPipelines 788 * @param[in] sp_info Subpass info if the driver implements render 789 * passes itself. This should be NULL for drivers 790 * that use the common render pass infrastructure 791 * built on top of dynamic rendering. 792 * @param[in] all The vk_graphics_pipeline_all_state to use to 793 * back any newly needed states. If NULL, newly 794 * needed states will be dynamically allocated 795 * instead. 796 * @param[in] alloc Allocation callbacks for dynamically allocating 797 * new state memory. 798 * @param[in] scope Allocation scope for dynamically allocating new 799 * state memory. 800 * @param[out] alloc_ptr_out Will be populated with a pointer to any newly 801 * allocated state. The driver is responsible for 802 * freeing this pointer. 803 */ 804VkResult 805vk_graphics_pipeline_state_fill(const struct vk_device *device, 806 struct vk_graphics_pipeline_state *state, 807 const VkGraphicsPipelineCreateInfo *info, 808 const struct vk_subpass_info *sp_info, 809 struct vk_graphics_pipeline_all_state *all, 810 const VkAllocationCallbacks *alloc, 811 VkSystemAllocationScope scope, 812 void **alloc_ptr_out); 813 814/** Merge one vk_graphics_pipeline_state into another 815 * 816 * Both the destination and source states are assumed to be valid (i.e., all 817 * pointers are NULL or point to valid states). Any states which exist in 818 * both are expected to be identical and the state already in dst is used. 819 * The only exception here is render pass state which may be only partially 820 * defined in which case the fully defined one (if any) is used. 821 * 822 * @param[out] dst The destination state. When the function returns, this 823 * will be the union of the original dst and src. 824 * @param[in] src The source state 825 */ 826void 827vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst, 828 const struct vk_graphics_pipeline_state *src); 829 830extern const struct vk_dynamic_graphics_state vk_default_dynamic_graphics_state; 831 832/** Initialize a vk_dynamic_graphics_state with defaults 833 * 834 * @param[out] dyn Dynamic graphics state to initizlie 835 */ 836void 837vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn); 838 839/** Clear a vk_dynamic_graphics_state to defaults 840 * 841 * @param[out] dyn Dynamic graphics state to initizlie 842 */ 843void 844vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn); 845 846/** Initialize a vk_dynamic_graphics_state for a pipeline 847 * 848 * @param[out] dyn Dynamic graphics state to initizlie 849 * @param[in] supported Bitset of all dynamic state supported by the driver. 850 * @param[in] p The pipeline state from which to initialize the 851 * dynamic state. 852 */ 853void 854vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn, 855 const struct vk_graphics_pipeline_state *p); 856 857/** Mark all states in the given vk_dynamic_graphics_state dirty 858 * 859 * @param[out] d Dynamic graphics state struct 860 */ 861static inline void 862vk_dynamic_graphics_state_dirty_all(struct vk_dynamic_graphics_state *d) 863{ 864 BITSET_SET_RANGE(d->dirty, 0, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX - 1); 865} 866 867/** Mark all states in the given vk_dynamic_graphics_state not dirty 868 * 869 * @param[out] d Dynamic graphics state struct 870 */ 871static inline void 872vk_dynamic_graphics_state_clear_dirty(struct vk_dynamic_graphics_state *d) 873{ 874 BITSET_ZERO(d->dirty); 875} 876 877/** Test if any states in the given vk_dynamic_graphics_state are dirty 878 * 879 * @param[in] d Dynamic graphics state struct to test 880 * @returns true if any state is dirty 881 */ 882static inline bool 883vk_dynamic_graphics_state_any_dirty(const struct vk_dynamic_graphics_state *d) 884{ 885 return BITSET_TEST_RANGE(d->dirty, 886 0, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX - 1); 887} 888 889/** Copies all set state from src to dst 890 * 891 * Both src and dst are assumed to be properly initialized dynamic state 892 * structs. Anything not set in src, as indicated by src->set, is ignored and 893 * those bits of dst are left untouched. 894 * 895 * @param[out] dst Copy destination 896 * @param[in] src Copy source 897 */ 898void 899vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst, 900 const struct vk_dynamic_graphics_state *src); 901 902/** Set all of the state in src on a command buffer 903 * 904 * Anything not set, as indicated by src->set, is ignored and those states in 905 * the command buffer are left untouched. 906 * 907 * @param[inout] cmd Command buffer to update 908 * @param[in] src State to set 909 */ 910void 911vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer *cmd, 912 const struct vk_dynamic_graphics_state *src); 913 914/** Set vertex binding strides on a command buffer 915 * 916 * This is the dynamic state part of vkCmdBindVertexBuffers2(). 917 * 918 * @param[inout] cmd Command buffer to update 919 * @param[in] first_binding First binding to update 920 * @param[in] binding_count Number of bindings to update 921 * @param[in] strides binding_count many stride values to set 922 */ 923void 924vk_cmd_set_vertex_binding_strides(struct vk_command_buffer *cmd, 925 uint32_t first_binding, 926 uint32_t binding_count, 927 const VkDeviceSize *strides); 928 929#ifdef __cplusplus 930} 931#endif 932 933#endif /* VK_GRAPHICS_STATE_H */ 934