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