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
34 extern "C" {
35 #endif
36
37 struct vk_command_buffer;
38 struct 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 */
47 enum 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 */
93 void
94 vk_get_dynamic_graphics_states(BITSET_WORD *dynamic,
95 const VkPipelineDynamicStateCreateInfo *info);
96
97 struct 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
108 struct 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
119 struct 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
129 struct 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
143 struct vk_tessellation_state {
144 /** VkPipelineTessellationStateCreateInfo::patchControlPoints */
145 uint8_t patch_control_points;
146
147 /** VkPipelineTessellationDomainOriginStateCreateInfo::domainOrigin */
148 uint8_t domain_origin;
149 };
150
151 struct 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
168 struct 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
179 struct 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
251 struct 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
265 struct 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
276 struct 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 */
306 struct 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
343 struct 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 */
420 void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
421 VkImageAspectFlags ds_aspects,
422 bool consider_write_mask);
423
424 struct 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
450 struct 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
470 struct 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 */
519 struct 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
687 struct 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
702 struct 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 */
748 struct 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 */
804 VkResult
805 vk_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 */
826 void
827 vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst,
828 const struct vk_graphics_pipeline_state *src);
829
830 extern 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 */
836 void
837 vk_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 */
843 void
844 vk_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 */
853 void
854 vk_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 */
861 static inline void
vk_dynamic_graphics_state_dirty_all(struct vk_dynamic_graphics_state * d)862 vk_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 */
871 static inline void
vk_dynamic_graphics_state_clear_dirty(struct vk_dynamic_graphics_state * d)872 vk_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 */
882 static inline bool
vk_dynamic_graphics_state_any_dirty(const struct vk_dynamic_graphics_state * d)883 vk_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 */
898 void
899 vk_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 */
910 void
911 vk_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 */
923 void
924 vk_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