st/mesa: initialize affected_states and uniform storage earlier in deserialize
[mesa.git] / src / intel / vulkan / anv_cmd_buffer.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "anv_private.h"
31
32 #include "vk_format_info.h"
33 #include "vk_util.h"
34
35 /** \file anv_cmd_buffer.c
36 *
37 * This file contains all of the stuff for emitting commands into a command
38 * buffer. This includes implementations of most of the vkCmd*
39 * entrypoints. This file is concerned entirely with state emission and
40 * not with the command buffer data structure itself. As far as this file
41 * is concerned, most of anv_cmd_buffer is magic.
42 */
43
44 /* TODO: These are taken from GLES. We should check the Vulkan spec */
45 const struct anv_dynamic_state default_dynamic_state = {
46 .viewport = {
47 .count = 0,
48 },
49 .scissor = {
50 .count = 0,
51 },
52 .line_width = 1.0f,
53 .depth_bias = {
54 .bias = 0.0f,
55 .clamp = 0.0f,
56 .slope = 0.0f,
57 },
58 .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
59 .depth_bounds = {
60 .min = 0.0f,
61 .max = 1.0f,
62 },
63 .stencil_compare_mask = {
64 .front = ~0u,
65 .back = ~0u,
66 },
67 .stencil_write_mask = {
68 .front = ~0u,
69 .back = ~0u,
70 },
71 .stencil_reference = {
72 .front = 0u,
73 .back = 0u,
74 },
75 .line_stipple = {
76 .factor = 0u,
77 .pattern = 0u,
78 },
79 };
80
81 /**
82 * Copy the dynamic state from src to dest based on the copy_mask.
83 *
84 * Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and
85 * BLEND_CONSTANTS (always copy them if they are in the copy_mask).
86 *
87 * Returns a mask of the states which changed.
88 */
89 anv_cmd_dirty_mask_t
90 anv_dynamic_state_copy(struct anv_dynamic_state *dest,
91 const struct anv_dynamic_state *src,
92 anv_cmd_dirty_mask_t copy_mask)
93 {
94 anv_cmd_dirty_mask_t changed = 0;
95
96 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {
97 dest->viewport.count = src->viewport.count;
98 typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
99 src->viewport.count);
100 changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
101 }
102
103 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {
104 dest->scissor.count = src->scissor.count;
105 typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
106 src->scissor.count);
107 changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
108 }
109
110 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
111 typed_memcpy(dest->blend_constants, src->blend_constants, 4);
112 changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
113 }
114
115 #define ANV_CMP_COPY(field, flag) \
116 if (copy_mask & flag) { \
117 if (dest->field != src->field) { \
118 dest->field = src->field; \
119 changed |= flag; \
120 } \
121 }
122
123 ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH);
124
125 ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
126 ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
127 ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
128
129 ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
130 ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
131
132 ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
133 ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
134
135 ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
136 ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
137
138 ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
139 ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
140
141 ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
142 ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
143
144 #undef ANV_CMP_COPY
145
146 return changed;
147 }
148
149 static void
150 anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
151 {
152 struct anv_cmd_state *state = &cmd_buffer->state;
153
154 memset(state, 0, sizeof(*state));
155
156 state->current_pipeline = UINT32_MAX;
157 state->restart_index = UINT32_MAX;
158 state->gfx.dynamic = default_dynamic_state;
159 }
160
161 static void
162 anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,
163 struct anv_cmd_pipeline_state *pipe_state)
164 {
165 for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) {
166 if (pipe_state->push_descriptors[i]) {
167 anv_descriptor_set_layout_unref(cmd_buffer->device,
168 pipe_state->push_descriptors[i]->set.layout);
169 vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]);
170 }
171 }
172 }
173
174 static void
175 anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)
176 {
177 struct anv_cmd_state *state = &cmd_buffer->state;
178
179 anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);
180 anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);
181
182 vk_free(&cmd_buffer->pool->alloc, state->attachments);
183 }
184
185 static void
186 anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
187 {
188 anv_cmd_state_finish(cmd_buffer);
189 anv_cmd_state_init(cmd_buffer);
190 }
191
192 static VkResult anv_create_cmd_buffer(
193 struct anv_device * device,
194 struct anv_cmd_pool * pool,
195 VkCommandBufferLevel level,
196 VkCommandBuffer* pCommandBuffer)
197 {
198 struct anv_cmd_buffer *cmd_buffer;
199 VkResult result;
200
201 cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
202 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
203 if (cmd_buffer == NULL)
204 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
205
206 cmd_buffer->batch.status = VK_SUCCESS;
207
208 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
209 cmd_buffer->device = device;
210 cmd_buffer->pool = pool;
211 cmd_buffer->level = level;
212
213 result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
214 if (result != VK_SUCCESS)
215 goto fail;
216
217 anv_state_stream_init(&cmd_buffer->surface_state_stream,
218 &device->surface_state_pool, 4096);
219 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
220 &device->dynamic_state_pool, 16384);
221
222 anv_cmd_state_init(cmd_buffer);
223
224 if (pool) {
225 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
226 } else {
227 /* Init the pool_link so we can safefly call list_del when we destroy
228 * the command buffer
229 */
230 list_inithead(&cmd_buffer->pool_link);
231 }
232
233 *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
234
235 return VK_SUCCESS;
236
237 fail:
238 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
239
240 return result;
241 }
242
243 VkResult anv_AllocateCommandBuffers(
244 VkDevice _device,
245 const VkCommandBufferAllocateInfo* pAllocateInfo,
246 VkCommandBuffer* pCommandBuffers)
247 {
248 ANV_FROM_HANDLE(anv_device, device, _device);
249 ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
250
251 VkResult result = VK_SUCCESS;
252 uint32_t i;
253
254 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
255 result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
256 &pCommandBuffers[i]);
257 if (result != VK_SUCCESS)
258 break;
259 }
260
261 if (result != VK_SUCCESS) {
262 anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
263 i, pCommandBuffers);
264 for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
265 pCommandBuffers[i] = VK_NULL_HANDLE;
266 }
267
268 return result;
269 }
270
271 static void
272 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
273 {
274 list_del(&cmd_buffer->pool_link);
275
276 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
277
278 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
279 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
280
281 anv_cmd_state_finish(cmd_buffer);
282
283 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
284 }
285
286 void anv_FreeCommandBuffers(
287 VkDevice device,
288 VkCommandPool commandPool,
289 uint32_t commandBufferCount,
290 const VkCommandBuffer* pCommandBuffers)
291 {
292 for (uint32_t i = 0; i < commandBufferCount; i++) {
293 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
294
295 if (!cmd_buffer)
296 continue;
297
298 anv_cmd_buffer_destroy(cmd_buffer);
299 }
300 }
301
302 VkResult
303 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
304 {
305 cmd_buffer->usage_flags = 0;
306 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
307 anv_cmd_state_reset(cmd_buffer);
308
309 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
310 anv_state_stream_init(&cmd_buffer->surface_state_stream,
311 &cmd_buffer->device->surface_state_pool, 4096);
312
313 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
314 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
315 &cmd_buffer->device->dynamic_state_pool, 16384);
316 return VK_SUCCESS;
317 }
318
319 VkResult anv_ResetCommandBuffer(
320 VkCommandBuffer commandBuffer,
321 VkCommandBufferResetFlags flags)
322 {
323 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
324 return anv_cmd_buffer_reset(cmd_buffer);
325 }
326
327 #define anv_genX_call(devinfo, func, ...) \
328 switch ((devinfo)->gen) { \
329 case 7: \
330 if ((devinfo)->is_haswell) { \
331 gen75_##func(__VA_ARGS__); \
332 } else { \
333 gen7_##func(__VA_ARGS__); \
334 } \
335 break; \
336 case 8: \
337 gen8_##func(__VA_ARGS__); \
338 break; \
339 case 9: \
340 gen9_##func(__VA_ARGS__); \
341 break; \
342 case 10: \
343 gen10_##func(__VA_ARGS__); \
344 break; \
345 case 11: \
346 gen11_##func(__VA_ARGS__); \
347 break; \
348 default: \
349 assert(!"Unknown hardware generation"); \
350 }
351
352 void
353 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
354 {
355 anv_genX_call(&cmd_buffer->device->info,
356 cmd_buffer_emit_state_base_address,
357 cmd_buffer);
358 }
359
360 void
361 anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
362 const struct anv_image *image,
363 VkImageAspectFlagBits aspect,
364 enum isl_aux_usage aux_usage,
365 uint32_t level,
366 uint32_t base_layer,
367 uint32_t layer_count)
368 {
369 anv_genX_call(&cmd_buffer->device->info,
370 cmd_buffer_mark_image_written,
371 cmd_buffer, image, aspect, aux_usage,
372 level, base_layer, layer_count);
373 }
374
375 void
376 anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)
377 {
378 anv_genX_call(&cmd_buffer->device->info,
379 cmd_emit_conditional_render_predicate,
380 cmd_buffer);
381 }
382
383 static bool
384 mem_update(void *dst, const void *src, size_t size)
385 {
386 if (memcmp(dst, src, size) == 0)
387 return false;
388
389 memcpy(dst, src, size);
390 return true;
391 }
392
393 static void
394 set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,
395 gl_shader_stage stage,
396 const struct anv_pipeline_bind_map *map)
397 {
398 if (mem_update(cmd_buffer->state.surface_sha1s[stage],
399 map->surface_sha1, sizeof(map->surface_sha1)))
400 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
401
402 if (mem_update(cmd_buffer->state.sampler_sha1s[stage],
403 map->sampler_sha1, sizeof(map->sampler_sha1)))
404 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
405
406 if (mem_update(cmd_buffer->state.push_sha1s[stage],
407 map->push_sha1, sizeof(map->push_sha1)))
408 cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);
409 }
410
411 void anv_CmdBindPipeline(
412 VkCommandBuffer commandBuffer,
413 VkPipelineBindPoint pipelineBindPoint,
414 VkPipeline _pipeline)
415 {
416 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
417 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
418
419 switch (pipelineBindPoint) {
420 case VK_PIPELINE_BIND_POINT_COMPUTE: {
421 if (cmd_buffer->state.compute.base.pipeline == pipeline)
422 return;
423
424 cmd_buffer->state.compute.base.pipeline = pipeline;
425 cmd_buffer->state.compute.pipeline_dirty = true;
426 const struct anv_pipeline_bind_map *bind_map =
427 &pipeline->shaders[MESA_SHADER_COMPUTE]->bind_map;
428 set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE, bind_map);
429 break;
430 }
431
432 case VK_PIPELINE_BIND_POINT_GRAPHICS:
433 if (cmd_buffer->state.gfx.base.pipeline == pipeline)
434 return;
435
436 cmd_buffer->state.gfx.base.pipeline = pipeline;
437 cmd_buffer->state.gfx.vb_dirty |= pipeline->vb_used;
438 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
439
440 anv_foreach_stage(stage, pipeline->active_stages) {
441 set_dirty_for_bind_map(cmd_buffer, stage,
442 &pipeline->shaders[stage]->bind_map);
443 }
444
445 /* Apply the dynamic state from the pipeline */
446 cmd_buffer->state.gfx.dirty |=
447 anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
448 &pipeline->dynamic_state,
449 pipeline->dynamic_state_mask);
450 break;
451
452 default:
453 assert(!"invalid bind point");
454 break;
455 }
456 }
457
458 void anv_CmdSetViewport(
459 VkCommandBuffer commandBuffer,
460 uint32_t firstViewport,
461 uint32_t viewportCount,
462 const VkViewport* pViewports)
463 {
464 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
465
466 const uint32_t total_count = firstViewport + viewportCount;
467 if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
468 cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
469
470 memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
471 pViewports, viewportCount * sizeof(*pViewports));
472
473 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
474 }
475
476 void anv_CmdSetScissor(
477 VkCommandBuffer commandBuffer,
478 uint32_t firstScissor,
479 uint32_t scissorCount,
480 const VkRect2D* pScissors)
481 {
482 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
483
484 const uint32_t total_count = firstScissor + scissorCount;
485 if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
486 cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
487
488 memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
489 pScissors, scissorCount * sizeof(*pScissors));
490
491 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
492 }
493
494 void anv_CmdSetLineWidth(
495 VkCommandBuffer commandBuffer,
496 float lineWidth)
497 {
498 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
499
500 cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
501 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
502 }
503
504 void anv_CmdSetDepthBias(
505 VkCommandBuffer commandBuffer,
506 float depthBiasConstantFactor,
507 float depthBiasClamp,
508 float depthBiasSlopeFactor)
509 {
510 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
511
512 cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
513 cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
514 cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
515
516 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
517 }
518
519 void anv_CmdSetBlendConstants(
520 VkCommandBuffer commandBuffer,
521 const float blendConstants[4])
522 {
523 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
524
525 memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
526 blendConstants, sizeof(float) * 4);
527
528 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
529 }
530
531 void anv_CmdSetDepthBounds(
532 VkCommandBuffer commandBuffer,
533 float minDepthBounds,
534 float maxDepthBounds)
535 {
536 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
537
538 cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
539 cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
540
541 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
542 }
543
544 void anv_CmdSetStencilCompareMask(
545 VkCommandBuffer commandBuffer,
546 VkStencilFaceFlags faceMask,
547 uint32_t compareMask)
548 {
549 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
550
551 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
552 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
553 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
554 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
555
556 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
557 }
558
559 void anv_CmdSetStencilWriteMask(
560 VkCommandBuffer commandBuffer,
561 VkStencilFaceFlags faceMask,
562 uint32_t writeMask)
563 {
564 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
565
566 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
567 cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
568 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
569 cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
570
571 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
572 }
573
574 void anv_CmdSetStencilReference(
575 VkCommandBuffer commandBuffer,
576 VkStencilFaceFlags faceMask,
577 uint32_t reference)
578 {
579 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
580
581 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
582 cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
583 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
584 cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
585
586 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
587 }
588
589 void anv_CmdSetLineStippleEXT(
590 VkCommandBuffer commandBuffer,
591 uint32_t lineStippleFactor,
592 uint16_t lineStipplePattern)
593 {
594 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
595
596 cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;
597 cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;
598
599 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
600 }
601
602 static void
603 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
604 VkPipelineBindPoint bind_point,
605 struct anv_pipeline_layout *layout,
606 uint32_t set_index,
607 struct anv_descriptor_set *set,
608 uint32_t *dynamic_offset_count,
609 const uint32_t **dynamic_offsets)
610 {
611 struct anv_descriptor_set_layout *set_layout =
612 layout->set[set_index].layout;
613
614 VkShaderStageFlags stages = set_layout->shader_stages &
615 (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE ?
616 VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS);
617
618 VkShaderStageFlags dirty_stages = 0;
619 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
620 if (cmd_buffer->state.compute.base.descriptors[set_index] != set) {
621 cmd_buffer->state.compute.base.descriptors[set_index] = set;
622 dirty_stages |= stages;
623 }
624 } else {
625 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
626 if (cmd_buffer->state.gfx.base.descriptors[set_index] != set) {
627 cmd_buffer->state.gfx.base.descriptors[set_index] = set;
628 dirty_stages |= stages;
629 }
630 }
631
632 /* If it's a push descriptor set, we have to flag things as dirty
633 * regardless of whether or not the CPU-side data structure changed as we
634 * may have edited in-place.
635 */
636 if (set->pool == NULL)
637 dirty_stages |= stages;
638
639 if (dynamic_offsets) {
640 if (set_layout->dynamic_offset_count > 0) {
641 uint32_t dynamic_offset_start =
642 layout->set[set_index].dynamic_offset_start;
643
644 anv_foreach_stage(stage, stages) {
645 struct anv_push_constants *push =
646 &cmd_buffer->state.push_constants[stage];
647 uint32_t *push_offsets =
648 &push->dynamic_offsets[dynamic_offset_start];
649
650 /* Assert that everything is in range */
651 assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
652 assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
653 ARRAY_SIZE(push->dynamic_offsets));
654
655 unsigned mask = set_layout->stage_dynamic_offsets[stage];
656 STATIC_ASSERT(MAX_DYNAMIC_BUFFERS <= sizeof(mask) * 8);
657 while (mask) {
658 int i = u_bit_scan(&mask);
659 if (push_offsets[i] != (*dynamic_offsets)[i]) {
660 push_offsets[i] = (*dynamic_offsets)[i];
661 dirty_stages |= mesa_to_vk_shader_stage(stage);
662 }
663 }
664 }
665
666 *dynamic_offsets += set_layout->dynamic_offset_count;
667 *dynamic_offset_count -= set_layout->dynamic_offset_count;
668 }
669 }
670
671 cmd_buffer->state.descriptors_dirty |= dirty_stages;
672 cmd_buffer->state.push_constants_dirty |= dirty_stages;
673 }
674
675 void anv_CmdBindDescriptorSets(
676 VkCommandBuffer commandBuffer,
677 VkPipelineBindPoint pipelineBindPoint,
678 VkPipelineLayout _layout,
679 uint32_t firstSet,
680 uint32_t descriptorSetCount,
681 const VkDescriptorSet* pDescriptorSets,
682 uint32_t dynamicOffsetCount,
683 const uint32_t* pDynamicOffsets)
684 {
685 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
686 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
687
688 assert(firstSet + descriptorSetCount <= MAX_SETS);
689
690 for (uint32_t i = 0; i < descriptorSetCount; i++) {
691 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
692 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
693 layout, firstSet + i, set,
694 &dynamicOffsetCount,
695 &pDynamicOffsets);
696 }
697 }
698
699 void anv_CmdBindVertexBuffers(
700 VkCommandBuffer commandBuffer,
701 uint32_t firstBinding,
702 uint32_t bindingCount,
703 const VkBuffer* pBuffers,
704 const VkDeviceSize* pOffsets)
705 {
706 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
707 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
708
709 /* We have to defer setting up vertex buffer since we need the buffer
710 * stride from the pipeline. */
711
712 assert(firstBinding + bindingCount <= MAX_VBS);
713 for (uint32_t i = 0; i < bindingCount; i++) {
714 vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
715 vb[firstBinding + i].offset = pOffsets[i];
716 cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
717 }
718 }
719
720 void anv_CmdBindTransformFeedbackBuffersEXT(
721 VkCommandBuffer commandBuffer,
722 uint32_t firstBinding,
723 uint32_t bindingCount,
724 const VkBuffer* pBuffers,
725 const VkDeviceSize* pOffsets,
726 const VkDeviceSize* pSizes)
727 {
728 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
729 struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;
730
731 /* We have to defer setting up vertex buffer since we need the buffer
732 * stride from the pipeline. */
733
734 assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);
735 for (uint32_t i = 0; i < bindingCount; i++) {
736 if (pBuffers[i] == VK_NULL_HANDLE) {
737 xfb[firstBinding + i].buffer = NULL;
738 } else {
739 ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
740 xfb[firstBinding + i].buffer = buffer;
741 xfb[firstBinding + i].offset = pOffsets[i];
742 xfb[firstBinding + i].size =
743 anv_buffer_get_range(buffer, pOffsets[i],
744 pSizes ? pSizes[i] : VK_WHOLE_SIZE);
745 }
746 }
747 }
748
749 enum isl_format
750 anv_isl_format_for_descriptor_type(VkDescriptorType type)
751 {
752 switch (type) {
753 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
754 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
755 return ISL_FORMAT_R32G32B32A32_FLOAT;
756
757 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
758 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
759 return ISL_FORMAT_RAW;
760
761 default:
762 unreachable("Invalid descriptor type");
763 }
764 }
765
766 struct anv_state
767 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
768 const void *data, uint32_t size, uint32_t alignment)
769 {
770 struct anv_state state;
771
772 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
773 memcpy(state.map, data, size);
774
775 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
776
777 return state;
778 }
779
780 struct anv_state
781 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
782 uint32_t *a, uint32_t *b,
783 uint32_t dwords, uint32_t alignment)
784 {
785 struct anv_state state;
786 uint32_t *p;
787
788 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
789 dwords * 4, alignment);
790 p = state.map;
791 for (uint32_t i = 0; i < dwords; i++)
792 p[i] = a[i] | b[i];
793
794 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
795
796 return state;
797 }
798
799 struct anv_state
800 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
801 gl_shader_stage stage)
802 {
803 struct anv_push_constants *data =
804 &cmd_buffer->state.push_constants[stage];
805
806 struct anv_state state =
807 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
808 sizeof(struct anv_push_constants),
809 32 /* bottom 5 bits MBZ */);
810 memcpy(state.map, data, sizeof(struct anv_push_constants));
811
812 return state;
813 }
814
815 struct anv_state
816 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
817 {
818 struct anv_push_constants *data =
819 &cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
820 struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
821 const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
822 const struct anv_push_range *range =
823 &pipeline->shaders[MESA_SHADER_COMPUTE]->bind_map.push_ranges[0];
824
825 if (cs_prog_data->push.total.size == 0)
826 return (struct anv_state) { .offset = 0 };
827
828 const unsigned push_constant_alignment =
829 cmd_buffer->device->info.gen < 8 ? 32 : 64;
830 const unsigned aligned_total_push_constants_size =
831 ALIGN(cs_prog_data->push.total.size, push_constant_alignment);
832 struct anv_state state =
833 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
834 aligned_total_push_constants_size,
835 push_constant_alignment);
836
837 void *dst = state.map;
838 const void *src = (char *)data + (range->start * 32);
839
840 if (cs_prog_data->push.cross_thread.size > 0) {
841 memcpy(dst, src, cs_prog_data->push.cross_thread.size);
842 dst += cs_prog_data->push.cross_thread.size;
843 src += cs_prog_data->push.cross_thread.size;
844 }
845
846 if (cs_prog_data->push.per_thread.size > 0) {
847 for (unsigned t = 0; t < cs_prog_data->threads; t++) {
848 memcpy(dst, src, cs_prog_data->push.per_thread.size);
849
850 uint32_t *subgroup_id = dst +
851 offsetof(struct anv_push_constants, cs.subgroup_id) -
852 (range->start * 32 + cs_prog_data->push.cross_thread.size);
853 *subgroup_id = t;
854
855 dst += cs_prog_data->push.per_thread.size;
856 }
857 }
858
859 return state;
860 }
861
862 void anv_CmdPushConstants(
863 VkCommandBuffer commandBuffer,
864 VkPipelineLayout layout,
865 VkShaderStageFlags stageFlags,
866 uint32_t offset,
867 uint32_t size,
868 const void* pValues)
869 {
870 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
871
872 anv_foreach_stage(stage, stageFlags) {
873 memcpy(cmd_buffer->state.push_constants[stage].client_data + offset,
874 pValues, size);
875 }
876
877 cmd_buffer->state.push_constants_dirty |= stageFlags;
878 }
879
880 VkResult anv_CreateCommandPool(
881 VkDevice _device,
882 const VkCommandPoolCreateInfo* pCreateInfo,
883 const VkAllocationCallbacks* pAllocator,
884 VkCommandPool* pCmdPool)
885 {
886 ANV_FROM_HANDLE(anv_device, device, _device);
887 struct anv_cmd_pool *pool;
888
889 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
890 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
891 if (pool == NULL)
892 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
893
894 if (pAllocator)
895 pool->alloc = *pAllocator;
896 else
897 pool->alloc = device->alloc;
898
899 list_inithead(&pool->cmd_buffers);
900
901 *pCmdPool = anv_cmd_pool_to_handle(pool);
902
903 return VK_SUCCESS;
904 }
905
906 void anv_DestroyCommandPool(
907 VkDevice _device,
908 VkCommandPool commandPool,
909 const VkAllocationCallbacks* pAllocator)
910 {
911 ANV_FROM_HANDLE(anv_device, device, _device);
912 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
913
914 if (!pool)
915 return;
916
917 list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
918 &pool->cmd_buffers, pool_link) {
919 anv_cmd_buffer_destroy(cmd_buffer);
920 }
921
922 vk_free2(&device->alloc, pAllocator, pool);
923 }
924
925 VkResult anv_ResetCommandPool(
926 VkDevice device,
927 VkCommandPool commandPool,
928 VkCommandPoolResetFlags flags)
929 {
930 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
931
932 list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
933 &pool->cmd_buffers, pool_link) {
934 anv_cmd_buffer_reset(cmd_buffer);
935 }
936
937 return VK_SUCCESS;
938 }
939
940 void anv_TrimCommandPool(
941 VkDevice device,
942 VkCommandPool commandPool,
943 VkCommandPoolTrimFlags flags)
944 {
945 /* Nothing for us to do here. Our pools stay pretty tidy. */
946 }
947
948 /**
949 * Return NULL if the current subpass has no depthstencil attachment.
950 */
951 const struct anv_image_view *
952 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
953 {
954 const struct anv_subpass *subpass = cmd_buffer->state.subpass;
955
956 if (subpass->depth_stencil_attachment == NULL)
957 return NULL;
958
959 const struct anv_image_view *iview =
960 cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view;
961
962 assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
963 VK_IMAGE_ASPECT_STENCIL_BIT));
964
965 return iview;
966 }
967
968 static struct anv_descriptor_set *
969 anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
970 VkPipelineBindPoint bind_point,
971 struct anv_descriptor_set_layout *layout,
972 uint32_t _set)
973 {
974 struct anv_cmd_pipeline_state *pipe_state;
975 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
976 pipe_state = &cmd_buffer->state.compute.base;
977 } else {
978 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
979 pipe_state = &cmd_buffer->state.gfx.base;
980 }
981
982 struct anv_push_descriptor_set **push_set =
983 &pipe_state->push_descriptors[_set];
984
985 if (*push_set == NULL) {
986 *push_set = vk_zalloc(&cmd_buffer->pool->alloc,
987 sizeof(struct anv_push_descriptor_set), 8,
988 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
989 if (*push_set == NULL) {
990 anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
991 return NULL;
992 }
993 }
994
995 struct anv_descriptor_set *set = &(*push_set)->set;
996
997 if (set->layout != layout) {
998 if (set->layout)
999 anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
1000 anv_descriptor_set_layout_ref(layout);
1001 set->layout = layout;
1002 }
1003 set->size = anv_descriptor_set_layout_size(layout);
1004 set->buffer_view_count = layout->buffer_view_count;
1005 set->buffer_views = (*push_set)->buffer_views;
1006
1007 if (layout->descriptor_buffer_size &&
1008 ((*push_set)->set_used_on_gpu ||
1009 set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {
1010 /* The previous buffer is either actively used by some GPU command (so
1011 * we can't modify it) or is too small. Allocate a new one.
1012 */
1013 struct anv_state desc_mem =
1014 anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
1015 layout->descriptor_buffer_size, 32);
1016 if (set->desc_mem.alloc_size) {
1017 /* TODO: Do we really need to copy all the time? */
1018 memcpy(desc_mem.map, set->desc_mem.map,
1019 MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));
1020 }
1021 set->desc_mem = desc_mem;
1022
1023 struct anv_address addr = {
1024 .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,
1025 .offset = set->desc_mem.offset,
1026 };
1027
1028 const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
1029 set->desc_surface_state =
1030 anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
1031 isl_dev->ss.size, isl_dev->ss.align);
1032 anv_fill_buffer_surface_state(cmd_buffer->device,
1033 set->desc_surface_state,
1034 ISL_FORMAT_R32G32B32A32_FLOAT,
1035 addr, layout->descriptor_buffer_size, 1);
1036 }
1037
1038 return set;
1039 }
1040
1041 void anv_CmdPushDescriptorSetKHR(
1042 VkCommandBuffer commandBuffer,
1043 VkPipelineBindPoint pipelineBindPoint,
1044 VkPipelineLayout _layout,
1045 uint32_t _set,
1046 uint32_t descriptorWriteCount,
1047 const VkWriteDescriptorSet* pDescriptorWrites)
1048 {
1049 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1050 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1051
1052 assert(_set < MAX_SETS);
1053
1054 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1055
1056 struct anv_descriptor_set *set =
1057 anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,
1058 set_layout, _set);
1059 if (!set)
1060 return;
1061
1062 /* Go through the user supplied descriptors. */
1063 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
1064 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
1065
1066 switch (write->descriptorType) {
1067 case VK_DESCRIPTOR_TYPE_SAMPLER:
1068 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1069 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1070 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1071 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1072 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1073 anv_descriptor_set_write_image_view(cmd_buffer->device, set,
1074 write->pImageInfo + j,
1075 write->descriptorType,
1076 write->dstBinding,
1077 write->dstArrayElement + j);
1078 }
1079 break;
1080
1081 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1082 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1083 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1084 ANV_FROM_HANDLE(anv_buffer_view, bview,
1085 write->pTexelBufferView[j]);
1086
1087 anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,
1088 write->descriptorType,
1089 bview,
1090 write->dstBinding,
1091 write->dstArrayElement + j);
1092 }
1093 break;
1094
1095 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1096 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1097 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1098 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1099 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1100 assert(write->pBufferInfo[j].buffer);
1101 ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
1102 assert(buffer);
1103
1104 anv_descriptor_set_write_buffer(cmd_buffer->device, set,
1105 &cmd_buffer->surface_state_stream,
1106 write->descriptorType,
1107 buffer,
1108 write->dstBinding,
1109 write->dstArrayElement + j,
1110 write->pBufferInfo[j].offset,
1111 write->pBufferInfo[j].range);
1112 }
1113 break;
1114
1115 default:
1116 break;
1117 }
1118 }
1119
1120 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1121 layout, _set, set, NULL, NULL);
1122 }
1123
1124 void anv_CmdPushDescriptorSetWithTemplateKHR(
1125 VkCommandBuffer commandBuffer,
1126 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1127 VkPipelineLayout _layout,
1128 uint32_t _set,
1129 const void* pData)
1130 {
1131 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1132 ANV_FROM_HANDLE(anv_descriptor_update_template, template,
1133 descriptorUpdateTemplate);
1134 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1135
1136 assert(_set < MAX_PUSH_DESCRIPTORS);
1137
1138 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1139
1140 struct anv_descriptor_set *set =
1141 anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,
1142 set_layout, _set);
1143 if (!set)
1144 return;
1145
1146 anv_descriptor_set_write_template(cmd_buffer->device, set,
1147 &cmd_buffer->surface_state_stream,
1148 template,
1149 pData);
1150
1151 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
1152 layout, _set, set, NULL, NULL);
1153 }
1154
1155 void anv_CmdSetDeviceMask(
1156 VkCommandBuffer commandBuffer,
1157 uint32_t deviceMask)
1158 {
1159 /* No-op */
1160 }