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