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