• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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