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