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