Merge branch 'nir-spirv' into vulkan
[mesa.git] / src / 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 /** \file anv_cmd_buffer.c
33 *
34 * This file contains all of the stuff for emitting commands into a command
35 * buffer. This includes implementations of most of the vkCmd*
36 * entrypoints. This file is concerned entirely with state emission and
37 * not with the command buffer data structure itself. As far as this file
38 * is concerned, most of anv_cmd_buffer is magic.
39 */
40
41 static void
42 anv_cmd_state_init(struct anv_cmd_state *state)
43 {
44 state->rs_state = NULL;
45 state->vp_state = NULL;
46 state->cb_state = NULL;
47 state->ds_state = NULL;
48 memset(&state->state_vf, 0, sizeof(state->state_vf));
49 memset(&state->descriptors, 0, sizeof(state->descriptors));
50 memset(&state->push_constants, 0, sizeof(state->push_constants));
51
52 state->dirty = 0;
53 state->vb_dirty = 0;
54 state->descriptors_dirty = 0;
55 state->push_constants_dirty = 0;
56 state->pipeline = NULL;
57 state->vp_state = NULL;
58 state->rs_state = NULL;
59 state->ds_state = NULL;
60
61 state->gen7.index_buffer = NULL;
62 }
63
64 VkResult anv_CreateCommandBuffer(
65 VkDevice _device,
66 const VkCmdBufferCreateInfo* pCreateInfo,
67 VkCmdBuffer* pCmdBuffer)
68 {
69 ANV_FROM_HANDLE(anv_device, device, _device);
70 ANV_FROM_HANDLE(anv_cmd_pool, pool, pCreateInfo->cmdPool);
71 struct anv_cmd_buffer *cmd_buffer;
72 VkResult result;
73
74 cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
75 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
76 if (cmd_buffer == NULL)
77 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
78
79 cmd_buffer->device = device;
80
81 result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
82 if (result != VK_SUCCESS)
83 goto fail;
84
85 anv_state_stream_init(&cmd_buffer->surface_state_stream,
86 &device->surface_state_block_pool);
87 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
88 &device->dynamic_state_block_pool);
89
90 cmd_buffer->level = pCreateInfo->level;
91 cmd_buffer->opt_flags = 0;
92
93 anv_cmd_state_init(&cmd_buffer->state);
94
95 if (pool) {
96 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
97 } else {
98 /* Init the pool_link so we can safefly call list_del when we destroy
99 * the command buffer
100 */
101 list_inithead(&cmd_buffer->pool_link);
102 }
103
104 *pCmdBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
105
106 return VK_SUCCESS;
107
108 fail: anv_device_free(device, cmd_buffer);
109
110 return result;
111 }
112
113 VkResult anv_DestroyCommandBuffer(
114 VkDevice _device,
115 VkCmdBuffer _cmd_buffer)
116 {
117 ANV_FROM_HANDLE(anv_device, device, _device);
118 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _cmd_buffer);
119
120 list_del(&cmd_buffer->pool_link);
121
122 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
123
124 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
125 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
126 anv_device_free(device, cmd_buffer);
127
128 return VK_SUCCESS;
129 }
130
131 VkResult anv_ResetCommandBuffer(
132 VkCmdBuffer cmdBuffer,
133 VkCmdBufferResetFlags flags)
134 {
135 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
136
137 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
138
139 anv_cmd_state_init(&cmd_buffer->state);
140
141 return VK_SUCCESS;
142 }
143
144 void
145 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
146 {
147 switch (cmd_buffer->device->info.gen) {
148 case 7:
149 return gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
150 case 8:
151 return gen8_cmd_buffer_emit_state_base_address(cmd_buffer);
152 default:
153 unreachable("unsupported gen\n");
154 }
155 }
156
157 VkResult anv_BeginCommandBuffer(
158 VkCmdBuffer cmdBuffer,
159 const VkCmdBufferBeginInfo* pBeginInfo)
160 {
161 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
162
163 cmd_buffer->opt_flags = pBeginInfo->flags;
164
165 if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_SECONDARY) {
166 cmd_buffer->state.framebuffer =
167 anv_framebuffer_from_handle(pBeginInfo->framebuffer);
168 cmd_buffer->state.pass =
169 anv_render_pass_from_handle(pBeginInfo->renderPass);
170
171 /* FIXME: We shouldn't be starting on the first subpass */
172 anv_cmd_buffer_begin_subpass(cmd_buffer,
173 &cmd_buffer->state.pass->subpasses[0]);
174 }
175
176 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
177 cmd_buffer->state.current_pipeline = UINT32_MAX;
178
179 return VK_SUCCESS;
180 }
181
182 VkResult anv_EndCommandBuffer(
183 VkCmdBuffer cmdBuffer)
184 {
185 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
186 struct anv_device *device = cmd_buffer->device;
187
188 anv_cmd_buffer_end_batch_buffer(cmd_buffer);
189
190 if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
191 /* The algorithm used to compute the validate list is not threadsafe as
192 * it uses the bo->index field. We have to lock the device around it.
193 * Fortunately, the chances for contention here are probably very low.
194 */
195 pthread_mutex_lock(&device->mutex);
196 anv_cmd_buffer_prepare_execbuf(cmd_buffer);
197 pthread_mutex_unlock(&device->mutex);
198 }
199
200 return VK_SUCCESS;
201 }
202
203 void anv_CmdBindPipeline(
204 VkCmdBuffer cmdBuffer,
205 VkPipelineBindPoint pipelineBindPoint,
206 VkPipeline _pipeline)
207 {
208 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
209 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
210
211 switch (pipelineBindPoint) {
212 case VK_PIPELINE_BIND_POINT_COMPUTE:
213 cmd_buffer->state.compute_pipeline = pipeline;
214 cmd_buffer->state.compute_dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
215 cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
216 break;
217
218 case VK_PIPELINE_BIND_POINT_GRAPHICS:
219 cmd_buffer->state.pipeline = pipeline;
220 cmd_buffer->state.vb_dirty |= pipeline->vb_used;
221 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
222 cmd_buffer->state.push_constants_dirty |= pipeline->active_stages;
223 break;
224
225 default:
226 assert(!"invalid bind point");
227 break;
228 }
229 }
230
231 void anv_CmdBindDynamicViewportState(
232 VkCmdBuffer cmdBuffer,
233 VkDynamicViewportState dynamicViewportState)
234 {
235 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
236 ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, dynamicViewportState);
237
238 cmd_buffer->state.vp_state = vp_state;
239 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_VP_DIRTY;
240 }
241
242 void anv_CmdBindDynamicRasterState(
243 VkCmdBuffer cmdBuffer,
244 VkDynamicRasterState dynamicRasterState)
245 {
246 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
247 ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, dynamicRasterState);
248
249 cmd_buffer->state.rs_state = rs_state;
250 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_RS_DIRTY;
251 }
252
253 void anv_CmdBindDynamicColorBlendState(
254 VkCmdBuffer cmdBuffer,
255 VkDynamicColorBlendState dynamicColorBlendState)
256 {
257 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
258 ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, dynamicColorBlendState);
259
260 cmd_buffer->state.cb_state = cb_state;
261 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_CB_DIRTY;
262 }
263
264 void anv_CmdBindDynamicDepthStencilState(
265 VkCmdBuffer cmdBuffer,
266 VkDynamicDepthStencilState dynamicDepthStencilState)
267 {
268 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
269 ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, dynamicDepthStencilState);
270
271 cmd_buffer->state.ds_state = ds_state;
272 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_DS_DIRTY;
273 }
274
275 void anv_CmdBindDescriptorSets(
276 VkCmdBuffer cmdBuffer,
277 VkPipelineBindPoint pipelineBindPoint,
278 VkPipelineLayout _layout,
279 uint32_t firstSet,
280 uint32_t setCount,
281 const VkDescriptorSet* pDescriptorSets,
282 uint32_t dynamicOffsetCount,
283 const uint32_t* pDynamicOffsets)
284 {
285 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
286 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
287 struct anv_descriptor_set_layout *set_layout;
288
289 assert(firstSet + setCount < MAX_SETS);
290
291 uint32_t dynamic_slot = 0;
292 for (uint32_t i = 0; i < setCount; i++) {
293 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
294 set_layout = layout->set[firstSet + i].layout;
295
296 cmd_buffer->state.descriptors[firstSet + i].set = set;
297
298 assert(set_layout->num_dynamic_buffers <
299 ARRAY_SIZE(cmd_buffer->state.descriptors[0].dynamic_offsets));
300 memcpy(cmd_buffer->state.descriptors[firstSet + i].dynamic_offsets,
301 pDynamicOffsets + dynamic_slot,
302 set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets));
303
304 cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
305
306 dynamic_slot += set_layout->num_dynamic_buffers;
307 }
308 }
309
310 void anv_CmdBindVertexBuffers(
311 VkCmdBuffer cmdBuffer,
312 uint32_t startBinding,
313 uint32_t bindingCount,
314 const VkBuffer* pBuffers,
315 const VkDeviceSize* pOffsets)
316 {
317 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
318 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
319
320 /* We have to defer setting up vertex buffer since we need the buffer
321 * stride from the pipeline. */
322
323 assert(startBinding + bindingCount < MAX_VBS);
324 for (uint32_t i = 0; i < bindingCount; i++) {
325 vb[startBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
326 vb[startBinding + i].offset = pOffsets[i];
327 cmd_buffer->state.vb_dirty |= 1 << (startBinding + i);
328 }
329 }
330
331 static void
332 add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
333 struct anv_state state, struct anv_bo *bo, uint32_t offset)
334 {
335 /* The address goes in SURFACE_STATE dword 1 for gens < 8 and dwords 8 and
336 * 9 for gen8+. We only write the first dword for gen8+ here and rely on
337 * the initial state to set the high bits to 0. */
338
339 const uint32_t dword = cmd_buffer->device->info.gen < 8 ? 1 : 8;
340
341 *(uint32_t *)(state.map + dword * 4) =
342 anv_reloc_list_add(anv_cmd_buffer_current_surface_relocs(cmd_buffer),
343 cmd_buffer->device, state.offset + dword * 4, bo, offset);
344 }
345
346 VkResult
347 anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
348 unsigned stage, struct anv_state *bt_state)
349 {
350 struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
351 struct anv_subpass *subpass = cmd_buffer->state.subpass;
352 struct anv_pipeline_layout *layout;
353 uint32_t attachments, bias, size;
354
355 if (stage == VK_SHADER_STAGE_COMPUTE)
356 layout = cmd_buffer->state.compute_pipeline->layout;
357 else
358 layout = cmd_buffer->state.pipeline->layout;
359
360 if (stage == VK_SHADER_STAGE_FRAGMENT) {
361 bias = MAX_RTS;
362 attachments = subpass->color_count;
363 } else {
364 bias = 0;
365 attachments = 0;
366 }
367
368 /* This is a little awkward: layout can be NULL but we still have to
369 * allocate and set a binding table for the PS stage for render
370 * targets. */
371 uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
372
373 if (attachments + surface_count == 0)
374 return VK_SUCCESS;
375
376 size = (bias + surface_count) * sizeof(uint32_t);
377 *bt_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, size, 32);
378 uint32_t *bt_map = bt_state->map;
379
380 if (bt_state->map == NULL)
381 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
382
383 /* This is highly annoying. The Vulkan spec puts the depth-stencil
384 * attachments in with the color attachments. Unfortunately, thanks to
385 * other aspects of the API, we cana't really saparate them before this
386 * point. Therefore, we have to walk all of the attachments but only
387 * put the color attachments into the binding table.
388 */
389 for (uint32_t a = 0; a < attachments; a++) {
390 const struct anv_attachment_view *attachment =
391 fb->attachments[subpass->color_attachments[a]];
392
393 assert(attachment->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_COLOR);
394 const struct anv_color_attachment_view *view =
395 (const struct anv_color_attachment_view *)attachment;
396
397 struct anv_state state =
398 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
399
400 if (state.map == NULL)
401 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
402
403 memcpy(state.map, view->view.surface_state.map, 64);
404
405 add_surface_state_reloc(cmd_buffer, state, view->view.bo, view->view.offset);
406
407 bt_map[a] = state.offset;
408 }
409
410 if (layout == NULL)
411 return VK_SUCCESS;
412
413 for (uint32_t set = 0; set < layout->num_sets; set++) {
414 struct anv_descriptor_set_binding *d = &cmd_buffer->state.descriptors[set];
415 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
416 struct anv_descriptor_slot *surface_slots =
417 set_layout->stage[stage].surface_start;
418
419 uint32_t start = bias + layout->set[set].surface_start[stage];
420
421 for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) {
422 struct anv_surface_view *view =
423 d->set->descriptors[surface_slots[b].index].view;
424
425 if (!view)
426 continue;
427
428 struct anv_state state =
429 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
430
431 if (state.map == NULL)
432 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
433
434 uint32_t offset;
435 if (surface_slots[b].dynamic_slot >= 0) {
436 uint32_t dynamic_offset =
437 d->dynamic_offsets[surface_slots[b].dynamic_slot];
438
439 offset = view->offset + dynamic_offset;
440 anv_fill_buffer_surface_state(cmd_buffer->device,
441 state.map, view->format, offset,
442 view->range - dynamic_offset);
443 } else {
444 offset = view->offset;
445 memcpy(state.map, view->surface_state.map, 64);
446 }
447
448 add_surface_state_reloc(cmd_buffer, state, view->bo, offset);
449
450 bt_map[start + b] = state.offset;
451 }
452 }
453
454 return VK_SUCCESS;
455 }
456
457 VkResult
458 anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
459 unsigned stage, struct anv_state *state)
460 {
461 struct anv_pipeline_layout *layout;
462 uint32_t sampler_count;
463
464 if (stage == VK_SHADER_STAGE_COMPUTE)
465 layout = cmd_buffer->state.compute_pipeline->layout;
466 else
467 layout = cmd_buffer->state.pipeline->layout;
468
469 sampler_count = layout ? layout->stage[stage].sampler_count : 0;
470 if (sampler_count == 0)
471 return VK_SUCCESS;
472
473 uint32_t size = sampler_count * 16;
474 *state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 32);
475
476 if (state->map == NULL)
477 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
478
479 for (uint32_t set = 0; set < layout->num_sets; set++) {
480 struct anv_descriptor_set_binding *d = &cmd_buffer->state.descriptors[set];
481 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
482 struct anv_descriptor_slot *sampler_slots =
483 set_layout->stage[stage].sampler_start;
484
485 uint32_t start = layout->set[set].sampler_start[stage];
486
487 for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) {
488 struct anv_sampler *sampler =
489 d->set->descriptors[sampler_slots[b].index].sampler;
490
491 if (!sampler)
492 continue;
493
494 memcpy(state->map + (start + b) * 16,
495 sampler->state, sizeof(sampler->state));
496 }
497 }
498
499 return VK_SUCCESS;
500 }
501
502 static VkResult
503 flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
504 {
505 struct anv_state surfaces = { 0, }, samplers = { 0, };
506 VkResult result;
507
508 result = anv_cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
509 if (result != VK_SUCCESS)
510 return result;
511 result = anv_cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
512 if (result != VK_SUCCESS)
513 return result;
514
515 static const uint32_t sampler_state_opcodes[] = {
516 [VK_SHADER_STAGE_VERTEX] = 43,
517 [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
518 [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
519 [VK_SHADER_STAGE_GEOMETRY] = 46,
520 [VK_SHADER_STAGE_FRAGMENT] = 47,
521 [VK_SHADER_STAGE_COMPUTE] = 0,
522 };
523
524 static const uint32_t binding_table_opcodes[] = {
525 [VK_SHADER_STAGE_VERTEX] = 38,
526 [VK_SHADER_STAGE_TESS_CONTROL] = 39,
527 [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
528 [VK_SHADER_STAGE_GEOMETRY] = 41,
529 [VK_SHADER_STAGE_FRAGMENT] = 42,
530 [VK_SHADER_STAGE_COMPUTE] = 0,
531 };
532
533 if (samplers.alloc_size > 0) {
534 anv_batch_emit(&cmd_buffer->batch,
535 GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS,
536 ._3DCommandSubOpcode = sampler_state_opcodes[stage],
537 .PointertoVSSamplerState = samplers.offset);
538 }
539
540 if (surfaces.alloc_size > 0) {
541 anv_batch_emit(&cmd_buffer->batch,
542 GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS,
543 ._3DCommandSubOpcode = binding_table_opcodes[stage],
544 .PointertoVSBindingTable = surfaces.offset);
545 }
546
547 return VK_SUCCESS;
548 }
549
550 void
551 anv_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
552 {
553 uint32_t s, dirty = cmd_buffer->state.descriptors_dirty &
554 cmd_buffer->state.pipeline->active_stages;
555
556 VkResult result = VK_SUCCESS;
557 for_each_bit(s, dirty) {
558 result = flush_descriptor_set(cmd_buffer, s);
559 if (result != VK_SUCCESS)
560 break;
561 }
562
563 if (result != VK_SUCCESS) {
564 assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
565
566 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
567 assert(result == VK_SUCCESS);
568
569 /* Re-emit state base addresses so we get the new surface state base
570 * address before we start emitting binding tables etc.
571 */
572 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
573
574 /* Re-emit all active binding tables */
575 for_each_bit(s, cmd_buffer->state.pipeline->active_stages) {
576 result = flush_descriptor_set(cmd_buffer, s);
577
578 /* It had better succeed this time */
579 assert(result == VK_SUCCESS);
580 }
581 }
582
583 cmd_buffer->state.descriptors_dirty &= ~cmd_buffer->state.pipeline->active_stages;
584 }
585
586 struct anv_state
587 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
588 uint32_t *a, uint32_t dwords, uint32_t alignment)
589 {
590 struct anv_state state;
591
592 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
593 dwords * 4, alignment);
594 memcpy(state.map, a, dwords * 4);
595
596 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
597
598 return state;
599 }
600
601 struct anv_state
602 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
603 uint32_t *a, uint32_t *b,
604 uint32_t dwords, uint32_t alignment)
605 {
606 struct anv_state state;
607 uint32_t *p;
608
609 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
610 dwords * 4, alignment);
611 p = state.map;
612 for (uint32_t i = 0; i < dwords; i++)
613 p[i] = a[i] | b[i];
614
615 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
616
617 return state;
618 }
619
620 void
621 anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
622 struct anv_subpass *subpass)
623 {
624 switch (cmd_buffer->device->info.gen) {
625 case 7:
626 gen7_cmd_buffer_begin_subpass(cmd_buffer, subpass);
627 break;
628 case 8:
629 gen8_cmd_buffer_begin_subpass(cmd_buffer, subpass);
630 break;
631 default:
632 unreachable("unsupported gen\n");
633 }
634 }
635
636 void anv_CmdSetEvent(
637 VkCmdBuffer cmdBuffer,
638 VkEvent event,
639 VkPipelineStageFlags stageMask)
640 {
641 stub();
642 }
643
644 void anv_CmdResetEvent(
645 VkCmdBuffer cmdBuffer,
646 VkEvent event,
647 VkPipelineStageFlags stageMask)
648 {
649 stub();
650 }
651
652 void anv_CmdWaitEvents(
653 VkCmdBuffer cmdBuffer,
654 uint32_t eventCount,
655 const VkEvent* pEvents,
656 VkPipelineStageFlags srcStageMask,
657 VkPipelineStageFlags destStageMask,
658 uint32_t memBarrierCount,
659 const void* const* ppMemBarriers)
660 {
661 stub();
662 }
663
664 struct anv_state
665 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
666 VkShaderStage stage)
667 {
668 struct anv_push_constant_data *data =
669 cmd_buffer->state.push_constants[stage].data;
670 struct brw_stage_prog_data *prog_data =
671 cmd_buffer->state.pipeline->prog_data[stage];
672
673 /* If we don't actually have any push constants, bail. */
674 if (data == NULL || prog_data->nr_params == 0)
675 return (struct anv_state) { .offset = 0 };
676
677 struct anv_state state =
678 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
679 prog_data->nr_params * sizeof(float),
680 32 /* bottom 5 bits MBZ */);
681
682 /* Walk through the param array and fill the buffer with data */
683 uint32_t *u32_map = state.map;
684 for (unsigned i = 0; i < prog_data->nr_params; i++) {
685 uint32_t offset = (uintptr_t)prog_data->param[i];
686 u32_map[i] = *(uint32_t *)((uint8_t *)data + offset);
687 }
688
689 return state;
690 }
691
692 void anv_CmdPushConstants(
693 VkCmdBuffer cmdBuffer,
694 VkPipelineLayout layout,
695 VkShaderStageFlags stageFlags,
696 uint32_t start,
697 uint32_t length,
698 const void* values)
699 {
700 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
701 uint32_t stage;
702
703 for_each_bit(stage, stageFlags) {
704 if (cmd_buffer->state.push_constants[stage].data == NULL) {
705 cmd_buffer->state.push_constants[stage].data =
706 anv_device_alloc(cmd_buffer->device,
707 sizeof(struct anv_push_constant_data), 8,
708 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
709 }
710
711 memcpy(cmd_buffer->state.push_constants[stage].data->client_data + start,
712 values, length);
713 }
714
715 cmd_buffer->state.push_constants_dirty |= stageFlags;
716 }
717
718 void anv_CmdExecuteCommands(
719 VkCmdBuffer cmdBuffer,
720 uint32_t cmdBuffersCount,
721 const VkCmdBuffer* pCmdBuffers)
722 {
723 ANV_FROM_HANDLE(anv_cmd_buffer, primary, cmdBuffer);
724
725 assert(primary->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
726
727 anv_assert(primary->state.subpass == &primary->state.pass->subpasses[0]);
728
729 for (uint32_t i = 0; i < cmdBuffersCount; i++) {
730 ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]);
731
732 assert(secondary->level == VK_CMD_BUFFER_LEVEL_SECONDARY);
733
734 anv_cmd_buffer_add_secondary(primary, secondary);
735 }
736 }
737
738 VkResult anv_CreateCommandPool(
739 VkDevice _device,
740 const VkCmdPoolCreateInfo* pCreateInfo,
741 VkCmdPool* pCmdPool)
742 {
743 ANV_FROM_HANDLE(anv_device, device, _device);
744 struct anv_cmd_pool *pool;
745
746 pool = anv_device_alloc(device, sizeof(*pool), 8,
747 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
748 if (pool == NULL)
749 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
750
751 list_inithead(&pool->cmd_buffers);
752
753 *pCmdPool = anv_cmd_pool_to_handle(pool);
754
755 return VK_SUCCESS;
756 }
757
758 VkResult anv_DestroyCommandPool(
759 VkDevice _device,
760 VkCmdPool cmdPool)
761 {
762 ANV_FROM_HANDLE(anv_device, device, _device);
763 ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
764
765 anv_ResetCommandPool(_device, cmdPool, 0);
766
767 anv_device_free(device, pool);
768
769 return VK_SUCCESS;
770 }
771
772 VkResult anv_ResetCommandPool(
773 VkDevice device,
774 VkCmdPool cmdPool,
775 VkCmdPoolResetFlags flags)
776 {
777 ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
778
779 list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
780 &pool->cmd_buffers, pool_link) {
781 anv_DestroyCommandBuffer(device, anv_cmd_buffer_to_handle(cmd_buffer));
782 }
783
784 return VK_SUCCESS;
785 }
786
787 /**
788 * Return NULL if the current subpass has no depthstencil attachment.
789 */
790 const struct anv_depth_stencil_view *
791 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
792 {
793 const struct anv_subpass *subpass = cmd_buffer->state.subpass;
794 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
795
796 if (subpass->depth_stencil_attachment == VK_ATTACHMENT_UNUSED)
797 return NULL;
798
799 const struct anv_attachment_view *aview =
800 fb->attachments[subpass->depth_stencil_attachment];
801
802 assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL);
803
804 return (const struct anv_depth_stencil_view *) aview;
805 }