1#include "vk_graphics_state.h"
2
3#include "vk_alloc.h"
4#include "vk_command_buffer.h"
5#include "vk_common_entrypoints.h"
6#include "vk_device.h"
7#include "vk_log.h"
8#include "vk_render_pass.h"
9#include "vk_standard_sample_locations.h"
10#include "vk_util.h"
11
12#include <assert.h>
13
14enum mesa_vk_graphics_state_groups {
15   MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT            = (1 << 0),
16   MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT          = (1 << 1),
17   MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT            = (1 << 2),
18   MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT                = (1 << 3),
19   MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT      = (1 << 4),
20   MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT           = (1 << 5),
21   MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT   = (1 << 6),
22   MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT             = (1 << 7),
23   MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT           = (1 << 8),
24   MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT             = (1 << 9),
25   MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT             = (1 << 10),
26};
27
28static void
29clear_all_dynamic_state(BITSET_WORD *dynamic)
30{
31   /* Clear the whole array so there are no undefined bits at the top */
32   memset(dynamic, 0, sizeof(*dynamic) *
33          BITSET_WORDS(MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX));
34}
35
36static void
37get_dynamic_state_groups(BITSET_WORD *dynamic,
38                         enum mesa_vk_graphics_state_groups groups)
39{
40   clear_all_dynamic_state(dynamic);
41
42   if (groups & MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT) {
43      BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI);
44      BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI_BINDING_STRIDES);
45   }
46
47   if (groups & MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT) {
48      BITSET_SET(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY);
49      BITSET_SET(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE);
50   }
51
52   if (groups & MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT)
53      BITSET_SET(dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS);
54
55   if (groups & MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT) {
56      BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT);
57      BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_VIEWPORTS);
58      BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT);
59      BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_SCISSORS);
60   }
61
62   if (groups & MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT)
63      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DR_RECTANGLES);
64
65   if (groups & MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT) {
66      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE);
67      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_CULL_MODE);
68      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_FRONT_FACE);
69      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE);
70      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS);
71      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_WIDTH);
72      BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_STIPPLE);
73   }
74
75   if (groups & MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT)
76      BITSET_SET(dynamic, MESA_VK_DYNAMIC_FSR);
77
78   if (groups & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT)
79      BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS);
80
81   if (groups & MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT) {
82      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE);
83      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE);
84      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP);
85      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE);
86      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS);
87      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE);
88      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP);
89      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK);
90      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK);
91      BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
92   }
93
94   if (groups & MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT) {
95      BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP);
96      BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
97      BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
98   }
99}
100
101static enum mesa_vk_graphics_state_groups
102fully_dynamic_state_groups(const BITSET_WORD *dynamic)
103{
104   enum mesa_vk_graphics_state_groups groups = 0;
105
106   if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_VI))
107      groups |= MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT;
108
109   if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) &&
110       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE))
111      groups |= MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT;
112
113   if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_FSR))
114      groups |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT;
115
116   if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) &&
117       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) &&
118       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) &&
119       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE) &&
120       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS) &&
121       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) &&
122       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP) &&
123       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) &&
124       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) &&
125       BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE))
126      groups |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT;
127
128   return groups;
129}
130
131static void
132validate_dynamic_state_groups(const BITSET_WORD *dynamic,
133                              enum mesa_vk_graphics_state_groups groups)
134{
135#ifndef NDEBUG
136   BITSET_DECLARE(all_dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
137   get_dynamic_state_groups(all_dynamic, groups);
138
139   for (uint32_t w = 0; w < ARRAY_SIZE(all_dynamic); w++)
140      assert(!(dynamic[w] & ~all_dynamic[w]));
141#endif
142}
143
144void
145vk_get_dynamic_graphics_states(BITSET_WORD *dynamic,
146                               const VkPipelineDynamicStateCreateInfo *info)
147{
148   clear_all_dynamic_state(dynamic);
149
150   /* From the Vulkan 1.3.218 spec:
151    *
152    *    "pDynamicState is a pointer to a VkPipelineDynamicStateCreateInfo
153    *    structure defining which properties of the pipeline state object are
154    *    dynamic and can be changed independently of the pipeline state. This
155    *    can be NULL, which means no state in the pipeline is considered
156    *    dynamic."
157    */
158   if (info == NULL)
159      return;
160
161#define CASE(VK, MESA) \
162   case VK_DYNAMIC_STATE_##VK: \
163      BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA); \
164      break;
165
166#define CASE2(VK, MESA1, MESA2) \
167   case VK_DYNAMIC_STATE_##VK: \
168      BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA1); \
169      BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA2); \
170      break;
171
172   for (uint32_t i = 0; i < info->dynamicStateCount; i++) {
173      switch (info->pDynamicStates[i]) {
174      CASE2(VERTEX_INPUT_EXT,             VI, VI_BINDING_STRIDES)
175      CASE( VERTEX_INPUT_BINDING_STRIDE,  VI_BINDING_STRIDES)
176      CASE( VIEWPORT,                     VP_VIEWPORTS)
177      CASE( SCISSOR,                      VP_SCISSORS)
178      CASE( LINE_WIDTH,                   RS_LINE_WIDTH)
179      CASE( DEPTH_BIAS,                   RS_DEPTH_BIAS_FACTORS)
180      CASE( BLEND_CONSTANTS,              CB_BLEND_CONSTANTS)
181      CASE( DEPTH_BOUNDS,                 DS_DEPTH_BOUNDS_TEST_BOUNDS)
182      CASE( STENCIL_COMPARE_MASK,         DS_STENCIL_COMPARE_MASK)
183      CASE( STENCIL_WRITE_MASK,           DS_STENCIL_WRITE_MASK)
184      CASE( STENCIL_REFERENCE,            DS_STENCIL_REFERENCE)
185      CASE( CULL_MODE,                    RS_CULL_MODE)
186      CASE( FRONT_FACE,                   RS_FRONT_FACE)
187      CASE( PRIMITIVE_TOPOLOGY,           IA_PRIMITIVE_TOPOLOGY)
188      CASE2(VIEWPORT_WITH_COUNT,          VP_VIEWPORT_COUNT, VP_VIEWPORTS)
189      CASE2(SCISSOR_WITH_COUNT,           VP_SCISSOR_COUNT, VP_SCISSORS)
190      CASE( DEPTH_TEST_ENABLE,            DS_DEPTH_TEST_ENABLE)
191      CASE( DEPTH_WRITE_ENABLE,           DS_DEPTH_WRITE_ENABLE)
192      CASE( DEPTH_COMPARE_OP,             DS_DEPTH_COMPARE_OP)
193      CASE( DEPTH_BOUNDS_TEST_ENABLE,     DS_DEPTH_BOUNDS_TEST_ENABLE)
194      CASE( STENCIL_TEST_ENABLE,          DS_STENCIL_TEST_ENABLE)
195      CASE( STENCIL_OP,                   DS_STENCIL_OP)
196      CASE( RASTERIZER_DISCARD_ENABLE,    RS_RASTERIZER_DISCARD_ENABLE)
197      CASE( DEPTH_BIAS_ENABLE,            RS_DEPTH_BIAS_ENABLE)
198      CASE( PRIMITIVE_RESTART_ENABLE,     IA_PRIMITIVE_RESTART_ENABLE)
199      CASE( DISCARD_RECTANGLE_EXT,        DR_RECTANGLES)
200      CASE( SAMPLE_LOCATIONS_EXT,         MS_SAMPLE_LOCATIONS)
201      CASE( FRAGMENT_SHADING_RATE_KHR,    FSR)
202      CASE( LINE_STIPPLE_EXT,             RS_LINE_STIPPLE)
203      CASE( PATCH_CONTROL_POINTS_EXT,     TS_PATCH_CONTROL_POINTS)
204      CASE( LOGIC_OP_EXT,                 CB_LOGIC_OP)
205      CASE( COLOR_WRITE_ENABLE_EXT,       CB_COLOR_WRITE_ENABLES)
206      default:
207         unreachable("Unsupported dynamic graphics state");
208      }
209   }
210}
211
212#define IS_DYNAMIC(STATE) \
213   BITSET_TEST(dynamic, MESA_VK_DYNAMIC_##STATE)
214
215#define IS_NEEDED(STATE) \
216   BITSET_TEST(needed, MESA_VK_DYNAMIC_##STATE)
217
218static void
219vk_vertex_input_state_init(struct vk_vertex_input_state *vi,
220                           const BITSET_WORD *dynamic,
221                           const VkPipelineVertexInputStateCreateInfo *vi_info)
222{
223   assert(!IS_DYNAMIC(VI));
224
225   memset(vi, 0, sizeof(*vi));
226
227   for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) {
228      const VkVertexInputBindingDescription *desc =
229         &vi_info->pVertexBindingDescriptions[i];
230
231      assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
232      assert(desc->stride <= MESA_VK_MAX_VERTEX_BINDING_STRIDE);
233      assert(desc->inputRate <= 1);
234
235      const uint32_t b = desc->binding;
236      vi->bindings_valid |= BITFIELD_BIT(b);
237      vi->bindings[b].stride = desc->stride;
238      vi->bindings[b].input_rate = desc->inputRate;
239      vi->bindings[b].divisor = 1;
240   }
241
242   for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
243      const VkVertexInputAttributeDescription *desc =
244         &vi_info->pVertexAttributeDescriptions[i];
245
246      assert(desc->location < MESA_VK_MAX_VERTEX_ATTRIBUTES);
247      assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
248      assert(vi->bindings_valid & BITFIELD_BIT(desc->binding));
249
250      const uint32_t a = desc->location;
251      vi->attributes_valid |= BITFIELD_BIT(a);
252      vi->attributes[a].binding = desc->binding;
253      vi->attributes[a].format = desc->format;
254      vi->attributes[a].offset = desc->offset;
255   }
256
257   const VkPipelineVertexInputDivisorStateCreateInfoEXT *vi_div_state =
258      vk_find_struct_const(vi_info->pNext,
259                           PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
260   if (vi_div_state) {
261      for (uint32_t i = 0; i < vi_div_state->vertexBindingDivisorCount; i++) {
262         const VkVertexInputBindingDivisorDescriptionEXT *desc =
263            &vi_div_state->pVertexBindingDivisors[i];
264
265         assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
266         assert(vi->bindings_valid & BITFIELD_BIT(desc->binding));
267
268         const uint32_t b = desc->binding;
269         vi->bindings[b].divisor = desc->divisor;
270      }
271   }
272}
273
274static void
275vk_dynamic_graphics_state_init_vi(struct vk_dynamic_graphics_state *dst,
276                                  const BITSET_WORD *needed,
277                                  const struct vk_vertex_input_state *vi)
278{
279   if (IS_NEEDED(VI))
280      *dst->vi = *vi;
281
282   if (IS_NEEDED(VI_BINDING_STRIDES)) {
283      for (uint32_t b = 0; b < MESA_VK_MAX_VERTEX_BINDINGS; b++) {
284         if (vi->bindings_valid & BITFIELD_BIT(b))
285            dst->vi_binding_strides[b] = vi->bindings[b].stride;
286         else
287            dst->vi_binding_strides[b] = 0;
288      }
289   }
290}
291
292static void
293vk_input_assembly_state_init(struct vk_input_assembly_state *ia,
294                             const BITSET_WORD *dynamic,
295                             const VkPipelineInputAssemblyStateCreateInfo *ia_info)
296{
297   if (IS_DYNAMIC(IA_PRIMITIVE_TOPOLOGY)) {
298      ia->primitive_topology = -1;
299   } else {
300      assert(ia_info->topology <= UINT8_MAX);
301      ia->primitive_topology = ia_info->topology;
302   }
303
304   ia->primitive_restart_enable = ia_info->primitiveRestartEnable;
305}
306
307static void
308vk_dynamic_graphics_state_init_ia(struct vk_dynamic_graphics_state *dst,
309                                  const BITSET_WORD *needed,
310                                  const struct vk_input_assembly_state *ia)
311{
312   dst->ia = *ia;
313}
314
315static void
316vk_tessellation_state_init(struct vk_tessellation_state *ts,
317                           const BITSET_WORD *dynamic,
318                           const VkPipelineTessellationStateCreateInfo *ts_info)
319{
320   if (IS_DYNAMIC(TS_PATCH_CONTROL_POINTS)) {
321      ts->patch_control_points = 0;
322   } else {
323      assert(ts_info->patchControlPoints <= UINT8_MAX);
324      ts->patch_control_points = ts_info->patchControlPoints;
325   }
326
327   const VkPipelineTessellationDomainOriginStateCreateInfo *ts_do_info =
328      vk_find_struct_const(ts_info->pNext,
329                           PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO);
330   if (ts_do_info != NULL) {
331      assert(ts_do_info->domainOrigin <= UINT8_MAX);
332      ts->domain_origin = ts_do_info->domainOrigin;
333   } else {
334      ts->domain_origin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT;
335   }
336}
337
338static void
339vk_dynamic_graphics_state_init_ts(struct vk_dynamic_graphics_state *dst,
340                                  const BITSET_WORD *needed,
341                                  const struct vk_tessellation_state *ts)
342{
343   dst->ts.patch_control_points = ts->patch_control_points;
344}
345
346static void
347vk_viewport_state_init(struct vk_viewport_state *vp,
348                       const BITSET_WORD *dynamic,
349                       const VkPipelineViewportStateCreateInfo *vp_info)
350{
351   memset(vp, 0, sizeof(*vp));
352
353   if (!IS_DYNAMIC(VP_VIEWPORT_COUNT)) {
354      assert(vp_info->viewportCount <= MESA_VK_MAX_VIEWPORTS);
355      vp->viewport_count = vp_info->viewportCount;
356   }
357
358   if (!IS_DYNAMIC(VP_VIEWPORTS)) {
359      assert(!IS_DYNAMIC(VP_VIEWPORT_COUNT));
360      typed_memcpy(vp->viewports, vp_info->pViewports,
361                   vp_info->viewportCount);
362   }
363
364   if (!IS_DYNAMIC(VP_SCISSOR_COUNT)) {
365      assert(vp_info->scissorCount <= MESA_VK_MAX_SCISSORS);
366      vp->scissor_count = vp_info->scissorCount;
367   }
368
369   if (!IS_DYNAMIC(VP_SCISSORS)) {
370      assert(!IS_DYNAMIC(VP_SCISSOR_COUNT));
371      typed_memcpy(vp->scissors, vp_info->pScissors,
372                   vp_info->scissorCount);
373   }
374
375   const VkPipelineViewportDepthClipControlCreateInfoEXT *vp_dcc_info =
376      vk_find_struct_const(vp_info->pNext,
377                           PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT);
378   if (vp_dcc_info != NULL)
379      vp->negative_one_to_one = vp_dcc_info->negativeOneToOne;
380}
381
382static void
383vk_dynamic_graphics_state_init_vp(struct vk_dynamic_graphics_state *dst,
384                                  const BITSET_WORD *needed,
385                                  const struct vk_viewport_state *vp)
386{
387   dst->vp.viewport_count = vp->viewport_count;
388   if (IS_NEEDED(VP_VIEWPORTS))
389      typed_memcpy(dst->vp.viewports, vp->viewports, vp->viewport_count);
390
391   dst->vp.scissor_count = vp->scissor_count;
392   if (IS_NEEDED(VP_SCISSORS))
393      typed_memcpy(dst->vp.scissors, vp->scissors, vp->scissor_count);
394}
395
396static void
397vk_discard_rectangles_state_init(struct vk_discard_rectangles_state *dr,
398                                 const BITSET_WORD *dynamic,
399                                 const VkPipelineDiscardRectangleStateCreateInfoEXT *dr_info)
400{
401   memset(dr, 0, sizeof(*dr));
402
403   if (dr_info == NULL)
404      return;
405
406   dr->mode = dr_info->discardRectangleMode;
407
408   if (!IS_DYNAMIC(DR_RECTANGLES)) {
409      assert(dr_info->discardRectangleCount <= MESA_VK_MAX_DISCARD_RECTANGLES);
410      dr->rectangle_count = dr_info->discardRectangleCount;
411      typed_memcpy(dr->rectangles, dr_info->pDiscardRectangles,
412                   dr_info->discardRectangleCount);
413   }
414}
415
416static void
417vk_dynamic_graphics_state_init_dr(struct vk_dynamic_graphics_state *dst,
418                                  const BITSET_WORD *needed,
419                                  const struct vk_discard_rectangles_state *dr)
420{
421   dst->dr.rectangle_count = dr->rectangle_count;
422   typed_memcpy(dst->dr.rectangles, dr->rectangles, dr->rectangle_count);
423}
424
425static void
426vk_rasterization_state_init(struct vk_rasterization_state *rs,
427                            const BITSET_WORD *dynamic,
428                            const VkPipelineRasterizationStateCreateInfo *rs_info)
429{
430   *rs = (struct vk_rasterization_state) {
431      .rasterizer_discard_enable = false,
432      .conservative_mode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT,
433      .rasterization_order_amd = VK_RASTERIZATION_ORDER_STRICT_AMD,
434      .provoking_vertex = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT,
435      .line.mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
436   };
437
438   if (!IS_DYNAMIC(RS_RASTERIZER_DISCARD_ENABLE))
439      rs->rasterizer_discard_enable = rs_info->rasterizerDiscardEnable;
440
441   /* From the Vulkan 1.3.218 spec:
442    *
443    *    "If VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in
444    *    the graphics pipeline state then depth clipping is disabled if
445    *    VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable
446    *    is VK_FALSE. Otherwise, if
447    *    VkPipelineRasterizationDepthClipStateCreateInfoEXT is not present,
448    *    depth clipping is disabled when
449    *    VkPipelineRasterizationStateCreateInfo::depthClampEnable is VK_TRUE.
450    */
451   rs->depth_clamp_enable = rs_info->depthClampEnable;
452   rs->depth_clip_enable = !rs_info->depthClampEnable;
453
454   rs->polygon_mode = rs_info->polygonMode;
455
456   rs->cull_mode = rs_info->cullMode;
457   rs->front_face = rs_info->frontFace;
458   rs->depth_bias.enable = rs_info->depthBiasEnable;
459   if ((rs_info->depthBiasEnable || IS_DYNAMIC(RS_DEPTH_BIAS_ENABLE)) &&
460       !IS_DYNAMIC(RS_DEPTH_BIAS_FACTORS)) {
461      rs->depth_bias.constant = rs_info->depthBiasConstantFactor;
462      rs->depth_bias.clamp = rs_info->depthBiasClamp;
463      rs->depth_bias.slope = rs_info->depthBiasSlopeFactor;
464   }
465   rs->line.width = rs_info->lineWidth;
466
467   vk_foreach_struct_const(ext, rs_info->pNext) {
468      switch (ext->sType) {
469      case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT: {
470         const VkPipelineRasterizationConservativeStateCreateInfoEXT *rcs_info =
471            (const VkPipelineRasterizationConservativeStateCreateInfoEXT *)ext;
472         rs->conservative_mode = rcs_info->conservativeRasterizationMode;
473         break;
474      }
475
476      case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
477         const VkPipelineRasterizationDepthClipStateCreateInfoEXT *rdc_info =
478            (const VkPipelineRasterizationDepthClipStateCreateInfoEXT *)ext;
479         rs->depth_clip_enable = rdc_info->depthClipEnable;
480         break;
481      }
482
483      case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT: {
484         const VkPipelineRasterizationLineStateCreateInfoEXT *rl_info =
485            (const VkPipelineRasterizationLineStateCreateInfoEXT *)ext;
486         rs->line.mode = rl_info->lineRasterizationMode;
487         rs->line.stipple.enable = rl_info->stippledLineEnable;
488         if (rs->line.stipple.enable && !IS_DYNAMIC(RS_LINE_STIPPLE)) {
489            rs->line.stipple.factor = rl_info->lineStippleFactor;
490            rs->line.stipple.pattern = rl_info->lineStipplePattern;
491         }
492         break;
493      }
494
495      case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT: {
496         const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *rpv_info =
497            (const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *)ext;
498         rs->provoking_vertex = rpv_info->provokingVertexMode;
499         break;
500      }
501
502      case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: {
503         const VkPipelineRasterizationStateRasterizationOrderAMD *rro_info =
504            (const VkPipelineRasterizationStateRasterizationOrderAMD *)ext;
505         rs->rasterization_order_amd = rro_info->rasterizationOrder;
506         break;
507      }
508
509      case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT: {
510         const VkPipelineRasterizationStateStreamCreateInfoEXT *rss_info =
511            (const VkPipelineRasterizationStateStreamCreateInfoEXT *)ext;
512         rs->rasterization_stream = rss_info->rasterizationStream;
513         break;
514      }
515
516      default:
517         break;
518      }
519   }
520}
521
522static void
523vk_dynamic_graphics_state_init_rs(struct vk_dynamic_graphics_state *dst,
524                                  const BITSET_WORD *needed,
525                                  const struct vk_rasterization_state *rs)
526{
527   dst->rs.rasterizer_discard_enable = rs->rasterizer_discard_enable;
528   dst->rs.cull_mode = rs->cull_mode;
529   dst->rs.front_face = rs->front_face;
530   dst->rs.depth_bias.enable = rs->depth_bias.enable;
531   dst->rs.depth_bias.constant = rs->depth_bias.constant;
532   dst->rs.depth_bias.clamp = rs->depth_bias.clamp;
533   dst->rs.depth_bias.slope = rs->depth_bias.slope;
534   dst->rs.line.width = rs->line.width;
535   dst->rs.line.stipple.factor = rs->line.stipple.factor;
536   dst->rs.line.stipple.pattern = rs->line.stipple.pattern;
537}
538
539static void
540vk_fragment_shading_rate_state_init(
541   struct vk_fragment_shading_rate_state *fsr,
542   const BITSET_WORD *dynamic,
543   const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info)
544{
545   if (fsr_info != NULL) {
546      fsr->fragment_size = fsr_info->fragmentSize;
547      fsr->combiner_ops[0] = fsr_info->combinerOps[0];
548      fsr->combiner_ops[1] = fsr_info->combinerOps[1];
549   } else {
550      fsr->fragment_size = (VkExtent2D) { 1, 1 };
551      fsr->combiner_ops[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
552      fsr->combiner_ops[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
553   }
554}
555
556static void
557vk_dynamic_graphics_state_init_fsr(
558   struct vk_dynamic_graphics_state *dst,
559   const BITSET_WORD *needed,
560   const struct vk_fragment_shading_rate_state *fsr)
561{
562   dst->fsr = *fsr;
563}
564
565static void
566vk_sample_locations_state_init(struct vk_sample_locations_state *sl,
567                               const VkSampleLocationsInfoEXT *sl_info)
568{
569   sl->per_pixel = sl_info->sampleLocationsPerPixel;
570   sl->grid_size = sl_info->sampleLocationGridSize;
571
572   /* From the Vulkan 1.3.218 spec:
573    *
574    *    VUID-VkSampleLocationsInfoEXT-sampleLocationsCount-01527
575    *
576    *    "sampleLocationsCount must equal sampleLocationsPerPixel *
577    *    sampleLocationGridSize.width * sampleLocationGridSize.height"
578    */
579   assert(sl_info->sampleLocationsCount ==
580          sl_info->sampleLocationsPerPixel *
581          sl_info->sampleLocationGridSize.width *
582          sl_info->sampleLocationGridSize.height);
583
584   assert(sl_info->sampleLocationsCount <= MESA_VK_MAX_SAMPLE_LOCATIONS);
585   typed_memcpy(sl->locations, sl_info->pSampleLocations,
586                sl_info->sampleLocationsCount);
587}
588
589static void
590vk_multisample_state_init(struct vk_multisample_state *ms,
591                          const BITSET_WORD *dynamic,
592                          const VkPipelineMultisampleStateCreateInfo *ms_info)
593{
594   ms->rasterization_samples = ms_info->rasterizationSamples;
595   ms->sample_shading_enable = ms_info->sampleShadingEnable;
596   ms->min_sample_shading = ms_info->minSampleShading;
597
598   /* From the Vulkan 1.3.218 spec:
599    *
600    *    "If pSampleMask is NULL, it is treated as if the mask has all bits
601    *    set to 1."
602    */
603   ms->sample_mask = ms_info->pSampleMask ? *ms_info->pSampleMask : ~0;
604
605   ms->alpha_to_coverage_enable = ms_info->alphaToCoverageEnable;
606   ms->alpha_to_one_enable = ms_info->alphaToOneEnable;
607
608   /* These get filled in by vk_multisample_sample_locations_state_init() */
609   ms->sample_locations_enable = false;
610   ms->sample_locations = NULL;
611}
612
613static bool
614needs_sample_locations_state(
615   const BITSET_WORD *dynamic,
616   const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info)
617{
618   return !IS_DYNAMIC(MS_SAMPLE_LOCATIONS) &&
619          sl_info != NULL && sl_info->sampleLocationsEnable;
620}
621
622static void
623vk_multisample_sample_locations_state_init(
624   struct vk_multisample_state *ms,
625   struct vk_sample_locations_state *sl,
626   const BITSET_WORD *dynamic,
627   const VkPipelineMultisampleStateCreateInfo *ms_info,
628   const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info)
629{
630   ms->sample_locations_enable =
631      sl_info != NULL && sl_info->sampleLocationsEnable;
632
633   assert(ms->sample_locations == NULL);
634   if (!IS_DYNAMIC(MS_SAMPLE_LOCATIONS)) {
635      if (ms->sample_locations_enable) {
636         vk_sample_locations_state_init(sl, &sl_info->sampleLocationsInfo);
637         ms->sample_locations = sl;
638      } else {
639         /* Otherwise, pre-populate with the standard sample locations.  If
640          * the driver doesn't support standard sample locations, it probably
641          * doesn't support custom locations either and can completely ignore
642          * this state.
643          */
644         ms->sample_locations =
645            vk_standard_sample_locations_state(ms_info->rasterizationSamples);
646      }
647   }
648}
649
650static void
651vk_dynamic_graphics_state_init_ms(struct vk_dynamic_graphics_state *dst,
652                                  const BITSET_WORD *needed,
653                                  const struct vk_multisample_state *ms)
654{
655   if (IS_NEEDED(MS_SAMPLE_LOCATIONS))
656      *dst->ms.sample_locations = *ms->sample_locations;
657}
658
659static void
660vk_stencil_test_face_state_init(struct vk_stencil_test_face_state *face,
661                                const VkStencilOpState *info)
662{
663   face->op.fail = info->failOp;
664   face->op.pass = info->passOp;
665   face->op.depth_fail = info->depthFailOp;
666   face->op.compare = info->compareOp;
667   face->compare_mask = info->compareMask;
668   face->write_mask = info->writeMask;
669   face->reference = info->reference;
670}
671
672static void
673vk_depth_stencil_state_init(struct vk_depth_stencil_state *ds,
674                            const BITSET_WORD *dynamic,
675                            const VkPipelineDepthStencilStateCreateInfo *ds_info)
676{
677   memset(ds, 0, sizeof(*ds));
678
679   ds->depth.test_enable = ds_info->depthTestEnable;
680   ds->depth.write_enable = ds_info->depthWriteEnable;
681   ds->depth.compare_op = ds_info->depthCompareOp;
682   ds->depth.bounds_test.enable = ds_info->depthBoundsTestEnable;
683   ds->depth.bounds_test.min = ds_info->minDepthBounds;
684   ds->depth.bounds_test.max = ds_info->maxDepthBounds;
685
686   ds->stencil.test_enable = ds_info->stencilTestEnable;
687   ds->stencil.write_enable = true;
688   vk_stencil_test_face_state_init(&ds->stencil.front, &ds_info->front);
689   vk_stencil_test_face_state_init(&ds->stencil.back, &ds_info->back);
690}
691
692static void
693vk_dynamic_graphics_state_init_ds(struct vk_dynamic_graphics_state *dst,
694                                  const BITSET_WORD *needed,
695                                  const struct vk_depth_stencil_state *ds)
696{
697   dst->ds = *ds;
698}
699
700static bool
701optimize_stencil_face(struct vk_stencil_test_face_state *face,
702                      VkCompareOp depthCompareOp,
703                      bool consider_write_mask)
704{
705   /* If compareOp is ALWAYS then the stencil test will never fail and failOp
706    * will never happen.  Set failOp to KEEP in this case.
707    */
708   if (face->op.compare == VK_COMPARE_OP_ALWAYS)
709      face->op.fail = VK_STENCIL_OP_KEEP;
710
711   /* If compareOp is NEVER or depthCompareOp is NEVER then one of the depth
712    * or stencil tests will fail and passOp will never happen.
713    */
714   if (face->op.compare == VK_COMPARE_OP_NEVER ||
715       depthCompareOp == VK_COMPARE_OP_NEVER)
716      face->op.pass = VK_STENCIL_OP_KEEP;
717
718   /* If compareOp is NEVER or depthCompareOp is ALWAYS then either the
719    * stencil test will fail or the depth test will pass.  In either case,
720    * depthFailOp will never happen.
721    */
722   if (face->op.compare == VK_COMPARE_OP_NEVER ||
723       depthCompareOp == VK_COMPARE_OP_ALWAYS)
724      face->op.depth_fail = VK_STENCIL_OP_KEEP;
725
726   /* If the write mask is zero, nothing will be written to the stencil buffer
727    * so it's as if all operations are KEEP.
728    */
729   if (consider_write_mask && face->write_mask == 0) {
730      face->op.pass = VK_STENCIL_OP_KEEP;
731      face->op.fail = VK_STENCIL_OP_KEEP;
732      face->op.depth_fail = VK_STENCIL_OP_KEEP;
733   }
734
735   return face->op.fail != VK_STENCIL_OP_KEEP ||
736          face->op.depth_fail != VK_STENCIL_OP_KEEP ||
737          face->op.pass != VK_STENCIL_OP_KEEP;
738}
739
740void
741vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
742                                VkImageAspectFlags ds_aspects,
743                                bool consider_write_mask)
744{
745   /* stencil.write_enable is a dummy right now that should always be true */
746   assert(ds->stencil.write_enable);
747
748   /* From the Vulkan 1.3.221 spec:
749    *
750    *    "If there is no depth attachment then the depth test is skipped."
751    */
752   if (!(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
753      ds->depth.test_enable = false;
754
755   /* From the Vulkan 1.3.221 spec:
756    *
757    *    "...or if there is no stencil attachment, the coverage mask is
758    *    unmodified by this operation."
759    */
760   if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT))
761      ds->stencil.test_enable = false;
762
763   /* If the depth test is disabled, we won't be writing anything. Make sure we
764    * treat the test as always passing later on as well.
765    */
766   if (!ds->depth.test_enable) {
767      ds->depth.write_enable = false;
768      ds->depth.compare_op = VK_COMPARE_OP_ALWAYS;
769   }
770
771   /* If the stencil test is disabled, we won't be writing anything. Make sure
772    * we treat the test as always passing later on as well.
773    */
774   if (!ds->stencil.test_enable) {
775      ds->stencil.write_enable = false;
776      ds->stencil.front.op.compare = VK_COMPARE_OP_ALWAYS;
777      ds->stencil.back.op.compare = VK_COMPARE_OP_ALWAYS;
778   }
779
780   /* If the stencil test is enabled and always fails, then we will never get
781    * to the depth test so we can just disable the depth test entirely.
782    */
783   if (ds->stencil.test_enable &&
784       ds->stencil.front.op.compare == VK_COMPARE_OP_NEVER &&
785       ds->stencil.back.op.compare == VK_COMPARE_OP_NEVER) {
786      ds->depth.test_enable = false;
787      ds->depth.write_enable = false;
788   }
789
790   /* If depthCompareOp is EQUAL then the value we would be writing to the
791    * depth buffer is the same as the value that's already there so there's no
792    * point in writing it.
793    */
794   if (ds->depth.compare_op == VK_COMPARE_OP_EQUAL)
795      ds->depth.write_enable = false;
796
797   /* If the stencil ops are such that we don't actually ever modify the
798    * stencil buffer, we should disable writes.
799    */
800   if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op,
801                              consider_write_mask) &&
802       !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op,
803                              consider_write_mask))
804      ds->stencil.write_enable = false;
805
806   /* If the depth test always passes and we never write out depth, that's the
807    * same as if the depth test is disabled entirely.
808    */
809   if (ds->depth.compare_op == VK_COMPARE_OP_ALWAYS && !ds->depth.write_enable)
810      ds->depth.test_enable = false;
811
812   /* If the stencil test always passes and we never write out stencil, that's
813    * the same as if the stencil test is disabled entirely.
814    */
815   if (ds->stencil.front.op.compare == VK_COMPARE_OP_ALWAYS &&
816       ds->stencil.back.op.compare == VK_COMPARE_OP_ALWAYS &&
817       !ds->stencil.write_enable)
818      ds->stencil.test_enable = false;
819}
820
821static void
822vk_color_blend_state_init(struct vk_color_blend_state *cb,
823                          const BITSET_WORD *dynamic,
824                          const VkPipelineColorBlendStateCreateInfo *cb_info)
825{
826   memset(cb, 0, sizeof(*cb));
827
828   cb->logic_op_enable = cb_info->logicOpEnable;
829   cb->logic_op = cb_info->logicOp;
830
831   assert(cb_info->attachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
832   cb->attachment_count = cb_info->attachmentCount;
833   for (uint32_t a = 0; a < cb_info->attachmentCount; a++) {
834      const VkPipelineColorBlendAttachmentState *att =
835         &cb_info->pAttachments[a];
836
837      cb->attachments[a] = (struct vk_color_blend_attachment_state) {
838         .blend_enable = att->blendEnable,
839         .src_color_blend_factor = att->srcColorBlendFactor,
840         .dst_color_blend_factor = att->dstColorBlendFactor,
841         .src_alpha_blend_factor = att->srcAlphaBlendFactor,
842         .dst_alpha_blend_factor = att->dstAlphaBlendFactor,
843         .write_mask = att->colorWriteMask,
844         .color_blend_op = att->colorBlendOp,
845         .alpha_blend_op = att->alphaBlendOp,
846      };
847   }
848
849   for (uint32_t i = 0; i < 4; i++)
850      cb->blend_constants[i] = cb_info->blendConstants[i];
851
852   const VkPipelineColorWriteCreateInfoEXT *cw_info =
853      vk_find_struct_const(cb_info->pNext, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
854   if (cw_info != NULL) {
855      assert(cb_info->attachmentCount == cw_info->attachmentCount);
856      for (uint32_t a = 0; a < cw_info->attachmentCount; a++) {
857         if (cw_info->pColorWriteEnables[a])
858            cb->color_write_enables |= BITFIELD_BIT(a);
859      }
860   } else {
861      cb->color_write_enables = BITFIELD_MASK(cb_info->attachmentCount);
862   }
863}
864
865static void
866vk_dynamic_graphics_state_init_cb(struct vk_dynamic_graphics_state *dst,
867                                  const BITSET_WORD *needed,
868                                  const struct vk_color_blend_state *cb)
869{
870   dst->cb.logic_op = cb->logic_op;
871   dst->cb.color_write_enables = cb->color_write_enables;
872
873   if (IS_NEEDED(CB_BLEND_CONSTANTS))
874      typed_memcpy(dst->cb.blend_constants, cb->blend_constants, 4);
875}
876
877static bool
878vk_render_pass_state_is_complete(const struct vk_render_pass_state *rp)
879{
880   return rp->attachment_aspects != VK_IMAGE_ASPECT_METADATA_BIT;
881}
882
883static void
884vk_render_pass_state_init(struct vk_render_pass_state *rp,
885                          const struct vk_render_pass_state *old_rp,
886                          const VkGraphicsPipelineCreateInfo *info,
887                          const struct vk_subpass_info *sp_info,
888                          VkGraphicsPipelineLibraryFlagsEXT lib)
889{
890   /* If we already have render pass state and it has attachment info, then
891    * it's complete and we don't need a new one.
892    */
893   if (old_rp != NULL && vk_render_pass_state_is_complete(old_rp)) {
894      *rp = *old_rp;
895      return;
896   }
897
898   *rp = (struct vk_render_pass_state) {
899      .render_pass = info->renderPass,
900      .subpass = info->subpass,
901      .depth_attachment_format = VK_FORMAT_UNDEFINED,
902      .stencil_attachment_format = VK_FORMAT_UNDEFINED,
903   };
904
905   if (info->renderPass != VK_NULL_HANDLE && sp_info != NULL) {
906      rp->attachment_aspects = sp_info->attachment_aspects;
907      rp->view_mask = sp_info->view_mask;
908      return;
909   }
910
911   const VkPipelineRenderingCreateInfo *r_info =
912      vk_get_pipeline_rendering_create_info(info);
913
914   if (r_info == NULL)
915      return;
916
917   rp->view_mask = r_info->viewMask;
918
919   /* From the Vulkan 1.3.218 spec description of pre-rasterization state:
920    *
921    *    "Fragment shader state is defined by:
922    *    ...
923    *     * VkRenderPass and subpass parameter
924    *     * The viewMask parameter of VkPipelineRenderingCreateInfo (formats
925    *       are ignored)"
926    *
927    * The description of fragment shader state contains identical text.
928    *
929    * If we have a render pass then we have full information.  Even if we're
930    * dynamic-rendering-only, the presence of a render pass means the
931    * rendering info came from a vk_render_pass and is therefore complete.
932    * Otherwise, all we can grab is the view mask and we have to leave the
933    * rest for later.
934    */
935   if (info->renderPass == VK_NULL_HANDLE &&
936       !(lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
937      rp->attachment_aspects = VK_IMAGE_ASPECT_METADATA_BIT;
938      return;
939   }
940
941   assert(r_info->colorAttachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
942   rp->color_attachment_count = r_info->colorAttachmentCount;
943   for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) {
944      rp->color_attachment_formats[i] = r_info->pColorAttachmentFormats[i];
945      if (r_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED)
946         rp->attachment_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
947   }
948
949   rp->depth_attachment_format = r_info->depthAttachmentFormat;
950   if (r_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED)
951      rp->attachment_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
952
953   rp->stencil_attachment_format = r_info->stencilAttachmentFormat;
954   if (r_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)
955      rp->attachment_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
956
957   const VkRenderingSelfDependencyInfoMESA *rsd_info =
958      vk_find_struct_const(r_info->pNext, RENDERING_SELF_DEPENDENCY_INFO_MESA);
959   if (rsd_info != NULL) {
960      STATIC_ASSERT(sizeof(rp->color_self_dependencies) * 8 >=
961                    MESA_VK_MAX_COLOR_ATTACHMENTS);
962      rp->color_self_dependencies = rsd_info->colorSelfDependencies;
963      rp->depth_self_dependency = rsd_info->depthSelfDependency;
964      rp->stencil_self_dependency = rsd_info->stencilSelfDependency;
965   }
966}
967
968static void
969vk_dynamic_graphics_state_init_rp(struct vk_dynamic_graphics_state *dst,
970                                  const BITSET_WORD *needed,
971                                  const struct vk_render_pass_state *rp)
972{ }
973
974#define FOREACH_STATE_GROUP(f)                           \
975   f(MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT,            \
976     vk_vertex_input_state, vi);                         \
977   f(MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT,          \
978     vk_input_assembly_state, ia);                       \
979   f(MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT,            \
980     vk_tessellation_state, ts);                         \
981   f(MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT,                \
982     vk_viewport_state, vp);                             \
983   f(MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT,      \
984     vk_discard_rectangles_state, dr);                   \
985   f(MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT,           \
986     vk_rasterization_state, rs);                        \
987   f(MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT,   \
988     vk_fragment_shading_rate_state, fsr);               \
989   f(MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT,             \
990     vk_multisample_state, ms);                          \
991   f(MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT,           \
992     vk_depth_stencil_state, ds);                        \
993   f(MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT,             \
994     vk_color_blend_state, cb);                          \
995   f(MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT,             \
996     vk_render_pass_state, rp);
997
998static enum mesa_vk_graphics_state_groups
999vk_graphics_pipeline_state_groups(const struct vk_graphics_pipeline_state *state)
1000{
1001   /* For now, we just validate dynamic state */
1002   enum mesa_vk_graphics_state_groups groups = 0;
1003
1004#define FILL_HAS(STATE, type, s) \
1005   if (state->s != NULL) groups |= STATE
1006
1007   FOREACH_STATE_GROUP(FILL_HAS)
1008
1009#undef FILL_HAS
1010
1011   return groups | fully_dynamic_state_groups(state->dynamic);
1012}
1013
1014static void
1015vk_graphics_pipeline_state_validate(const struct vk_graphics_pipeline_state *state)
1016{
1017#ifndef NDEBUG
1018   /* For now, we just validate dynamic state */
1019   enum mesa_vk_graphics_state_groups groups =
1020      vk_graphics_pipeline_state_groups(state);
1021   validate_dynamic_state_groups(state->dynamic, groups);
1022#endif
1023}
1024
1025static bool
1026may_have_rasterization(const struct vk_graphics_pipeline_state *state,
1027                       const BITSET_WORD *dynamic,
1028                       const VkGraphicsPipelineCreateInfo *info)
1029{
1030   if (state->rs) {
1031      /* We default rasterizer_discard_enable to false when dynamic */
1032      return !state->rs->rasterizer_discard_enable;
1033   } else {
1034      return IS_DYNAMIC(RS_RASTERIZER_DISCARD_ENABLE) ||
1035             !info->pRasterizationState->rasterizerDiscardEnable;
1036   }
1037}
1038
1039VkResult
1040vk_graphics_pipeline_state_fill(const struct vk_device *device,
1041                                struct vk_graphics_pipeline_state *state,
1042                                const VkGraphicsPipelineCreateInfo *info,
1043                                const struct vk_subpass_info *sp_info,
1044                                struct vk_graphics_pipeline_all_state *all,
1045                                const VkAllocationCallbacks *alloc,
1046                                VkSystemAllocationScope scope,
1047                                void **alloc_ptr_out)
1048{
1049   vk_graphics_pipeline_state_validate(state);
1050
1051   BITSET_DECLARE(dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1052   vk_get_dynamic_graphics_states(dynamic, info->pDynamicState);
1053
1054   for (uint32_t i = 0; i < info->stageCount; i++)
1055      state->shader_stages |= info->pStages[i].stage;
1056
1057   /* In case we return early */
1058   if (alloc_ptr_out != NULL)
1059      *alloc_ptr_out = NULL;
1060
1061   /*
1062    * First, figure out which library-level shader/state groups we need
1063    */
1064
1065   VkGraphicsPipelineLibraryFlagsEXT lib;
1066   if (info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) {
1067      const VkGraphicsPipelineLibraryCreateInfoEXT *gfx_lib_info =
1068         vk_find_struct_const(info->pNext, GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
1069      lib = gfx_lib_info->flags;
1070   } else {
1071      /* We're building a complete pipeline.  From the Vulkan 1.3.218 spec:
1072       *
1073       *    "A complete graphics pipeline always includes pre-rasterization
1074       *    shader state, with other subsets included depending on that state.
1075       *    If the pre-rasterization shader state includes a vertex shader,
1076       *    then vertex input state is included in a complete graphics
1077       *    pipeline. If the value of
1078       *    VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable in
1079       *    the pre-rasterization shader state is VK_FALSE or the
1080       *    VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE dynamic state is
1081       *    enabled fragment shader state and fragment output interface state
1082       *    is included in a complete graphics pipeline."
1083       */
1084      lib = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
1085
1086      if (state->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
1087         lib |= VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
1088
1089      if (may_have_rasterization(state, dynamic, info)) {
1090         lib |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
1091         lib |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
1092      }
1093   }
1094
1095   /*
1096    * Next, turn those into individual states.  Among other things, this
1097    * de-duplicates things like FSR and multisample state which appear in
1098    * multiple library groups.
1099    */
1100
1101   enum mesa_vk_graphics_state_groups needs = 0;
1102   if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) {
1103      needs |= MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT;
1104      needs |= MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT;
1105   }
1106
1107   /* Other stuff potentially depends on this so gather it early */
1108   struct vk_render_pass_state rp;
1109   if (lib & (VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
1110              VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
1111              VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
1112      vk_render_pass_state_init(&rp, state->rp, info, sp_info, lib);
1113
1114      needs |= MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT;
1115
1116      /* If the old state was incomplete but the new one isn't, set state->rp
1117       * to NULL so it gets replaced with the new version.
1118       */
1119      if (state->rp != NULL &&
1120          !vk_render_pass_state_is_complete(state->rp) &&
1121          vk_render_pass_state_is_complete(&rp))
1122         state->rp = NULL;
1123   }
1124
1125   if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) {
1126      /* From the Vulkan 1.3.218 spec:
1127       *
1128       *    VUID-VkGraphicsPipelineCreateInfo-stage-02096
1129       *
1130       *    "If the pipeline is being created with pre-rasterization shader
1131       *    state the stage member of one element of pStages must be either
1132       *    VK_SHADER_STAGE_VERTEX_BIT or VK_SHADER_STAGE_MESH_BIT_NV"
1133       */
1134      assert(state->shader_stages & (VK_SHADER_STAGE_VERTEX_BIT |
1135                                     VK_SHADER_STAGE_MESH_BIT_NV));
1136
1137      if (state->shader_stages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
1138                                  VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
1139         needs |= MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT;
1140
1141      if (may_have_rasterization(state, dynamic, info))
1142         needs |= MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT;
1143
1144      needs |= MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT;
1145      needs |= MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT;
1146      needs |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT;
1147   }
1148
1149   if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
1150      needs |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT;
1151
1152      /* From the Vulkan 1.3.218 spec:
1153       *
1154       *    "Fragment shader state is defined by:
1155       *    ...
1156       *     - VkPipelineMultisampleStateCreateInfo if sample shading is
1157       *       enabled or renderpass is not VK_NULL_HANDLE"
1158       *
1159       * and
1160       *
1161       *    VUID-VkGraphicsPipelineCreateInfo-pMultisampleState-06629
1162       *
1163       *    "If the pipeline is being created with fragment shader state
1164       *    pMultisampleState must be NULL or a valid pointer to a valid
1165       *    VkPipelineMultisampleStateCreateInfo structure"
1166       *
1167       * so we can reliably detect when to include it based on the
1168       * pMultisampleState pointer.
1169       */
1170      if (info->pMultisampleState != NULL)
1171         needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT;
1172
1173      /* From the Vulkan 1.3.218 spec:
1174       *
1175       *    VUID-VkGraphicsPipelineCreateInfo-renderPass-06043
1176       *
1177       *    "If renderPass is not VK_NULL_HANDLE, the pipeline is being
1178       *    created with fragment shader state, and subpass uses a
1179       *    depth/stencil attachment, pDepthStencilState must be a valid
1180       *    pointer to a valid VkPipelineDepthStencilStateCreateInfo
1181       *    structure"
1182       *
1183       *    VUID-VkGraphicsPipelineCreateInfo-renderPass-06053
1184       *
1185       *    "If renderPass is VK_NULL_HANDLE, the pipeline is being created
1186       *    with fragment shader state and fragment output interface state,
1187       *    and either of VkPipelineRenderingCreateInfo::depthAttachmentFormat
1188       *    or VkPipelineRenderingCreateInfo::stencilAttachmentFormat are not
1189       *    VK_FORMAT_UNDEFINED, pDepthStencilState must be a valid pointer to
1190       *    a valid VkPipelineDepthStencilStateCreateInfo structure"
1191       *
1192       *    VUID-VkGraphicsPipelineCreateInfo-renderPass-06590
1193       *
1194       *    "If renderPass is VK_NULL_HANDLE and the pipeline is being created
1195       *    with fragment shader state but not fragment output interface
1196       *    state, pDepthStencilState must be a valid pointer to a valid
1197       *    VkPipelineDepthStencilStateCreateInfo structure"
1198       *
1199       * In the first case, we'll have a real set of aspects in rp.  In the
1200       * second case, where we have both fragment shader and fragment output
1201       * state, we will also have a valid set of aspects.  In the third case
1202       * where we only have fragment shader state and no render pass, the
1203       * vk_render_pass_state will be incomplete.
1204       */
1205      if ((rp.attachment_aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
1206                                    VK_IMAGE_ASPECT_STENCIL_BIT)) ||
1207          !vk_render_pass_state_is_complete(&rp))
1208         needs |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT;
1209   }
1210
1211   if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) {
1212      if (rp.attachment_aspects & (VK_IMAGE_ASPECT_COLOR_BIT))
1213         needs |= MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT;
1214
1215      needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT;
1216   }
1217
1218   /*
1219    * Next, Filter off any states we already have.
1220    */
1221
1222#define FILTER_NEEDS(STATE, type, s) \
1223   if (state->s != NULL) needs &= ~STATE
1224
1225   FOREACH_STATE_GROUP(FILTER_NEEDS)
1226
1227#undef FILTER_NEEDS
1228
1229   /* Filter dynamic state down to just what we're adding */
1230   BITSET_DECLARE(dynamic_filter, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1231   get_dynamic_state_groups(dynamic_filter, needs);
1232   BITSET_AND(dynamic, dynamic, dynamic_filter);
1233
1234   /* And add it in */
1235   BITSET_OR(state->dynamic, state->dynamic, dynamic);
1236
1237   /*
1238    * If a state is fully dynamic, we don't need to even allocate them.  Do
1239    * this after we've filtered dynamic state because we still want them to
1240    * show up in the dynamic state but don't want the actual state.
1241    */
1242   needs &= ~fully_dynamic_state_groups(state->dynamic);
1243
1244   /* If we don't need to set up any new states, bail early */
1245   if (needs == 0)
1246      return VK_SUCCESS;
1247
1248   /*
1249    * Now, ensure that we have space for each of the states we're going to
1250    * fill.  If all != NULL, we'll pull from that.  Otherwise, we need to
1251    * allocate memory.
1252    */
1253
1254   VK_MULTIALLOC(ma);
1255
1256#define ENSURE_STATE_IF_NEEDED(STATE, type, s) \
1257   struct type *new_##s = NULL; \
1258   if (needs & STATE) { \
1259      if (all == NULL) { \
1260         vk_multialloc_add(&ma, &new_##s, struct type, 1); \
1261      } else { \
1262         new_##s = &all->s; \
1263      } \
1264   }
1265
1266   FOREACH_STATE_GROUP(ENSURE_STATE_IF_NEEDED)
1267
1268#undef ENSURE_STATE_IF_NEEDED
1269
1270   /* Sample locations are a bit special.  We don't want to waste the memory
1271    * for 64 floats if we don't need to.  Also, we set up standard sample
1272    * locations if no user-provided sample locations are available.
1273    */
1274   const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info = NULL;
1275   struct vk_sample_locations_state *new_sl = NULL;
1276   if (needs & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) {
1277      sl_info = vk_find_struct_const(info->pMultisampleState->pNext,
1278                                     PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT);
1279      if (needs_sample_locations_state(dynamic, sl_info)) {
1280         if (all == NULL) {
1281            vk_multialloc_add(&ma, &new_sl, struct vk_sample_locations_state, 1);
1282         } else {
1283            new_sl = &all->ms_sample_locations;
1284         }
1285      }
1286   }
1287
1288   /*
1289    * Allocate memory, if needed
1290    */
1291
1292   if (ma.size > 0) {
1293      assert(all == NULL);
1294      *alloc_ptr_out = vk_multialloc_alloc2(&ma, &device->alloc, alloc, scope);
1295      if (*alloc_ptr_out == NULL)
1296         return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1297   }
1298
1299   /*
1300    * Create aliases for various input infos so we can use or FOREACH macro
1301    */
1302
1303#define INFO_ALIAS(_State, s) \
1304   const VkPipeline##_State##StateCreateInfo *s##_info = info->p##_State##State
1305
1306   INFO_ALIAS(VertexInput, vi);
1307   INFO_ALIAS(InputAssembly, ia);
1308   INFO_ALIAS(Tessellation, ts);
1309   INFO_ALIAS(Viewport, vp);
1310   INFO_ALIAS(Rasterization, rs);
1311   INFO_ALIAS(Multisample, ms);
1312   INFO_ALIAS(DepthStencil, ds);
1313   INFO_ALIAS(ColorBlend, cb);
1314
1315#undef INFO_ALIAS
1316
1317   const VkPipelineDiscardRectangleStateCreateInfoEXT *dr_info =
1318      vk_find_struct_const(info->pNext, PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT);
1319
1320   const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info =
1321      vk_find_struct_const(info->pNext, PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR);
1322
1323   /*
1324    * Finally, fill out all the states
1325    */
1326
1327#define INIT_STATE_IF_NEEDED(STATE, type, s) \
1328   if (needs & STATE) { \
1329      type##_init(new_##s, dynamic, s##_info); \
1330      state->s = new_##s; \
1331   }
1332
1333   /* render pass state is special and we just copy it */
1334#define vk_render_pass_state_init(s, d, i) *s = rp
1335
1336   FOREACH_STATE_GROUP(INIT_STATE_IF_NEEDED)
1337
1338#undef vk_render_pass_state_init
1339#undef INIT_STATE_IF_NEEDED
1340
1341   if (needs & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) {
1342       vk_multisample_sample_locations_state_init(new_ms, new_sl, dynamic,
1343                                                  ms_info, sl_info);
1344   }
1345
1346   return VK_SUCCESS;
1347}
1348
1349#undef IS_DYNAMIC
1350#undef IS_NEEDED
1351
1352void
1353vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst,
1354                                 const struct vk_graphics_pipeline_state *src)
1355{
1356   vk_graphics_pipeline_state_validate(dst);
1357   vk_graphics_pipeline_state_validate(src);
1358
1359   BITSET_OR(dst->dynamic, dst->dynamic, src->dynamic);
1360
1361   dst->shader_stages |= src->shader_stages;
1362
1363   /* Render pass state needs special care because a render pass state may be
1364    * incomplete (view mask only).  See vk_render_pass_state_init().
1365    */
1366   if (dst->rp != NULL && src->rp != NULL &&
1367       !vk_render_pass_state_is_complete(dst->rp) &&
1368       vk_render_pass_state_is_complete(src->rp))
1369      dst->rp = src->rp;
1370
1371#define MERGE(STATE, type, state) \
1372   if (dst->state == NULL && src->state != NULL) dst->state = src->state;
1373
1374   FOREACH_STATE_GROUP(MERGE)
1375
1376#undef MERGE
1377}
1378
1379const struct vk_dynamic_graphics_state vk_default_dynamic_graphics_state = {
1380   .rs = {
1381      .line = {
1382         .width = 1.0f,
1383      },
1384   },
1385   .fsr = {
1386      .fragment_size = {1u, 1u},
1387      .combiner_ops = {
1388         VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1389         VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1390      },
1391   },
1392   .ds = {
1393      .depth = {
1394         .bounds_test = {
1395            .min = 0.0f,
1396            .max = 1.0f,
1397         },
1398      },
1399      .stencil = {
1400         .write_enable = true,
1401         .front = {
1402            .compare_mask = -1,
1403            .write_mask = -1,
1404         },
1405         .back = {
1406            .compare_mask = -1,
1407            .write_mask = -1,
1408         },
1409      },
1410   },
1411   .cb = {
1412      .color_write_enables = 0xffffffffu,
1413   },
1414};
1415
1416void
1417vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn)
1418{
1419   *dyn = vk_default_dynamic_graphics_state;
1420}
1421
1422void
1423vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn)
1424{
1425   struct vk_vertex_input_state *vi = dyn->vi;
1426   struct vk_sample_locations_state *sl = dyn->ms.sample_locations;
1427
1428   *dyn = vk_default_dynamic_graphics_state;
1429
1430   if (vi != NULL) {
1431      memset(vi, 0, sizeof(*vi));
1432      dyn->vi = vi;
1433   }
1434
1435   if (sl != NULL) {
1436      memset(sl, 0, sizeof(*sl));
1437      dyn->ms.sample_locations = sl;
1438   }
1439}
1440
1441void
1442vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn,
1443                               const struct vk_graphics_pipeline_state *p)
1444{
1445   /* This funciton (and the individual vk_dynamic_graphics_state_init_*
1446    * functions it calls) are a bit sloppy.  Instead of checking every single
1447    * bit, we just copy everything and set the bits the right way at the end
1448    * based on what groups we actually had.
1449    */
1450   enum mesa_vk_graphics_state_groups groups = 0;
1451
1452   BITSET_DECLARE(needed, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1453   BITSET_COPY(needed, p->dynamic);
1454   BITSET_NOT(needed);
1455
1456   /* We only want to copy these if the driver has filled out the relevant
1457    * pointer in the dynamic state struct.  If not, they don't support them
1458    * as dynamic state and we should leave them alone.
1459    */
1460   if (dyn->vi == NULL)
1461      BITSET_CLEAR(needed, MESA_VK_DYNAMIC_VI);
1462   if (dyn->ms.sample_locations == NULL)
1463      BITSET_CLEAR(needed, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS);
1464
1465#define INIT_DYNAMIC_STATE(STATE, type, s) \
1466   if (p->s != NULL) { \
1467      vk_dynamic_graphics_state_init_##s(dyn, needed, p->s); \
1468      groups |= STATE; \
1469   }
1470
1471   FOREACH_STATE_GROUP(INIT_DYNAMIC_STATE);
1472
1473#undef INIT_DYNAMIC_STATE
1474
1475   /* Mask off all but the groups we actually found */
1476   get_dynamic_state_groups(dyn->set, groups);
1477   BITSET_AND(dyn->set, dyn->set, needed);
1478}
1479
1480#define SET_DYN_VALUE(dst, STATE, state, value) do {        \
1481   if (!BITSET_TEST((dst)->set, MESA_VK_DYNAMIC_##STATE) || \
1482       (dst)->state != (value)) {                           \
1483      (dst)->state = (value);                               \
1484      assert((dst)->state == (value));                      \
1485      BITSET_SET(dst->set, MESA_VK_DYNAMIC_##STATE);        \
1486      BITSET_SET(dst->dirty, MESA_VK_DYNAMIC_##STATE);      \
1487   }                                                        \
1488} while(0)
1489
1490#define SET_DYN_BOOL(dst, STATE, state, value) \
1491   SET_DYN_VALUE(dst, STATE, state, (bool)value);
1492
1493#define SET_DYN_ARRAY(dst, STATE, state, start, count, src) do {  \
1494   assert(start + count <= ARRAY_SIZE((dst)->state));             \
1495   STATIC_ASSERT(sizeof(*(dst)->state) == sizeof(*(src)));        \
1496   const size_t __state_size = sizeof(*(dst)->state) * (count);   \
1497   if (!BITSET_TEST((dst)->set, MESA_VK_DYNAMIC_##STATE) ||       \
1498       memcmp((dst)->state + start, src, __state_size)) {         \
1499      memcpy((dst)->state + start, src, __state_size);            \
1500      BITSET_SET(dst->set, MESA_VK_DYNAMIC_##STATE);              \
1501      BITSET_SET(dst->dirty, MESA_VK_DYNAMIC_##STATE);            \
1502   }                                                              \
1503} while(0)
1504
1505void
1506vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst,
1507                               const struct vk_dynamic_graphics_state *src)
1508{
1509#define IS_SET_IN_SRC(STATE) \
1510   BITSET_TEST(src->set, MESA_VK_DYNAMIC_##STATE)
1511
1512#define COPY_MEMBER(STATE, state) \
1513   SET_DYN_VALUE(dst, STATE, state, src->state)
1514
1515#define COPY_ARRAY(STATE, state, count) \
1516   SET_DYN_ARRAY(dst, STATE, state, 0, count, src->state)
1517
1518#define COPY_IF_SET(STATE, state) \
1519   if (IS_SET_IN_SRC(STATE)) SET_DYN_VALUE(dst, STATE, state, src->state)
1520
1521   assert((dst->vi != NULL) == (src->vi != NULL));
1522   if (dst->vi != NULL && IS_SET_IN_SRC(VI)) {
1523      COPY_MEMBER(VI, vi->bindings_valid);
1524      u_foreach_bit(b, src->vi->bindings_valid) {
1525         COPY_MEMBER(VI, vi->bindings[b].stride);
1526         COPY_MEMBER(VI, vi->bindings[b].input_rate);
1527         COPY_MEMBER(VI, vi->bindings[b].divisor);
1528      }
1529      COPY_MEMBER(VI, vi->attributes_valid);
1530      u_foreach_bit(a, src->vi->attributes_valid) {
1531         COPY_MEMBER(VI, vi->attributes[a].binding);
1532         COPY_MEMBER(VI, vi->attributes[a].format);
1533         COPY_MEMBER(VI, vi->attributes[a].offset);
1534      }
1535   }
1536
1537   if (IS_SET_IN_SRC(VI_BINDING_STRIDES)) {
1538      COPY_ARRAY(VI_BINDING_STRIDES, vi_binding_strides,
1539                 MESA_VK_MAX_VERTEX_BINDINGS);
1540   }
1541
1542   COPY_IF_SET(IA_PRIMITIVE_TOPOLOGY, ia.primitive_topology);
1543   COPY_IF_SET(IA_PRIMITIVE_RESTART_ENABLE, ia.primitive_restart_enable);
1544   COPY_IF_SET(TS_PATCH_CONTROL_POINTS, ts.patch_control_points);
1545
1546   COPY_IF_SET(VP_VIEWPORT_COUNT, vp.viewport_count);
1547   if (IS_SET_IN_SRC(VP_VIEWPORTS)) {
1548      assert(IS_SET_IN_SRC(VP_VIEWPORT_COUNT));
1549      COPY_ARRAY(VP_VIEWPORTS, vp.viewports, src->vp.viewport_count);
1550   }
1551
1552   COPY_IF_SET(VP_SCISSOR_COUNT, vp.scissor_count);
1553   if (IS_SET_IN_SRC(VP_SCISSORS)) {
1554      assert(IS_SET_IN_SRC(VP_SCISSOR_COUNT));
1555      COPY_ARRAY(VP_SCISSORS, vp.scissors, src->vp.scissor_count);
1556   }
1557
1558   if (IS_SET_IN_SRC(DR_RECTANGLES)) {
1559      COPY_MEMBER(DR_RECTANGLES, dr.rectangle_count);
1560      COPY_ARRAY(DR_RECTANGLES, dr.rectangles, src->dr.rectangle_count);
1561   }
1562
1563   COPY_IF_SET(RS_RASTERIZER_DISCARD_ENABLE, rs.rasterizer_discard_enable);
1564   COPY_IF_SET(RS_CULL_MODE, rs.cull_mode);
1565   COPY_IF_SET(RS_FRONT_FACE, rs.front_face);
1566   COPY_IF_SET(RS_DEPTH_BIAS_ENABLE, rs.depth_bias.enable);
1567   COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.constant);
1568   COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.clamp);
1569   COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.slope);
1570   COPY_IF_SET(RS_LINE_WIDTH, rs.line.width);
1571   COPY_IF_SET(RS_LINE_STIPPLE, rs.line.stipple.factor);
1572   COPY_IF_SET(RS_LINE_STIPPLE, rs.line.stipple.pattern);
1573
1574   COPY_IF_SET(FSR, fsr.fragment_size.width);
1575   COPY_IF_SET(FSR, fsr.fragment_size.height);
1576   COPY_IF_SET(FSR, fsr.combiner_ops[0]);
1577   COPY_IF_SET(FSR, fsr.combiner_ops[1]);
1578
1579   assert((dst->ms.sample_locations == NULL) ==
1580          (src->ms.sample_locations == NULL));
1581   if (dst->ms.sample_locations != NULL &&
1582       IS_SET_IN_SRC(MS_SAMPLE_LOCATIONS)) {
1583      COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->per_pixel);
1584      COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->grid_size.width);
1585      COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->grid_size.height);
1586      const uint32_t sl_count = src->ms.sample_locations->per_pixel *
1587                                src->ms.sample_locations->grid_size.width *
1588                                src->ms.sample_locations->grid_size.height;
1589      COPY_ARRAY(MS_SAMPLE_LOCATIONS, ms.sample_locations->locations, sl_count);
1590   }
1591
1592   COPY_IF_SET(DS_DEPTH_TEST_ENABLE, ds.depth.test_enable);
1593   COPY_IF_SET(DS_DEPTH_WRITE_ENABLE, ds.depth.write_enable);
1594   COPY_IF_SET(DS_DEPTH_COMPARE_OP, ds.depth.compare_op);
1595   COPY_IF_SET(DS_DEPTH_BOUNDS_TEST_ENABLE, ds.depth.bounds_test.enable);
1596   if (IS_SET_IN_SRC(DS_DEPTH_BOUNDS_TEST_BOUNDS)) {
1597      COPY_MEMBER(DS_DEPTH_BOUNDS_TEST_BOUNDS, ds.depth.bounds_test.min);
1598      COPY_MEMBER(DS_DEPTH_BOUNDS_TEST_BOUNDS, ds.depth.bounds_test.max);
1599   }
1600
1601   COPY_IF_SET(DS_STENCIL_TEST_ENABLE, ds.stencil.test_enable);
1602   if (IS_SET_IN_SRC(DS_STENCIL_OP)) {
1603      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.fail);
1604      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.pass);
1605      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.depth_fail);
1606      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.compare);
1607      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.fail);
1608      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.pass);
1609      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.depth_fail);
1610      COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.compare);
1611   }
1612   if (IS_SET_IN_SRC(DS_STENCIL_COMPARE_MASK)) {
1613      COPY_MEMBER(DS_STENCIL_COMPARE_MASK, ds.stencil.front.compare_mask);
1614      COPY_MEMBER(DS_STENCIL_COMPARE_MASK, ds.stencil.back.compare_mask);
1615   }
1616   if (IS_SET_IN_SRC(DS_STENCIL_WRITE_MASK)) {
1617      COPY_MEMBER(DS_STENCIL_WRITE_MASK, ds.stencil.front.write_mask);
1618      COPY_MEMBER(DS_STENCIL_WRITE_MASK, ds.stencil.back.write_mask);
1619   }
1620   if (IS_SET_IN_SRC(DS_STENCIL_REFERENCE)) {
1621      COPY_MEMBER(DS_STENCIL_REFERENCE, ds.stencil.front.reference);
1622      COPY_MEMBER(DS_STENCIL_REFERENCE, ds.stencil.back.reference);
1623   }
1624
1625   COPY_IF_SET(CB_LOGIC_OP, cb.logic_op);
1626   COPY_IF_SET(CB_COLOR_WRITE_ENABLES, cb.color_write_enables);
1627   if (IS_SET_IN_SRC(CB_BLEND_CONSTANTS))
1628      COPY_ARRAY(CB_BLEND_CONSTANTS, cb.blend_constants, 4);
1629
1630#undef IS_SET_IN_SRC
1631#undef MARK_DIRTY
1632#undef COPY_MEMBER
1633#undef COPY_ARRAY
1634#undef COPY_IF_SET
1635
1636   for (uint32_t w = 0; w < ARRAY_SIZE(dst->dirty); w++) {
1637      /* If it's in the source but isn't set in the destination at all, mark
1638       * it dirty.  It's possible that the default values just happen to equal
1639       * the value from src.
1640       */
1641      dst->dirty[w] |= src->set[w] & ~dst->set[w];
1642
1643      /* Everything that was in the source is now in the destination */
1644      dst->set[w] |= src->set[w];
1645   }
1646}
1647
1648void
1649vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer *cmd,
1650                                  const struct vk_dynamic_graphics_state *state)
1651{
1652   vk_dynamic_graphics_state_copy(&cmd->dynamic_graphics_state, state);
1653}
1654
1655VKAPI_ATTR void VKAPI_CALL
1656vk_common_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer,
1657   uint32_t vertexBindingDescriptionCount,
1658   const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions,
1659   uint32_t vertexAttributeDescriptionCount,
1660   const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions)
1661{
1662   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1663   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1664
1665   uint32_t bindings_valid = 0;
1666   for (uint32_t i = 0; i < vertexBindingDescriptionCount; i++) {
1667      const VkVertexInputBindingDescription2EXT *desc =
1668         &pVertexBindingDescriptions[i];
1669
1670      assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
1671      assert(desc->stride <= MESA_VK_MAX_VERTEX_BINDING_STRIDE);
1672      assert(desc->inputRate <= UINT8_MAX);
1673
1674      const uint32_t b = desc->binding;
1675      bindings_valid |= BITFIELD_BIT(b);
1676      SET_DYN_VALUE(dyn, VI, vi->bindings[b].stride, desc->stride);
1677      SET_DYN_VALUE(dyn, VI, vi->bindings[b].input_rate, desc->inputRate);
1678      SET_DYN_VALUE(dyn, VI, vi->bindings[b].divisor, desc->divisor);
1679
1680      /* Also set bindings_strides in case a driver is keying off that */
1681      SET_DYN_VALUE(dyn, VI_BINDING_STRIDES,
1682                    vi_binding_strides[b], desc->stride);
1683   }
1684   SET_DYN_VALUE(dyn, VI, vi->bindings_valid, bindings_valid);
1685
1686   uint32_t attributes_valid = 0;
1687   for (uint32_t i = 0; i < vertexAttributeDescriptionCount; i++) {
1688      const VkVertexInputAttributeDescription2EXT *desc =
1689         &pVertexAttributeDescriptions[i];
1690
1691      assert(desc->location < MESA_VK_MAX_VERTEX_ATTRIBUTES);
1692      assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
1693      assert(bindings_valid & BITFIELD_BIT(desc->binding));
1694
1695      const uint32_t a = desc->location;
1696      attributes_valid |= BITFIELD_BIT(a);
1697      SET_DYN_VALUE(dyn, VI, vi->attributes[a].binding, desc->binding);
1698      SET_DYN_VALUE(dyn, VI, vi->attributes[a].format, desc->format);
1699      SET_DYN_VALUE(dyn, VI, vi->attributes[a].offset, desc->offset);
1700   }
1701   SET_DYN_VALUE(dyn, VI, vi->attributes_valid, attributes_valid);
1702}
1703
1704void
1705vk_cmd_set_vertex_binding_strides(struct vk_command_buffer *cmd,
1706                                  uint32_t first_binding,
1707                                  uint32_t binding_count,
1708                                  const VkDeviceSize *strides)
1709{
1710   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1711
1712   for (uint32_t i = 0; i < binding_count; i++) {
1713      SET_DYN_VALUE(dyn, VI_BINDING_STRIDES,
1714                    vi_binding_strides[first_binding + i], strides[i]);
1715   }
1716}
1717
1718VKAPI_ATTR void VKAPI_CALL
1719vk_common_CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,
1720                                  VkPrimitiveTopology primitiveTopology)
1721{
1722   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1723   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1724
1725   SET_DYN_VALUE(dyn, IA_PRIMITIVE_TOPOLOGY,
1726                 ia.primitive_topology, primitiveTopology);
1727}
1728
1729VKAPI_ATTR void VKAPI_CALL
1730vk_common_CmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,
1731                                       VkBool32 primitiveRestartEnable)
1732{
1733   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1734   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1735
1736   SET_DYN_BOOL(dyn, IA_PRIMITIVE_RESTART_ENABLE,
1737                ia.primitive_restart_enable, primitiveRestartEnable);
1738}
1739
1740VKAPI_ATTR void VKAPI_CALL
1741vk_common_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
1742                                      uint32_t patchControlPoints)
1743{
1744   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1745   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1746
1747   SET_DYN_VALUE(dyn, TS_PATCH_CONTROL_POINTS,
1748                 ts.patch_control_points, patchControlPoints);
1749}
1750
1751VKAPI_ATTR void VKAPI_CALL
1752vk_common_CmdSetViewport(VkCommandBuffer commandBuffer,
1753                         uint32_t firstViewport,
1754                         uint32_t viewportCount,
1755                         const VkViewport *pViewports)
1756{
1757   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1758   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1759
1760   SET_DYN_ARRAY(dyn, VP_VIEWPORTS, vp.viewports,
1761                 firstViewport, viewportCount, pViewports);
1762}
1763
1764VKAPI_ATTR void VKAPI_CALL
1765vk_common_CmdSetViewportWithCount(VkCommandBuffer commandBuffer,
1766                                  uint32_t viewportCount,
1767                                  const VkViewport *pViewports)
1768{
1769   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1770   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1771
1772   SET_DYN_VALUE(dyn, VP_VIEWPORT_COUNT, vp.viewport_count, viewportCount);
1773   SET_DYN_ARRAY(dyn, VP_VIEWPORTS, vp.viewports, 0, viewportCount, pViewports);
1774}
1775
1776VKAPI_ATTR void VKAPI_CALL
1777vk_common_CmdSetScissor(VkCommandBuffer commandBuffer,
1778                        uint32_t firstScissor,
1779                        uint32_t scissorCount,
1780                        const VkRect2D *pScissors)
1781{
1782   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1783   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1784
1785   SET_DYN_ARRAY(dyn, VP_SCISSORS, vp.scissors,
1786                 firstScissor, scissorCount, pScissors);
1787}
1788
1789VKAPI_ATTR void VKAPI_CALL
1790vk_common_CmdSetScissorWithCount(VkCommandBuffer commandBuffer,
1791                                 uint32_t scissorCount,
1792                                 const VkRect2D *pScissors)
1793{
1794   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1795   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1796
1797   SET_DYN_VALUE(dyn, VP_SCISSOR_COUNT, vp.scissor_count, scissorCount);
1798   SET_DYN_ARRAY(dyn, VP_SCISSORS, vp.scissors, 0, scissorCount, pScissors);
1799}
1800
1801VKAPI_ATTR void VKAPI_CALL
1802vk_common_CmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer,
1803                                    uint32_t firstDiscardRectangle,
1804                                    uint32_t discardRectangleCount,
1805                                    const VkRect2D *pDiscardRectangles)
1806{
1807   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1808   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1809
1810   SET_DYN_VALUE(dyn, DR_RECTANGLES, dr.rectangle_count, discardRectangleCount);
1811   SET_DYN_ARRAY(dyn, DR_RECTANGLES, dr.rectangles, firstDiscardRectangle,
1812                 discardRectangleCount, pDiscardRectangles);
1813}
1814
1815VKAPI_ATTR void VKAPI_CALL
1816vk_common_CmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
1817                                           VkBool32 rasterizerDiscardEnable)
1818{
1819   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1820   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1821
1822   SET_DYN_BOOL(dyn, RS_RASTERIZER_DISCARD_ENABLE,
1823                rs.rasterizer_discard_enable, rasterizerDiscardEnable);
1824}
1825
1826VKAPI_ATTR void VKAPI_CALL
1827vk_common_CmdSetCullMode(VkCommandBuffer commandBuffer,
1828                         VkCullModeFlags cullMode)
1829{
1830   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1831   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1832
1833   SET_DYN_VALUE(dyn, RS_CULL_MODE, rs.cull_mode, cullMode);
1834}
1835
1836VKAPI_ATTR void VKAPI_CALL
1837vk_common_CmdSetFrontFace(VkCommandBuffer commandBuffer,
1838                          VkFrontFace frontFace)
1839{
1840   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1841   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1842
1843   SET_DYN_VALUE(dyn, RS_FRONT_FACE, rs.front_face, frontFace);
1844}
1845
1846VKAPI_ATTR void VKAPI_CALL
1847vk_common_CmdSetDepthBiasEnable(VkCommandBuffer commandBuffer,
1848                                VkBool32 depthBiasEnable)
1849{
1850   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1851   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1852
1853   SET_DYN_BOOL(dyn, RS_DEPTH_BIAS_ENABLE,
1854                rs.depth_bias.enable, depthBiasEnable);
1855}
1856
1857VKAPI_ATTR void VKAPI_CALL
1858vk_common_CmdSetDepthBias(VkCommandBuffer commandBuffer,
1859                          float depthBiasConstantFactor,
1860                          float depthBiasClamp,
1861                          float depthBiasSlopeFactor)
1862{
1863   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1864   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1865
1866   SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
1867                 rs.depth_bias.constant, depthBiasConstantFactor);
1868   SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
1869                 rs.depth_bias.clamp, depthBiasClamp);
1870   SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
1871                 rs.depth_bias.slope, depthBiasSlopeFactor);
1872}
1873
1874VKAPI_ATTR void VKAPI_CALL
1875vk_common_CmdSetLineWidth(VkCommandBuffer commandBuffer,
1876                          float lineWidth)
1877{
1878   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1879   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1880
1881   SET_DYN_VALUE(dyn, RS_LINE_WIDTH, rs.line.width, lineWidth);
1882}
1883
1884VKAPI_ATTR void VKAPI_CALL
1885vk_common_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
1886                               uint32_t lineStippleFactor,
1887                               uint16_t lineStipplePattern)
1888{
1889   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1890   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1891
1892   SET_DYN_VALUE(dyn, RS_LINE_STIPPLE,
1893                 rs.line.stipple.factor, lineStippleFactor);
1894   SET_DYN_VALUE(dyn, RS_LINE_STIPPLE,
1895                 rs.line.stipple.pattern, lineStipplePattern);
1896}
1897
1898VKAPI_ATTR void VKAPI_CALL
1899vk_common_CmdSetFragmentShadingRateKHR(VkCommandBuffer commandBuffer,
1900   const VkExtent2D *pFragmentSize,
1901   const VkFragmentShadingRateCombinerOpKHR combinerOps[2])
1902{
1903   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1904   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1905
1906   SET_DYN_VALUE(dyn, FSR, fsr.fragment_size.width, pFragmentSize->width);
1907   SET_DYN_VALUE(dyn, FSR, fsr.fragment_size.height, pFragmentSize->height);
1908   SET_DYN_VALUE(dyn, FSR, fsr.combiner_ops[0], combinerOps[0]);
1909   SET_DYN_VALUE(dyn, FSR, fsr.combiner_ops[1], combinerOps[1]);
1910}
1911
1912VKAPI_ATTR void VKAPI_CALL
1913vk_common_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
1914                                   const VkSampleLocationsInfoEXT *pSampleLocationsInfo)
1915{
1916   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1917   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1918
1919   SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS,
1920                 ms.sample_locations->per_pixel,
1921                 pSampleLocationsInfo->sampleLocationsPerPixel);
1922   SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS,
1923                 ms.sample_locations->grid_size.width,
1924                 pSampleLocationsInfo->sampleLocationGridSize.width);
1925   SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS,
1926                 ms.sample_locations->grid_size.height,
1927                 pSampleLocationsInfo->sampleLocationGridSize.height);
1928
1929   assert(pSampleLocationsInfo->sampleLocationsCount ==
1930          pSampleLocationsInfo->sampleLocationsPerPixel *
1931          pSampleLocationsInfo->sampleLocationGridSize.width *
1932          pSampleLocationsInfo->sampleLocationGridSize.height);
1933
1934   assert(pSampleLocationsInfo->sampleLocationsCount <=
1935          MESA_VK_MAX_SAMPLE_LOCATIONS);
1936
1937   SET_DYN_ARRAY(dyn, MS_SAMPLE_LOCATIONS,
1938                 ms.sample_locations->locations,
1939                 0, pSampleLocationsInfo->sampleLocationsCount,
1940                 pSampleLocationsInfo->pSampleLocations);
1941}
1942
1943VKAPI_ATTR void VKAPI_CALL
1944vk_common_CmdSetDepthTestEnable(VkCommandBuffer commandBuffer,
1945                                VkBool32 depthTestEnable)
1946{
1947   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1948   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1949
1950   SET_DYN_BOOL(dyn, DS_DEPTH_TEST_ENABLE,
1951                ds.depth.test_enable, depthTestEnable);
1952}
1953
1954VKAPI_ATTR void VKAPI_CALL
1955vk_common_CmdSetDepthWriteEnable(VkCommandBuffer commandBuffer,
1956                                VkBool32 depthWriteEnable)
1957{
1958   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1959   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1960
1961   SET_DYN_BOOL(dyn, DS_DEPTH_WRITE_ENABLE,
1962                ds.depth.write_enable, depthWriteEnable);
1963}
1964
1965VKAPI_ATTR void VKAPI_CALL
1966vk_common_CmdSetDepthCompareOp(VkCommandBuffer commandBuffer,
1967                               VkCompareOp depthCompareOp)
1968{
1969   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1970   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1971
1972   SET_DYN_VALUE(dyn, DS_DEPTH_COMPARE_OP, ds.depth.compare_op,
1973                 depthCompareOp);
1974}
1975
1976VKAPI_ATTR void VKAPI_CALL
1977vk_common_CmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,
1978                                      VkBool32 depthBoundsTestEnable)
1979{
1980   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1981   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1982
1983   SET_DYN_BOOL(dyn, DS_DEPTH_BOUNDS_TEST_ENABLE,
1984                ds.depth.bounds_test.enable, depthBoundsTestEnable);
1985}
1986
1987VKAPI_ATTR void VKAPI_CALL
1988vk_common_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
1989                            float minDepthBounds,
1990                            float maxDepthBounds)
1991{
1992   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
1993   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
1994
1995   SET_DYN_VALUE(dyn, DS_DEPTH_BOUNDS_TEST_BOUNDS,
1996                 ds.depth.bounds_test.min, minDepthBounds);
1997   SET_DYN_VALUE(dyn, DS_DEPTH_BOUNDS_TEST_BOUNDS,
1998                 ds.depth.bounds_test.max, maxDepthBounds);
1999}
2000
2001VKAPI_ATTR void VKAPI_CALL
2002vk_common_CmdSetStencilTestEnable(VkCommandBuffer commandBuffer,
2003                                  VkBool32 stencilTestEnable)
2004{
2005   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2006   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2007
2008   SET_DYN_BOOL(dyn, DS_STENCIL_TEST_ENABLE,
2009                ds.stencil.test_enable, stencilTestEnable);
2010}
2011
2012VKAPI_ATTR void VKAPI_CALL
2013vk_common_CmdSetStencilOp(VkCommandBuffer commandBuffer,
2014                          VkStencilFaceFlags faceMask,
2015                          VkStencilOp failOp,
2016                          VkStencilOp passOp,
2017                          VkStencilOp depthFailOp,
2018                          VkCompareOp compareOp)
2019{
2020   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2021   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2022
2023   if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2024      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.fail, failOp);
2025      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.pass, passOp);
2026      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.depth_fail, depthFailOp);
2027      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.compare, compareOp);
2028   }
2029
2030   if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2031      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.fail, failOp);
2032      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.pass, passOp);
2033      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.depth_fail, depthFailOp);
2034      SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.compare, compareOp);
2035   }
2036}
2037
2038VKAPI_ATTR void VKAPI_CALL
2039vk_common_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
2040                                   VkStencilFaceFlags faceMask,
2041                                   uint32_t compareMask)
2042{
2043   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2044   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2045
2046   /* We assume 8-bit stencil always */
2047   STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1);
2048
2049   if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2050      SET_DYN_VALUE(dyn, DS_STENCIL_COMPARE_MASK,
2051                    ds.stencil.front.compare_mask, (uint8_t)compareMask);
2052   }
2053   if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2054      SET_DYN_VALUE(dyn, DS_STENCIL_COMPARE_MASK,
2055                    ds.stencil.back.compare_mask, (uint8_t)compareMask);
2056   }
2057}
2058
2059VKAPI_ATTR void VKAPI_CALL
2060vk_common_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
2061                                 VkStencilFaceFlags faceMask,
2062                                 uint32_t writeMask)
2063{
2064   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2065   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2066
2067   /* We assume 8-bit stencil always */
2068   STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1);
2069
2070   if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2071      SET_DYN_VALUE(dyn, DS_STENCIL_WRITE_MASK,
2072                    ds.stencil.front.write_mask, (uint8_t)writeMask);
2073   }
2074   if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2075      SET_DYN_VALUE(dyn, DS_STENCIL_WRITE_MASK,
2076                    ds.stencil.back.write_mask, (uint8_t)writeMask);
2077   }
2078}
2079
2080VKAPI_ATTR void VKAPI_CALL
2081vk_common_CmdSetStencilReference(VkCommandBuffer commandBuffer,
2082                                 VkStencilFaceFlags faceMask,
2083                                 uint32_t reference)
2084{
2085   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2086   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2087
2088   /* We assume 8-bit stencil always */
2089   STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1);
2090
2091   if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2092      SET_DYN_VALUE(dyn, DS_STENCIL_REFERENCE,
2093                    ds.stencil.front.reference, (uint8_t)reference);
2094   }
2095   if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2096      SET_DYN_VALUE(dyn, DS_STENCIL_REFERENCE,
2097                    ds.stencil.back.reference, (uint8_t)reference);
2098   }
2099}
2100
2101VKAPI_ATTR void VKAPI_CALL
2102vk_common_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer,
2103                           VkLogicOp logicOp)
2104{
2105   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2106   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2107
2108   SET_DYN_VALUE(dyn, CB_LOGIC_OP, cb.logic_op, logicOp);
2109}
2110
2111VKAPI_ATTR void VKAPI_CALL
2112vk_common_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
2113                                    uint32_t attachmentCount,
2114                                    const VkBool32 *pColorWriteEnables)
2115{
2116   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2117   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2118
2119   assert(attachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
2120
2121   uint8_t color_write_enables = 0;
2122   for (uint32_t a = 0; a < attachmentCount; a++) {
2123      if (pColorWriteEnables[a])
2124         color_write_enables |= BITFIELD_BIT(a);
2125   }
2126
2127   SET_DYN_VALUE(dyn, CB_COLOR_WRITE_ENABLES,
2128                 cb.color_write_enables, color_write_enables);
2129}
2130
2131VKAPI_ATTR void VKAPI_CALL
2132vk_common_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
2133                               const float  blendConstants[4])
2134{
2135   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2136   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2137
2138   SET_DYN_ARRAY(dyn, CB_BLEND_CONSTANTS, cb.blend_constants,
2139                 0, 4, blendConstants);
2140}
2141