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