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