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_pipeline.h"
9 #include "vk_render_pass.h"
10 #include "vk_standard_sample_locations.h"
11 #include "vk_util.h"
12
13 #include <assert.h>
14
15 enum mesa_vk_graphics_state_groups {
16 MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT = (1 << 0),
17 MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT = (1 << 1),
18 MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT = (1 << 2),
19 MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT = (1 << 3),
20 MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT = (1 << 4),
21 MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT = (1 << 5),
22 MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT = (1 << 6),
23 MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT = (1 << 7),
24 MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT = (1 << 8),
25 MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT = (1 << 9),
26 MESA_VK_GRAPHICS_STATE_INPUT_ATTACHMENT_MAP_BIT = (1 << 10),
27 MESA_VK_GRAPHICS_STATE_COLOR_ATTACHMENT_MAP_BIT = (1 << 11),
28 MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT = (1 << 12),
29 };
30
31 static void
clear_all_dynamic_state(BITSET_WORD * dynamic)32 clear_all_dynamic_state(BITSET_WORD *dynamic)
33 {
34 /* Clear the whole array so there are no undefined bits at the top */
35 memset(dynamic, 0, sizeof(*dynamic) *
36 BITSET_WORDS(MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX));
37 }
38
39 static void
get_dynamic_state_groups(BITSET_WORD * dynamic,enum mesa_vk_graphics_state_groups groups)40 get_dynamic_state_groups(BITSET_WORD *dynamic,
41 enum mesa_vk_graphics_state_groups groups)
42 {
43 clear_all_dynamic_state(dynamic);
44
45 if (groups & MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT) {
46 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI);
47 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI_BINDINGS_VALID);
48 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI_BINDING_STRIDES);
49 }
50
51 if (groups & MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT) {
52 BITSET_SET(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY);
53 BITSET_SET(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE);
54 }
55
56 if (groups & MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT) {
57 BITSET_SET(dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS);
58 BITSET_SET(dynamic, MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN);
59 }
60
61 if (groups & MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT) {
62 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT);
63 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_VIEWPORTS);
64 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT);
65 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_SCISSORS);
66 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE);
67 }
68
69 if (groups & MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT) {
70 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DR_RECTANGLES);
71 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DR_ENABLE);
72 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DR_MODE);
73 }
74
75 if (groups & MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT) {
76 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE);
77 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE);
78 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE);
79 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_POLYGON_MODE);
80 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_CULL_MODE);
81 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_FRONT_FACE);
82 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_CONSERVATIVE_MODE);
83 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_RASTERIZATION_ORDER_AMD);
84 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX);
85 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_RASTERIZATION_STREAM);
86 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE);
87 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS);
88 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_WIDTH);
89 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_MODE);
90 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_STIPPLE_ENABLE);
91 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_STIPPLE);
92 }
93
94 if (groups & MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT)
95 BITSET_SET(dynamic, MESA_VK_DYNAMIC_FSR);
96
97 if (groups & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) {
98 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES);
99 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_MASK);
100 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE);
101 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE);
102 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS_ENABLE);
103 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS);
104 }
105
106 if (groups & MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT) {
107 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE);
108 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE);
109 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP);
110 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE);
111 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS);
112 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE);
113 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP);
114 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK);
115 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK);
116 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
117 }
118
119 if (groups & MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT) {
120 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE);
121 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP);
122 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT);
123 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
124 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_BLEND_ENABLES);
125 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS);
126 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_WRITE_MASKS);
127 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
128 }
129
130 if (groups & MESA_VK_GRAPHICS_STATE_COLOR_ATTACHMENT_MAP_BIT)
131 BITSET_SET(dynamic, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP);
132
133 if (groups & MESA_VK_GRAPHICS_STATE_INPUT_ATTACHMENT_MAP_BIT)
134 BITSET_SET(dynamic, MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP);
135
136 if (groups & MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT) {
137 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RP_ATTACHMENTS);
138 BITSET_SET(dynamic, MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE);
139 }
140 }
141
142 static enum mesa_vk_graphics_state_groups
fully_dynamic_state_groups(const BITSET_WORD * dynamic)143 fully_dynamic_state_groups(const BITSET_WORD *dynamic)
144 {
145 enum mesa_vk_graphics_state_groups groups = 0;
146
147 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_VI) &&
148 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_VI_BINDING_STRIDES) &&
149 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_VI_BINDINGS_VALID))
150 groups |= MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT;
151
152 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) &&
153 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN))
154 groups |= MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT;
155
156 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_FSR))
157 groups |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT;
158
159 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) &&
160 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) &&
161 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) &&
162 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE) &&
163 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS) &&
164 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) &&
165 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP) &&
166 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) &&
167 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) &&
168 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE))
169 groups |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT;
170
171 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE) &&
172 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP) &&
173 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT) &&
174 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES) &&
175 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_BLEND_ENABLES) &&
176 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS) &&
177 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_WRITE_MASKS) &&
178 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS))
179 groups |= MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT;
180
181 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP))
182 groups |= MESA_VK_GRAPHICS_STATE_COLOR_ATTACHMENT_MAP_BIT;
183
184 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP))
185 groups |= MESA_VK_GRAPHICS_STATE_INPUT_ATTACHMENT_MAP_BIT;
186
187 return groups;
188 }
189
190 static void
validate_dynamic_state_groups(const BITSET_WORD * dynamic,enum mesa_vk_graphics_state_groups groups)191 validate_dynamic_state_groups(const BITSET_WORD *dynamic,
192 enum mesa_vk_graphics_state_groups groups)
193 {
194 #ifndef NDEBUG
195 BITSET_DECLARE(all_dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
196 get_dynamic_state_groups(all_dynamic, groups);
197
198 for (uint32_t w = 0; w < ARRAY_SIZE(all_dynamic); w++)
199 assert(!(dynamic[w] & ~all_dynamic[w]));
200 #endif
201 }
202
203 void
vk_get_dynamic_graphics_states(BITSET_WORD * dynamic,const VkPipelineDynamicStateCreateInfo * info)204 vk_get_dynamic_graphics_states(BITSET_WORD *dynamic,
205 const VkPipelineDynamicStateCreateInfo *info)
206 {
207 clear_all_dynamic_state(dynamic);
208
209 /* From the Vulkan 1.3.218 spec:
210 *
211 * "pDynamicState is a pointer to a VkPipelineDynamicStateCreateInfo
212 * structure defining which properties of the pipeline state object are
213 * dynamic and can be changed independently of the pipeline state. This
214 * can be NULL, which means no state in the pipeline is considered
215 * dynamic."
216 */
217 if (info == NULL)
218 return;
219
220 #define CASE(VK, MESA) \
221 case VK_DYNAMIC_STATE_##VK: \
222 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA); \
223 break;
224
225 #define CASE2(VK, MESA1, MESA2) \
226 case VK_DYNAMIC_STATE_##VK: \
227 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA1); \
228 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA2); \
229 break;
230
231 #define CASE3(VK, MESA1, MESA2, MESA3) \
232 case VK_DYNAMIC_STATE_##VK: \
233 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA1); \
234 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA2); \
235 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA3); \
236 break;
237
238 for (uint32_t i = 0; i < info->dynamicStateCount; i++) {
239 switch (info->pDynamicStates[i]) {
240 CASE3(VERTEX_INPUT_EXT, VI, VI_BINDINGS_VALID, VI_BINDING_STRIDES)
241 CASE( VERTEX_INPUT_BINDING_STRIDE, VI_BINDING_STRIDES)
242 CASE( VIEWPORT, VP_VIEWPORTS)
243 CASE( SCISSOR, VP_SCISSORS)
244 CASE( LINE_WIDTH, RS_LINE_WIDTH)
245 CASE( DEPTH_BIAS, RS_DEPTH_BIAS_FACTORS)
246 CASE( BLEND_CONSTANTS, CB_BLEND_CONSTANTS)
247 CASE( DEPTH_BOUNDS, DS_DEPTH_BOUNDS_TEST_BOUNDS)
248 CASE( STENCIL_COMPARE_MASK, DS_STENCIL_COMPARE_MASK)
249 CASE( STENCIL_WRITE_MASK, DS_STENCIL_WRITE_MASK)
250 CASE( STENCIL_REFERENCE, DS_STENCIL_REFERENCE)
251 CASE( CULL_MODE, RS_CULL_MODE)
252 CASE( FRONT_FACE, RS_FRONT_FACE)
253 CASE( PRIMITIVE_TOPOLOGY, IA_PRIMITIVE_TOPOLOGY)
254 CASE2(VIEWPORT_WITH_COUNT, VP_VIEWPORT_COUNT, VP_VIEWPORTS)
255 CASE2(SCISSOR_WITH_COUNT, VP_SCISSOR_COUNT, VP_SCISSORS)
256 CASE( DEPTH_TEST_ENABLE, DS_DEPTH_TEST_ENABLE)
257 CASE( DEPTH_WRITE_ENABLE, DS_DEPTH_WRITE_ENABLE)
258 CASE( DEPTH_COMPARE_OP, DS_DEPTH_COMPARE_OP)
259 CASE( DEPTH_BOUNDS_TEST_ENABLE, DS_DEPTH_BOUNDS_TEST_ENABLE)
260 CASE( STENCIL_TEST_ENABLE, DS_STENCIL_TEST_ENABLE)
261 CASE( STENCIL_OP, DS_STENCIL_OP)
262 CASE( RASTERIZER_DISCARD_ENABLE, RS_RASTERIZER_DISCARD_ENABLE)
263 CASE( DEPTH_BIAS_ENABLE, RS_DEPTH_BIAS_ENABLE)
264 CASE( PRIMITIVE_RESTART_ENABLE, IA_PRIMITIVE_RESTART_ENABLE)
265 CASE( DISCARD_RECTANGLE_EXT, DR_RECTANGLES)
266 CASE( DISCARD_RECTANGLE_ENABLE_EXT, DR_ENABLE)
267 CASE( DISCARD_RECTANGLE_MODE_EXT, DR_MODE)
268 CASE( SAMPLE_LOCATIONS_EXT, MS_SAMPLE_LOCATIONS)
269 CASE( FRAGMENT_SHADING_RATE_KHR, FSR)
270 CASE( LINE_STIPPLE_EXT, RS_LINE_STIPPLE)
271 CASE( PATCH_CONTROL_POINTS_EXT, TS_PATCH_CONTROL_POINTS)
272 CASE( LOGIC_OP_EXT, CB_LOGIC_OP)
273 CASE( COLOR_WRITE_ENABLE_EXT, CB_COLOR_WRITE_ENABLES)
274 CASE( TESSELLATION_DOMAIN_ORIGIN_EXT, TS_DOMAIN_ORIGIN)
275 CASE( DEPTH_CLAMP_ENABLE_EXT, RS_DEPTH_CLAMP_ENABLE)
276 CASE( POLYGON_MODE_EXT, RS_POLYGON_MODE)
277 CASE( RASTERIZATION_SAMPLES_EXT, MS_RASTERIZATION_SAMPLES)
278 CASE( SAMPLE_MASK_EXT, MS_SAMPLE_MASK)
279 CASE( ALPHA_TO_COVERAGE_ENABLE_EXT, MS_ALPHA_TO_COVERAGE_ENABLE)
280 CASE( ALPHA_TO_ONE_ENABLE_EXT, MS_ALPHA_TO_ONE_ENABLE)
281 CASE( LOGIC_OP_ENABLE_EXT, CB_LOGIC_OP_ENABLE)
282 CASE( COLOR_BLEND_ENABLE_EXT, CB_BLEND_ENABLES)
283 CASE( COLOR_BLEND_EQUATION_EXT, CB_BLEND_EQUATIONS)
284 CASE( COLOR_WRITE_MASK_EXT, CB_WRITE_MASKS)
285 CASE( RASTERIZATION_STREAM_EXT, RS_RASTERIZATION_STREAM)
286 CASE( CONSERVATIVE_RASTERIZATION_MODE_EXT, RS_CONSERVATIVE_MODE)
287 CASE( DEPTH_CLIP_ENABLE_EXT, RS_DEPTH_CLIP_ENABLE)
288 CASE( SAMPLE_LOCATIONS_ENABLE_EXT, MS_SAMPLE_LOCATIONS_ENABLE)
289 CASE( PROVOKING_VERTEX_MODE_EXT, RS_PROVOKING_VERTEX)
290 CASE( LINE_RASTERIZATION_MODE_EXT, RS_LINE_MODE)
291 CASE( LINE_STIPPLE_ENABLE_EXT, RS_LINE_STIPPLE_ENABLE)
292 CASE( DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT, VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE)
293 CASE( ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT, ATTACHMENT_FEEDBACK_LOOP_ENABLE)
294 default:
295 unreachable("Unsupported dynamic graphics state");
296 }
297 }
298
299 /* attachmentCount is ignored if all of the states using it are dyanmic.
300 *
301 * TODO: Handle advanced blending here when supported.
302 */
303 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_BLEND_ENABLES) &&
304 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS) &&
305 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_CB_WRITE_MASKS))
306 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT);
307 }
308
309 #define IS_DYNAMIC(STATE) \
310 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_##STATE)
311
312 #define IS_NEEDED(STATE) \
313 BITSET_TEST(needed, MESA_VK_DYNAMIC_##STATE)
314
315 static void
vk_vertex_input_state_init(struct vk_vertex_input_state * vi,const BITSET_WORD * dynamic,const VkPipelineVertexInputStateCreateInfo * vi_info)316 vk_vertex_input_state_init(struct vk_vertex_input_state *vi,
317 const BITSET_WORD *dynamic,
318 const VkPipelineVertexInputStateCreateInfo *vi_info)
319 {
320 assert(!IS_DYNAMIC(VI));
321
322 memset(vi, 0, sizeof(*vi));
323 if (!vi_info)
324 return;
325
326 for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) {
327 const VkVertexInputBindingDescription *desc =
328 &vi_info->pVertexBindingDescriptions[i];
329
330 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
331 assert(desc->stride <= MESA_VK_MAX_VERTEX_BINDING_STRIDE);
332 assert(desc->inputRate <= 1);
333
334 const uint32_t b = desc->binding;
335 vi->bindings_valid |= BITFIELD_BIT(b);
336 vi->bindings[b].stride = desc->stride;
337 vi->bindings[b].input_rate = desc->inputRate;
338 vi->bindings[b].divisor = 1;
339 }
340
341 for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
342 const VkVertexInputAttributeDescription *desc =
343 &vi_info->pVertexAttributeDescriptions[i];
344
345 assert(desc->location < MESA_VK_MAX_VERTEX_ATTRIBUTES);
346 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
347 assert(vi->bindings_valid & BITFIELD_BIT(desc->binding));
348
349 const uint32_t a = desc->location;
350 vi->attributes_valid |= BITFIELD_BIT(a);
351 vi->attributes[a].binding = desc->binding;
352 vi->attributes[a].format = desc->format;
353 vi->attributes[a].offset = desc->offset;
354 }
355
356 const VkPipelineVertexInputDivisorStateCreateInfoKHR *vi_div_state =
357 vk_find_struct_const(vi_info->pNext,
358 PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_KHR);
359 if (vi_div_state) {
360 for (uint32_t i = 0; i < vi_div_state->vertexBindingDivisorCount; i++) {
361 const VkVertexInputBindingDivisorDescriptionKHR *desc =
362 &vi_div_state->pVertexBindingDivisors[i];
363
364 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
365 assert(vi->bindings_valid & BITFIELD_BIT(desc->binding));
366
367 const uint32_t b = desc->binding;
368 vi->bindings[b].divisor = desc->divisor;
369 }
370 }
371 }
372
373 static void
vk_dynamic_graphics_state_init_vi(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_vertex_input_state * vi)374 vk_dynamic_graphics_state_init_vi(struct vk_dynamic_graphics_state *dst,
375 const BITSET_WORD *needed,
376 const struct vk_vertex_input_state *vi)
377 {
378 if (IS_NEEDED(VI))
379 *dst->vi = *vi;
380
381 if (IS_NEEDED(VI_BINDINGS_VALID))
382 dst->vi_bindings_valid = vi->bindings_valid;
383
384 if (IS_NEEDED(VI_BINDING_STRIDES)) {
385 for (uint32_t b = 0; b < MESA_VK_MAX_VERTEX_BINDINGS; b++) {
386 if (vi->bindings_valid & BITFIELD_BIT(b))
387 dst->vi_binding_strides[b] = vi->bindings[b].stride;
388 else
389 dst->vi_binding_strides[b] = 0;
390 }
391 }
392 }
393
394 static void
vk_input_assembly_state_init(struct vk_input_assembly_state * ia,const BITSET_WORD * dynamic,const VkPipelineInputAssemblyStateCreateInfo * ia_info)395 vk_input_assembly_state_init(struct vk_input_assembly_state *ia,
396 const BITSET_WORD *dynamic,
397 const VkPipelineInputAssemblyStateCreateInfo *ia_info)
398 {
399 memset(ia, 0, sizeof(*ia));
400 if (!ia_info)
401 return;
402
403 /* From the Vulkan 1.3.224 spec:
404 *
405 * "VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY specifies that the topology
406 * state in VkPipelineInputAssemblyStateCreateInfo only specifies the
407 * topology class, and the specific topology order and adjacency must be
408 * set dynamically with vkCmdSetPrimitiveTopology before any drawing
409 * commands."
410 */
411 assert(ia_info->topology <= UINT8_MAX);
412 ia->primitive_topology = ia_info->topology;
413
414 ia->primitive_restart_enable = ia_info->primitiveRestartEnable;
415 }
416
417 static void
vk_dynamic_graphics_state_init_ia(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_input_assembly_state * ia)418 vk_dynamic_graphics_state_init_ia(struct vk_dynamic_graphics_state *dst,
419 const BITSET_WORD *needed,
420 const struct vk_input_assembly_state *ia)
421 {
422 dst->ia = *ia;
423 }
424
425 static void
vk_tessellation_state_init(struct vk_tessellation_state * ts,const BITSET_WORD * dynamic,const VkPipelineTessellationStateCreateInfo * ts_info)426 vk_tessellation_state_init(struct vk_tessellation_state *ts,
427 const BITSET_WORD *dynamic,
428 const VkPipelineTessellationStateCreateInfo *ts_info)
429 {
430 *ts = (struct vk_tessellation_state) {
431 .domain_origin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT,
432 };
433 if (!ts_info)
434 return;
435
436 if (!IS_DYNAMIC(TS_PATCH_CONTROL_POINTS)) {
437 assert(ts_info->patchControlPoints <= UINT8_MAX);
438 ts->patch_control_points = ts_info->patchControlPoints;
439 }
440
441 if (!IS_DYNAMIC(TS_DOMAIN_ORIGIN)) {
442 const VkPipelineTessellationDomainOriginStateCreateInfo *ts_do_info =
443 vk_find_struct_const(ts_info->pNext,
444 PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO);
445 if (ts_do_info != NULL) {
446 assert(ts_do_info->domainOrigin <= UINT8_MAX);
447 ts->domain_origin = ts_do_info->domainOrigin;
448 }
449 }
450 }
451
452 static void
vk_dynamic_graphics_state_init_ts(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_tessellation_state * ts)453 vk_dynamic_graphics_state_init_ts(struct vk_dynamic_graphics_state *dst,
454 const BITSET_WORD *needed,
455 const struct vk_tessellation_state *ts)
456 {
457 dst->ts = *ts;
458 }
459
460 static void
vk_viewport_state_init(struct vk_viewport_state * vp,const BITSET_WORD * dynamic,const VkPipelineViewportStateCreateInfo * vp_info)461 vk_viewport_state_init(struct vk_viewport_state *vp,
462 const BITSET_WORD *dynamic,
463 const VkPipelineViewportStateCreateInfo *vp_info)
464 {
465 memset(vp, 0, sizeof(*vp));
466 if (!vp_info)
467 return;
468
469 if (!IS_DYNAMIC(VP_VIEWPORT_COUNT)) {
470 assert(vp_info->viewportCount <= MESA_VK_MAX_VIEWPORTS);
471 vp->viewport_count = vp_info->viewportCount;
472 }
473
474 if (!IS_DYNAMIC(VP_VIEWPORTS)) {
475 assert(!IS_DYNAMIC(VP_VIEWPORT_COUNT));
476 typed_memcpy(vp->viewports, vp_info->pViewports,
477 vp_info->viewportCount);
478 }
479
480 if (!IS_DYNAMIC(VP_SCISSOR_COUNT)) {
481 assert(vp_info->scissorCount <= MESA_VK_MAX_SCISSORS);
482 vp->scissor_count = vp_info->scissorCount;
483 }
484
485 if (!IS_DYNAMIC(VP_SCISSORS)) {
486 assert(!IS_DYNAMIC(VP_SCISSOR_COUNT));
487 typed_memcpy(vp->scissors, vp_info->pScissors,
488 vp_info->scissorCount);
489 }
490
491 if (!IS_DYNAMIC(VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE)) {
492 const VkPipelineViewportDepthClipControlCreateInfoEXT *vp_dcc_info =
493 vk_find_struct_const(vp_info->pNext,
494 PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT);
495 if (vp_dcc_info != NULL)
496 vp->depth_clip_negative_one_to_one = vp_dcc_info->negativeOneToOne;
497 }
498 }
499
500 static void
vk_dynamic_graphics_state_init_vp(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_viewport_state * vp)501 vk_dynamic_graphics_state_init_vp(struct vk_dynamic_graphics_state *dst,
502 const BITSET_WORD *needed,
503 const struct vk_viewport_state *vp)
504 {
505 dst->vp.viewport_count = vp->viewport_count;
506 if (IS_NEEDED(VP_VIEWPORTS))
507 typed_memcpy(dst->vp.viewports, vp->viewports, vp->viewport_count);
508
509 dst->vp.scissor_count = vp->scissor_count;
510 if (IS_NEEDED(VP_SCISSORS))
511 typed_memcpy(dst->vp.scissors, vp->scissors, vp->scissor_count);
512
513 dst->vp.depth_clip_negative_one_to_one = vp->depth_clip_negative_one_to_one;
514 }
515
516 static void
vk_discard_rectangles_state_init(struct vk_discard_rectangles_state * dr,const BITSET_WORD * dynamic,const VkPipelineDiscardRectangleStateCreateInfoEXT * dr_info)517 vk_discard_rectangles_state_init(struct vk_discard_rectangles_state *dr,
518 const BITSET_WORD *dynamic,
519 const VkPipelineDiscardRectangleStateCreateInfoEXT *dr_info)
520 {
521 memset(dr, 0, sizeof(*dr));
522
523 if (dr_info == NULL)
524 return;
525
526 assert(dr_info->discardRectangleCount <= MESA_VK_MAX_DISCARD_RECTANGLES);
527 dr->mode = dr_info->discardRectangleMode;
528 dr->rectangle_count = dr_info->discardRectangleCount;
529
530 if (!IS_DYNAMIC(DR_RECTANGLES)) {
531 typed_memcpy(dr->rectangles, dr_info->pDiscardRectangles,
532 dr_info->discardRectangleCount);
533 }
534 }
535
536 static void
vk_dynamic_graphics_state_init_dr(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_discard_rectangles_state * dr)537 vk_dynamic_graphics_state_init_dr(struct vk_dynamic_graphics_state *dst,
538 const BITSET_WORD *needed,
539 const struct vk_discard_rectangles_state *dr)
540 {
541 dst->dr.enable = dr->rectangle_count > 0;
542 dst->dr.mode = dr->mode;
543 dst->dr.rectangle_count = dr->rectangle_count;
544 typed_memcpy(dst->dr.rectangles, dr->rectangles, dr->rectangle_count);
545 }
546
547 static void
vk_rasterization_state_init(struct vk_rasterization_state * rs,const BITSET_WORD * dynamic,const VkPipelineRasterizationStateCreateInfo * rs_info)548 vk_rasterization_state_init(struct vk_rasterization_state *rs,
549 const BITSET_WORD *dynamic,
550 const VkPipelineRasterizationStateCreateInfo *rs_info)
551 {
552 *rs = (struct vk_rasterization_state) {
553 .rasterizer_discard_enable = false,
554 .conservative_mode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT,
555 .extra_primitive_overestimation_size = 0.0f,
556 .rasterization_order_amd = VK_RASTERIZATION_ORDER_STRICT_AMD,
557 .provoking_vertex = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT,
558 .line.mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR,
559 .depth_clip_enable = IS_DYNAMIC(RS_DEPTH_CLAMP_ENABLE) ? VK_MESA_DEPTH_CLIP_ENABLE_NOT_CLAMP : VK_MESA_DEPTH_CLIP_ENABLE_FALSE,
560 .depth_bias.representation = VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT,
561 .depth_bias.exact = false,
562 };
563 if (!rs_info)
564 return;
565
566 if (!IS_DYNAMIC(RS_RASTERIZER_DISCARD_ENABLE))
567 rs->rasterizer_discard_enable = rs_info->rasterizerDiscardEnable;
568
569 /* From the Vulkan 1.3.218 spec:
570 *
571 * "If VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in
572 * the graphics pipeline state then depth clipping is disabled if
573 * VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable
574 * is VK_FALSE. Otherwise, if
575 * VkPipelineRasterizationDepthClipStateCreateInfoEXT is not present,
576 * depth clipping is disabled when
577 * VkPipelineRasterizationStateCreateInfo::depthClampEnable is VK_TRUE.
578 */
579 if (!IS_DYNAMIC(RS_DEPTH_CLAMP_ENABLE)) {
580 rs->depth_clamp_enable = rs_info->depthClampEnable;
581 rs->depth_clip_enable = rs_info->depthClampEnable ?
582 VK_MESA_DEPTH_CLIP_ENABLE_FALSE :
583 VK_MESA_DEPTH_CLIP_ENABLE_TRUE;
584 }
585
586 rs->polygon_mode = rs_info->polygonMode;
587
588 rs->cull_mode = rs_info->cullMode;
589 rs->front_face = rs_info->frontFace;
590 rs->depth_bias.enable = rs_info->depthBiasEnable;
591 if ((rs_info->depthBiasEnable || IS_DYNAMIC(RS_DEPTH_BIAS_ENABLE)) &&
592 !IS_DYNAMIC(RS_DEPTH_BIAS_FACTORS)) {
593 rs->depth_bias.constant = rs_info->depthBiasConstantFactor;
594 rs->depth_bias.clamp = rs_info->depthBiasClamp;
595 rs->depth_bias.slope = rs_info->depthBiasSlopeFactor;
596 }
597 rs->line.width = rs_info->lineWidth;
598
599 vk_foreach_struct_const(ext, rs_info->pNext) {
600 switch (ext->sType) {
601 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT: {
602 const VkPipelineRasterizationConservativeStateCreateInfoEXT *rcs_info =
603 (const VkPipelineRasterizationConservativeStateCreateInfoEXT *)ext;
604 rs->conservative_mode = rcs_info->conservativeRasterizationMode;
605 rs->extra_primitive_overestimation_size =
606 rcs_info->extraPrimitiveOverestimationSize;
607 break;
608 }
609
610 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
611 const VkPipelineRasterizationDepthClipStateCreateInfoEXT *rdc_info =
612 (const VkPipelineRasterizationDepthClipStateCreateInfoEXT *)ext;
613 rs->depth_clip_enable = rdc_info->depthClipEnable ?
614 VK_MESA_DEPTH_CLIP_ENABLE_TRUE :
615 VK_MESA_DEPTH_CLIP_ENABLE_FALSE;
616 break;
617 }
618
619 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT: {
620 const VkPipelineRasterizationLineStateCreateInfoKHR *rl_info =
621 (const VkPipelineRasterizationLineStateCreateInfoKHR *)ext;
622 rs->line.mode = rl_info->lineRasterizationMode;
623 if (!IS_DYNAMIC(RS_LINE_STIPPLE_ENABLE))
624 rs->line.stipple.enable = rl_info->stippledLineEnable;
625 if ((IS_DYNAMIC(RS_LINE_STIPPLE_ENABLE) || rs->line.stipple.enable) && !IS_DYNAMIC(RS_LINE_STIPPLE)) {
626 rs->line.stipple.factor = rl_info->lineStippleFactor;
627 rs->line.stipple.pattern = rl_info->lineStipplePattern;
628 }
629 break;
630 }
631
632 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT: {
633 const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *rpv_info =
634 (const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *)ext;
635 rs->provoking_vertex = rpv_info->provokingVertexMode;
636 break;
637 }
638
639 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: {
640 const VkPipelineRasterizationStateRasterizationOrderAMD *rro_info =
641 (const VkPipelineRasterizationStateRasterizationOrderAMD *)ext;
642 rs->rasterization_order_amd = rro_info->rasterizationOrder;
643 break;
644 }
645
646 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT: {
647 const VkPipelineRasterizationStateStreamCreateInfoEXT *rss_info =
648 (const VkPipelineRasterizationStateStreamCreateInfoEXT *)ext;
649 rs->rasterization_stream = rss_info->rasterizationStream;
650 break;
651 }
652
653 case VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT: {
654 const VkDepthBiasRepresentationInfoEXT *dbr_info =
655 (const VkDepthBiasRepresentationInfoEXT *)ext;
656 if (!IS_DYNAMIC(RS_DEPTH_BIAS_FACTORS)) {
657 rs->depth_bias.representation = dbr_info->depthBiasRepresentation;
658 rs->depth_bias.exact = dbr_info->depthBiasExact;
659 }
660 break;
661 }
662
663 default:
664 break;
665 }
666 }
667 }
668
669 static void
vk_dynamic_graphics_state_init_rs(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_rasterization_state * rs)670 vk_dynamic_graphics_state_init_rs(struct vk_dynamic_graphics_state *dst,
671 const BITSET_WORD *needed,
672 const struct vk_rasterization_state *rs)
673 {
674 dst->rs = *rs;
675 }
676
677 static void
vk_fragment_shading_rate_state_init(struct vk_fragment_shading_rate_state * fsr,const BITSET_WORD * dynamic,const VkPipelineFragmentShadingRateStateCreateInfoKHR * fsr_info)678 vk_fragment_shading_rate_state_init(
679 struct vk_fragment_shading_rate_state *fsr,
680 const BITSET_WORD *dynamic,
681 const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info)
682 {
683 if (fsr_info != NULL) {
684 fsr->fragment_size = fsr_info->fragmentSize;
685 fsr->combiner_ops[0] = fsr_info->combinerOps[0];
686 fsr->combiner_ops[1] = fsr_info->combinerOps[1];
687 } else {
688 fsr->fragment_size = (VkExtent2D) { 1, 1 };
689 fsr->combiner_ops[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
690 fsr->combiner_ops[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
691 }
692 }
693
694 static void
vk_dynamic_graphics_state_init_fsr(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_fragment_shading_rate_state * fsr)695 vk_dynamic_graphics_state_init_fsr(
696 struct vk_dynamic_graphics_state *dst,
697 const BITSET_WORD *needed,
698 const struct vk_fragment_shading_rate_state *fsr)
699 {
700 dst->fsr = *fsr;
701 }
702
703 static void
vk_sample_locations_state_init(struct vk_sample_locations_state * sl,const VkSampleLocationsInfoEXT * sl_info)704 vk_sample_locations_state_init(struct vk_sample_locations_state *sl,
705 const VkSampleLocationsInfoEXT *sl_info)
706 {
707 sl->per_pixel = sl_info->sampleLocationsPerPixel;
708 sl->grid_size = sl_info->sampleLocationGridSize;
709
710 /* From the Vulkan 1.3.218 spec:
711 *
712 * VUID-VkSampleLocationsInfoEXT-sampleLocationsCount-01527
713 *
714 * "sampleLocationsCount must equal sampleLocationsPerPixel *
715 * sampleLocationGridSize.width * sampleLocationGridSize.height"
716 */
717 assert(sl_info->sampleLocationsCount ==
718 sl_info->sampleLocationsPerPixel *
719 sl_info->sampleLocationGridSize.width *
720 sl_info->sampleLocationGridSize.height);
721
722 assert(sl_info->sampleLocationsCount <= MESA_VK_MAX_SAMPLE_LOCATIONS);
723 typed_memcpy(sl->locations, sl_info->pSampleLocations,
724 sl_info->sampleLocationsCount);
725 }
726
727 static void
vk_multisample_state_init(struct vk_multisample_state * ms,const BITSET_WORD * dynamic,const VkPipelineMultisampleStateCreateInfo * ms_info)728 vk_multisample_state_init(struct vk_multisample_state *ms,
729 const BITSET_WORD *dynamic,
730 const VkPipelineMultisampleStateCreateInfo *ms_info)
731 {
732 memset(ms, 0, sizeof(*ms));
733 if (!ms_info)
734 return;
735
736 if (!IS_DYNAMIC(MS_RASTERIZATION_SAMPLES)) {
737 assert(ms_info->rasterizationSamples <= MESA_VK_MAX_SAMPLES);
738 ms->rasterization_samples = ms_info->rasterizationSamples;
739 }
740
741 ms->sample_shading_enable = ms_info->sampleShadingEnable;
742 ms->min_sample_shading = ms_info->minSampleShading;
743
744 /* From the Vulkan 1.3.218 spec:
745 *
746 * "If pSampleMask is NULL, it is treated as if the mask has all bits
747 * set to 1."
748 */
749 ms->sample_mask = ms_info->pSampleMask ? *ms_info->pSampleMask : ~0;
750
751 ms->alpha_to_coverage_enable = ms_info->alphaToCoverageEnable;
752 ms->alpha_to_one_enable = ms_info->alphaToOneEnable;
753
754 /* These get filled in by vk_multisample_sample_locations_state_init() */
755 ms->sample_locations_enable = false;
756 ms->sample_locations = NULL;
757 }
758
759 static bool
needs_sample_locations_state(const BITSET_WORD * dynamic,const VkPipelineSampleLocationsStateCreateInfoEXT * sl_info)760 needs_sample_locations_state(
761 const BITSET_WORD *dynamic,
762 const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info)
763 {
764 return !IS_DYNAMIC(MS_SAMPLE_LOCATIONS) &&
765 (IS_DYNAMIC(MS_SAMPLE_LOCATIONS_ENABLE) ||
766 (sl_info != NULL && sl_info->sampleLocationsEnable));
767 }
768
769 static void
vk_multisample_sample_locations_state_init(struct vk_multisample_state * ms,struct vk_sample_locations_state * sl,const BITSET_WORD * dynamic,const VkPipelineMultisampleStateCreateInfo * ms_info,const VkPipelineSampleLocationsStateCreateInfoEXT * sl_info)770 vk_multisample_sample_locations_state_init(
771 struct vk_multisample_state *ms,
772 struct vk_sample_locations_state *sl,
773 const BITSET_WORD *dynamic,
774 const VkPipelineMultisampleStateCreateInfo *ms_info,
775 const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info)
776 {
777 ms->sample_locations_enable =
778 IS_DYNAMIC(MS_SAMPLE_LOCATIONS_ENABLE) ||
779 (sl_info != NULL && sl_info->sampleLocationsEnable);
780
781 assert(ms->sample_locations == NULL);
782 if (!IS_DYNAMIC(MS_SAMPLE_LOCATIONS)) {
783 if (ms->sample_locations_enable) {
784 vk_sample_locations_state_init(sl, &sl_info->sampleLocationsInfo);
785 ms->sample_locations = sl;
786 } else if (!IS_DYNAMIC(MS_RASTERIZATION_SAMPLES)) {
787 /* Otherwise, pre-populate with the standard sample locations. If
788 * the driver doesn't support standard sample locations, it probably
789 * doesn't support custom locations either and can completely ignore
790 * this state.
791 */
792 ms->sample_locations =
793 vk_standard_sample_locations_state(ms_info->rasterizationSamples);
794 }
795 /* In the case that the rasterization samples are dynamic we cannot
796 * pre-populate with a specific set of standard sample locations
797 */
798 }
799 }
800
801 static void
vk_dynamic_graphics_state_init_ms(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_multisample_state * ms)802 vk_dynamic_graphics_state_init_ms(struct vk_dynamic_graphics_state *dst,
803 const BITSET_WORD *needed,
804 const struct vk_multisample_state *ms)
805 {
806 dst->ms.rasterization_samples = ms->rasterization_samples;
807 dst->ms.sample_mask = ms->sample_mask;
808 dst->ms.alpha_to_coverage_enable = ms->alpha_to_coverage_enable;
809 dst->ms.alpha_to_one_enable = ms->alpha_to_one_enable;
810 dst->ms.sample_locations_enable = ms->sample_locations_enable;
811
812 if (IS_NEEDED(MS_SAMPLE_LOCATIONS) && ms->sample_locations)
813 *dst->ms.sample_locations = *ms->sample_locations;
814 }
815
816 static void
vk_stencil_test_face_state_init(struct vk_stencil_test_face_state * face,const VkStencilOpState * info)817 vk_stencil_test_face_state_init(struct vk_stencil_test_face_state *face,
818 const VkStencilOpState *info)
819 {
820 face->op.fail = info->failOp;
821 face->op.pass = info->passOp;
822 face->op.depth_fail = info->depthFailOp;
823 face->op.compare = info->compareOp;
824 face->compare_mask = info->compareMask;
825 face->write_mask = info->writeMask;
826 face->reference = info->reference;
827 }
828
829 static void
vk_depth_stencil_state_init(struct vk_depth_stencil_state * ds,const BITSET_WORD * dynamic,const VkPipelineDepthStencilStateCreateInfo * ds_info)830 vk_depth_stencil_state_init(struct vk_depth_stencil_state *ds,
831 const BITSET_WORD *dynamic,
832 const VkPipelineDepthStencilStateCreateInfo *ds_info)
833 {
834 *ds = (struct vk_depth_stencil_state) {
835 .stencil.write_enable = true,
836 };
837 if (!ds_info)
838 return;
839
840 ds->depth.test_enable = ds_info->depthTestEnable;
841 ds->depth.write_enable = ds_info->depthWriteEnable;
842 ds->depth.compare_op = ds_info->depthCompareOp;
843 ds->depth.bounds_test.enable = ds_info->depthBoundsTestEnable;
844 ds->depth.bounds_test.min = ds_info->minDepthBounds;
845 ds->depth.bounds_test.max = ds_info->maxDepthBounds;
846 ds->stencil.test_enable = ds_info->stencilTestEnable;
847 vk_stencil_test_face_state_init(&ds->stencil.front, &ds_info->front);
848 vk_stencil_test_face_state_init(&ds->stencil.back, &ds_info->back);
849 }
850
851 static void
vk_dynamic_graphics_state_init_ds(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_depth_stencil_state * ds)852 vk_dynamic_graphics_state_init_ds(struct vk_dynamic_graphics_state *dst,
853 const BITSET_WORD *needed,
854 const struct vk_depth_stencil_state *ds)
855 {
856 dst->ds = *ds;
857 }
858
859 static bool
optimize_stencil_face(struct vk_stencil_test_face_state * face,VkCompareOp depthCompareOp,bool consider_write_mask)860 optimize_stencil_face(struct vk_stencil_test_face_state *face,
861 VkCompareOp depthCompareOp,
862 bool consider_write_mask)
863 {
864 /* If compareOp is ALWAYS then the stencil test will never fail and failOp
865 * will never happen. Set failOp to KEEP in this case.
866 */
867 if (face->op.compare == VK_COMPARE_OP_ALWAYS)
868 face->op.fail = VK_STENCIL_OP_KEEP;
869
870 /* If compareOp is NEVER or depthCompareOp is NEVER then one of the depth
871 * or stencil tests will fail and passOp will never happen.
872 */
873 if (face->op.compare == VK_COMPARE_OP_NEVER ||
874 depthCompareOp == VK_COMPARE_OP_NEVER)
875 face->op.pass = VK_STENCIL_OP_KEEP;
876
877 /* If compareOp is NEVER or depthCompareOp is ALWAYS then either the
878 * stencil test will fail or the depth test will pass. In either case,
879 * depthFailOp will never happen.
880 */
881 if (face->op.compare == VK_COMPARE_OP_NEVER ||
882 depthCompareOp == VK_COMPARE_OP_ALWAYS)
883 face->op.depth_fail = VK_STENCIL_OP_KEEP;
884
885 /* If the write mask is zero, nothing will be written to the stencil buffer
886 * so it's as if all operations are KEEP.
887 */
888 if (consider_write_mask && face->write_mask == 0) {
889 face->op.pass = VK_STENCIL_OP_KEEP;
890 face->op.fail = VK_STENCIL_OP_KEEP;
891 face->op.depth_fail = VK_STENCIL_OP_KEEP;
892 }
893
894 return face->op.fail != VK_STENCIL_OP_KEEP ||
895 face->op.depth_fail != VK_STENCIL_OP_KEEP ||
896 face->op.pass != VK_STENCIL_OP_KEEP;
897 }
898
899 void
vk_optimize_depth_stencil_state(struct vk_depth_stencil_state * ds,VkImageAspectFlags ds_aspects,bool consider_write_mask)900 vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
901 VkImageAspectFlags ds_aspects,
902 bool consider_write_mask)
903 {
904 /* stencil.write_enable is a dummy right now that should always be true */
905 assert(ds->stencil.write_enable);
906
907 /* From the Vulkan 1.3.221 spec:
908 *
909 * "If there is no depth attachment then the depth test is skipped."
910 */
911 if (!(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
912 ds->depth.test_enable = false;
913
914 /* From the Vulkan 1.3.221 spec:
915 *
916 * "...or if there is no stencil attachment, the coverage mask is
917 * unmodified by this operation."
918 */
919 if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT))
920 ds->stencil.test_enable = false;
921
922 /* If the depth test is disabled, we won't be writing anything. Make sure we
923 * treat the test as always passing later on as well.
924 */
925 if (!ds->depth.test_enable) {
926 ds->depth.write_enable = false;
927 ds->depth.compare_op = VK_COMPARE_OP_ALWAYS;
928 }
929
930 /* If the stencil test is disabled, we won't be writing anything. Make sure
931 * we treat the test as always passing later on as well.
932 */
933 if (!ds->stencil.test_enable) {
934 ds->stencil.write_enable = false;
935 ds->stencil.front.op.compare = VK_COMPARE_OP_ALWAYS;
936 ds->stencil.back.op.compare = VK_COMPARE_OP_ALWAYS;
937 }
938
939 /* If the stencil test is enabled and always fails, then we will never get
940 * to the depth test so we can just disable the depth test entirely.
941 */
942 if (ds->stencil.test_enable &&
943 ds->stencil.front.op.compare == VK_COMPARE_OP_NEVER &&
944 ds->stencil.back.op.compare == VK_COMPARE_OP_NEVER) {
945 ds->depth.test_enable = false;
946 ds->depth.write_enable = false;
947 }
948
949 /* If depthCompareOp is EQUAL then the value we would be writing to the
950 * depth buffer is the same as the value that's already there so there's no
951 * point in writing it.
952 */
953 if (ds->depth.compare_op == VK_COMPARE_OP_EQUAL)
954 ds->depth.write_enable = false;
955
956 /* If the stencil ops are such that we don't actually ever modify the
957 * stencil buffer, we should disable writes.
958 */
959 if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op,
960 consider_write_mask) &&
961 !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op,
962 consider_write_mask))
963 ds->stencil.write_enable = false;
964
965 /* If the depth test always passes and we never write out depth, that's the
966 * same as if the depth test is disabled entirely.
967 */
968 if (ds->depth.compare_op == VK_COMPARE_OP_ALWAYS && !ds->depth.write_enable)
969 ds->depth.test_enable = false;
970
971 /* If the stencil test always passes and we never write out stencil, that's
972 * the same as if the stencil test is disabled entirely.
973 */
974 if (ds->stencil.front.op.compare == VK_COMPARE_OP_ALWAYS &&
975 ds->stencil.back.op.compare == VK_COMPARE_OP_ALWAYS &&
976 !ds->stencil.write_enable)
977 ds->stencil.test_enable = false;
978 }
979
980 static void
vk_color_blend_state_init(struct vk_color_blend_state * cb,const BITSET_WORD * dynamic,const VkPipelineColorBlendStateCreateInfo * cb_info)981 vk_color_blend_state_init(struct vk_color_blend_state *cb,
982 const BITSET_WORD *dynamic,
983 const VkPipelineColorBlendStateCreateInfo *cb_info)
984 {
985 *cb = (struct vk_color_blend_state) {
986 .color_write_enables = BITFIELD_MASK(MESA_VK_MAX_COLOR_ATTACHMENTS),
987 };
988 if (!cb_info)
989 return;
990
991 cb->logic_op_enable = cb_info->logicOpEnable;
992 cb->logic_op = cb_info->logicOp;
993
994 assert(cb_info->attachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
995 cb->attachment_count = cb_info->attachmentCount;
996 /* pAttachments is ignored if any of these is not set */
997 bool full_dynamic = IS_DYNAMIC(CB_BLEND_ENABLES) && IS_DYNAMIC(CB_BLEND_EQUATIONS) && IS_DYNAMIC(CB_WRITE_MASKS);
998 for (uint32_t a = 0; a < cb_info->attachmentCount; a++) {
999 const VkPipelineColorBlendAttachmentState *att = full_dynamic ? NULL : &cb_info->pAttachments[a];
1000
1001 cb->attachments[a] = (struct vk_color_blend_attachment_state) {
1002 .blend_enable = IS_DYNAMIC(CB_BLEND_ENABLES) || att->blendEnable,
1003 .src_color_blend_factor = IS_DYNAMIC(CB_BLEND_EQUATIONS) ? 0 : att->srcColorBlendFactor,
1004 .dst_color_blend_factor = IS_DYNAMIC(CB_BLEND_EQUATIONS) ? 0 : att->dstColorBlendFactor,
1005 .src_alpha_blend_factor = IS_DYNAMIC(CB_BLEND_EQUATIONS) ? 0 : att->srcAlphaBlendFactor,
1006 .dst_alpha_blend_factor = IS_DYNAMIC(CB_BLEND_EQUATIONS) ? 0 : att->dstAlphaBlendFactor,
1007 .write_mask = IS_DYNAMIC(CB_WRITE_MASKS) ? 0xf : att->colorWriteMask,
1008 .color_blend_op = IS_DYNAMIC(CB_BLEND_EQUATIONS) ? 0 : att->colorBlendOp,
1009 .alpha_blend_op = IS_DYNAMIC(CB_BLEND_EQUATIONS) ? 0 : att->alphaBlendOp,
1010 };
1011 }
1012
1013 for (uint32_t i = 0; i < 4; i++)
1014 cb->blend_constants[i] = cb_info->blendConstants[i];
1015
1016 const VkPipelineColorWriteCreateInfoEXT *cw_info =
1017 vk_find_struct_const(cb_info->pNext, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
1018 if (!IS_DYNAMIC(CB_COLOR_WRITE_ENABLES) && cw_info != NULL) {
1019 uint8_t color_write_enables = 0;
1020 assert(cb_info->attachmentCount == cw_info->attachmentCount);
1021 for (uint32_t a = 0; a < cw_info->attachmentCount; a++) {
1022 if (cw_info->pColorWriteEnables[a])
1023 color_write_enables |= BITFIELD_BIT(a);
1024 }
1025 cb->color_write_enables = color_write_enables;
1026 } else {
1027 cb->color_write_enables = BITFIELD_MASK(MESA_VK_MAX_COLOR_ATTACHMENTS);
1028 }
1029 }
1030
1031 static void
vk_input_attachment_location_state_init(struct vk_input_attachment_location_state * ial,const BITSET_WORD * dynamic,const VkRenderingInputAttachmentIndexInfoKHR * ial_info)1032 vk_input_attachment_location_state_init(struct vk_input_attachment_location_state *ial,
1033 const BITSET_WORD *dynamic,
1034 const VkRenderingInputAttachmentIndexInfoKHR *ial_info)
1035 {
1036 *ial = (struct vk_input_attachment_location_state) {
1037 .color_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
1038 .depth_att = MESA_VK_ATTACHMENT_UNUSED,
1039 .stencil_att = MESA_VK_ATTACHMENT_UNUSED,
1040 };
1041 if (!ial_info)
1042 return;
1043
1044 for (uint32_t a = 0; a < MIN2(ial_info->colorAttachmentCount,
1045 MESA_VK_MAX_COLOR_ATTACHMENTS); a++) {
1046 ial->color_map[a] =
1047 ial_info->pColorAttachmentInputIndices[a] == VK_ATTACHMENT_UNUSED ?
1048 MESA_VK_ATTACHMENT_UNUSED : ial_info->pColorAttachmentInputIndices[a];
1049 }
1050 ial->depth_att = ial_info->pDepthInputAttachmentIndex != NULL ?
1051 *ial_info->pDepthInputAttachmentIndex : MESA_VK_ATTACHMENT_UNUSED;
1052 ial->stencil_att = ial_info->pStencilInputAttachmentIndex != NULL ?
1053 *ial_info->pStencilInputAttachmentIndex : MESA_VK_ATTACHMENT_UNUSED;
1054 }
1055
1056 static void
vk_color_attachment_location_state_init(struct vk_color_attachment_location_state * cal,const BITSET_WORD * dynamic,const VkRenderingAttachmentLocationInfoKHR * cal_info)1057 vk_color_attachment_location_state_init(struct vk_color_attachment_location_state *cal,
1058 const BITSET_WORD *dynamic,
1059 const VkRenderingAttachmentLocationInfoKHR *cal_info)
1060 {
1061 *cal = (struct vk_color_attachment_location_state) {
1062 .color_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
1063 };
1064 if (!cal_info)
1065 return;
1066
1067 for (uint32_t a = 0; a < MIN2(cal_info->colorAttachmentCount,
1068 MESA_VK_MAX_COLOR_ATTACHMENTS); a++) {
1069 cal->color_map[a] =
1070 cal_info->pColorAttachmentLocations[a] == VK_ATTACHMENT_UNUSED ?
1071 MESA_VK_ATTACHMENT_UNUSED : cal_info->pColorAttachmentLocations[a];
1072 }
1073 }
1074
1075 static void
vk_dynamic_graphics_state_init_cb(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_color_blend_state * cb)1076 vk_dynamic_graphics_state_init_cb(struct vk_dynamic_graphics_state *dst,
1077 const BITSET_WORD *needed,
1078 const struct vk_color_blend_state *cb)
1079 {
1080 dst->cb.logic_op_enable = cb->logic_op_enable;
1081 dst->cb.logic_op = cb->logic_op;
1082 dst->cb.color_write_enables = cb->color_write_enables;
1083 dst->cb.attachment_count = cb->attachment_count;
1084
1085 if (IS_NEEDED(CB_BLEND_ENABLES) ||
1086 IS_NEEDED(CB_BLEND_EQUATIONS) ||
1087 IS_NEEDED(CB_WRITE_MASKS)) {
1088 typed_memcpy(dst->cb.attachments, cb->attachments, cb->attachment_count);
1089 }
1090
1091 if (IS_NEEDED(CB_BLEND_CONSTANTS))
1092 typed_memcpy(dst->cb.blend_constants, cb->blend_constants, 4);
1093 }
1094
1095 static void
vk_dynamic_graphics_state_init_ial(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_input_attachment_location_state * ial)1096 vk_dynamic_graphics_state_init_ial(struct vk_dynamic_graphics_state *dst,
1097 const BITSET_WORD *needed,
1098 const struct vk_input_attachment_location_state *ial)
1099 {
1100 if (IS_NEEDED(INPUT_ATTACHMENT_MAP)) {
1101 typed_memcpy(dst->ial.color_map, ial->color_map, MESA_VK_MAX_COLOR_ATTACHMENTS);
1102 dst->ial.depth_att = ial->depth_att;
1103 dst->ial.stencil_att = ial->stencil_att;
1104 }
1105 }
1106
1107 static void
vk_dynamic_graphics_state_init_cal(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_color_attachment_location_state * cal)1108 vk_dynamic_graphics_state_init_cal(struct vk_dynamic_graphics_state *dst,
1109 const BITSET_WORD *needed,
1110 const struct vk_color_attachment_location_state *cal)
1111 {
1112 if (IS_NEEDED(COLOR_ATTACHMENT_MAP))
1113 typed_memcpy(dst->cal.color_map, cal->color_map, MESA_VK_MAX_COLOR_ATTACHMENTS);
1114 }
1115
1116 static void
vk_pipeline_flags_init(struct vk_graphics_pipeline_state * state,VkPipelineCreateFlags2KHR driver_rp_flags,bool has_driver_rp,const VkGraphicsPipelineCreateInfo * info,const BITSET_WORD * dynamic,VkGraphicsPipelineLibraryFlagsEXT lib)1117 vk_pipeline_flags_init(struct vk_graphics_pipeline_state *state,
1118 VkPipelineCreateFlags2KHR driver_rp_flags,
1119 bool has_driver_rp,
1120 const VkGraphicsPipelineCreateInfo *info,
1121 const BITSET_WORD *dynamic,
1122 VkGraphicsPipelineLibraryFlagsEXT lib)
1123 {
1124 VkPipelineCreateFlags2KHR valid_pipeline_flags = 0;
1125 VkPipelineCreateFlags2KHR valid_renderpass_flags = 0;
1126 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
1127 valid_renderpass_flags |=
1128 VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
1129 VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
1130 valid_pipeline_flags |=
1131 VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
1132 VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
1133 }
1134 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) {
1135 valid_renderpass_flags |=
1136 VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
1137 VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1138 if (!IS_DYNAMIC(ATTACHMENT_FEEDBACK_LOOP_ENABLE)) {
1139 valid_pipeline_flags |=
1140 VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
1141 VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1142 }
1143 }
1144 const VkPipelineCreateFlags2KHR renderpass_flags =
1145 (has_driver_rp ? driver_rp_flags :
1146 vk_get_pipeline_rendering_flags(info)) & valid_renderpass_flags;
1147
1148 const VkPipelineCreateFlags2KHR pipeline_flags =
1149 vk_graphics_pipeline_create_flags(info) & valid_pipeline_flags;
1150
1151 bool pipeline_feedback_loop = pipeline_flags &
1152 (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
1153 VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT);
1154
1155 bool renderpass_feedback_loop = renderpass_flags &
1156 (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
1157 VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT);
1158
1159 state->pipeline_flags |= renderpass_flags | pipeline_flags;
1160 state->feedback_loop_not_input_only |=
1161 pipeline_feedback_loop || (!has_driver_rp && renderpass_feedback_loop);
1162 }
1163
1164 static void
vk_render_pass_state_init(struct vk_render_pass_state * rp,const struct vk_render_pass_state * old_rp,const struct vk_render_pass_state * driver_rp,const VkGraphicsPipelineCreateInfo * info,VkGraphicsPipelineLibraryFlagsEXT lib)1165 vk_render_pass_state_init(struct vk_render_pass_state *rp,
1166 const struct vk_render_pass_state *old_rp,
1167 const struct vk_render_pass_state *driver_rp,
1168 const VkGraphicsPipelineCreateInfo *info,
1169 VkGraphicsPipelineLibraryFlagsEXT lib)
1170 {
1171 /* If we already have render pass state and it has attachment info, then
1172 * it's complete and we don't need a new one. The one caveat here is that
1173 * we may need to add in some rendering flags.
1174 */
1175 if (old_rp != NULL && vk_render_pass_state_has_attachment_info(old_rp)) {
1176 *rp = *old_rp;
1177 return;
1178 }
1179
1180 *rp = (struct vk_render_pass_state) {
1181 .depth_attachment_format = VK_FORMAT_UNDEFINED,
1182 .stencil_attachment_format = VK_FORMAT_UNDEFINED,
1183 };
1184
1185 if (info->renderPass != VK_NULL_HANDLE && driver_rp != NULL) {
1186 *rp = *driver_rp;
1187 return;
1188 }
1189
1190 const VkPipelineRenderingCreateInfo *r_info =
1191 vk_get_pipeline_rendering_create_info(info);
1192
1193 if (r_info == NULL)
1194 return;
1195
1196 rp->view_mask = r_info->viewMask;
1197
1198 /* From the Vulkan 1.3.218 spec description of pre-rasterization state:
1199 *
1200 * "Fragment shader state is defined by:
1201 * ...
1202 * * VkRenderPass and subpass parameter
1203 * * The viewMask parameter of VkPipelineRenderingCreateInfo (formats
1204 * are ignored)"
1205 *
1206 * The description of fragment shader state contains identical text.
1207 *
1208 * If we have a render pass then we have full information. Even if we're
1209 * dynamic-rendering-only, the presence of a render pass means the
1210 * rendering info came from a vk_render_pass and is therefore complete.
1211 * Otherwise, all we can grab is the view mask and we have to leave the
1212 * rest for later.
1213 */
1214 if (info->renderPass == VK_NULL_HANDLE &&
1215 !(lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
1216 rp->attachments = MESA_VK_RP_ATTACHMENT_INFO_INVALID;
1217 return;
1218 }
1219
1220 assert(r_info->colorAttachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
1221 rp->color_attachment_count = r_info->colorAttachmentCount;
1222 for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) {
1223 rp->color_attachment_formats[i] = r_info->pColorAttachmentFormats[i];
1224 if (r_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED)
1225 rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
1226 }
1227
1228 rp->depth_attachment_format = r_info->depthAttachmentFormat;
1229 if (r_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED)
1230 rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
1231
1232 rp->stencil_attachment_format = r_info->stencilAttachmentFormat;
1233 if (r_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)
1234 rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
1235
1236 const VkAttachmentSampleCountInfoAMD *asc_info =
1237 vk_get_pipeline_sample_count_info_amd(info);
1238 if (asc_info != NULL) {
1239 assert(asc_info->colorAttachmentCount == rp->color_attachment_count);
1240 for (uint32_t i = 0; i < asc_info->colorAttachmentCount; i++) {
1241 rp->color_attachment_samples[i] = asc_info->pColorAttachmentSamples[i];
1242 }
1243
1244 rp->depth_stencil_attachment_samples = asc_info->depthStencilAttachmentSamples;
1245 }
1246 }
1247
1248 static void
vk_dynamic_graphics_state_init_rp(struct vk_dynamic_graphics_state * dst,const BITSET_WORD * needed,const struct vk_render_pass_state * rp)1249 vk_dynamic_graphics_state_init_rp(struct vk_dynamic_graphics_state *dst,
1250 const BITSET_WORD *needed,
1251 const struct vk_render_pass_state *rp)
1252 {
1253 dst->rp.attachments = rp->attachments;
1254 }
1255
1256 #define FOREACH_STATE_GROUP(f) \
1257 f(MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT, \
1258 vk_vertex_input_state, vi); \
1259 f(MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT, \
1260 vk_input_assembly_state, ia); \
1261 f(MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT, \
1262 vk_tessellation_state, ts); \
1263 f(MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT, \
1264 vk_viewport_state, vp); \
1265 f(MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT, \
1266 vk_discard_rectangles_state, dr); \
1267 f(MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT, \
1268 vk_rasterization_state, rs); \
1269 f(MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT, \
1270 vk_fragment_shading_rate_state, fsr); \
1271 f(MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT, \
1272 vk_multisample_state, ms); \
1273 f(MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT, \
1274 vk_depth_stencil_state, ds); \
1275 f(MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT, \
1276 vk_color_blend_state, cb); \
1277 f(MESA_VK_GRAPHICS_STATE_INPUT_ATTACHMENT_MAP_BIT, \
1278 vk_input_attachment_location_state, ial); \
1279 f(MESA_VK_GRAPHICS_STATE_COLOR_ATTACHMENT_MAP_BIT, \
1280 vk_color_attachment_location_state, cal); \
1281 f(MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT, \
1282 vk_render_pass_state, rp);
1283
1284 static enum mesa_vk_graphics_state_groups
vk_graphics_pipeline_state_groups(const struct vk_graphics_pipeline_state * state)1285 vk_graphics_pipeline_state_groups(const struct vk_graphics_pipeline_state *state)
1286 {
1287 /* For now, we just validate dynamic state */
1288 enum mesa_vk_graphics_state_groups groups = 0;
1289
1290 #define FILL_HAS(STATE, type, s) \
1291 if (state->s != NULL) groups |= STATE
1292
1293 FOREACH_STATE_GROUP(FILL_HAS)
1294
1295 #undef FILL_HAS
1296
1297 return groups | fully_dynamic_state_groups(state->dynamic);
1298 }
1299
1300 void
vk_graphics_pipeline_get_state(const struct vk_graphics_pipeline_state * state,BITSET_WORD * set_state_out)1301 vk_graphics_pipeline_get_state(const struct vk_graphics_pipeline_state *state,
1302 BITSET_WORD *set_state_out)
1303 {
1304 /* For now, we just validate dynamic state */
1305 enum mesa_vk_graphics_state_groups groups = 0;
1306
1307 #define FILL_HAS(STATE, type, s) \
1308 if (state->s != NULL) groups |= STATE
1309
1310 FOREACH_STATE_GROUP(FILL_HAS)
1311
1312 #undef FILL_HAS
1313
1314 BITSET_DECLARE(set_state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1315 get_dynamic_state_groups(set_state, groups);
1316 BITSET_ANDNOT(set_state, set_state, state->dynamic);
1317 memcpy(set_state_out, set_state, sizeof(set_state));
1318 }
1319
1320 static void
vk_graphics_pipeline_state_validate(const struct vk_graphics_pipeline_state * state)1321 vk_graphics_pipeline_state_validate(const struct vk_graphics_pipeline_state *state)
1322 {
1323 #ifndef NDEBUG
1324 /* For now, we just validate dynamic state */
1325 enum mesa_vk_graphics_state_groups groups =
1326 vk_graphics_pipeline_state_groups(state);
1327 validate_dynamic_state_groups(state->dynamic, groups);
1328 #endif
1329 }
1330
1331 static bool
may_have_rasterization(const struct vk_graphics_pipeline_state * state,const BITSET_WORD * dynamic,const VkGraphicsPipelineCreateInfo * info)1332 may_have_rasterization(const struct vk_graphics_pipeline_state *state,
1333 const BITSET_WORD *dynamic,
1334 const VkGraphicsPipelineCreateInfo *info)
1335 {
1336 if (state->rs) {
1337 /* We default rasterizer_discard_enable to false when dynamic */
1338 return !state->rs->rasterizer_discard_enable;
1339 } else {
1340 return IS_DYNAMIC(RS_RASTERIZER_DISCARD_ENABLE) ||
1341 !info->pRasterizationState->rasterizerDiscardEnable;
1342 }
1343 }
1344
1345 VkResult
vk_graphics_pipeline_state_fill(const struct vk_device * device,struct vk_graphics_pipeline_state * state,const VkGraphicsPipelineCreateInfo * info,const struct vk_render_pass_state * driver_rp,VkPipelineCreateFlags2KHR driver_rp_flags,struct vk_graphics_pipeline_all_state * all,const VkAllocationCallbacks * alloc,VkSystemAllocationScope scope,void ** alloc_ptr_out)1346 vk_graphics_pipeline_state_fill(const struct vk_device *device,
1347 struct vk_graphics_pipeline_state *state,
1348 const VkGraphicsPipelineCreateInfo *info,
1349 const struct vk_render_pass_state *driver_rp,
1350 VkPipelineCreateFlags2KHR driver_rp_flags,
1351 struct vk_graphics_pipeline_all_state *all,
1352 const VkAllocationCallbacks *alloc,
1353 VkSystemAllocationScope scope,
1354 void **alloc_ptr_out)
1355 {
1356 vk_graphics_pipeline_state_validate(state);
1357
1358 BITSET_DECLARE(dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1359 vk_get_dynamic_graphics_states(dynamic, info->pDynamicState);
1360
1361 /*
1362 * First, figure out which library-level shader/state groups we need
1363 */
1364
1365 VkGraphicsPipelineLibraryFlagsEXT lib;
1366 const VkGraphicsPipelineLibraryCreateInfoEXT *gpl_info =
1367 vk_find_struct_const(info->pNext, GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
1368 const VkPipelineLibraryCreateInfoKHR *lib_info =
1369 vk_find_struct_const(info->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
1370
1371 VkShaderStageFlagBits allowed_stages;
1372 if (!(info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR)) {
1373 allowed_stages = VK_SHADER_STAGE_ALL_GRAPHICS |
1374 VK_SHADER_STAGE_TASK_BIT_EXT |
1375 VK_SHADER_STAGE_MESH_BIT_EXT;
1376 } else if (gpl_info) {
1377 allowed_stages = 0;
1378
1379 /* If we're creating a pipeline library without pre-rasterization,
1380 * discard all the associated stages.
1381 */
1382 if (gpl_info->flags &
1383 VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) {
1384 allowed_stages |= (VK_SHADER_STAGE_VERTEX_BIT |
1385 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
1386 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT |
1387 VK_SHADER_STAGE_GEOMETRY_BIT |
1388 VK_SHADER_STAGE_TASK_BIT_EXT |
1389 VK_SHADER_STAGE_MESH_BIT_EXT);
1390 }
1391
1392 /* If we're creating a pipeline library without fragment shader,
1393 * discard that stage.
1394 */
1395 if (gpl_info->flags &
1396 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)
1397 allowed_stages |= VK_SHADER_STAGE_FRAGMENT_BIT;
1398 } else {
1399 /* VkGraphicsPipelineLibraryCreateInfoEXT was omitted, flags should
1400 * be assumed to be empty and therefore no shader stage should be
1401 * considered.
1402 */
1403 allowed_stages = 0;
1404 }
1405
1406 for (uint32_t i = 0; i < info->stageCount; i++) {
1407 state->shader_stages |= info->pStages[i].stage & allowed_stages;
1408 }
1409
1410 /* In case we return early */
1411 if (alloc_ptr_out != NULL)
1412 *alloc_ptr_out = NULL;
1413
1414 if (gpl_info) {
1415 lib = gpl_info->flags;
1416 } else if ((lib_info && lib_info->libraryCount > 0) ||
1417 (info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR)) {
1418 /*
1419 * From the Vulkan 1.3.210 spec:
1420 * "If this structure is omitted, and either VkGraphicsPipelineCreateInfo::flags
1421 * includes VK_PIPELINE_CREATE_LIBRARY_BIT_KHR or the
1422 * VkGraphicsPipelineCreateInfo::pNext chain includes a
1423 * VkPipelineLibraryCreateInfoKHR structure with a libraryCount greater than 0,
1424 * it is as if flags is 0. Otherwise if this structure is omitted, it is as if
1425 * flags includes all possible subsets of the graphics pipeline."
1426 */
1427 lib = 0;
1428 } else {
1429 /* We're building a complete pipeline. From the Vulkan 1.3.218 spec:
1430 *
1431 * "A complete graphics pipeline always includes pre-rasterization
1432 * shader state, with other subsets included depending on that state.
1433 * If the pre-rasterization shader state includes a vertex shader,
1434 * then vertex input state is included in a complete graphics
1435 * pipeline. If the value of
1436 * VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable in
1437 * the pre-rasterization shader state is VK_FALSE or the
1438 * VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE dynamic state is
1439 * enabled fragment shader state and fragment output interface state
1440 * is included in a complete graphics pipeline."
1441 */
1442 lib = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
1443
1444 if (state->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
1445 lib |= VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
1446
1447 if (may_have_rasterization(state, dynamic, info)) {
1448 lib |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
1449 lib |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
1450 }
1451 }
1452
1453 /*
1454 * Next, turn those into individual states. Among other things, this
1455 * de-duplicates things like FSR and multisample state which appear in
1456 * multiple library groups.
1457 */
1458
1459 enum mesa_vk_graphics_state_groups needs = 0;
1460 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) {
1461 needs |= MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT;
1462 needs |= MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT;
1463 }
1464
1465 /* Other stuff potentially depends on this so gather it early */
1466 struct vk_render_pass_state rp;
1467 if (lib & (VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
1468 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
1469 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
1470 vk_render_pass_state_init(&rp, state->rp, driver_rp, info, lib);
1471
1472 needs |= MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT;
1473
1474 /* If the old state was incomplete but the new one isn't, set state->rp
1475 * to NULL so it gets replaced with the new version.
1476 */
1477 if (state->rp != NULL &&
1478 !vk_render_pass_state_has_attachment_info(state->rp) &&
1479 !vk_render_pass_state_has_attachment_info(&rp))
1480 state->rp = NULL;
1481 }
1482
1483 if (lib & (VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
1484 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
1485 vk_pipeline_flags_init(state, driver_rp_flags, !!driver_rp, info, dynamic, lib);
1486 }
1487
1488 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) {
1489 /* From the Vulkan 1.3.218 spec:
1490 *
1491 * VUID-VkGraphicsPipelineCreateInfo-stage-02096
1492 *
1493 * "If the pipeline is being created with pre-rasterization shader
1494 * state the stage member of one element of pStages must be either
1495 * VK_SHADER_STAGE_VERTEX_BIT or VK_SHADER_STAGE_MESH_BIT_EXT"
1496 */
1497 assert(state->shader_stages & (VK_SHADER_STAGE_VERTEX_BIT |
1498 VK_SHADER_STAGE_MESH_BIT_EXT));
1499
1500 if (state->shader_stages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
1501 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
1502 needs |= MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT;
1503
1504 if (may_have_rasterization(state, dynamic, info))
1505 needs |= MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT;
1506
1507 needs |= MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT;
1508 needs |= MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT;
1509 needs |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT;
1510 }
1511
1512 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
1513 needs |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT;
1514
1515 /* From the Vulkan 1.3.218 spec:
1516 *
1517 * "Fragment shader state is defined by:
1518 * ...
1519 * - VkPipelineMultisampleStateCreateInfo if sample shading is
1520 * enabled or renderpass is not VK_NULL_HANDLE"
1521 *
1522 * and
1523 *
1524 * VUID-VkGraphicsPipelineCreateInfo-pMultisampleState-06629
1525 *
1526 * "If the pipeline is being created with fragment shader state
1527 * pMultisampleState must be NULL or a valid pointer to a valid
1528 * VkPipelineMultisampleStateCreateInfo structure"
1529 *
1530 * so we can reliably detect when to include it based on the
1531 * pMultisampleState pointer.
1532 */
1533 if (info->pMultisampleState != NULL)
1534 needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT;
1535
1536 /* From the Vulkan 1.3.218 spec:
1537 *
1538 * VUID-VkGraphicsPipelineCreateInfo-renderPass-06043
1539 *
1540 * "If renderPass is not VK_NULL_HANDLE, the pipeline is being
1541 * created with fragment shader state, and subpass uses a
1542 * depth/stencil attachment, pDepthStencilState must be a valid
1543 * pointer to a valid VkPipelineDepthStencilStateCreateInfo
1544 * structure"
1545 *
1546 * VUID-VkGraphicsPipelineCreateInfo-renderPass-06053
1547 *
1548 * "If renderPass is VK_NULL_HANDLE, the pipeline is being created
1549 * with fragment shader state and fragment output interface state,
1550 * and either of VkPipelineRenderingCreateInfo::depthAttachmentFormat
1551 * or VkPipelineRenderingCreateInfo::stencilAttachmentFormat are not
1552 * VK_FORMAT_UNDEFINED, pDepthStencilState must be a valid pointer to
1553 * a valid VkPipelineDepthStencilStateCreateInfo structure"
1554 *
1555 * VUID-VkGraphicsPipelineCreateInfo-renderPass-06590
1556 *
1557 * "If renderPass is VK_NULL_HANDLE and the pipeline is being created
1558 * with fragment shader state but not fragment output interface
1559 * state, pDepthStencilState must be a valid pointer to a valid
1560 * VkPipelineDepthStencilStateCreateInfo structure"
1561 *
1562 * In the first case, we'll have a real set of aspects in rp. In the
1563 * second case, where we have both fragment shader and fragment output
1564 * state, we will also have a valid set of aspects. In the third case
1565 * where we only have fragment shader state and no render pass, the
1566 * vk_render_pass_state will be incomplete.
1567 */
1568 if (!vk_render_pass_state_has_attachment_info(&rp) ||
1569 (rp.attachments & (MESA_VK_RP_ATTACHMENT_DEPTH_BIT |
1570 MESA_VK_RP_ATTACHMENT_STENCIL_BIT)))
1571 needs |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT;
1572
1573 needs |= MESA_VK_GRAPHICS_STATE_INPUT_ATTACHMENT_MAP_BIT;
1574 }
1575
1576 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) {
1577 if (rp.attachments & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)
1578 needs |= MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT;
1579
1580 needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT;
1581
1582 needs |= MESA_VK_GRAPHICS_STATE_COLOR_ATTACHMENT_MAP_BIT;
1583 }
1584
1585 /*
1586 * Next, Filter off any states we already have.
1587 */
1588
1589 #define FILTER_NEEDS(STATE, type, s) \
1590 if (state->s != NULL) needs &= ~STATE
1591
1592 FOREACH_STATE_GROUP(FILTER_NEEDS)
1593
1594 #undef FILTER_NEEDS
1595
1596 /* Filter dynamic state down to just what we're adding */
1597 BITSET_DECLARE(dynamic_filter, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1598 get_dynamic_state_groups(dynamic_filter, needs);
1599
1600 /* Attachment feedback loop state is part of the renderpass state in mesa
1601 * because attachment feedback loops can also come from the render pass,
1602 * but in Vulkan it is part of the fragment output interface. The
1603 * renderpass state also exists, possibly in an incomplete state, in other
1604 * stages for things like the view mask, but it does not contain the
1605 * feedback loop flags. In those other stages we have to ignore
1606 * VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT, even though it is
1607 * part of a state group that exists in those stages.
1608 */
1609 if (!(lib &
1610 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
1611 BITSET_CLEAR(dynamic_filter,
1612 MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE);
1613 }
1614
1615 BITSET_AND(dynamic, dynamic, dynamic_filter);
1616
1617 /* And add it in */
1618 BITSET_OR(state->dynamic, state->dynamic, dynamic);
1619
1620 /*
1621 * If a state is fully dynamic, we don't need to even allocate them. Do
1622 * this after we've filtered dynamic state because we still want them to
1623 * show up in the dynamic state but don't want the actual state.
1624 */
1625 needs &= ~fully_dynamic_state_groups(state->dynamic);
1626
1627 /* If we don't need to set up any new states, bail early */
1628 if (needs == 0)
1629 return VK_SUCCESS;
1630
1631 /*
1632 * Now, ensure that we have space for each of the states we're going to
1633 * fill. If all != NULL, we'll pull from that. Otherwise, we need to
1634 * allocate memory.
1635 */
1636
1637 VK_MULTIALLOC(ma);
1638
1639 #define ENSURE_STATE_IF_NEEDED(STATE, type, s) \
1640 struct type *new_##s = NULL; \
1641 if (needs & STATE) { \
1642 if (all == NULL) { \
1643 vk_multialloc_add(&ma, &new_##s, struct type, 1); \
1644 } else { \
1645 new_##s = &all->s; \
1646 } \
1647 }
1648
1649 FOREACH_STATE_GROUP(ENSURE_STATE_IF_NEEDED)
1650
1651 #undef ENSURE_STATE_IF_NEEDED
1652
1653 /* Sample locations are a bit special. We don't want to waste the memory
1654 * for 64 floats if we don't need to. Also, we set up standard sample
1655 * locations if no user-provided sample locations are available.
1656 */
1657 const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info = NULL;
1658 struct vk_sample_locations_state *new_sl = NULL;
1659 if (needs & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) {
1660 if (info->pMultisampleState)
1661 sl_info = vk_find_struct_const(info->pMultisampleState->pNext,
1662 PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT);
1663 if (needs_sample_locations_state(dynamic, sl_info)) {
1664 if (all == NULL) {
1665 vk_multialloc_add(&ma, &new_sl, struct vk_sample_locations_state, 1);
1666 } else {
1667 new_sl = &all->ms_sample_locations;
1668 }
1669 }
1670 }
1671
1672 /*
1673 * Allocate memory, if needed
1674 */
1675
1676 if (ma.size > 0) {
1677 assert(all == NULL);
1678 *alloc_ptr_out = vk_multialloc_alloc2(&ma, &device->alloc, alloc, scope);
1679 if (*alloc_ptr_out == NULL)
1680 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1681 }
1682
1683 /*
1684 * Create aliases for various input infos so we can use or FOREACH macro
1685 */
1686
1687 #define INFO_ALIAS(_State, s) \
1688 const VkPipeline##_State##StateCreateInfo *s##_info = info->p##_State##State
1689
1690 INFO_ALIAS(VertexInput, vi);
1691 INFO_ALIAS(InputAssembly, ia);
1692 INFO_ALIAS(Tessellation, ts);
1693 INFO_ALIAS(Viewport, vp);
1694 INFO_ALIAS(Rasterization, rs);
1695 INFO_ALIAS(Multisample, ms);
1696 INFO_ALIAS(DepthStencil, ds);
1697 INFO_ALIAS(ColorBlend, cb);
1698
1699 #undef INFO_ALIAS
1700
1701 const VkPipelineDiscardRectangleStateCreateInfoEXT *dr_info =
1702 vk_find_struct_const(info->pNext, PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT);
1703
1704 const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info =
1705 vk_find_struct_const(info->pNext, PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR);
1706
1707 const VkRenderingInputAttachmentIndexInfoKHR *ial_info =
1708 vk_find_struct_const(info->pNext, RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR);
1709 const VkRenderingAttachmentLocationInfoKHR *cal_info =
1710 vk_find_struct_const(info->pNext, RENDERING_ATTACHMENT_LOCATION_INFO_KHR);
1711
1712 /*
1713 * Finally, fill out all the states
1714 */
1715
1716 #define INIT_STATE_IF_NEEDED(STATE, type, s) \
1717 if (needs & STATE) { \
1718 type##_init(new_##s, dynamic, s##_info); \
1719 state->s = new_##s; \
1720 }
1721
1722 /* render pass state is special and we just copy it */
1723 #define vk_render_pass_state_init(s, d, i) *s = rp
1724
1725 FOREACH_STATE_GROUP(INIT_STATE_IF_NEEDED)
1726
1727 #undef vk_render_pass_state_init
1728 #undef INIT_STATE_IF_NEEDED
1729
1730 if (needs & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) {
1731 vk_multisample_sample_locations_state_init(new_ms, new_sl, dynamic,
1732 ms_info, sl_info);
1733 }
1734
1735 return VK_SUCCESS;
1736 }
1737
1738 #undef IS_DYNAMIC
1739 #undef IS_NEEDED
1740
1741 void
vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state * dst,const struct vk_graphics_pipeline_state * src)1742 vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst,
1743 const struct vk_graphics_pipeline_state *src)
1744 {
1745 vk_graphics_pipeline_state_validate(dst);
1746 vk_graphics_pipeline_state_validate(src);
1747
1748 BITSET_OR(dst->dynamic, dst->dynamic, src->dynamic);
1749
1750 dst->shader_stages |= src->shader_stages;
1751
1752 dst->pipeline_flags |= src->pipeline_flags;
1753 dst->feedback_loop_not_input_only |= src->feedback_loop_not_input_only;
1754
1755 /* Render pass state needs special care because a render pass state may be
1756 * incomplete (view mask only). See vk_render_pass_state_init().
1757 */
1758 if (dst->rp != NULL && src->rp != NULL &&
1759 !vk_render_pass_state_has_attachment_info(dst->rp) &&
1760 vk_render_pass_state_has_attachment_info(src->rp))
1761 dst->rp = src->rp;
1762
1763 #define MERGE(STATE, type, state) \
1764 if (dst->state == NULL && src->state != NULL) dst->state = src->state;
1765
1766 FOREACH_STATE_GROUP(MERGE)
1767
1768 #undef MERGE
1769 }
1770
1771 static bool
is_group_all_dynamic(const struct vk_graphics_pipeline_state * state,enum mesa_vk_graphics_state_groups group)1772 is_group_all_dynamic(const struct vk_graphics_pipeline_state *state,
1773 enum mesa_vk_graphics_state_groups group)
1774 {
1775 /* Render pass is a bit special, because it contains always-static state
1776 * (e.g. the view mask). It's never all dynamic.
1777 */
1778 if (group == MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT)
1779 return false;
1780
1781 BITSET_DECLARE(group_state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1782 BITSET_DECLARE(dynamic_state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1783 get_dynamic_state_groups(group_state, group);
1784 BITSET_AND(dynamic_state, group_state, state->dynamic);
1785 return BITSET_EQUAL(dynamic_state, group_state);
1786 }
1787
1788 VkResult
vk_graphics_pipeline_state_copy(const struct vk_device * device,struct vk_graphics_pipeline_state * state,const struct vk_graphics_pipeline_state * old_state,const VkAllocationCallbacks * alloc,VkSystemAllocationScope scope,void ** alloc_ptr_out)1789 vk_graphics_pipeline_state_copy(const struct vk_device *device,
1790 struct vk_graphics_pipeline_state *state,
1791 const struct vk_graphics_pipeline_state *old_state,
1792 const VkAllocationCallbacks *alloc,
1793 VkSystemAllocationScope scope,
1794 void **alloc_ptr_out)
1795 {
1796 vk_graphics_pipeline_state_validate(old_state);
1797
1798 VK_MULTIALLOC(ma);
1799
1800 #define ENSURE_STATE_IF_NEEDED(STATE, type, s) \
1801 struct type *new_##s = NULL; \
1802 if (old_state->s && !is_group_all_dynamic(state, STATE)) { \
1803 vk_multialloc_add(&ma, &new_##s, struct type, 1); \
1804 }
1805
1806 FOREACH_STATE_GROUP(ENSURE_STATE_IF_NEEDED)
1807
1808 #undef ENSURE_STATE_IF_NEEDED
1809
1810 /* Sample locations are a bit special. */
1811 struct vk_sample_locations_state *new_sample_locations = NULL;
1812 if (old_state->ms && old_state->ms->sample_locations &&
1813 !BITSET_TEST(old_state->dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS)) {
1814 assert(old_state->ms->sample_locations);
1815 vk_multialloc_add(&ma, &new_sample_locations,
1816 struct vk_sample_locations_state, 1);
1817 }
1818
1819 if (ma.size > 0) {
1820 *alloc_ptr_out = vk_multialloc_alloc2(&ma, &device->alloc, alloc, scope);
1821 if (*alloc_ptr_out == NULL)
1822 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1823 }
1824
1825 if (new_sample_locations) {
1826 *new_sample_locations = *old_state->ms->sample_locations;
1827 }
1828
1829 #define COPY_STATE_IF_NEEDED(STATE, type, s) \
1830 if (new_##s) { \
1831 *new_##s = *old_state->s; \
1832 } \
1833 state->s = new_##s;
1834
1835 FOREACH_STATE_GROUP(COPY_STATE_IF_NEEDED)
1836
1837 if (new_ms) {
1838 new_ms->sample_locations = new_sample_locations;
1839 }
1840
1841 state->shader_stages = old_state->shader_stages;
1842 BITSET_COPY(state->dynamic, old_state->dynamic);
1843
1844 #undef COPY_STATE_IF_NEEDED
1845
1846 state->pipeline_flags = old_state->pipeline_flags;
1847 state->feedback_loop_not_input_only =
1848 old_state->feedback_loop_not_input_only;
1849
1850 vk_graphics_pipeline_state_validate(state);
1851 return VK_SUCCESS;
1852 }
1853
1854 const struct vk_dynamic_graphics_state vk_default_dynamic_graphics_state = {
1855 .rs = {
1856 .line = {
1857 .width = 1.0f,
1858 },
1859 },
1860 .fsr = {
1861 .fragment_size = {1u, 1u},
1862 .combiner_ops = {
1863 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1864 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1865 },
1866 },
1867 .ds = {
1868 .depth = {
1869 .bounds_test = {
1870 .min = 0.0f,
1871 .max = 1.0f,
1872 },
1873 },
1874 .stencil = {
1875 .write_enable = true,
1876 .front = {
1877 .compare_mask = -1,
1878 .write_mask = -1,
1879 },
1880 .back = {
1881 .compare_mask = -1,
1882 .write_mask = -1,
1883 },
1884 },
1885 },
1886 .cb = {
1887 .color_write_enables = 0xffu,
1888 .attachment_count = MESA_VK_MAX_COLOR_ATTACHMENTS,
1889 },
1890 .ial = {
1891 .color_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
1892 .depth_att = MESA_VK_ATTACHMENT_UNUSED,
1893 .stencil_att = MESA_VK_ATTACHMENT_UNUSED,
1894 },
1895 .cal = {
1896 .color_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
1897 },
1898 };
1899
1900 void
vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state * dyn)1901 vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn)
1902 {
1903 *dyn = vk_default_dynamic_graphics_state;
1904 }
1905
1906 void
vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state * dyn)1907 vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn)
1908 {
1909 struct vk_vertex_input_state *vi = dyn->vi;
1910 struct vk_sample_locations_state *sl = dyn->ms.sample_locations;
1911
1912 *dyn = vk_default_dynamic_graphics_state;
1913
1914 if (vi != NULL) {
1915 memset(vi, 0, sizeof(*vi));
1916 dyn->vi = vi;
1917 }
1918
1919 if (sl != NULL) {
1920 memset(sl, 0, sizeof(*sl));
1921 dyn->ms.sample_locations = sl;
1922 }
1923 }
1924
1925 void
vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state * dyn,const struct vk_graphics_pipeline_state * p)1926 vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn,
1927 const struct vk_graphics_pipeline_state *p)
1928 {
1929 /* This funciton (and the individual vk_dynamic_graphics_state_init_*
1930 * functions it calls) are a bit sloppy. Instead of checking every single
1931 * bit, we just copy everything and set the bits the right way at the end
1932 * based on what groups we actually had.
1933 */
1934 enum mesa_vk_graphics_state_groups groups = 0;
1935
1936 BITSET_DECLARE(needed, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
1937 BITSET_COPY(needed, p->dynamic);
1938 BITSET_NOT(needed);
1939
1940 /* We only want to copy these if the driver has filled out the relevant
1941 * pointer in the dynamic state struct. If not, they don't support them
1942 * as dynamic state and we should leave them alone.
1943 */
1944 if (dyn->vi == NULL)
1945 BITSET_CLEAR(needed, MESA_VK_DYNAMIC_VI);
1946 if (dyn->ms.sample_locations == NULL)
1947 BITSET_CLEAR(needed, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS);
1948
1949 #define INIT_DYNAMIC_STATE(STATE, type, s) \
1950 if (p->s != NULL) { \
1951 vk_dynamic_graphics_state_init_##s(dyn, needed, p->s); \
1952 groups |= STATE; \
1953 }
1954
1955 FOREACH_STATE_GROUP(INIT_DYNAMIC_STATE);
1956
1957 #undef INIT_DYNAMIC_STATE
1958
1959 /* Feedback loop state is weird: implicit feedback loops from the
1960 * renderpass and dynamically-enabled feedback loops can in theory both be
1961 * enabled independently, so we can't just use one field; instead drivers
1962 * have to OR the pipeline state (in vk_render_pass_state::pipeline_flags)
1963 * and dynamic state. Due to this it isn't worth tracking
1964 * implicit render pass flags vs. pipeline flags in the pipeline state, and
1965 * we just combine the two in vk_render_pass_flags_init() and don't bother
1966 * setting the dynamic state from the pipeline here, instead just making
1967 * sure the dynamic state is reset to 0 when feedback loop state is static.
1968 */
1969 dyn->feedback_loops = 0;
1970
1971 get_dynamic_state_groups(dyn->set, groups);
1972
1973 /* Vertex input state is always included in a complete pipeline. If p->vi
1974 * is NULL, that means that it has been precompiled by the driver, but we
1975 * should still track vi_bindings_valid.
1976 */
1977 BITSET_SET(dyn->set, MESA_VK_DYNAMIC_VI_BINDINGS_VALID);
1978
1979 /* If the pipeline doesn't render any color attachments, we should still
1980 * keep track of the fact that it writes 0 attachments, even though none of
1981 * the other blend states will be initialized. Normally this would be
1982 * initialized with the other blend states.
1983 */
1984 if (!p->rp || !(p->rp->attachments & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)) {
1985 dyn->cb.attachment_count = 0;
1986 BITSET_SET(dyn->set, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT);
1987 }
1988
1989 /* Mask off all but the groups we actually found */
1990 BITSET_AND(dyn->set, dyn->set, needed);
1991 }
1992
1993 #define SET_DYN_VALUE(dst, STATE, state, value) do { \
1994 if (!BITSET_TEST((dst)->set, MESA_VK_DYNAMIC_##STATE) || \
1995 (dst)->state != (value)) { \
1996 (dst)->state = (value); \
1997 assert((dst)->state == (value)); \
1998 BITSET_SET(dst->set, MESA_VK_DYNAMIC_##STATE); \
1999 BITSET_SET(dst->dirty, MESA_VK_DYNAMIC_##STATE); \
2000 } \
2001 } while(0)
2002
2003 #define SET_DYN_BOOL(dst, STATE, state, value) \
2004 SET_DYN_VALUE(dst, STATE, state, (bool)value);
2005
2006 #define SET_DYN_ARRAY(dst, STATE, state, start, count, src) do { \
2007 assert(start + count <= ARRAY_SIZE((dst)->state)); \
2008 STATIC_ASSERT(sizeof(*(dst)->state) == sizeof(*(src))); \
2009 const size_t __state_size = sizeof(*(dst)->state) * (count); \
2010 if (!BITSET_TEST((dst)->set, MESA_VK_DYNAMIC_##STATE) || \
2011 memcmp((dst)->state + start, src, __state_size)) { \
2012 memcpy((dst)->state + start, src, __state_size); \
2013 BITSET_SET(dst->set, MESA_VK_DYNAMIC_##STATE); \
2014 BITSET_SET(dst->dirty, MESA_VK_DYNAMIC_##STATE); \
2015 } \
2016 } while(0)
2017
2018 void
vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state * dst,const struct vk_dynamic_graphics_state * src)2019 vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst,
2020 const struct vk_dynamic_graphics_state *src)
2021 {
2022 #define IS_SET_IN_SRC(STATE) \
2023 BITSET_TEST(src->set, MESA_VK_DYNAMIC_##STATE)
2024
2025 #define COPY_MEMBER(STATE, state) \
2026 SET_DYN_VALUE(dst, STATE, state, src->state)
2027
2028 #define COPY_ARRAY(STATE, state, count) \
2029 SET_DYN_ARRAY(dst, STATE, state, 0, count, src->state)
2030
2031 #define COPY_IF_SET(STATE, state) \
2032 if (IS_SET_IN_SRC(STATE)) SET_DYN_VALUE(dst, STATE, state, src->state)
2033
2034 if (IS_SET_IN_SRC(VI)) {
2035 assert(dst->vi != NULL);
2036 COPY_MEMBER(VI, vi->bindings_valid);
2037 u_foreach_bit(b, src->vi->bindings_valid) {
2038 COPY_MEMBER(VI, vi->bindings[b].stride);
2039 COPY_MEMBER(VI, vi->bindings[b].input_rate);
2040 COPY_MEMBER(VI, vi->bindings[b].divisor);
2041 }
2042 COPY_MEMBER(VI, vi->attributes_valid);
2043 u_foreach_bit(a, src->vi->attributes_valid) {
2044 COPY_MEMBER(VI, vi->attributes[a].binding);
2045 COPY_MEMBER(VI, vi->attributes[a].format);
2046 COPY_MEMBER(VI, vi->attributes[a].offset);
2047 }
2048 }
2049
2050 if (IS_SET_IN_SRC(VI_BINDINGS_VALID))
2051 COPY_MEMBER(VI_BINDINGS_VALID, vi_bindings_valid);
2052
2053 if (IS_SET_IN_SRC(VI_BINDING_STRIDES)) {
2054 assert(IS_SET_IN_SRC(VI_BINDINGS_VALID));
2055 u_foreach_bit(a, src->vi_bindings_valid) {
2056 COPY_MEMBER(VI_BINDING_STRIDES, vi_binding_strides[a]);
2057 }
2058 }
2059
2060 COPY_IF_SET(IA_PRIMITIVE_TOPOLOGY, ia.primitive_topology);
2061 COPY_IF_SET(IA_PRIMITIVE_RESTART_ENABLE, ia.primitive_restart_enable);
2062 COPY_IF_SET(TS_PATCH_CONTROL_POINTS, ts.patch_control_points);
2063 COPY_IF_SET(TS_DOMAIN_ORIGIN, ts.domain_origin);
2064
2065 COPY_IF_SET(VP_VIEWPORT_COUNT, vp.viewport_count);
2066 if (IS_SET_IN_SRC(VP_VIEWPORTS)) {
2067 assert(IS_SET_IN_SRC(VP_VIEWPORT_COUNT));
2068 COPY_ARRAY(VP_VIEWPORTS, vp.viewports, src->vp.viewport_count);
2069 }
2070
2071 COPY_IF_SET(VP_SCISSOR_COUNT, vp.scissor_count);
2072 if (IS_SET_IN_SRC(VP_SCISSORS)) {
2073 assert(IS_SET_IN_SRC(VP_SCISSOR_COUNT));
2074 COPY_ARRAY(VP_SCISSORS, vp.scissors, src->vp.scissor_count);
2075 }
2076
2077 COPY_IF_SET(VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,
2078 vp.depth_clip_negative_one_to_one);
2079
2080 COPY_IF_SET(DR_ENABLE, dr.enable);
2081 COPY_IF_SET(DR_MODE, dr.mode);
2082 if (IS_SET_IN_SRC(DR_RECTANGLES)) {
2083 COPY_MEMBER(DR_RECTANGLES, dr.rectangle_count);
2084 COPY_ARRAY(DR_RECTANGLES, dr.rectangles, src->dr.rectangle_count);
2085 }
2086
2087 COPY_IF_SET(RS_RASTERIZER_DISCARD_ENABLE, rs.rasterizer_discard_enable);
2088 COPY_IF_SET(RS_DEPTH_CLAMP_ENABLE, rs.depth_clamp_enable);
2089 COPY_IF_SET(RS_DEPTH_CLIP_ENABLE, rs.depth_clip_enable);
2090 COPY_IF_SET(RS_POLYGON_MODE, rs.polygon_mode);
2091 COPY_IF_SET(RS_CULL_MODE, rs.cull_mode);
2092 COPY_IF_SET(RS_FRONT_FACE, rs.front_face);
2093 COPY_IF_SET(RS_CONSERVATIVE_MODE, rs.conservative_mode);
2094 COPY_IF_SET(RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE,
2095 rs.extra_primitive_overestimation_size);
2096 COPY_IF_SET(RS_RASTERIZATION_ORDER_AMD, rs.rasterization_order_amd);
2097 COPY_IF_SET(RS_PROVOKING_VERTEX, rs.provoking_vertex);
2098 COPY_IF_SET(RS_RASTERIZATION_STREAM, rs.rasterization_stream);
2099 COPY_IF_SET(RS_DEPTH_BIAS_ENABLE, rs.depth_bias.enable);
2100 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.constant);
2101 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.clamp);
2102 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.slope);
2103 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.representation);
2104 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.exact);
2105 COPY_IF_SET(RS_LINE_WIDTH, rs.line.width);
2106 COPY_IF_SET(RS_LINE_MODE, rs.line.mode);
2107 COPY_IF_SET(RS_LINE_STIPPLE_ENABLE, rs.line.stipple.enable);
2108 COPY_IF_SET(RS_LINE_STIPPLE, rs.line.stipple.factor);
2109 COPY_IF_SET(RS_LINE_STIPPLE, rs.line.stipple.pattern);
2110
2111 COPY_IF_SET(FSR, fsr.fragment_size.width);
2112 COPY_IF_SET(FSR, fsr.fragment_size.height);
2113 COPY_IF_SET(FSR, fsr.combiner_ops[0]);
2114 COPY_IF_SET(FSR, fsr.combiner_ops[1]);
2115
2116 COPY_IF_SET(MS_RASTERIZATION_SAMPLES, ms.rasterization_samples);
2117 COPY_IF_SET(MS_SAMPLE_MASK, ms.sample_mask);
2118 COPY_IF_SET(MS_ALPHA_TO_COVERAGE_ENABLE, ms.alpha_to_coverage_enable);
2119 COPY_IF_SET(MS_ALPHA_TO_ONE_ENABLE, ms.alpha_to_one_enable);
2120 COPY_IF_SET(MS_SAMPLE_LOCATIONS_ENABLE, ms.sample_locations_enable);
2121
2122 if (IS_SET_IN_SRC(MS_SAMPLE_LOCATIONS)) {
2123 assert(dst->ms.sample_locations != NULL);
2124 COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->per_pixel);
2125 COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->grid_size.width);
2126 COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->grid_size.height);
2127 const uint32_t sl_count = src->ms.sample_locations->per_pixel *
2128 src->ms.sample_locations->grid_size.width *
2129 src->ms.sample_locations->grid_size.height;
2130 COPY_ARRAY(MS_SAMPLE_LOCATIONS, ms.sample_locations->locations, sl_count);
2131 }
2132
2133 COPY_IF_SET(DS_DEPTH_TEST_ENABLE, ds.depth.test_enable);
2134 COPY_IF_SET(DS_DEPTH_WRITE_ENABLE, ds.depth.write_enable);
2135 COPY_IF_SET(DS_DEPTH_COMPARE_OP, ds.depth.compare_op);
2136 COPY_IF_SET(DS_DEPTH_BOUNDS_TEST_ENABLE, ds.depth.bounds_test.enable);
2137 if (IS_SET_IN_SRC(DS_DEPTH_BOUNDS_TEST_BOUNDS)) {
2138 COPY_MEMBER(DS_DEPTH_BOUNDS_TEST_BOUNDS, ds.depth.bounds_test.min);
2139 COPY_MEMBER(DS_DEPTH_BOUNDS_TEST_BOUNDS, ds.depth.bounds_test.max);
2140 }
2141
2142 COPY_IF_SET(DS_STENCIL_TEST_ENABLE, ds.stencil.test_enable);
2143 if (IS_SET_IN_SRC(DS_STENCIL_OP)) {
2144 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.fail);
2145 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.pass);
2146 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.depth_fail);
2147 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.compare);
2148 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.fail);
2149 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.pass);
2150 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.depth_fail);
2151 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.compare);
2152 }
2153 if (IS_SET_IN_SRC(DS_STENCIL_COMPARE_MASK)) {
2154 COPY_MEMBER(DS_STENCIL_COMPARE_MASK, ds.stencil.front.compare_mask);
2155 COPY_MEMBER(DS_STENCIL_COMPARE_MASK, ds.stencil.back.compare_mask);
2156 }
2157 if (IS_SET_IN_SRC(DS_STENCIL_WRITE_MASK)) {
2158 COPY_MEMBER(DS_STENCIL_WRITE_MASK, ds.stencil.front.write_mask);
2159 COPY_MEMBER(DS_STENCIL_WRITE_MASK, ds.stencil.back.write_mask);
2160 }
2161 if (IS_SET_IN_SRC(DS_STENCIL_REFERENCE)) {
2162 COPY_MEMBER(DS_STENCIL_REFERENCE, ds.stencil.front.reference);
2163 COPY_MEMBER(DS_STENCIL_REFERENCE, ds.stencil.back.reference);
2164 }
2165
2166 COPY_IF_SET(CB_LOGIC_OP_ENABLE, cb.logic_op_enable);
2167 COPY_IF_SET(CB_LOGIC_OP, cb.logic_op);
2168 COPY_IF_SET(CB_ATTACHMENT_COUNT, cb.attachment_count);
2169 COPY_IF_SET(CB_COLOR_WRITE_ENABLES, cb.color_write_enables);
2170 if (IS_SET_IN_SRC(CB_BLEND_ENABLES)) {
2171 for (uint32_t a = 0; a < src->cb.attachment_count; a++)
2172 COPY_MEMBER(CB_BLEND_ENABLES, cb.attachments[a].blend_enable);
2173 }
2174 if (IS_SET_IN_SRC(CB_BLEND_EQUATIONS)) {
2175 for (uint32_t a = 0; a < src->cb.attachment_count; a++) {
2176 COPY_MEMBER(CB_BLEND_EQUATIONS,
2177 cb.attachments[a].src_color_blend_factor);
2178 COPY_MEMBER(CB_BLEND_EQUATIONS,
2179 cb.attachments[a].dst_color_blend_factor);
2180 COPY_MEMBER(CB_BLEND_EQUATIONS,
2181 cb.attachments[a].src_alpha_blend_factor);
2182 COPY_MEMBER(CB_BLEND_EQUATIONS,
2183 cb.attachments[a].dst_alpha_blend_factor);
2184 COPY_MEMBER(CB_BLEND_EQUATIONS, cb.attachments[a].color_blend_op);
2185 COPY_MEMBER(CB_BLEND_EQUATIONS, cb.attachments[a].alpha_blend_op);
2186 }
2187 }
2188 if (IS_SET_IN_SRC(CB_WRITE_MASKS)) {
2189 for (uint32_t a = 0; a < src->cb.attachment_count; a++)
2190 COPY_MEMBER(CB_WRITE_MASKS, cb.attachments[a].write_mask);
2191 }
2192 if (IS_SET_IN_SRC(CB_BLEND_CONSTANTS))
2193 COPY_ARRAY(CB_BLEND_CONSTANTS, cb.blend_constants, 4);
2194
2195 COPY_IF_SET(RP_ATTACHMENTS, rp.attachments);
2196
2197 if (IS_SET_IN_SRC(COLOR_ATTACHMENT_MAP)) {
2198 COPY_ARRAY(COLOR_ATTACHMENT_MAP, cal.color_map,
2199 MESA_VK_MAX_COLOR_ATTACHMENTS);
2200 }
2201
2202 COPY_IF_SET(ATTACHMENT_FEEDBACK_LOOP_ENABLE, feedback_loops);
2203
2204 #undef IS_SET_IN_SRC
2205 #undef MARK_DIRTY
2206 #undef COPY_MEMBER
2207 #undef COPY_ARRAY
2208 #undef COPY_IF_SET
2209
2210 for (uint32_t w = 0; w < ARRAY_SIZE(dst->dirty); w++) {
2211 /* If it's in the source but isn't set in the destination at all, mark
2212 * it dirty. It's possible that the default values just happen to equal
2213 * the value from src.
2214 */
2215 dst->dirty[w] |= src->set[w] & ~dst->set[w];
2216
2217 /* Everything that was in the source is now in the destination */
2218 dst->set[w] |= src->set[w];
2219 }
2220 }
2221
2222 void
vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer * cmd,const struct vk_dynamic_graphics_state * state)2223 vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer *cmd,
2224 const struct vk_dynamic_graphics_state *state)
2225 {
2226 vk_dynamic_graphics_state_copy(&cmd->dynamic_graphics_state, state);
2227 }
2228
2229 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer,uint32_t vertexBindingDescriptionCount,const VkVertexInputBindingDescription2EXT * pVertexBindingDescriptions,uint32_t vertexAttributeDescriptionCount,const VkVertexInputAttributeDescription2EXT * pVertexAttributeDescriptions)2230 vk_common_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer,
2231 uint32_t vertexBindingDescriptionCount,
2232 const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions,
2233 uint32_t vertexAttributeDescriptionCount,
2234 const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions)
2235 {
2236 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2237 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2238
2239 uint32_t bindings_valid = 0;
2240 for (uint32_t i = 0; i < vertexBindingDescriptionCount; i++) {
2241 const VkVertexInputBindingDescription2EXT *desc =
2242 &pVertexBindingDescriptions[i];
2243
2244 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
2245 assert(desc->stride <= MESA_VK_MAX_VERTEX_BINDING_STRIDE);
2246 assert(desc->inputRate <= UINT8_MAX);
2247
2248 const uint32_t b = desc->binding;
2249 bindings_valid |= BITFIELD_BIT(b);
2250 dyn->vi->bindings[b].stride = desc->stride;
2251 dyn->vi->bindings[b].input_rate = desc->inputRate;
2252 dyn->vi->bindings[b].divisor = desc->divisor;
2253
2254 /* Also set bindings_strides in case a driver is keying off that */
2255 dyn->vi_binding_strides[b] = desc->stride;
2256 }
2257
2258 dyn->vi->bindings_valid = bindings_valid;
2259 SET_DYN_VALUE(dyn, VI_BINDINGS_VALID, vi_bindings_valid, bindings_valid);
2260
2261 uint32_t attributes_valid = 0;
2262 for (uint32_t i = 0; i < vertexAttributeDescriptionCount; i++) {
2263 const VkVertexInputAttributeDescription2EXT *desc =
2264 &pVertexAttributeDescriptions[i];
2265
2266 assert(desc->location < MESA_VK_MAX_VERTEX_ATTRIBUTES);
2267 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS);
2268 assert(bindings_valid & BITFIELD_BIT(desc->binding));
2269
2270 const uint32_t a = desc->location;
2271 attributes_valid |= BITFIELD_BIT(a);
2272 dyn->vi->attributes[a].binding = desc->binding;
2273 dyn->vi->attributes[a].format = desc->format;
2274 dyn->vi->attributes[a].offset = desc->offset;
2275 }
2276 dyn->vi->attributes_valid = attributes_valid;
2277
2278 BITSET_SET(dyn->set, MESA_VK_DYNAMIC_VI);
2279 BITSET_SET(dyn->set, MESA_VK_DYNAMIC_VI_BINDING_STRIDES);
2280 BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_VI);
2281 BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_VI_BINDING_STRIDES);
2282 }
2283
2284 void
vk_cmd_set_vertex_binding_strides(struct vk_command_buffer * cmd,uint32_t first_binding,uint32_t binding_count,const VkDeviceSize * strides)2285 vk_cmd_set_vertex_binding_strides(struct vk_command_buffer *cmd,
2286 uint32_t first_binding,
2287 uint32_t binding_count,
2288 const VkDeviceSize *strides)
2289 {
2290 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2291
2292 for (uint32_t i = 0; i < binding_count; i++) {
2293 SET_DYN_VALUE(dyn, VI_BINDING_STRIDES,
2294 vi_binding_strides[first_binding + i], strides[i]);
2295 }
2296 }
2297
2298 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,VkPrimitiveTopology primitiveTopology)2299 vk_common_CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,
2300 VkPrimitiveTopology primitiveTopology)
2301 {
2302 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2303 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2304
2305 SET_DYN_VALUE(dyn, IA_PRIMITIVE_TOPOLOGY,
2306 ia.primitive_topology, primitiveTopology);
2307 }
2308
2309 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,VkBool32 primitiveRestartEnable)2310 vk_common_CmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,
2311 VkBool32 primitiveRestartEnable)
2312 {
2313 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2314 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2315
2316 SET_DYN_BOOL(dyn, IA_PRIMITIVE_RESTART_ENABLE,
2317 ia.primitive_restart_enable, primitiveRestartEnable);
2318 }
2319
2320 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,uint32_t patchControlPoints)2321 vk_common_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
2322 uint32_t patchControlPoints)
2323 {
2324 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2325 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2326
2327 SET_DYN_VALUE(dyn, TS_PATCH_CONTROL_POINTS,
2328 ts.patch_control_points, patchControlPoints);
2329 }
2330
2331 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetTessellationDomainOriginEXT(VkCommandBuffer commandBuffer,VkTessellationDomainOrigin domainOrigin)2332 vk_common_CmdSetTessellationDomainOriginEXT(VkCommandBuffer commandBuffer,
2333 VkTessellationDomainOrigin domainOrigin)
2334 {
2335 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2336 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2337
2338 SET_DYN_VALUE(dyn, TS_DOMAIN_ORIGIN, ts.domain_origin, domainOrigin);
2339 }
2340
2341 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetViewport(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)2342 vk_common_CmdSetViewport(VkCommandBuffer commandBuffer,
2343 uint32_t firstViewport,
2344 uint32_t viewportCount,
2345 const VkViewport *pViewports)
2346 {
2347 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2348 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2349
2350 SET_DYN_ARRAY(dyn, VP_VIEWPORTS, vp.viewports,
2351 firstViewport, viewportCount, pViewports);
2352 }
2353
2354 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetViewportWithCount(VkCommandBuffer commandBuffer,uint32_t viewportCount,const VkViewport * pViewports)2355 vk_common_CmdSetViewportWithCount(VkCommandBuffer commandBuffer,
2356 uint32_t viewportCount,
2357 const VkViewport *pViewports)
2358 {
2359 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2360 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2361
2362 SET_DYN_VALUE(dyn, VP_VIEWPORT_COUNT, vp.viewport_count, viewportCount);
2363 SET_DYN_ARRAY(dyn, VP_VIEWPORTS, vp.viewports, 0, viewportCount, pViewports);
2364 }
2365
2366 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetScissor(VkCommandBuffer commandBuffer,uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)2367 vk_common_CmdSetScissor(VkCommandBuffer commandBuffer,
2368 uint32_t firstScissor,
2369 uint32_t scissorCount,
2370 const VkRect2D *pScissors)
2371 {
2372 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2373 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2374
2375 SET_DYN_ARRAY(dyn, VP_SCISSORS, vp.scissors,
2376 firstScissor, scissorCount, pScissors);
2377 }
2378
2379 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetScissorWithCount(VkCommandBuffer commandBuffer,uint32_t scissorCount,const VkRect2D * pScissors)2380 vk_common_CmdSetScissorWithCount(VkCommandBuffer commandBuffer,
2381 uint32_t scissorCount,
2382 const VkRect2D *pScissors)
2383 {
2384 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2385 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2386
2387 SET_DYN_VALUE(dyn, VP_SCISSOR_COUNT, vp.scissor_count, scissorCount);
2388 SET_DYN_ARRAY(dyn, VP_SCISSORS, vp.scissors, 0, scissorCount, pScissors);
2389 }
2390
2391 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthClipNegativeOneToOneEXT(VkCommandBuffer commandBuffer,VkBool32 negativeOneToOne)2392 vk_common_CmdSetDepthClipNegativeOneToOneEXT(VkCommandBuffer commandBuffer,
2393 VkBool32 negativeOneToOne)
2394 {
2395 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2396 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2397
2398 SET_DYN_BOOL(dyn, VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,
2399 vp.depth_clip_negative_one_to_one, negativeOneToOne);
2400 }
2401
2402 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer,uint32_t firstDiscardRectangle,uint32_t discardRectangleCount,const VkRect2D * pDiscardRectangles)2403 vk_common_CmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer,
2404 uint32_t firstDiscardRectangle,
2405 uint32_t discardRectangleCount,
2406 const VkRect2D *pDiscardRectangles)
2407 {
2408 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2409 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2410
2411 SET_DYN_VALUE(dyn, DR_RECTANGLES, dr.rectangle_count, discardRectangleCount);
2412 SET_DYN_ARRAY(dyn, DR_RECTANGLES, dr.rectangles, firstDiscardRectangle,
2413 discardRectangleCount, pDiscardRectangles);
2414 }
2415
2416 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer,VkBool32 rasterizerDiscardEnable)2417 vk_common_CmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer,
2418 VkBool32 rasterizerDiscardEnable)
2419 {
2420 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2421 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2422
2423 SET_DYN_BOOL(dyn, RS_RASTERIZER_DISCARD_ENABLE,
2424 rs.rasterizer_discard_enable, rasterizerDiscardEnable);
2425 }
2426
2427 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthClampEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthClampEnable)2428 vk_common_CmdSetDepthClampEnableEXT(VkCommandBuffer commandBuffer,
2429 VkBool32 depthClampEnable)
2430 {
2431 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2432 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2433
2434 SET_DYN_BOOL(dyn, RS_DEPTH_CLAMP_ENABLE,
2435 rs.depth_clamp_enable, depthClampEnable);
2436 }
2437
2438 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthClipEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthClipEnable)2439 vk_common_CmdSetDepthClipEnableEXT(VkCommandBuffer commandBuffer,
2440 VkBool32 depthClipEnable)
2441 {
2442 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2443 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2444
2445 SET_DYN_VALUE(dyn, RS_DEPTH_CLIP_ENABLE, rs.depth_clip_enable,
2446 depthClipEnable ? VK_MESA_DEPTH_CLIP_ENABLE_TRUE :
2447 VK_MESA_DEPTH_CLIP_ENABLE_FALSE);
2448 }
2449
2450 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetPolygonModeEXT(VkCommandBuffer commandBuffer,VkPolygonMode polygonMode)2451 vk_common_CmdSetPolygonModeEXT(VkCommandBuffer commandBuffer,
2452 VkPolygonMode polygonMode)
2453 {
2454 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2455 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2456
2457 SET_DYN_VALUE(dyn, RS_POLYGON_MODE, rs.polygon_mode, polygonMode);
2458 }
2459
2460 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCullMode(VkCommandBuffer commandBuffer,VkCullModeFlags cullMode)2461 vk_common_CmdSetCullMode(VkCommandBuffer commandBuffer,
2462 VkCullModeFlags cullMode)
2463 {
2464 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2465 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2466
2467 SET_DYN_VALUE(dyn, RS_CULL_MODE, rs.cull_mode, cullMode);
2468 }
2469
2470 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetFrontFace(VkCommandBuffer commandBuffer,VkFrontFace frontFace)2471 vk_common_CmdSetFrontFace(VkCommandBuffer commandBuffer,
2472 VkFrontFace frontFace)
2473 {
2474 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2475 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2476
2477 SET_DYN_VALUE(dyn, RS_FRONT_FACE, rs.front_face, frontFace);
2478 }
2479
2480 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetConservativeRasterizationModeEXT(VkCommandBuffer commandBuffer,VkConservativeRasterizationModeEXT conservativeRasterizationMode)2481 vk_common_CmdSetConservativeRasterizationModeEXT(
2482 VkCommandBuffer commandBuffer,
2483 VkConservativeRasterizationModeEXT conservativeRasterizationMode)
2484 {
2485 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2486 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2487
2488 SET_DYN_VALUE(dyn, RS_CONSERVATIVE_MODE, rs.conservative_mode,
2489 conservativeRasterizationMode);
2490 }
2491
2492 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetExtraPrimitiveOverestimationSizeEXT(VkCommandBuffer commandBuffer,float extraPrimitiveOverestimationSize)2493 vk_common_CmdSetExtraPrimitiveOverestimationSizeEXT(
2494 VkCommandBuffer commandBuffer,
2495 float extraPrimitiveOverestimationSize)
2496 {
2497 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2498 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2499
2500 SET_DYN_VALUE(dyn, RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE,
2501 rs.extra_primitive_overestimation_size,
2502 extraPrimitiveOverestimationSize);
2503 }
2504
2505 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetProvokingVertexModeEXT(VkCommandBuffer commandBuffer,VkProvokingVertexModeEXT provokingVertexMode)2506 vk_common_CmdSetProvokingVertexModeEXT(VkCommandBuffer commandBuffer,
2507 VkProvokingVertexModeEXT provokingVertexMode)
2508 {
2509 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2510 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2511
2512 SET_DYN_VALUE(dyn, RS_PROVOKING_VERTEX,
2513 rs.provoking_vertex, provokingVertexMode);
2514 }
2515
2516 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetAttachmentFeedbackLoopEnableEXT(VkCommandBuffer commandBuffer,VkImageAspectFlags aspectMask)2517 vk_common_CmdSetAttachmentFeedbackLoopEnableEXT(VkCommandBuffer commandBuffer,
2518 VkImageAspectFlags aspectMask)
2519 {
2520 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2521 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2522
2523 SET_DYN_VALUE(dyn, ATTACHMENT_FEEDBACK_LOOP_ENABLE,
2524 feedback_loops, aspectMask);
2525 }
2526
2527 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRasterizationStreamEXT(VkCommandBuffer commandBuffer,uint32_t rasterizationStream)2528 vk_common_CmdSetRasterizationStreamEXT(VkCommandBuffer commandBuffer,
2529 uint32_t rasterizationStream)
2530 {
2531 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2532 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2533
2534 SET_DYN_VALUE(dyn, RS_RASTERIZATION_STREAM,
2535 rs.rasterization_stream, rasterizationStream);
2536 }
2537
2538 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthBiasEnable(VkCommandBuffer commandBuffer,VkBool32 depthBiasEnable)2539 vk_common_CmdSetDepthBiasEnable(VkCommandBuffer commandBuffer,
2540 VkBool32 depthBiasEnable)
2541 {
2542 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2543 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2544
2545 SET_DYN_BOOL(dyn, RS_DEPTH_BIAS_ENABLE,
2546 rs.depth_bias.enable, depthBiasEnable);
2547 }
2548
2549 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthBias(VkCommandBuffer commandBuffer,float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)2550 vk_common_CmdSetDepthBias(VkCommandBuffer commandBuffer,
2551 float depthBiasConstantFactor,
2552 float depthBiasClamp,
2553 float depthBiasSlopeFactor)
2554 {
2555 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2556
2557 VkDepthBiasInfoEXT depth_bias_info = {
2558 .sType = VK_STRUCTURE_TYPE_DEPTH_BIAS_INFO_EXT,
2559 .depthBiasConstantFactor = depthBiasConstantFactor,
2560 .depthBiasClamp = depthBiasClamp,
2561 .depthBiasSlopeFactor = depthBiasSlopeFactor,
2562 };
2563
2564 cmd->base.device->dispatch_table.CmdSetDepthBias2EXT(commandBuffer,
2565 &depth_bias_info);
2566 }
2567
2568 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetLineWidth(VkCommandBuffer commandBuffer,float lineWidth)2569 vk_common_CmdSetLineWidth(VkCommandBuffer commandBuffer,
2570 float lineWidth)
2571 {
2572 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2573 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2574
2575 SET_DYN_VALUE(dyn, RS_LINE_WIDTH, rs.line.width, lineWidth);
2576 }
2577
2578 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetLineRasterizationModeEXT(VkCommandBuffer commandBuffer,VkLineRasterizationModeKHR lineRasterizationMode)2579 vk_common_CmdSetLineRasterizationModeEXT(VkCommandBuffer commandBuffer,
2580 VkLineRasterizationModeKHR lineRasterizationMode)
2581 {
2582 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2583 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2584
2585 SET_DYN_VALUE(dyn, RS_LINE_MODE, rs.line.mode, lineRasterizationMode);
2586 }
2587
2588 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetLineStippleEnableEXT(VkCommandBuffer commandBuffer,VkBool32 stippledLineEnable)2589 vk_common_CmdSetLineStippleEnableEXT(VkCommandBuffer commandBuffer,
2590 VkBool32 stippledLineEnable)
2591 {
2592 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2593 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2594
2595 SET_DYN_BOOL(dyn, RS_LINE_STIPPLE_ENABLE,
2596 rs.line.stipple.enable, stippledLineEnable);
2597 }
2598
2599 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetLineStippleKHR(VkCommandBuffer commandBuffer,uint32_t lineStippleFactor,uint16_t lineStipplePattern)2600 vk_common_CmdSetLineStippleKHR(VkCommandBuffer commandBuffer,
2601 uint32_t lineStippleFactor,
2602 uint16_t lineStipplePattern)
2603 {
2604 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2605 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2606
2607 SET_DYN_VALUE(dyn, RS_LINE_STIPPLE,
2608 rs.line.stipple.factor, lineStippleFactor);
2609 SET_DYN_VALUE(dyn, RS_LINE_STIPPLE,
2610 rs.line.stipple.pattern, lineStipplePattern);
2611 }
2612
2613 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetFragmentShadingRateKHR(VkCommandBuffer commandBuffer,const VkExtent2D * pFragmentSize,const VkFragmentShadingRateCombinerOpKHR combinerOps[2])2614 vk_common_CmdSetFragmentShadingRateKHR(VkCommandBuffer commandBuffer,
2615 const VkExtent2D *pFragmentSize,
2616 const VkFragmentShadingRateCombinerOpKHR combinerOps[2])
2617 {
2618 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2619 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2620
2621 SET_DYN_VALUE(dyn, FSR, fsr.fragment_size.width, pFragmentSize->width);
2622 SET_DYN_VALUE(dyn, FSR, fsr.fragment_size.height, pFragmentSize->height);
2623 SET_DYN_VALUE(dyn, FSR, fsr.combiner_ops[0], combinerOps[0]);
2624 SET_DYN_VALUE(dyn, FSR, fsr.combiner_ops[1], combinerOps[1]);
2625 }
2626
2627 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRasterizationSamplesEXT(VkCommandBuffer commandBuffer,VkSampleCountFlagBits rasterizationSamples)2628 vk_common_CmdSetRasterizationSamplesEXT(VkCommandBuffer commandBuffer,
2629 VkSampleCountFlagBits rasterizationSamples)
2630 {
2631 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2632 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2633
2634 assert(rasterizationSamples <= MESA_VK_MAX_SAMPLES);
2635
2636 SET_DYN_VALUE(dyn, MS_RASTERIZATION_SAMPLES,
2637 ms.rasterization_samples, rasterizationSamples);
2638 }
2639
2640 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetSampleMaskEXT(VkCommandBuffer commandBuffer,VkSampleCountFlagBits samples,const VkSampleMask * pSampleMask)2641 vk_common_CmdSetSampleMaskEXT(VkCommandBuffer commandBuffer,
2642 VkSampleCountFlagBits samples,
2643 const VkSampleMask *pSampleMask)
2644 {
2645 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2646 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2647
2648 VkSampleMask sample_mask = *pSampleMask & BITFIELD_MASK(MESA_VK_MAX_SAMPLES);
2649
2650 SET_DYN_VALUE(dyn, MS_SAMPLE_MASK, ms.sample_mask, sample_mask);
2651 }
2652
2653 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetAlphaToCoverageEnableEXT(VkCommandBuffer commandBuffer,VkBool32 alphaToCoverageEnable)2654 vk_common_CmdSetAlphaToCoverageEnableEXT(VkCommandBuffer commandBuffer,
2655 VkBool32 alphaToCoverageEnable)
2656 {
2657 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2658 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2659
2660 SET_DYN_VALUE(dyn, MS_ALPHA_TO_COVERAGE_ENABLE,
2661 ms.alpha_to_coverage_enable, alphaToCoverageEnable);
2662 }
2663
2664 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetAlphaToOneEnableEXT(VkCommandBuffer commandBuffer,VkBool32 alphaToOneEnable)2665 vk_common_CmdSetAlphaToOneEnableEXT(VkCommandBuffer commandBuffer,
2666 VkBool32 alphaToOneEnable)
2667 {
2668 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2669 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2670
2671 SET_DYN_VALUE(dyn, MS_ALPHA_TO_ONE_ENABLE,
2672 ms.alpha_to_one_enable, alphaToOneEnable);
2673 }
2674
2675 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,const VkSampleLocationsInfoEXT * pSampleLocationsInfo)2676 vk_common_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
2677 const VkSampleLocationsInfoEXT *pSampleLocationsInfo)
2678 {
2679 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2680 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2681
2682 SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS,
2683 ms.sample_locations->per_pixel,
2684 pSampleLocationsInfo->sampleLocationsPerPixel);
2685 SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS,
2686 ms.sample_locations->grid_size.width,
2687 pSampleLocationsInfo->sampleLocationGridSize.width);
2688 SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS,
2689 ms.sample_locations->grid_size.height,
2690 pSampleLocationsInfo->sampleLocationGridSize.height);
2691
2692 assert(pSampleLocationsInfo->sampleLocationsCount ==
2693 pSampleLocationsInfo->sampleLocationsPerPixel *
2694 pSampleLocationsInfo->sampleLocationGridSize.width *
2695 pSampleLocationsInfo->sampleLocationGridSize.height);
2696
2697 assert(pSampleLocationsInfo->sampleLocationsCount <=
2698 MESA_VK_MAX_SAMPLE_LOCATIONS);
2699
2700 SET_DYN_ARRAY(dyn, MS_SAMPLE_LOCATIONS,
2701 ms.sample_locations->locations,
2702 0, pSampleLocationsInfo->sampleLocationsCount,
2703 pSampleLocationsInfo->pSampleLocations);
2704 }
2705
2706 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetSampleLocationsEnableEXT(VkCommandBuffer commandBuffer,VkBool32 sampleLocationsEnable)2707 vk_common_CmdSetSampleLocationsEnableEXT(VkCommandBuffer commandBuffer,
2708 VkBool32 sampleLocationsEnable)
2709 {
2710 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2711 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2712
2713 SET_DYN_BOOL(dyn, MS_SAMPLE_LOCATIONS_ENABLE,
2714 ms.sample_locations_enable, sampleLocationsEnable);
2715 }
2716
2717 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthTestEnable(VkCommandBuffer commandBuffer,VkBool32 depthTestEnable)2718 vk_common_CmdSetDepthTestEnable(VkCommandBuffer commandBuffer,
2719 VkBool32 depthTestEnable)
2720 {
2721 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2722 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2723
2724 SET_DYN_BOOL(dyn, DS_DEPTH_TEST_ENABLE,
2725 ds.depth.test_enable, depthTestEnable);
2726 }
2727
2728 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthWriteEnable(VkCommandBuffer commandBuffer,VkBool32 depthWriteEnable)2729 vk_common_CmdSetDepthWriteEnable(VkCommandBuffer commandBuffer,
2730 VkBool32 depthWriteEnable)
2731 {
2732 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2733 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2734
2735 SET_DYN_BOOL(dyn, DS_DEPTH_WRITE_ENABLE,
2736 ds.depth.write_enable, depthWriteEnable);
2737 }
2738
2739 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthCompareOp(VkCommandBuffer commandBuffer,VkCompareOp depthCompareOp)2740 vk_common_CmdSetDepthCompareOp(VkCommandBuffer commandBuffer,
2741 VkCompareOp depthCompareOp)
2742 {
2743 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2744 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2745
2746 SET_DYN_VALUE(dyn, DS_DEPTH_COMPARE_OP, ds.depth.compare_op,
2747 depthCompareOp);
2748 }
2749
2750 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,VkBool32 depthBoundsTestEnable)2751 vk_common_CmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,
2752 VkBool32 depthBoundsTestEnable)
2753 {
2754 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2755 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2756
2757 SET_DYN_BOOL(dyn, DS_DEPTH_BOUNDS_TEST_ENABLE,
2758 ds.depth.bounds_test.enable, depthBoundsTestEnable);
2759 }
2760
2761 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthBounds(VkCommandBuffer commandBuffer,float minDepthBounds,float maxDepthBounds)2762 vk_common_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
2763 float minDepthBounds,
2764 float maxDepthBounds)
2765 {
2766 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2767 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2768
2769 SET_DYN_VALUE(dyn, DS_DEPTH_BOUNDS_TEST_BOUNDS,
2770 ds.depth.bounds_test.min, minDepthBounds);
2771 SET_DYN_VALUE(dyn, DS_DEPTH_BOUNDS_TEST_BOUNDS,
2772 ds.depth.bounds_test.max, maxDepthBounds);
2773 }
2774
2775 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetStencilTestEnable(VkCommandBuffer commandBuffer,VkBool32 stencilTestEnable)2776 vk_common_CmdSetStencilTestEnable(VkCommandBuffer commandBuffer,
2777 VkBool32 stencilTestEnable)
2778 {
2779 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2780 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2781
2782 SET_DYN_BOOL(dyn, DS_STENCIL_TEST_ENABLE,
2783 ds.stencil.test_enable, stencilTestEnable);
2784 }
2785
2786 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetStencilOp(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,VkStencilOp failOp,VkStencilOp passOp,VkStencilOp depthFailOp,VkCompareOp compareOp)2787 vk_common_CmdSetStencilOp(VkCommandBuffer commandBuffer,
2788 VkStencilFaceFlags faceMask,
2789 VkStencilOp failOp,
2790 VkStencilOp passOp,
2791 VkStencilOp depthFailOp,
2792 VkCompareOp compareOp)
2793 {
2794 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2795 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2796
2797 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2798 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.fail, failOp);
2799 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.pass, passOp);
2800 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.depth_fail, depthFailOp);
2801 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.compare, compareOp);
2802 }
2803
2804 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2805 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.fail, failOp);
2806 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.pass, passOp);
2807 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.depth_fail, depthFailOp);
2808 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.compare, compareOp);
2809 }
2810 }
2811
2812 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t compareMask)2813 vk_common_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
2814 VkStencilFaceFlags faceMask,
2815 uint32_t compareMask)
2816 {
2817 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2818 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2819
2820 /* We assume 8-bit stencil always */
2821 STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1);
2822
2823 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2824 SET_DYN_VALUE(dyn, DS_STENCIL_COMPARE_MASK,
2825 ds.stencil.front.compare_mask, (uint8_t)compareMask);
2826 }
2827 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2828 SET_DYN_VALUE(dyn, DS_STENCIL_COMPARE_MASK,
2829 ds.stencil.back.compare_mask, (uint8_t)compareMask);
2830 }
2831 }
2832
2833 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t writeMask)2834 vk_common_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
2835 VkStencilFaceFlags faceMask,
2836 uint32_t writeMask)
2837 {
2838 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2839 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2840
2841 /* We assume 8-bit stencil always */
2842 STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1);
2843
2844 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2845 SET_DYN_VALUE(dyn, DS_STENCIL_WRITE_MASK,
2846 ds.stencil.front.write_mask, (uint8_t)writeMask);
2847 }
2848 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2849 SET_DYN_VALUE(dyn, DS_STENCIL_WRITE_MASK,
2850 ds.stencil.back.write_mask, (uint8_t)writeMask);
2851 }
2852 }
2853
2854 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetStencilReference(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t reference)2855 vk_common_CmdSetStencilReference(VkCommandBuffer commandBuffer,
2856 VkStencilFaceFlags faceMask,
2857 uint32_t reference)
2858 {
2859 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2860 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2861
2862 /* We assume 8-bit stencil always */
2863 STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1);
2864
2865 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2866 SET_DYN_VALUE(dyn, DS_STENCIL_REFERENCE,
2867 ds.stencil.front.reference, (uint8_t)reference);
2868 }
2869 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2870 SET_DYN_VALUE(dyn, DS_STENCIL_REFERENCE,
2871 ds.stencil.back.reference, (uint8_t)reference);
2872 }
2873 }
2874
2875 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetLogicOpEnableEXT(VkCommandBuffer commandBuffer,VkBool32 logicOpEnable)2876 vk_common_CmdSetLogicOpEnableEXT(VkCommandBuffer commandBuffer,
2877 VkBool32 logicOpEnable)
2878 {
2879 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2880 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2881
2882 SET_DYN_BOOL(dyn, CB_LOGIC_OP_ENABLE, cb.logic_op_enable, logicOpEnable);
2883 }
2884
2885 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer,VkLogicOp logicOp)2886 vk_common_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer,
2887 VkLogicOp logicOp)
2888 {
2889 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2890 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2891
2892 SET_DYN_VALUE(dyn, CB_LOGIC_OP, cb.logic_op, logicOp);
2893 }
2894
2895 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkBool32 * pColorWriteEnables)2896 vk_common_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
2897 uint32_t attachmentCount,
2898 const VkBool32 *pColorWriteEnables)
2899 {
2900 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2901 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2902
2903 assert(attachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
2904
2905 uint8_t color_write_enables = 0;
2906 for (uint32_t a = 0; a < attachmentCount; a++) {
2907 if (pColorWriteEnables[a])
2908 color_write_enables |= BITFIELD_BIT(a);
2909 }
2910
2911 SET_DYN_VALUE(dyn, CB_COLOR_WRITE_ENABLES,
2912 cb.color_write_enables, color_write_enables);
2913 }
2914
2915 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetColorBlendEnableEXT(VkCommandBuffer commandBuffer,uint32_t firstAttachment,uint32_t attachmentCount,const VkBool32 * pColorBlendEnables)2916 vk_common_CmdSetColorBlendEnableEXT(VkCommandBuffer commandBuffer,
2917 uint32_t firstAttachment,
2918 uint32_t attachmentCount,
2919 const VkBool32 *pColorBlendEnables)
2920 {
2921 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2922 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2923
2924 for (uint32_t i = 0; i < attachmentCount; i++) {
2925 uint32_t a = firstAttachment + i;
2926 assert(a < ARRAY_SIZE(dyn->cb.attachments));
2927
2928 SET_DYN_BOOL(dyn, CB_BLEND_ENABLES,
2929 cb.attachments[a].blend_enable, pColorBlendEnables[i]);
2930 }
2931 }
2932
2933 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetColorBlendEquationEXT(VkCommandBuffer commandBuffer,uint32_t firstAttachment,uint32_t attachmentCount,const VkColorBlendEquationEXT * pColorBlendEquations)2934 vk_common_CmdSetColorBlendEquationEXT(VkCommandBuffer commandBuffer,
2935 uint32_t firstAttachment,
2936 uint32_t attachmentCount,
2937 const VkColorBlendEquationEXT *pColorBlendEquations)
2938 {
2939 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2940 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2941
2942 for (uint32_t i = 0; i < attachmentCount; i++) {
2943 uint32_t a = firstAttachment + i;
2944 assert(a < ARRAY_SIZE(dyn->cb.attachments));
2945
2946 SET_DYN_VALUE(dyn, CB_BLEND_EQUATIONS,
2947 cb.attachments[a].src_color_blend_factor,
2948 pColorBlendEquations[i].srcColorBlendFactor);
2949
2950 SET_DYN_VALUE(dyn, CB_BLEND_EQUATIONS,
2951 cb.attachments[a].dst_color_blend_factor,
2952 pColorBlendEquations[i].dstColorBlendFactor);
2953
2954 SET_DYN_VALUE(dyn, CB_BLEND_EQUATIONS,
2955 cb.attachments[a].color_blend_op,
2956 pColorBlendEquations[i].colorBlendOp);
2957
2958 SET_DYN_VALUE(dyn, CB_BLEND_EQUATIONS,
2959 cb.attachments[a].src_alpha_blend_factor,
2960 pColorBlendEquations[i].srcAlphaBlendFactor);
2961
2962 SET_DYN_VALUE(dyn, CB_BLEND_EQUATIONS,
2963 cb.attachments[a].dst_alpha_blend_factor,
2964 pColorBlendEquations[i].dstAlphaBlendFactor);
2965
2966 SET_DYN_VALUE(dyn, CB_BLEND_EQUATIONS,
2967 cb.attachments[a].alpha_blend_op,
2968 pColorBlendEquations[i].alphaBlendOp);
2969 }
2970 }
2971
2972 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetColorWriteMaskEXT(VkCommandBuffer commandBuffer,uint32_t firstAttachment,uint32_t attachmentCount,const VkColorComponentFlags * pColorWriteMasks)2973 vk_common_CmdSetColorWriteMaskEXT(VkCommandBuffer commandBuffer,
2974 uint32_t firstAttachment,
2975 uint32_t attachmentCount,
2976 const VkColorComponentFlags *pColorWriteMasks)
2977 {
2978 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2979 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2980
2981 for (uint32_t i = 0; i < attachmentCount; i++) {
2982 uint32_t a = firstAttachment + i;
2983 assert(a < ARRAY_SIZE(dyn->cb.attachments));
2984
2985 SET_DYN_VALUE(dyn, CB_WRITE_MASKS,
2986 cb.attachments[a].write_mask, pColorWriteMasks[i]);
2987 }
2988 }
2989
2990 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetBlendConstants(VkCommandBuffer commandBuffer,const float blendConstants[4])2991 vk_common_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
2992 const float blendConstants[4])
2993 {
2994 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
2995 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
2996
2997 SET_DYN_ARRAY(dyn, CB_BLEND_CONSTANTS, cb.blend_constants,
2998 0, 4, blendConstants);
2999 }
3000
3001 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetColorBlendAdvancedEXT(VkCommandBuffer commandBuffer,uint32_t firstAttachment,uint32_t attachmentCount,const VkColorBlendAdvancedEXT * pColorBlendAdvanced)3002 vk_common_CmdSetColorBlendAdvancedEXT(VkCommandBuffer commandBuffer,
3003 uint32_t firstAttachment,
3004 uint32_t attachmentCount,
3005 const VkColorBlendAdvancedEXT* pColorBlendAdvanced)
3006 {
3007 unreachable("VK_EXT_blend_operation_advanced unsupported");
3008 }
3009
3010 void
vk_cmd_set_cb_attachment_count(struct vk_command_buffer * cmd,uint32_t attachment_count)3011 vk_cmd_set_cb_attachment_count(struct vk_command_buffer *cmd,
3012 uint32_t attachment_count)
3013 {
3014 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3015
3016 SET_DYN_VALUE(dyn, CB_ATTACHMENT_COUNT, cb.attachment_count, attachment_count);
3017 }
3018
3019 void
vk_cmd_set_rp_attachments(struct vk_command_buffer * cmd,enum vk_rp_attachment_flags attachments)3020 vk_cmd_set_rp_attachments(struct vk_command_buffer *cmd,
3021 enum vk_rp_attachment_flags attachments)
3022 {
3023 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3024
3025 SET_DYN_VALUE(dyn, RP_ATTACHMENTS, rp.attachments, attachments);
3026 }
3027
3028 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDiscardRectangleEnableEXT(VkCommandBuffer commandBuffer,VkBool32 discardRectangleEnable)3029 vk_common_CmdSetDiscardRectangleEnableEXT(VkCommandBuffer commandBuffer,
3030 VkBool32 discardRectangleEnable)
3031 {
3032 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
3033 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3034
3035 SET_DYN_VALUE(dyn, DR_ENABLE, dr.enable, discardRectangleEnable);
3036 }
3037
3038 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDiscardRectangleModeEXT(VkCommandBuffer commandBuffer,VkDiscardRectangleModeEXT discardRectangleMode)3039 vk_common_CmdSetDiscardRectangleModeEXT(VkCommandBuffer commandBuffer,
3040 VkDiscardRectangleModeEXT discardRectangleMode)
3041 {
3042 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
3043 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3044
3045 SET_DYN_VALUE(dyn, DR_MODE, dr.mode, discardRectangleMode);
3046 }
3047
3048 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetDepthBias2EXT(VkCommandBuffer commandBuffer,const VkDepthBiasInfoEXT * pDepthBiasInfo)3049 vk_common_CmdSetDepthBias2EXT(
3050 VkCommandBuffer commandBuffer,
3051 const VkDepthBiasInfoEXT* pDepthBiasInfo)
3052 {
3053 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
3054 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3055
3056 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3057 rs.depth_bias.constant, pDepthBiasInfo->depthBiasConstantFactor);
3058 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3059 rs.depth_bias.clamp, pDepthBiasInfo->depthBiasClamp);
3060 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3061 rs.depth_bias.slope, pDepthBiasInfo->depthBiasSlopeFactor);
3062
3063 /** From the Vulkan 1.3.254 spec:
3064 *
3065 * "If pNext does not contain a VkDepthBiasRepresentationInfoEXT
3066 * structure, then this command is equivalent to including a
3067 * VkDepthBiasRepresentationInfoEXT with depthBiasExact set to VK_FALSE
3068 * and depthBiasRepresentation set to
3069 * VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT."
3070 */
3071 const VkDepthBiasRepresentationInfoEXT *dbr_info =
3072 vk_find_struct_const(pDepthBiasInfo->pNext, DEPTH_BIAS_REPRESENTATION_INFO_EXT);
3073 if (dbr_info) {
3074 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3075 rs.depth_bias.representation, dbr_info->depthBiasRepresentation);
3076 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3077 rs.depth_bias.exact, dbr_info->depthBiasExact);
3078 } else {
3079 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3080 rs.depth_bias.representation,
3081 VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT);
3082 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS,
3083 rs.depth_bias.exact, false);
3084 }
3085 }
3086
3087 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRenderingAttachmentLocationsKHR(VkCommandBuffer commandBuffer,const VkRenderingAttachmentLocationInfoKHR * pLocationInfo)3088 vk_common_CmdSetRenderingAttachmentLocationsKHR(
3089 VkCommandBuffer commandBuffer,
3090 const VkRenderingAttachmentLocationInfoKHR* pLocationInfo)
3091 {
3092 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
3093 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3094
3095 assert(pLocationInfo->colorAttachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
3096 for (uint32_t i = 0; i < pLocationInfo->colorAttachmentCount; i++) {
3097 uint8_t val =
3098 pLocationInfo->pColorAttachmentLocations[i] == VK_ATTACHMENT_UNUSED ?
3099 MESA_VK_ATTACHMENT_UNUSED : pLocationInfo->pColorAttachmentLocations[i];
3100 SET_DYN_VALUE(dyn, COLOR_ATTACHMENT_MAP, cal.color_map[i], val);
3101 }
3102 }
3103
3104 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRenderingInputAttachmentIndicesKHR(VkCommandBuffer commandBuffer,const VkRenderingInputAttachmentIndexInfoKHR * pLocationInfo)3105 vk_common_CmdSetRenderingInputAttachmentIndicesKHR(
3106 VkCommandBuffer commandBuffer,
3107 const VkRenderingInputAttachmentIndexInfoKHR* pLocationInfo)
3108 {
3109 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
3110 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
3111
3112 assert(pLocationInfo->colorAttachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS);
3113 for (uint32_t i = 0; i < pLocationInfo->colorAttachmentCount; i++) {
3114 uint8_t val =
3115 pLocationInfo->pColorAttachmentInputIndices[i] == VK_ATTACHMENT_UNUSED ?
3116 MESA_VK_ATTACHMENT_UNUSED : pLocationInfo->pColorAttachmentInputIndices[i];
3117 SET_DYN_VALUE(dyn, INPUT_ATTACHMENT_MAP,
3118 ial.color_map[i], val);
3119 }
3120
3121 uint8_t depth_att =
3122 (pLocationInfo->pDepthInputAttachmentIndex == NULL ||
3123 *pLocationInfo->pDepthInputAttachmentIndex == VK_ATTACHMENT_UNUSED) ?
3124 MESA_VK_ATTACHMENT_UNUSED : *pLocationInfo->pDepthInputAttachmentIndex;
3125 uint8_t stencil_att =
3126 (pLocationInfo->pStencilInputAttachmentIndex == NULL ||
3127 *pLocationInfo->pStencilInputAttachmentIndex == VK_ATTACHMENT_UNUSED) ?
3128 MESA_VK_ATTACHMENT_UNUSED : *pLocationInfo->pStencilInputAttachmentIndex;
3129 SET_DYN_VALUE(dyn, INPUT_ATTACHMENT_MAP, ial.depth_att, depth_att);
3130 SET_DYN_VALUE(dyn, INPUT_ATTACHMENT_MAP, ial.stencil_att, stencil_att);
3131 }
3132
3133 /* These are stubs required by VK_EXT_shader_object */
3134
3135 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetViewportWScalingEnableNV(VkCommandBuffer commandBuffer,VkBool32 viewportWScalingEnable)3136 vk_common_CmdSetViewportWScalingEnableNV(
3137 VkCommandBuffer commandBuffer,
3138 VkBool32 viewportWScalingEnable)
3139 {
3140 }
3141
3142 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCoverageReductionModeNV(VkCommandBuffer commandBuffer,VkCoverageReductionModeNV coverageReductionMode)3143 vk_common_CmdSetCoverageReductionModeNV(
3144 VkCommandBuffer commandBuffer,
3145 VkCoverageReductionModeNV coverageReductionMode)
3146 {
3147 }
3148
3149 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCoverageToColorEnableNV(VkCommandBuffer commandBuffer,VkBool32 coverageToColorEnable)3150 vk_common_CmdSetCoverageToColorEnableNV(
3151 VkCommandBuffer commandBuffer,
3152 VkBool32 coverageToColorEnable)
3153 {
3154 }
3155
3156 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCoverageToColorLocationNV(VkCommandBuffer commandBuffer,uint32_t coverageToColorLocation)3157 vk_common_CmdSetCoverageToColorLocationNV(
3158 VkCommandBuffer commandBuffer,
3159 uint32_t coverageToColorLocation)
3160 {
3161 }
3162
3163 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCoverageModulationModeNV(VkCommandBuffer commandBuffer,VkCoverageModulationModeNV coverageModulationMode)3164 vk_common_CmdSetCoverageModulationModeNV(
3165 VkCommandBuffer commandBuffer,
3166 VkCoverageModulationModeNV coverageModulationMode)
3167 {
3168 }
3169
3170 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCoverageModulationTableEnableNV(VkCommandBuffer commandBuffer,VkBool32 coverageModulationTableEnable)3171 vk_common_CmdSetCoverageModulationTableEnableNV(
3172 VkCommandBuffer commandBuffer,
3173 VkBool32 coverageModulationTableEnable)
3174 {
3175 }
3176
3177 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetCoverageModulationTableNV(VkCommandBuffer commandBuffer,uint32_t coverageModulationTableCount,const float * pCoverageModulationTable)3178 vk_common_CmdSetCoverageModulationTableNV(
3179 VkCommandBuffer commandBuffer,
3180 uint32_t coverageModulationTableCount,
3181 const float* pCoverageModulationTable)
3182 {
3183 }
3184
3185 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRepresentativeFragmentTestEnableNV(VkCommandBuffer commandBuffer,VkBool32 representativeFragmentTestEnable)3186 vk_common_CmdSetRepresentativeFragmentTestEnableNV(
3187 VkCommandBuffer commandBuffer,
3188 VkBool32 representativeFragmentTestEnable)
3189 {
3190 }
3191
3192 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetShadingRateImageEnableNV(VkCommandBuffer commandBuffer,VkBool32 shadingRateImageEnable)3193 vk_common_CmdSetShadingRateImageEnableNV(
3194 VkCommandBuffer commandBuffer,
3195 VkBool32 shadingRateImageEnable)
3196 {
3197 }
3198
3199 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetViewportSwizzleNV(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewportSwizzleNV * pViewportSwizzles)3200 vk_common_CmdSetViewportSwizzleNV(
3201 VkCommandBuffer commandBuffer,
3202 uint32_t firstViewport,
3203 uint32_t viewportCount,
3204 const VkViewportSwizzleNV* pViewportSwizzles)
3205 {
3206 }
3207
3208 const char *
vk_dynamic_graphic_state_to_str(enum mesa_vk_dynamic_graphics_state state)3209 vk_dynamic_graphic_state_to_str(enum mesa_vk_dynamic_graphics_state state)
3210 {
3211 #define NAME(name) \
3212 case MESA_VK_DYNAMIC_##name: return #name
3213
3214 switch (state) {
3215 NAME(VI);
3216 NAME(VI_BINDINGS_VALID);
3217 NAME(VI_BINDING_STRIDES);
3218 NAME(IA_PRIMITIVE_TOPOLOGY);
3219 NAME(IA_PRIMITIVE_RESTART_ENABLE);
3220 NAME(TS_PATCH_CONTROL_POINTS);
3221 NAME(TS_DOMAIN_ORIGIN);
3222 NAME(VP_VIEWPORT_COUNT);
3223 NAME(VP_VIEWPORTS);
3224 NAME(VP_SCISSOR_COUNT);
3225 NAME(VP_SCISSORS);
3226 NAME(VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE);
3227 NAME(DR_RECTANGLES);
3228 NAME(DR_MODE);
3229 NAME(DR_ENABLE);
3230 NAME(RS_RASTERIZER_DISCARD_ENABLE);
3231 NAME(RS_DEPTH_CLAMP_ENABLE);
3232 NAME(RS_DEPTH_CLIP_ENABLE);
3233 NAME(RS_POLYGON_MODE);
3234 NAME(RS_CULL_MODE);
3235 NAME(RS_FRONT_FACE);
3236 NAME(RS_CONSERVATIVE_MODE);
3237 NAME(RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE);
3238 NAME(RS_RASTERIZATION_ORDER_AMD);
3239 NAME(RS_PROVOKING_VERTEX);
3240 NAME(RS_RASTERIZATION_STREAM);
3241 NAME(RS_DEPTH_BIAS_ENABLE);
3242 NAME(RS_DEPTH_BIAS_FACTORS);
3243 NAME(RS_LINE_WIDTH);
3244 NAME(RS_LINE_MODE);
3245 NAME(RS_LINE_STIPPLE_ENABLE);
3246 NAME(RS_LINE_STIPPLE);
3247 NAME(FSR);
3248 NAME(MS_RASTERIZATION_SAMPLES);
3249 NAME(MS_SAMPLE_MASK);
3250 NAME(MS_ALPHA_TO_COVERAGE_ENABLE);
3251 NAME(MS_ALPHA_TO_ONE_ENABLE);
3252 NAME(MS_SAMPLE_LOCATIONS_ENABLE);
3253 NAME(MS_SAMPLE_LOCATIONS);
3254 NAME(DS_DEPTH_TEST_ENABLE);
3255 NAME(DS_DEPTH_WRITE_ENABLE);
3256 NAME(DS_DEPTH_COMPARE_OP);
3257 NAME(DS_DEPTH_BOUNDS_TEST_ENABLE);
3258 NAME(DS_DEPTH_BOUNDS_TEST_BOUNDS);
3259 NAME(DS_STENCIL_TEST_ENABLE);
3260 NAME(DS_STENCIL_OP);
3261 NAME(DS_STENCIL_COMPARE_MASK);
3262 NAME(DS_STENCIL_WRITE_MASK);
3263 NAME(DS_STENCIL_REFERENCE);
3264 NAME(CB_LOGIC_OP_ENABLE);
3265 NAME(CB_LOGIC_OP);
3266 NAME(CB_ATTACHMENT_COUNT);
3267 NAME(CB_COLOR_WRITE_ENABLES);
3268 NAME(CB_BLEND_ENABLES);
3269 NAME(CB_BLEND_EQUATIONS);
3270 NAME(CB_WRITE_MASKS);
3271 NAME(CB_BLEND_CONSTANTS);
3272 NAME(ATTACHMENT_FEEDBACK_LOOP_ENABLE);
3273 NAME(COLOR_ATTACHMENT_MAP);
3274 default: unreachable("Invalid state");
3275 }
3276
3277 #undef NAME
3278 }
3279