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