anv: stop storing prog param data into shader blobs
[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 case 12: \
349 gen12_##func(__VA_ARGS__); \
350 break; \
351 default: \
352 assert(!"Unknown hardware generation"); \
353 }
354
355 void
356 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
357 {
358 anv_genX_call(&cmd_buffer->device->info,
359 cmd_buffer_emit_state_base_address,
360 cmd_buffer);
361 }
362
363 void
364 anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
365 const struct anv_image *image,
366 VkImageAspectFlagBits aspect,
367 enum isl_aux_usage aux_usage,
368 uint32_t level,
369 uint32_t base_layer,
370 uint32_t layer_count)
371 {
372 anv_genX_call(&cmd_buffer->device->info,
373 cmd_buffer_mark_image_written,
374 cmd_buffer, image, aspect, aux_usage,
375 level, base_layer, layer_count);
376 }
377
378 void
379 anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)
380 {
381 anv_genX_call(&cmd_buffer->device->info,
382 cmd_emit_conditional_render_predicate,
383 cmd_buffer);
384 }
385
386 static bool
387 mem_update(void *dst, const void *src, size_t size)
388 {
389 if (memcmp(dst, src, size) == 0)
390 return false;
391
392 memcpy(dst, src, size);
393 return true;
394 }
395
396 static void
397 set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,
398 gl_shader_stage stage,
399 const struct anv_pipeline_bind_map *map)
400 {
401 if (mem_update(cmd_buffer->state.surface_sha1s[stage],
402 map->surface_sha1, sizeof(map->surface_sha1)))
403 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
404
405 if (mem_update(cmd_buffer->state.sampler_sha1s[stage],
406 map->sampler_sha1, sizeof(map->sampler_sha1)))
407 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
408
409 if (mem_update(cmd_buffer->state.push_sha1s[stage],
410 map->push_sha1, sizeof(map->push_sha1)))
411 cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);
412 }
413
414 void anv_CmdBindPipeline(
415 VkCommandBuffer commandBuffer,
416 VkPipelineBindPoint pipelineBindPoint,
417 VkPipeline _pipeline)
418 {
419 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
420 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
421
422 switch (pipelineBindPoint) {
423 case VK_PIPELINE_BIND_POINT_COMPUTE: {
424 if (cmd_buffer->state.compute.base.pipeline == pipeline)
425 return;
426
427 cmd_buffer->state.compute.base.pipeline = pipeline;
428 cmd_buffer->state.compute.pipeline_dirty = true;
429 const struct anv_pipeline_bind_map *bind_map =
430 &pipeline->shaders[MESA_SHADER_COMPUTE]->bind_map;
431 set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE, bind_map);
432 break;
433 }
434
435 case VK_PIPELINE_BIND_POINT_GRAPHICS:
436 if (cmd_buffer->state.gfx.base.pipeline == pipeline)
437 return;
438
439 cmd_buffer->state.gfx.base.pipeline = pipeline;
440 cmd_buffer->state.gfx.vb_dirty |= pipeline->vb_used;
441 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
442
443 anv_foreach_stage(stage, pipeline->active_stages) {
444 set_dirty_for_bind_map(cmd_buffer, stage,
445 &pipeline->shaders[stage]->bind_map);
446 }
447
448 /* Apply the dynamic state from the pipeline */
449 cmd_buffer->state.gfx.dirty |=
450 anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
451 &pipeline->dynamic_state,
452 pipeline->dynamic_state_mask);
453 break;
454
455 default:
456 assert(!"invalid bind point");
457 break;
458 }
459 }
460
461 void anv_CmdSetViewport(
462 VkCommandBuffer commandBuffer,
463 uint32_t firstViewport,
464 uint32_t viewportCount,
465 const VkViewport* pViewports)
466 {
467 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
468
469 const uint32_t total_count = firstViewport + viewportCount;
470 if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
471 cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
472
473 memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
474 pViewports, viewportCount * sizeof(*pViewports));
475
476 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
477 }
478
479 void anv_CmdSetScissor(
480 VkCommandBuffer commandBuffer,
481 uint32_t firstScissor,
482 uint32_t scissorCount,
483 const VkRect2D* pScissors)
484 {
485 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
486
487 const uint32_t total_count = firstScissor + scissorCount;
488 if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
489 cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
490
491 memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
492 pScissors, scissorCount * sizeof(*pScissors));
493
494 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
495 }
496
497 void anv_CmdSetLineWidth(
498 VkCommandBuffer commandBuffer,
499 float lineWidth)
500 {
501 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
502
503 cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
504 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
505 }
506
507 void anv_CmdSetDepthBias(
508 VkCommandBuffer commandBuffer,
509 float depthBiasConstantFactor,
510 float depthBiasClamp,
511 float depthBiasSlopeFactor)
512 {
513 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
514
515 cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
516 cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
517 cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
518
519 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
520 }
521
522 void anv_CmdSetBlendConstants(
523 VkCommandBuffer commandBuffer,
524 const float blendConstants[4])
525 {
526 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
527
528 memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
529 blendConstants, sizeof(float) * 4);
530
531 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
532 }
533
534 void anv_CmdSetDepthBounds(
535 VkCommandBuffer commandBuffer,
536 float minDepthBounds,
537 float maxDepthBounds)
538 {
539 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
540
541 cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
542 cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
543
544 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
545 }
546
547 void anv_CmdSetStencilCompareMask(
548 VkCommandBuffer commandBuffer,
549 VkStencilFaceFlags faceMask,
550 uint32_t compareMask)
551 {
552 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
553
554 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
555 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
556 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
557 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
558
559 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
560 }
561
562 void anv_CmdSetStencilWriteMask(
563 VkCommandBuffer commandBuffer,
564 VkStencilFaceFlags faceMask,
565 uint32_t writeMask)
566 {
567 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
568
569 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
570 cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
571 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
572 cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
573
574 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
575 }
576
577 void anv_CmdSetStencilReference(
578 VkCommandBuffer commandBuffer,
579 VkStencilFaceFlags faceMask,
580 uint32_t reference)
581 {
582 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
583
584 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
585 cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
586 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
587 cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
588
589 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
590 }
591
592 void anv_CmdSetLineStippleEXT(
593 VkCommandBuffer commandBuffer,
594 uint32_t lineStippleFactor,
595 uint16_t lineStipplePattern)
596 {
597 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
598
599 cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;
600 cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;
601
602 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
603 }
604
605 static void
606 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
607 VkPipelineBindPoint bind_point,
608 struct anv_pipeline_layout *layout,
609 uint32_t set_index,
610 struct anv_descriptor_set *set,
611 uint32_t *dynamic_offset_count,
612 const uint32_t **dynamic_offsets)
613 {
614 struct anv_descriptor_set_layout *set_layout =
615 layout->set[set_index].layout;
616
617 VkShaderStageFlags stages = set_layout->shader_stages &
618 (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE ?
619 VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS);
620
621 VkShaderStageFlags dirty_stages = 0;
622 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
623 if (cmd_buffer->state.compute.base.descriptors[set_index] != set) {
624 cmd_buffer->state.compute.base.descriptors[set_index] = set;
625 dirty_stages |= stages;
626 }
627 } else {
628 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
629 if (cmd_buffer->state.gfx.base.descriptors[set_index] != set) {
630 cmd_buffer->state.gfx.base.descriptors[set_index] = set;
631 dirty_stages |= stages;
632 }
633 }
634
635 /* If it's a push descriptor set, we have to flag things as dirty
636 * regardless of whether or not the CPU-side data structure changed as we
637 * may have edited in-place.
638 */
639 if (set->pool == NULL)
640 dirty_stages |= stages;
641
642 if (dynamic_offsets) {
643 if (set_layout->dynamic_offset_count > 0) {
644 uint32_t dynamic_offset_start =
645 layout->set[set_index].dynamic_offset_start;
646
647 anv_foreach_stage(stage, stages) {
648 struct anv_push_constants *push =
649 &cmd_buffer->state.push_constants[stage];
650 uint32_t *push_offsets =
651 &push->dynamic_offsets[dynamic_offset_start];
652
653 /* Assert that everything is in range */
654 assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
655 assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
656 ARRAY_SIZE(push->dynamic_offsets));
657
658 unsigned mask = set_layout->stage_dynamic_offsets[stage];
659 STATIC_ASSERT(MAX_DYNAMIC_BUFFERS <= sizeof(mask) * 8);
660 while (mask) {
661 int i = u_bit_scan(&mask);
662 if (push_offsets[i] != (*dynamic_offsets)[i]) {
663 push_offsets[i] = (*dynamic_offsets)[i];
664 dirty_stages |= mesa_to_vk_shader_stage(stage);
665 }
666 }
667 }
668
669 *dynamic_offsets += set_layout->dynamic_offset_count;
670 *dynamic_offset_count -= set_layout->dynamic_offset_count;
671 }
672 }
673
674 cmd_buffer->state.descriptors_dirty |= dirty_stages;
675 cmd_buffer->state.push_constants_dirty |= dirty_stages;
676 }
677
678 void anv_CmdBindDescriptorSets(
679 VkCommandBuffer commandBuffer,
680 VkPipelineBindPoint pipelineBindPoint,
681 VkPipelineLayout _layout,
682 uint32_t firstSet,
683 uint32_t descriptorSetCount,
684 const VkDescriptorSet* pDescriptorSets,
685 uint32_t dynamicOffsetCount,
686 const uint32_t* pDynamicOffsets)
687 {
688 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
689 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
690
691 assert(firstSet + descriptorSetCount <= MAX_SETS);
692
693 for (uint32_t i = 0; i < descriptorSetCount; i++) {
694 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
695 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
696 layout, firstSet + i, set,
697 &dynamicOffsetCount,
698 &pDynamicOffsets);
699 }
700 }
701
702 void anv_CmdBindVertexBuffers(
703 VkCommandBuffer commandBuffer,
704 uint32_t firstBinding,
705 uint32_t bindingCount,
706 const VkBuffer* pBuffers,
707 const VkDeviceSize* pOffsets)
708 {
709 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
710 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
711
712 /* We have to defer setting up vertex buffer since we need the buffer
713 * stride from the pipeline. */
714
715 assert(firstBinding + bindingCount <= MAX_VBS);
716 for (uint32_t i = 0; i < bindingCount; i++) {
717 vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
718 vb[firstBinding + i].offset = pOffsets[i];
719 cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
720 }
721 }
722
723 void anv_CmdBindTransformFeedbackBuffersEXT(
724 VkCommandBuffer commandBuffer,
725 uint32_t firstBinding,
726 uint32_t bindingCount,
727 const VkBuffer* pBuffers,
728 const VkDeviceSize* pOffsets,
729 const VkDeviceSize* pSizes)
730 {
731 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
732 struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;
733
734 /* We have to defer setting up vertex buffer since we need the buffer
735 * stride from the pipeline. */
736
737 assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);
738 for (uint32_t i = 0; i < bindingCount; i++) {
739 if (pBuffers[i] == VK_NULL_HANDLE) {
740 xfb[firstBinding + i].buffer = NULL;
741 } else {
742 ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
743 xfb[firstBinding + i].buffer = buffer;
744 xfb[firstBinding + i].offset = pOffsets[i];
745 xfb[firstBinding + i].size =
746 anv_buffer_get_range(buffer, pOffsets[i],
747 pSizes ? pSizes[i] : VK_WHOLE_SIZE);
748 }
749 }
750 }
751
752 enum isl_format
753 anv_isl_format_for_descriptor_type(VkDescriptorType type)
754 {
755 switch (type) {
756 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
757 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
758 return ISL_FORMAT_R32G32B32A32_FLOAT;
759
760 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
761 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
762 return ISL_FORMAT_RAW;
763
764 default:
765 unreachable("Invalid descriptor type");
766 }
767 }
768
769 struct anv_state
770 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
771 const void *data, uint32_t size, uint32_t alignment)
772 {
773 struct anv_state state;
774
775 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
776 memcpy(state.map, data, size);
777
778 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
779
780 return state;
781 }
782
783 struct anv_state
784 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
785 uint32_t *a, uint32_t *b,
786 uint32_t dwords, uint32_t alignment)
787 {
788 struct anv_state state;
789 uint32_t *p;
790
791 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
792 dwords * 4, alignment);
793 p = state.map;
794 for (uint32_t i = 0; i < dwords; i++)
795 p[i] = a[i] | b[i];
796
797 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
798
799 return state;
800 }
801
802 struct anv_state
803 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
804 gl_shader_stage stage)
805 {
806 struct anv_push_constants *data =
807 &cmd_buffer->state.push_constants[stage];
808
809 struct anv_state state =
810 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
811 sizeof(struct anv_push_constants),
812 32 /* bottom 5 bits MBZ */);
813 memcpy(state.map, data, sizeof(struct anv_push_constants));
814
815 return state;
816 }
817
818 struct anv_state
819 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
820 {
821 struct anv_push_constants *data =
822 &cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
823 struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
824 const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
825 const struct anv_push_range *range =
826 &pipeline->shaders[MESA_SHADER_COMPUTE]->bind_map.push_ranges[0];
827
828 if (cs_prog_data->push.total.size == 0)
829 return (struct anv_state) { .offset = 0 };
830
831 const unsigned push_constant_alignment =
832 cmd_buffer->device->info.gen < 8 ? 32 : 64;
833 const unsigned aligned_total_push_constants_size =
834 ALIGN(cs_prog_data->push.total.size, push_constant_alignment);
835 struct anv_state state =
836 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
837 aligned_total_push_constants_size,
838 push_constant_alignment);
839
840 void *dst = state.map;
841 const void *src = (char *)data + (range->start * 32);
842
843 if (cs_prog_data->push.cross_thread.size > 0) {
844 memcpy(dst, src, cs_prog_data->push.cross_thread.size);
845 dst += cs_prog_data->push.cross_thread.size;
846 src += cs_prog_data->push.cross_thread.size;
847 }
848
849 if (cs_prog_data->push.per_thread.size > 0) {
850 for (unsigned t = 0; t < cs_prog_data->threads; t++) {
851 memcpy(dst, src, cs_prog_data->push.per_thread.size);
852
853 uint32_t *subgroup_id = dst +
854 offsetof(struct anv_push_constants, cs.subgroup_id) -
855 (range->start * 32 + cs_prog_data->push.cross_thread.size);
856 *subgroup_id = t;
857
858 dst += cs_prog_data->push.per_thread.size;
859 }
860 }
861
862 return state;
863 }
864
865 void anv_CmdPushConstants(
866 VkCommandBuffer commandBuffer,
867 VkPipelineLayout layout,
868 VkShaderStageFlags stageFlags,
869 uint32_t offset,
870 uint32_t size,
871 const void* pValues)
872 {
873 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
874
875 anv_foreach_stage(stage, stageFlags) {
876 memcpy(cmd_buffer->state.push_constants[stage].client_data + offset,
877 pValues, size);
878 }
879
880 cmd_buffer->state.push_constants_dirty |= stageFlags;
881 }
882
883 VkResult anv_CreateCommandPool(
884 VkDevice _device,
885 const VkCommandPoolCreateInfo* pCreateInfo,
886 const VkAllocationCallbacks* pAllocator,
887 VkCommandPool* pCmdPool)
888 {
889 ANV_FROM_HANDLE(anv_device, device, _device);
890 struct anv_cmd_pool *pool;
891
892 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
893 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
894 if (pool == NULL)
895 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
896
897 if (pAllocator)
898 pool->alloc = *pAllocator;
899 else
900 pool->alloc = device->alloc;
901
902 list_inithead(&pool->cmd_buffers);
903
904 *pCmdPool = anv_cmd_pool_to_handle(pool);
905
906 return VK_SUCCESS;
907 }
908
909 void anv_DestroyCommandPool(
910 VkDevice _device,
911 VkCommandPool commandPool,
912 const VkAllocationCallbacks* pAllocator)
913 {
914 ANV_FROM_HANDLE(anv_device, device, _device);
915 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
916
917 if (!pool)
918 return;
919
920 list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
921 &pool->cmd_buffers, pool_link) {
922 anv_cmd_buffer_destroy(cmd_buffer);
923 }
924
925 vk_free2(&device->alloc, pAllocator, pool);
926 }
927
928 VkResult anv_ResetCommandPool(
929 VkDevice device,
930 VkCommandPool commandPool,
931 VkCommandPoolResetFlags flags)
932 {
933 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
934
935 list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
936 &pool->cmd_buffers, pool_link) {
937 anv_cmd_buffer_reset(cmd_buffer);
938 }
939
940 return VK_SUCCESS;
941 }
942
943 void anv_TrimCommandPool(
944 VkDevice device,
945 VkCommandPool commandPool,
946 VkCommandPoolTrimFlags flags)
947 {
948 /* Nothing for us to do here. Our pools stay pretty tidy. */
949 }
950
951 /**
952 * Return NULL if the current subpass has no depthstencil attachment.
953 */
954 const struct anv_image_view *
955 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
956 {
957 const struct anv_subpass *subpass = cmd_buffer->state.subpass;
958
959 if (subpass->depth_stencil_attachment == NULL)
960 return NULL;
961
962 const struct anv_image_view *iview =
963 cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view;
964
965 assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
966 VK_IMAGE_ASPECT_STENCIL_BIT));
967
968 return iview;
969 }
970
971 static struct anv_descriptor_set *
972 anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
973 VkPipelineBindPoint bind_point,
974 struct anv_descriptor_set_layout *layout,
975 uint32_t _set)
976 {
977 struct anv_cmd_pipeline_state *pipe_state;
978 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
979 pipe_state = &cmd_buffer->state.compute.base;
980 } else {
981 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
982 pipe_state = &cmd_buffer->state.gfx.base;
983 }
984
985 struct anv_push_descriptor_set **push_set =
986 &pipe_state->push_descriptors[_set];
987
988 if (*push_set == NULL) {
989 *push_set = vk_zalloc(&cmd_buffer->pool->alloc,
990 sizeof(struct anv_push_descriptor_set), 8,
991 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
992 if (*push_set == NULL) {
993 anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
994 return NULL;
995 }
996 }
997
998 struct anv_descriptor_set *set = &(*push_set)->set;
999
1000 if (set->layout != layout) {
1001 if (set->layout)
1002 anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
1003 anv_descriptor_set_layout_ref(layout);
1004 set->layout = layout;
1005 }
1006 set->size = anv_descriptor_set_layout_size(layout);
1007 set->buffer_view_count = layout->buffer_view_count;
1008 set->buffer_views = (*push_set)->buffer_views;
1009
1010 if (layout->descriptor_buffer_size &&
1011 ((*push_set)->set_used_on_gpu ||
1012 set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {
1013 /* The previous buffer is either actively used by some GPU command (so
1014 * we can't modify it) or is too small. Allocate a new one.
1015 */
1016 struct anv_state desc_mem =
1017 anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
1018 layout->descriptor_buffer_size, 32);
1019 if (set->desc_mem.alloc_size) {
1020 /* TODO: Do we really need to copy all the time? */
1021 memcpy(desc_mem.map, set->desc_mem.map,
1022 MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));
1023 }
1024 set->desc_mem = desc_mem;
1025
1026 struct anv_address addr = {
1027 .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,
1028 .offset = set->desc_mem.offset,
1029 };
1030
1031 const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
1032 set->desc_surface_state =
1033 anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
1034 isl_dev->ss.size, isl_dev->ss.align);
1035 anv_fill_buffer_surface_state(cmd_buffer->device,
1036 set->desc_surface_state,
1037 ISL_FORMAT_R32G32B32A32_FLOAT,
1038 addr, layout->descriptor_buffer_size, 1);
1039 }
1040
1041 return set;
1042 }
1043
1044 void anv_CmdPushDescriptorSetKHR(
1045 VkCommandBuffer commandBuffer,
1046 VkPipelineBindPoint pipelineBindPoint,
1047 VkPipelineLayout _layout,
1048 uint32_t _set,
1049 uint32_t descriptorWriteCount,
1050 const VkWriteDescriptorSet* pDescriptorWrites)
1051 {
1052 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1053 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1054
1055 assert(_set < MAX_SETS);
1056
1057 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1058
1059 struct anv_descriptor_set *set =
1060 anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,
1061 set_layout, _set);
1062 if (!set)
1063 return;
1064
1065 /* Go through the user supplied descriptors. */
1066 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
1067 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
1068
1069 switch (write->descriptorType) {
1070 case VK_DESCRIPTOR_TYPE_SAMPLER:
1071 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1072 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1073 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1074 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1075 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1076 anv_descriptor_set_write_image_view(cmd_buffer->device, set,
1077 write->pImageInfo + j,
1078 write->descriptorType,
1079 write->dstBinding,
1080 write->dstArrayElement + j);
1081 }
1082 break;
1083
1084 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1085 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1086 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1087 ANV_FROM_HANDLE(anv_buffer_view, bview,
1088 write->pTexelBufferView[j]);
1089
1090 anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,
1091 write->descriptorType,
1092 bview,
1093 write->dstBinding,
1094 write->dstArrayElement + j);
1095 }
1096 break;
1097
1098 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1099 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1100 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1101 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1102 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1103 assert(write->pBufferInfo[j].buffer);
1104 ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
1105 assert(buffer);
1106
1107 anv_descriptor_set_write_buffer(cmd_buffer->device, set,
1108 &cmd_buffer->surface_state_stream,
1109 write->descriptorType,
1110 buffer,
1111 write->dstBinding,
1112 write->dstArrayElement + j,
1113 write->pBufferInfo[j].offset,
1114 write->pBufferInfo[j].range);
1115 }
1116 break;
1117
1118 default:
1119 break;
1120 }
1121 }
1122
1123 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1124 layout, _set, set, NULL, NULL);
1125 }
1126
1127 void anv_CmdPushDescriptorSetWithTemplateKHR(
1128 VkCommandBuffer commandBuffer,
1129 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1130 VkPipelineLayout _layout,
1131 uint32_t _set,
1132 const void* pData)
1133 {
1134 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1135 ANV_FROM_HANDLE(anv_descriptor_update_template, template,
1136 descriptorUpdateTemplate);
1137 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1138
1139 assert(_set < MAX_PUSH_DESCRIPTORS);
1140
1141 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1142
1143 struct anv_descriptor_set *set =
1144 anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,
1145 set_layout, _set);
1146 if (!set)
1147 return;
1148
1149 anv_descriptor_set_write_template(cmd_buffer->device, set,
1150 &cmd_buffer->surface_state_stream,
1151 template,
1152 pData);
1153
1154 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
1155 layout, _set, set, NULL, NULL);
1156 }
1157
1158 void anv_CmdSetDeviceMask(
1159 VkCommandBuffer commandBuffer,
1160 uint32_t deviceMask)
1161 {
1162 /* No-op */
1163 }