xref: /aosp_15_r20/external/mesa3d/src/vulkan/runtime/vk_graphics_state.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 #include "util/enum_operators.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 struct vk_command_buffer;
39 struct vk_device;
40 
41 /** Enumeration of all Vulkan dynamic graphics states
42  *
43  * Enumerants are named with both the abbreviation of the state group to which
44  * the state belongs as well as the name of the state itself.  These are
45  * intended to pretty closely match the VkDynamicState enum but may not match
46  * perfectly all the time.
47  */
48 enum mesa_vk_dynamic_graphics_state {
49    MESA_VK_DYNAMIC_VI,
50    MESA_VK_DYNAMIC_VI_BINDINGS_VALID,
51    MESA_VK_DYNAMIC_VI_BINDING_STRIDES,
52    MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY,
53    MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE,
54    MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS,
55    MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN,
56    MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT,
57    MESA_VK_DYNAMIC_VP_VIEWPORTS,
58    MESA_VK_DYNAMIC_VP_SCISSOR_COUNT,
59    MESA_VK_DYNAMIC_VP_SCISSORS,
60    MESA_VK_DYNAMIC_VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,
61    MESA_VK_DYNAMIC_DR_RECTANGLES,
62    MESA_VK_DYNAMIC_DR_MODE,
63    MESA_VK_DYNAMIC_DR_ENABLE,
64    MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE,
65    MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE,
66    MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE,
67    MESA_VK_DYNAMIC_RS_POLYGON_MODE,
68    MESA_VK_DYNAMIC_RS_CULL_MODE,
69    MESA_VK_DYNAMIC_RS_FRONT_FACE,
70    MESA_VK_DYNAMIC_RS_CONSERVATIVE_MODE,
71    MESA_VK_DYNAMIC_RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE,
72    MESA_VK_DYNAMIC_RS_RASTERIZATION_ORDER_AMD,
73    MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX,
74    MESA_VK_DYNAMIC_RS_RASTERIZATION_STREAM,
75    MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE,
76    MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS,
77    MESA_VK_DYNAMIC_RS_LINE_WIDTH,
78    MESA_VK_DYNAMIC_RS_LINE_MODE,
79    MESA_VK_DYNAMIC_RS_LINE_STIPPLE_ENABLE,
80    MESA_VK_DYNAMIC_RS_LINE_STIPPLE,
81    MESA_VK_DYNAMIC_FSR,
82    MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES,
83    MESA_VK_DYNAMIC_MS_SAMPLE_MASK,
84    MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE,
85    MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE,
86    MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS_ENABLE,
87    MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS,
88    MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE,
89    MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE,
90    MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP,
91    MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE,
92    MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS,
93    MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE,
94    MESA_VK_DYNAMIC_DS_STENCIL_OP,
95    MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK,
96    MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK,
97    MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE,
98    MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE,
99    MESA_VK_DYNAMIC_CB_LOGIC_OP,
100    MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT,
101    MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES,
102    MESA_VK_DYNAMIC_CB_BLEND_ENABLES,
103    MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS,
104    MESA_VK_DYNAMIC_CB_WRITE_MASKS,
105    MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS,
106    MESA_VK_DYNAMIC_RP_ATTACHMENTS,
107    MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE,
108    MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP,
109    MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP,
110 
111    /* Must be left at the end */
112    MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX,
113 };
114 
115 #define MESA_VK_ATTACHMENT_UNUSED (0xff)
116 
117 /** Populate a bitset with dynamic states
118  *
119  * This function maps a VkPipelineDynamicStateCreateInfo to a bitset indexed
120  * by mesa_vk_dynamic_graphics_state enumerants.
121  *
122  * :param dynamic:      |out| Bitset to populate
123  * :param info:         |in|  VkPipelineDynamicStateCreateInfo or NULL
124  */
125 void
126 vk_get_dynamic_graphics_states(BITSET_WORD *dynamic,
127                                const VkPipelineDynamicStateCreateInfo *info);
128 
129 /***/
130 struct vk_vertex_binding_state {
131    /** VkVertexInputBindingDescription::stride */
132    uint16_t stride;
133 
134    /** VkVertexInputBindingDescription::inputRate */
135    uint16_t input_rate;
136 
137    /** VkVertexInputBindingDivisorDescriptionKHR::divisor or 1 */
138    uint32_t divisor;
139 };
140 
141 /***/
142 struct vk_vertex_attribute_state {
143    /** VkVertexInputAttributeDescription::binding */
144    uint32_t binding;
145 
146    /** VkVertexInputAttributeDescription::format */
147    VkFormat format;
148 
149    /** VkVertexInputAttributeDescription::offset */
150    uint32_t offset;
151 };
152 
153 /***/
154 struct vk_vertex_input_state {
155    /** Bitset of which bindings are valid, indexed by binding */
156    uint32_t bindings_valid;
157    struct vk_vertex_binding_state bindings[MESA_VK_MAX_VERTEX_BINDINGS];
158 
159    /** Bitset of which attributes are valid, indexed by location */
160    uint32_t attributes_valid;
161    struct vk_vertex_attribute_state attributes[MESA_VK_MAX_VERTEX_ATTRIBUTES];
162 };
163 
164 /***/
165 struct vk_input_assembly_state {
166    /** VkPipelineInputAssemblyStateCreateInfo::topology
167      *
168      * MESA_VK_DYNAMIC_GRAPHICS_STATE_IA_PRIMITIVE_TOPOLOGY
169      */
170    uint8_t primitive_topology;
171 
172    /** VkPipelineInputAssemblyStateCreateInfo::primitiveRestartEnable
173      *
174      * MESA_VK_DYNAMIC_GRAPHICS_STATE_IA_PRIMITIVE_RESTART_ENABLE
175      */
176    bool primitive_restart_enable;
177 };
178 
179 /***/
180 struct vk_tessellation_state {
181    /** VkPipelineTessellationStateCreateInfo::patchControlPoints
182     *
183     * MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS
184     */
185    uint8_t patch_control_points;
186 
187    /** VkPipelineTessellationDomainOriginStateCreateInfo::domainOrigin
188     *
189     * MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN
190     */
191    uint8_t domain_origin;
192 };
193 
194 /***/
195 struct vk_viewport_state {
196    /** VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOne
197     */
198    bool depth_clip_negative_one_to_one;
199 
200    /** VkPipelineViewportStateCreateInfo::viewportCount
201     *
202     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORT_COUNT
203     */
204    uint8_t viewport_count;
205 
206    /** VkPipelineViewportStateCreateInfo::scissorCount
207     *
208     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSOR_COUNT
209     */
210    uint8_t scissor_count;
211 
212    /** VkPipelineViewportStateCreateInfo::pViewports
213     *
214     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORTS
215     */
216    VkViewport viewports[MESA_VK_MAX_VIEWPORTS];
217 
218    /** VkPipelineViewportStateCreateInfo::pScissors
219     *
220     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSORS
221     */
222    VkRect2D scissors[MESA_VK_MAX_SCISSORS];
223 };
224 
225 /***/
226 struct vk_discard_rectangles_state {
227    /** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode */
228    VkDiscardRectangleModeEXT mode;
229 
230    /** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount */
231    uint32_t rectangle_count;
232 
233    /** VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles */
234    VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES];
235 };
236 
237 enum ENUM_PACKED vk_mesa_depth_clip_enable {
238    /** Depth clipping should be disabled */
239    VK_MESA_DEPTH_CLIP_ENABLE_FALSE = 0,
240 
241    /** Depth clipping should be enabled */
242    VK_MESA_DEPTH_CLIP_ENABLE_TRUE = 1,
243 
244    /** Depth clipping should be enabled iff depth clamping is disabled */
245    VK_MESA_DEPTH_CLIP_ENABLE_NOT_CLAMP,
246 };
247 
248 /***/
249 struct vk_rasterization_state {
250    /** VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable
251     *
252     * This will be false if rasterizer discard is dynamic
253     *
254     * MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE
255     */
256    bool rasterizer_discard_enable;
257 
258    /** VkPipelineRasterizationStateCreateInfo::depthClampEnable
259     *
260     * MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE
261     */
262    bool depth_clamp_enable;
263 
264    /** VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable
265     *
266     * MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE
267     */
268    enum vk_mesa_depth_clip_enable depth_clip_enable;
269 
270    /** VkPipelineRasterizationStateCreateInfo::polygonMode
271     *
272     * MESA_VK_DYNAMIC_RS_POLYGON_MODE_ENABLEDEPTH_CLIP_ENABLE
273     */
274    VkPolygonMode polygon_mode;
275 
276    /** VkPipelineRasterizationStateCreateInfo::cullMode
277     *
278     * MESA_VK_DYNAMIC_RS_CULL_MODE
279     */
280    VkCullModeFlags cull_mode;
281 
282    /** VkPipelineRasterizationStateCreateInfo::frontFace
283     *
284     * MESA_VK_DYNAMIC_RS_FRONT_FACE
285     */
286    VkFrontFace front_face;
287 
288    /** VkPipelineRasterizationConservativeStateCreateInfoEXT::conservativeRasterizationMode
289     *
290     * MESA_VK_DYNAMIC_RS_CONSERVATIVE_MODE
291     */
292    VkConservativeRasterizationModeEXT conservative_mode;
293 
294    /** VkPipelineRasterizationConservativeStateCreateInfoEXT::extraPrimitiveOverestimationSize
295     *
296     * MESA_VK_DYNAMIC_RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE
297     */
298    float extra_primitive_overestimation_size;
299 
300    /** VkPipelineRasterizationStateRasterizationOrderAMD::rasterizationOrder */
301    VkRasterizationOrderAMD rasterization_order_amd;
302 
303    /** VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::provokingVertexMode
304     *
305     * MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX
306     */
307    VkProvokingVertexModeEXT provoking_vertex;
308 
309    /** VkPipelineRasterizationStateStreamCreateInfoEXT::rasterizationStream
310     *
311     * MESA_VK_DYNAMIC_RS_RASTERIZATION_STREAM
312     */
313    uint32_t rasterization_stream;
314 
315    struct {
316       /** VkPipelineRasterizationStateCreateInfo::depthBiasEnable
317        *
318        * MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE
319        */
320       bool enable;
321 
322       /** VkPipelineRasterizationStateCreateInfo::depthBiasConstantFactor
323        *
324        * MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
325        */
326       float constant;
327 
328       /** VkPipelineRasterizationStateCreateInfo::depthBiasClamp
329        *
330        * MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
331        */
332       float clamp;
333 
334       /** VkPipelineRasterizationStateCreateInfo::depthBiasSlopeFactor
335        *
336        * MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
337        */
338       float slope;
339 
340       /** VkDepthBiasRepresentationInfoEXT::depthBiasRepresentation
341        *
342        * MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
343        */
344       VkDepthBiasRepresentationEXT representation;
345 
346       /** VkDepthBiasRepresentationInfoEXT::depthBiasExact
347        *
348        * MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
349        */
350       bool exact;
351    } depth_bias;
352 
353    struct {
354       /** VkPipelineRasterizationStateCreateInfo::lineWidth
355        *
356        * MESA_VK_DYNAMIC_RS_LINE_WIDTH
357        */
358       float width;
359 
360       /** VkPipelineRasterizationLineStateCreateInfoKHR::lineRasterizationMode
361        *
362        * Will be set to VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR if
363        * VkPipelineRasterizationLineStateCreateInfoKHR is not provided.
364        *
365        * MESA_VK_DYNAMIC_RS_LINE_MODE
366        */
367       VkLineRasterizationModeKHR mode;
368 
369       struct {
370          /** VkPipelineRasterizationLineStateCreateInfoKHR::stippledLineEnable
371           *
372           * MESA_VK_DYNAMIC_RS_LINE_STIPPLE_ENABLE
373           */
374          bool enable;
375 
376          /** VkPipelineRasterizationLineStateCreateInfoKHR::lineStippleFactor
377           *
378           * MESA_VK_DYNAMIC_RS_LINE_STIPPLE
379           */
380          uint32_t factor;
381 
382          /** VkPipelineRasterizationLineStateCreateInfoKHR::lineStipplePattern
383           *
384           * MESA_VK_DYNAMIC_RS_LINE_STIPPLE
385           */
386          uint16_t pattern;
387       } stipple;
388    } line;
389 };
390 
391 static inline bool
vk_rasterization_state_depth_clip_enable(const struct vk_rasterization_state * rs)392 vk_rasterization_state_depth_clip_enable(const struct vk_rasterization_state *rs)
393 {
394    switch (rs->depth_clip_enable) {
395    case VK_MESA_DEPTH_CLIP_ENABLE_FALSE:     return false;
396    case VK_MESA_DEPTH_CLIP_ENABLE_TRUE:      return true;
397    case VK_MESA_DEPTH_CLIP_ENABLE_NOT_CLAMP: return !rs->depth_clamp_enable;
398    }
399    unreachable("Invalid depth clip enable");
400 }
401 
402 /***/
403 struct vk_fragment_shading_rate_state {
404    /** VkPipelineFragmentShadingRateStateCreateInfoKHR::fragmentSize
405     *
406     * MESA_VK_DYNAMIC_GRAPHICS_STATE_FSR
407     */
408    VkExtent2D fragment_size;
409 
410    /** VkPipelineFragmentShadingRateStateCreateInfoKHR::combinerOps
411     *
412     * MESA_VK_DYNAMIC_GRAPHICS_STATE_FSR
413     */
414    VkFragmentShadingRateCombinerOpKHR combiner_ops[2];
415 };
416 
417 /***/
418 struct vk_sample_locations_state {
419    /** VkSampleLocationsInfoEXT::sampleLocationsPerPixel */
420    VkSampleCountFlagBits per_pixel;
421 
422    /** VkSampleLocationsInfoEXT::sampleLocationGridSize */
423    VkExtent2D grid_size;
424 
425    /** VkSampleLocationsInfoEXT::sampleLocations */
426    VkSampleLocationEXT locations[MESA_VK_MAX_SAMPLE_LOCATIONS];
427 };
428 
429 /***/
430 struct vk_multisample_state {
431    /** VkPipelineMultisampleStateCreateInfo::rasterizationSamples */
432    VkSampleCountFlagBits rasterization_samples;
433 
434    /** VkPipelineMultisampleStateCreateInfo::sampleShadingEnable */
435    bool sample_shading_enable;
436 
437    /** VkPipelineMultisampleStateCreateInfo::minSampleShading */
438    float min_sample_shading;
439 
440    /** VkPipelineMultisampleStateCreateInfo::pSampleMask */
441    uint16_t sample_mask;
442 
443    /** VkPipelineMultisampleStateCreateInfo::alphaToCoverageEnable */
444    bool alpha_to_coverage_enable;
445 
446    /** VkPipelineMultisampleStateCreateInfo::alphaToOneEnable */
447    bool alpha_to_one_enable;
448 
449    /** VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable
450     *
451     * This will be true if sample locations enable dynamic.
452     */
453    bool sample_locations_enable;
454 
455    /** VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsInfo
456     *
457     * May be NULL for dynamic sample locations.
458     */
459    const struct vk_sample_locations_state *sample_locations;
460 };
461 
462 /** Represents the stencil test state for a face */
463 struct vk_stencil_test_face_state {
464    /*
465     * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_OP
466     */
467    struct {
468       /** VkStencilOpState::failOp */
469       uint8_t fail;
470 
471       /** VkStencilOpState::passOp */
472       uint8_t pass;
473 
474       /** VkStencilOpState::depthFailOp */
475       uint8_t depth_fail;
476 
477       /** VkStencilOpState::compareOp */
478       uint8_t compare;
479    } op;
480 
481    /** VkStencilOpState::compareMask
482     *
483     * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_COMPARE_MASK
484     */
485    uint8_t compare_mask;
486 
487    /** VkStencilOpState::writeMask
488     *
489     * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_WRITE_MASK
490     */
491    uint8_t write_mask;
492 
493    /** VkStencilOpState::reference
494     *
495     * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_REFERENCE
496     */
497    uint8_t reference;
498 };
499 
500 /***/
501 struct vk_depth_stencil_state {
502    struct {
503       /** VkPipelineDepthStencilStateCreateInfo::depthTestEnable
504        *
505        * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_TEST_ENABLE
506        */
507       bool test_enable;
508 
509       /** VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
510        *
511        * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_WRITE_ENABLE
512        */
513       bool write_enable;
514 
515       /** VkPipelineDepthStencilStateCreateInfo::depthCompareOp
516        *
517        * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_COMPARE_OP
518        */
519       VkCompareOp compare_op;
520 
521       struct {
522          /** VkPipelineDepthStencilStateCreateInfo::depthBoundsTestEnable
523           *
524           * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_BOUNDS_TEST_ENABLE
525           */
526          bool enable;
527 
528          /** VkPipelineDepthStencilStateCreateInfo::min/maxDepthBounds
529           *
530           * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_BOUNDS_TEST_BOUNDS
531           */
532          float min, max;
533       } bounds_test;
534    } depth;
535 
536    struct {
537       /** VkPipelineDepthStencilStateCreateInfo::stencilTestEnable
538        *
539        * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_TEST_ENABLE
540        */
541       bool test_enable;
542 
543       /** Whether or not stencil is should be written
544        *
545        * This does not map directly to any particular Vulkan API state and is
546        * initialized to true.  If independent stencil disable ever becomes a
547        * thing, it will use this state.  vk_optimize_depth_stencil_state() may
548        * set this to false if it can prove that the stencil test will never
549        * alter the stencil value.
550        */
551       bool write_enable;
552 
553       /** VkPipelineDepthStencilStateCreateInfo::front */
554       struct vk_stencil_test_face_state front;
555 
556       /** VkPipelineDepthStencilStateCreateInfo::back */
557       struct vk_stencil_test_face_state back;
558    } stencil;
559 };
560 
561 /** Optimize a depth/stencil state
562  *
563  * The way depth and stencil testing is specified, there are many case where,
564  * regardless of depth/stencil writes being enabled, nothing actually gets
565  * written due to some other bit of state being set.  In the presence of
566  * discards, it's fairly easy to get into cases where early depth/stencil
567  * testing is disabled on some hardware, leading to a fairly big performance
568  * hit.  This function attempts to optimize the depth stencil state and
569  * disable writes and sometimes even testing whenever possible.
570  *
571  * :param ds:                   |inout| The depth stencil state to optimize
572  * :param ds_aspects:           |in|    Which image aspects are present in the
573  *                                      render pass.
574  * :param consider_write_mask:  |in|    If true, the write mask will be taken
575  *                                      into account when optimizing.  If
576  *                                      false, it will be ignored.
577  */
578 void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
579                                      VkImageAspectFlags ds_aspects,
580                                      bool consider_write_mask);
581 
582 struct vk_color_blend_attachment_state {
583    /** VkPipelineColorBlendAttachmentState::blendEnable
584     *
585     * This will be true if blend enables are dynamic
586     *
587     * MESA_VK_DYNAMIC_CB_BLEND_ENABLES
588     */
589    bool blend_enable;
590 
591    /** VkPipelineColorBlendAttachmentState::srcColorBlendFactor
592     *
593     * MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
594     */
595    uint8_t src_color_blend_factor;
596 
597    /** VkPipelineColorBlendAttachmentState::dstColorBlendFactor
598     *
599     * MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
600     */
601    uint8_t dst_color_blend_factor;
602 
603    /** VkPipelineColorBlendAttachmentState::srcAlphaBlendFactor
604     *
605     * MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
606     */
607    uint8_t src_alpha_blend_factor;
608 
609    /** VkPipelineColorBlendAttachmentState::dstAlphaBlendFactor
610     *
611     * MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
612     */
613    uint8_t dst_alpha_blend_factor;
614 
615    /** VkPipelineColorBlendAttachmentState::colorWriteMask
616     *
617     * MESA_VK_DYNAMIC_CB_WRITE_MASKS
618     */
619    uint8_t write_mask;
620 
621    /** VkPipelineColorBlendAttachmentState::colorBlendOp
622     *
623     * MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
624     */
625    VkBlendOp color_blend_op;
626 
627    /** VkPipelineColorBlendAttachmentState::alphaBlendOp
628     *
629     * MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
630     */
631    VkBlendOp alpha_blend_op;
632 };
633 
634 /***/
635 struct vk_color_blend_state {
636    /** VkPipelineColorBlendStateCreateInfo::logicOpEnable
637     *
638     * MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE,
639     */
640    bool logic_op_enable;
641 
642    /** VkPipelineColorBlendStateCreateInfo::logicOp
643     *
644     * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_LOGIC_OP,
645     */
646    uint8_t logic_op;
647 
648    /** VkPipelineColorBlendStateCreateInfo::attachmentCount
649     *
650     * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_ATTACHMENT_COUNT,
651     */
652    uint8_t attachment_count;
653 
654    /** VkPipelineColorWriteCreateInfoEXT::pColorWriteEnables
655     *
656     * Bitmask of color write enables, indexed by color attachment index.
657     *
658     * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_COLOR_WRITE_ENABLES,
659     */
660    uint8_t color_write_enables;
661 
662    /** VkPipelineColorBlendStateCreateInfo::pAttachments */
663    struct vk_color_blend_attachment_state attachments[MESA_VK_MAX_COLOR_ATTACHMENTS];
664 
665    /** VkPipelineColorBlendStateCreateInfo::blendConstants
666     *
667     * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_BLEND_CONSTANTS,
668     */
669    float blend_constants[4];
670 };
671 
672 enum vk_rp_attachment_flags {
673    MESA_VK_RP_ATTACHMENT_NONE                      = 0,
674 
675    MESA_VK_RP_ATTACHMENT_COLOR_0_BIT               = (1 << 0),
676    MESA_VK_RP_ATTACHMENT_COLOR_1_BIT               = (1 << 1),
677    MESA_VK_RP_ATTACHMENT_COLOR_2_BIT               = (1 << 2),
678    MESA_VK_RP_ATTACHMENT_COLOR_3_BIT               = (1 << 3),
679    MESA_VK_RP_ATTACHMENT_COLOR_4_BIT               = (1 << 4),
680    MESA_VK_RP_ATTACHMENT_COLOR_5_BIT               = (1 << 5),
681    MESA_VK_RP_ATTACHMENT_COLOR_6_BIT               = (1 << 6),
682    MESA_VK_RP_ATTACHMENT_COLOR_7_BIT               = (1 << 7),
683    MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS            = 0xff,
684 
685    MESA_VK_RP_ATTACHMENT_DEPTH_BIT                 = (1 << 8),
686    MESA_VK_RP_ATTACHMENT_STENCIL_BIT               = (1 << 9),
687 
688    MESA_VK_RP_ATTACHMENT_INFO_INVALID = 0xffff,
689 };
690 MESA_DEFINE_CPP_ENUM_BITFIELD_OPERATORS(vk_rp_attachment_flags)
691 static_assert(MESA_VK_MAX_COLOR_ATTACHMENTS == 8,
692               "This enum must match the global runtime limit");
693 
694 #define MESA_VK_RP_ATTACHMENT_COLOR_BIT(n) \
695    ((enum vk_rp_attachment_flags)(MESA_VK_RP_ATTACHMENT_COLOR_0_BIT << (n)))
696 
697 /***/
698 struct vk_input_attachment_location_state {
699    /** VkRenderingInputAttachmentIndexInfoKHR::pColorAttachmentLocations
700     *
701     * MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
702     */
703    uint8_t color_map[MESA_VK_MAX_COLOR_ATTACHMENTS];
704 
705    /** VkRenderingInputAttachmentIndexInfoKHR::pDepthInputAttachmentIndex
706     *
707     * MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
708     */
709    uint8_t depth_att;
710 
711    /** VkRenderingInputAttachmentIndexInfoKHR::pStencilInputAttachmentIndex
712     *
713     * MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
714     */
715    uint8_t stencil_att;
716 };
717 
718 /***/
719 struct vk_color_attachment_location_state {
720    /** VkRenderingAttachmentLocationInfoKHR::pColorAttachmentLocations
721     *
722     * MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP
723     */
724    uint8_t color_map[MESA_VK_MAX_COLOR_ATTACHMENTS];
725 };
726 
727 /***/
728 struct vk_render_pass_state {
729    /** Set of image aspects bound as color/depth/stencil attachments
730     *
731     * Set to MESA_VK_RP_ATTACHMENT_INFO_INVALID to indicate that attachment
732     * info is invalid.
733     */
734    enum vk_rp_attachment_flags attachments;
735 
736    /** VkPipelineRenderingCreateInfo::viewMask */
737    uint32_t view_mask;
738 
739    /** VkPipelineRenderingCreateInfo::colorAttachmentCount */
740    uint8_t color_attachment_count;
741 
742    /** VkPipelineRenderingCreateInfo::pColorAttachmentFormats */
743    VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS];
744 
745    /** VkPipelineRenderingCreateInfo::depthAttachmentFormat */
746    VkFormat depth_attachment_format;
747 
748    /** VkPipelineRenderingCreateInfo::stencilAttachmentFormat */
749    VkFormat stencil_attachment_format;
750 
751    /** VkAttachmentSampleCountInfoAMD::pColorAttachmentSamples */
752    uint8_t color_attachment_samples[MESA_VK_MAX_COLOR_ATTACHMENTS];
753 
754    /** VkAttachmentSampleCountInfoAMD::depthStencilAttachmentSamples */
755    uint8_t depth_stencil_attachment_samples;
756 };
757 
758 static inline bool
vk_render_pass_state_has_attachment_info(const struct vk_render_pass_state * rp)759 vk_render_pass_state_has_attachment_info(const struct vk_render_pass_state *rp)
760 {
761    return rp->attachments != MESA_VK_RP_ATTACHMENT_INFO_INVALID;
762 }
763 
764 static inline VkImageAspectFlags
vk_pipeline_flags_feedback_loops(VkPipelineCreateFlags2KHR flags)765 vk_pipeline_flags_feedback_loops(VkPipelineCreateFlags2KHR flags)
766 {
767    VkImageAspectFlags feedback_loops = 0;
768    if (flags &
769        VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
770       feedback_loops |= VK_IMAGE_ASPECT_COLOR_BIT;
771    if (flags &
772        VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
773       feedback_loops |= VK_IMAGE_ASPECT_DEPTH_BIT;
774    return feedback_loops;
775 }
776 
777 /** Struct representing all dynamic graphics state
778  *
779  * Before invoking any core functions, the driver must properly populate
780  * initialize this struct:
781  *
782  *  - Initialize using vk_default_dynamic_graphics_state, if desired
783  *  - Set vi to a driver-allocated vk_vertex_input_state struct
784  *  - Set ms.sample_locations to a driver-allocated
785  *    vk_sample_locations_state struct
786  */
787 struct vk_dynamic_graphics_state {
788    /** Vertex input state
789     *
790     * Must be provided by the driver if VK_EXT_vertex_input_dynamic_state is
791     * supported.
792     *
793     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI
794     */
795    struct vk_vertex_input_state *vi;
796 
797    /* This is a copy of vi->bindings_valid, used when the vertex input state
798     * is precompiled in the pipeline (so that vi is NULL) but the strides are
799     * set dynamically.
800     *
801     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI_BINDINGS_VALID
802     */
803    uint32_t vi_bindings_valid;
804 
805    /** Vertex binding strides
806     *
807     * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI_BINDING_STRIDES
808     */
809    uint16_t vi_binding_strides[MESA_VK_MAX_VERTEX_BINDINGS];
810 
811    /** Input assembly state */
812    struct vk_input_assembly_state ia;
813 
814    /** Tessellation state */
815    struct vk_tessellation_state ts;
816 
817    /** Viewport state */
818    struct vk_viewport_state vp;
819 
820    /** Discard rectangles state */
821    struct {
822       /** Custom enable
823        *
824        * MESA_VK_DYNAMIC_DR_ENABLE
825        */
826       bool enable;
827 
828       /** Mode
829        *
830        * MESA_VK_DYNAMIC_DR_MODE
831        */
832       VkDiscardRectangleModeEXT mode;
833 
834       /** Rectangles
835        *
836        * MESA_VK_DYNAMIC_DR_RECTANGLES
837        */
838       VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES];
839 
840       /** Number of rectangles
841        *
842        * MESA_VK_DYNAMIC_GRAPHICS_STATE_DR_RECTANGLES
843        */
844       uint32_t rectangle_count;
845    } dr;
846 
847    /** Rasterization state */
848    struct vk_rasterization_state rs;
849 
850    /* Fragment shading rate state */
851    struct vk_fragment_shading_rate_state fsr;
852 
853    /** Multisample state */
854    struct {
855       /** Rasterization samples
856        *
857        * MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES
858        */
859       VkSampleCountFlagBits rasterization_samples;
860 
861       /** Sample mask
862        *
863        * MESA_VK_DYNAMIC_MS_SAMPLE_MASK
864        */
865       uint16_t sample_mask;
866 
867       /** Alpha to coverage enable
868        *
869        * MESA_VK_DYNAMIC_MS_ALPHA_TO_CONVERAGE_ENABLE
870        */
871       bool alpha_to_coverage_enable;
872 
873       /** Alpha to one enable
874        *
875        * MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE
876        */
877       bool alpha_to_one_enable;
878 
879       /** Custom sample locations enable
880        *
881        * MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS_ENABLE
882        */
883       bool sample_locations_enable;
884 
885       /** Sample locations
886        *
887        * Must be provided by the driver if VK_EXT_sample_locations is
888        * supported.
889        *
890        * MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS
891        */
892       struct vk_sample_locations_state *sample_locations;
893    } ms;
894 
895    /** Depth stencil state */
896    struct vk_depth_stencil_state ds;
897 
898    /** Color blend state */
899    struct vk_color_blend_state cb;
900 
901    struct {
902       enum vk_rp_attachment_flags attachments;
903    } rp;
904 
905    /** MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE */
906    VkImageAspectFlags feedback_loops;
907 
908    /** MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP */
909    struct vk_input_attachment_location_state ial;
910 
911    /** MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP */
912    struct vk_color_attachment_location_state cal;
913 
914    /** For pipelines, which bits of dynamic state are set */
915    BITSET_DECLARE(set, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
916 
917    /** For command buffers, which bits of dynamic state have changed */
918    BITSET_DECLARE(dirty, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
919 };
920 
921 /***/
922 struct vk_graphics_pipeline_all_state {
923    struct vk_vertex_input_state vi;
924    struct vk_input_assembly_state ia;
925    struct vk_tessellation_state ts;
926    struct vk_viewport_state vp;
927    struct vk_discard_rectangles_state dr;
928    struct vk_rasterization_state rs;
929    struct vk_fragment_shading_rate_state fsr;
930    struct vk_multisample_state ms;
931    struct vk_sample_locations_state ms_sample_locations;
932    struct vk_depth_stencil_state ds;
933    struct vk_color_blend_state cb;
934    struct vk_input_attachment_location_state ial;
935    struct vk_color_attachment_location_state cal;
936    struct vk_render_pass_state rp;
937 };
938 
939 /***/
940 struct vk_graphics_pipeline_state {
941    /** Bitset of which states are dynamic */
942    BITSET_DECLARE(dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
943 
944    VkShaderStageFlags shader_stages;
945 
946    /** Flags from VkGraphicsPipelineCreateInfo::flags that are considered part
947     * of a stage and need to be merged when linking libraries.
948     *
949     * For drivers which use vk_render_pass, this will also include flags
950     * generated based on subpass self-dependencies and fragment density map.
951     */
952    VkPipelineCreateFlags2KHR pipeline_flags;
953 
954    /* True if there are feedback loops that do not involve input attachments
955     * managed by the driver. This is set to true by the runtime if there
956     * are loops indicated by a pipeline flag (which may involve any image
957     * rather than only input attachments under the control of the driver) or
958     * there was no driver-provided render pass info struct (because input
959     * attachments for emulated renderpasses cannot be managed by the driver).
960     */
961    bool feedback_loop_not_input_only;
962 
963    /** Vertex input state */
964    const struct vk_vertex_input_state *vi;
965 
966    /** Input assembly state */
967    const struct vk_input_assembly_state *ia;
968 
969    /** Tessellation state */
970    const struct vk_tessellation_state *ts;
971 
972    /** Viewport state */
973    const struct vk_viewport_state *vp;
974 
975    /** Discard Rectangles state */
976    const struct vk_discard_rectangles_state *dr;
977 
978    /** Rasterization state */
979    const struct vk_rasterization_state *rs;
980 
981    /** Fragment shading rate state */
982    const struct vk_fragment_shading_rate_state *fsr;
983 
984    /** Multisample state */
985    const struct vk_multisample_state *ms;
986 
987    /** Depth stencil state */
988    const struct vk_depth_stencil_state *ds;
989 
990    /** Color blend state */
991    const struct vk_color_blend_state *cb;
992 
993    /** Input attachment mapping state */
994    const struct vk_input_attachment_location_state *ial;
995 
996    /** Color attachment mapping state */
997    const struct vk_color_attachment_location_state *cal;
998 
999    /** Render pass state */
1000    const struct vk_render_pass_state *rp;
1001 };
1002 
1003 /** Populate a vk_graphics_pipeline_state from VkGraphicsPipelineCreateInfo
1004  *
1005  * This function crawls the provided VkGraphicsPipelineCreateInfo and uses it
1006  * to populate the vk_graphics_pipeline_state.  Upon returning from this
1007  * function, all pointers in `state` will either be `NULL` or point to a valid
1008  * sub-state structure.  Whenever an extension struct is missing, a reasonable
1009  * default value is provided whenever possible.  Some states may be left NULL
1010  * if the state does not exist (such as when rasterizer discard is enabled) or
1011  * if all of the corresponding states are dynamic.
1012  *
1013  * This function assumes that the vk_graphics_pipeline_state is already valid
1014  * (i.e., all pointers are NULL or point to valid states).  Any states already
1015  * present are assumed to be identical to how we would populate them from
1016  * VkGraphicsPipelineCreateInfo.
1017  *
1018  * This function can operate in one of two modes with respect to how the
1019  * memory for states is allocated.  If a `vk_graphics_pipeline_all_state`
1020  * struct is provided, any newly populated states will point to the relevant
1021  * field in `all`.  If `all == NULL`, it attempts to dynamically allocate any
1022  * newly required states using the provided allocator and scope.  The pointer
1023  * to this new blob of memory is returned via `alloc_ptr_out` and must
1024  * eventually be freed by the driver.
1025  *
1026  * :param device:       |in|  The Vulkan device
1027  * :param state:        |out| The graphics pipeline state to populate
1028  * :param info:         |in|  The pCreateInfo from vkCreateGraphicsPipelines
1029  * :param driver_rp:    |in|  Renderpass state if the driver implements render
1030  *                            passes itself.  This should be NULL for drivers
1031  *                            that use the common render pass infrastructure
1032  *                            built on top of dynamic rendering.
1033  * :param driver_rp_flags: |in| Pipeline create flags implied by the
1034  *                              renderpass or subpass if the driver implements
1035  *                              render passes itself.  This is only used if
1036  *                              driver_rp is non-NULL.
1037  * :param  all:         |in|  The vk_graphics_pipeline_all_state to use to
1038  *                            back any newly needed states.  If NULL, newly
1039  *                            needed states will be dynamically allocated
1040  *                            instead.
1041  * :param alloc:        |in|  Allocation callbacks for dynamically allocating
1042  *                            new state memory.
1043  * :param scope:        |in|  Allocation scope for dynamically allocating new
1044  *                            state memory.
1045  * :param alloc_ptr_out: |out| Will be populated with a pointer to any newly
1046  *                             allocated state.  The driver is responsible for
1047  *                             freeing this pointer.
1048  */
1049 VkResult
1050 vk_graphics_pipeline_state_fill(const struct vk_device *device,
1051                                 struct vk_graphics_pipeline_state *state,
1052                                 const VkGraphicsPipelineCreateInfo *info,
1053                                 const struct vk_render_pass_state *driver_rp,
1054                                 VkPipelineCreateFlags2KHR driver_rp_flags,
1055                                 struct vk_graphics_pipeline_all_state *all,
1056                                 const VkAllocationCallbacks *alloc,
1057                                 VkSystemAllocationScope scope,
1058                                 void **alloc_ptr_out);
1059 
1060 /** Populate a vk_graphics_pipeline_state from another one.
1061  *
1062  * This allocates space for graphics pipeline state and copies it from another
1063  * pipeline state. It ignores state in `old_state` which is not set and does
1064  * not allocate memory if the entire group is unused. The intended use-case is
1065  * for drivers that may be able to precompile some state ahead of time, to
1066  * avoid allocating memory for it in pipeline libraries. The workflow looks
1067  * something like this:
1068  *
1069  *     struct vk_graphics_pipeline_all_state all;
1070  *     struct vk_graphics_pipeline_state state;
1071  *     vk_graphics_pipeline_state_fill(dev, &state, ..., &all, NULL, 0, NULL);
1072  *
1073  *     ...
1074  *
1075  *     BITSET_DECLARE(set_state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1076  *     vk_graphics_pipeline_get_state(&state, &set_state);
1077  *
1078  *     ...
1079  *
1080  *     if (BITSET_TEST(set_state, MESA_VK_DYNAMIC_FOO)) {
1081  *        emit_foo(&state.foo, ...);
1082  *        BITSET_SET(state.dynamic, MESA_VK_DYNAMIC_FOO);
1083  *     }
1084  *
1085  *     ...
1086  *
1087  *     if (pipeline->is_library) {
1088  *        library = pipeline_to_library(pipeline);
1089  *        vk_graphics_pipeline_state_copy(dev, &library->state, &state, ...);
1090  *     }
1091  *
1092  * In this case we will avoid allocating memory for `library->state.foo`.
1093  *
1094  * :param device:       |in|  The Vulkan device
1095  * :param state:        |out| The graphics pipeline state to populate
1096  * :param old_state:    |in|  The graphics pipeline state to copy from
1097  * :param alloc:        |in|  Allocation callbacks for dynamically allocating
1098  *                            new state memory.
1099  * :param scope:        |in|  Allocation scope for dynamically allocating new
1100  *                            state memory.
1101  * :param alloc_ptr_out: |out| Will be populated with a pointer to any newly
1102  *                             allocated state.  The driver is responsible for
1103  *                             freeing this pointer.
1104  */
1105 VkResult
1106 vk_graphics_pipeline_state_copy(const struct vk_device *device,
1107                                 struct vk_graphics_pipeline_state *state,
1108                                 const struct vk_graphics_pipeline_state *old_state,
1109                                 const VkAllocationCallbacks *alloc,
1110                                 VkSystemAllocationScope scope,
1111                                 void **alloc_ptr_out);
1112 
1113 /** Merge one vk_graphics_pipeline_state into another
1114  *
1115  * Both the destination and source states are assumed to be valid (i.e., all
1116  * pointers are NULL or point to valid states).  Any states which exist in
1117  * both are expected to be identical and the state already in dst is used.
1118  * The only exception here is render pass state which may be only partially
1119  * defined in which case the fully defined one (if any) is used.
1120  *
1121  * :param dst:          |out| The destination state.  When the function returns, this
1122  *                            will be the union of the original dst and src.
1123  * :param src:          |in|  The source state
1124  */
1125 void
1126 vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst,
1127                                  const struct vk_graphics_pipeline_state *src);
1128 
1129 /** Get the states which will be set for a given vk_graphics_pipeline_state
1130  *
1131  * Return which states should be set when the pipeline is bound.
1132  */
1133 void
1134 vk_graphics_pipeline_get_state(const struct vk_graphics_pipeline_state *state,
1135                                BITSET_WORD *set_state_out);
1136 
1137 /** Initialize a vk_dynamic_graphics_state with defaults
1138  *
1139  * :param dyn:          |out| Dynamic graphics state to initialize
1140  */
1141 void
1142 vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn);
1143 
1144 /** Clear a vk_dynamic_graphics_state to defaults
1145  *
1146  * :param dyn:          |out| Dynamic graphics state to initialize
1147  */
1148 void
1149 vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn);
1150 
1151 /** Initialize a vk_dynamic_graphics_state for a pipeline
1152  *
1153  * :param dyn:          |out| Dynamic graphics state to initialize
1154  * :param supported:    |in|  Bitset of all dynamic state supported by the driver.
1155  * :param p:            |in|  The pipeline state from which to initialize the
1156  *                            dynamic state.
1157  */
1158 void
1159 vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn,
1160                                const struct vk_graphics_pipeline_state *p);
1161 
1162 /** Mark all states in the given vk_dynamic_graphics_state dirty
1163  *
1164  * :param d:    |out| Dynamic graphics state struct
1165  */
1166 static inline void
vk_dynamic_graphics_state_dirty_all(struct vk_dynamic_graphics_state * d)1167 vk_dynamic_graphics_state_dirty_all(struct vk_dynamic_graphics_state *d)
1168 {
1169    BITSET_SET_RANGE(d->dirty, 0, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX - 1);
1170 }
1171 
1172 /** Mark all states in the given vk_dynamic_graphics_state not dirty
1173  *
1174  * :param d:    |out| Dynamic graphics state struct
1175  */
1176 static inline void
vk_dynamic_graphics_state_clear_dirty(struct vk_dynamic_graphics_state * d)1177 vk_dynamic_graphics_state_clear_dirty(struct vk_dynamic_graphics_state *d)
1178 {
1179    BITSET_ZERO(d->dirty);
1180 }
1181 
1182 /** Test if any states in the given vk_dynamic_graphics_state are dirty
1183  *
1184  * :param d:    |in|  Dynamic graphics state struct to test
1185  * :returns:          true if any state is dirty
1186  */
1187 static inline bool
vk_dynamic_graphics_state_any_dirty(const struct vk_dynamic_graphics_state * d)1188 vk_dynamic_graphics_state_any_dirty(const struct vk_dynamic_graphics_state *d)
1189 {
1190    return !BITSET_IS_EMPTY(d->dirty);
1191 }
1192 
1193 /** Copies all set state from src to dst
1194  *
1195  * Both src and dst are assumed to be properly initialized dynamic state
1196  * structs.  Anything not set in src, as indicated by src->set, is ignored and
1197  * those bits of dst are left untouched.
1198  *
1199  * :param dst:  |out| Copy destination
1200  * :param src:  |in|  Copy source
1201  */
1202 void
1203 vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst,
1204                                const struct vk_dynamic_graphics_state *src);
1205 
1206 /** Set all of the state in src on a command buffer
1207  *
1208  * Anything not set, as indicated by src->set, is ignored and those states in
1209  * the command buffer are left untouched.
1210  *
1211  * :param cmd:  |inout| Command buffer to update
1212  * :param src:  |in|    State to set
1213  */
1214 void
1215 vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer *cmd,
1216                                   const struct vk_dynamic_graphics_state *src);
1217 
1218 /** Set vertex binding strides on a command buffer
1219  *
1220  * This is the dynamic state part of vkCmdBindVertexBuffers2().
1221  *
1222  * :param cmd:            |inout|  Command buffer to update
1223  * :param first_binding:  |in|     First binding to update
1224  * :param binding_count:  |in|     Number of bindings to update
1225  * :param strides:        |in|     binding_count many stride values to set
1226  */
1227 void
1228 vk_cmd_set_vertex_binding_strides(struct vk_command_buffer *cmd,
1229                                   uint32_t first_binding,
1230                                   uint32_t binding_count,
1231                                   const VkDeviceSize *strides);
1232 
1233 /* Set color attachment count for blending on a command buffer.
1234  *
1235  * This is an implicit part of starting a subpass or a secondary command
1236  * buffer in a subpass.
1237  */
1238 void
1239 vk_cmd_set_cb_attachment_count(struct vk_command_buffer *cmd,
1240                                uint32_t attachment_count);
1241 
1242 /* Set render pass attachments on a command buffer.
1243  *
1244  * This is required for VK_EXT_shader_object in order to disable attachments
1245  * based on bound shaders.
1246  */
1247 void
1248 vk_cmd_set_rp_attachments(struct vk_command_buffer *cmd,
1249                           enum vk_rp_attachment_flags attachments);
1250 
1251 /* This is equivalent to CmdSetRenderingAttachmentLocationsKHR() but easier to
1252  * invoke from inside drivers.
1253  */
1254 void
1255 vk_cmd_set_rendering_attachment_locations(struct vk_command_buffer *cmd,
1256                                           const VkRenderingAttachmentLocationInfoKHR *info);
1257 
1258 const char *
1259 vk_dynamic_graphic_state_to_str(enum mesa_vk_dynamic_graphics_state state);
1260 
1261 /** Check whether the color attachment location map is the identity
1262  *
1263  * :param cal: |in| Color attachment location state
1264  */
1265 static inline bool
vk_color_attachment_location_state_is_identity(const struct vk_color_attachment_location_state * cal)1266 vk_color_attachment_location_state_is_identity(
1267    const struct vk_color_attachment_location_state *cal)
1268 {
1269    for (unsigned i = 0; i < ARRAY_SIZE(cal->color_map); i++) {
1270       if (cal->color_map[i] != i)
1271          return false;
1272    }
1273    return true;
1274 }
1275 
1276 #ifdef __cplusplus
1277 }
1278 #endif
1279 
1280 #endif  /* VK_GRAPHICS_STATE_H */
1281