Lines Matching refs:batch
29 * collect into a "batch buffer". Typically, many draw calls are grouped
30 * into a single batch to amortize command submission overhead.
36 * virtual memory address before executing our batch. If a BO is not in
70 iris_batch_reset(struct iris_batch *batch);
73 num_fences(struct iris_batch *batch)
75 return util_dynarray_num_elements(&batch->exec_fences,
83 dump_fence_list(struct iris_batch *batch)
85 fprintf(stderr, "Fence list (length %u): ", num_fences(batch));
87 util_dynarray_foreach(&batch->exec_fences,
102 dump_bo_list(struct iris_batch *batch)
104 fprintf(stderr, "BO list (length %d):\n", batch->exec_count);
106 for (int i = 0; i < batch->exec_count; i++) {
107 struct iris_bo *bo = batch->exec_bos[i];
109 bool written = BITSET_TEST(batch->bos_written, i);
129 * Return BO information to the batch decoder (for debugging).
134 struct iris_batch *batch = v_batch;
138 for (int i = 0; i < batch->exec_count; i++) {
139 struct iris_bo *bo = batch->exec_bos[i];
147 .map = iris_bo_map(batch->dbg, bo, MAP_READ | MAP_ASYNC),
160 struct iris_batch *batch = v_batch;
162 _mesa_hash_table_u64_search(batch->state_sizes, address);
168 * Decode the current batch.
171 decode_batch(struct iris_batch *batch)
173 void *map = iris_bo_map(batch->dbg, batch->exec_bos[0], MAP_READ);
174 intel_print_batch(&batch->decoder, map, batch->primary_batch_size,
175 batch->exec_bos[0]->address, false);
182 struct iris_batch *batch = &ice->batches[name];
192 batch->dbg = &ice->dbg;
193 batch->reset = &ice->reset;
194 batch->state_sizes = ice->state.sizes;
195 batch->name = name;
196 batch->ice = ice;
197 batch->contains_fence_signal = false;
199 batch->fine_fences.uploader =
202 iris_fine_fence_init(batch);
204 util_dynarray_init(&batch->exec_fences, ralloc_context(NULL));
205 util_dynarray_init(&batch->syncobjs, ralloc_context(NULL));
207 batch->exec_count = 0;
208 batch->max_gem_handle = 0;
209 batch->exec_array_size = 128;
210 batch->exec_bos =
211 malloc(batch->exec_array_size * sizeof(batch->exec_bos[0]));
212 batch->bos_written =
213 rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(batch->exec_array_size));
215 batch->cache.render = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
218 batch->num_other_batches = 0;
219 memset(batch->other_batches, 0, sizeof(batch->other_batches));
222 if (batch != other_batch)
223 batch->other_batches[batch->num_other_batches++] = other_batch;
233 intel_batch_decode_ctx_init(&batch->decoder, &screen->compiler->isa,
236 decode_get_bo, decode_get_state_size, batch);
237 batch->decoder.dynamic_base = IRIS_MEMZONE_DYNAMIC_START;
238 batch->decoder.instruction_base = IRIS_MEMZONE_SHADER_START;
239 batch->decoder.surface_base = IRIS_MEMZONE_BINDER_START;
240 batch->decoder.max_vbo_decoded_lines = 32;
241 if (batch->name == IRIS_BATCH_BLITTER)
242 batch->decoder.engine = I915_ENGINE_CLASS_COPY;
245 iris_init_batch_measure(ice, batch);
247 u_trace_init(&batch->trace, &ice->ds.trace_context);
249 iris_batch_reset(batch);
257 iris_foreach_batch(ice, batch) {
258 batch->ctx_id = iris_create_hw_context(screen->bufmgr);
259 batch->exec_flags = I915_EXEC_RENDER;
260 batch->has_engines_context = false;
261 assert(batch->ctx_id);
262 iris_hw_context_set_priority(screen->bufmgr, batch->ctx_id, priority);
326 iris_foreach_batch(ice, batch) {
327 unsigned i = batch - &ice->batches[0];
328 batch->ctx_id = engines_ctx;
329 batch->exec_flags = i;
330 batch->has_engines_context = true;
345 iris_foreach_batch(ice, batch)
346 iris_init_batch(ice, batch - &ice->batches[0]);
350 find_exec_index(struct iris_batch *batch, struct iris_bo *bo)
354 if (index < batch->exec_count && batch->exec_bos[index] == bo)
358 for (index = 0; index < batch->exec_count; index++) {
359 if (batch->exec_bos[index] == bo)
367 ensure_exec_obj_space(struct iris_batch *batch, uint32_t count)
369 while (batch->exec_count + count > batch->exec_array_size) {
370 unsigned old_size = batch->exec_array_size;
372 batch->exec_array_size *= 2;
373 batch->exec_bos =
374 realloc(batch->exec_bos,
375 batch->exec_array_size * sizeof(batch->exec_bos[0]));
376 batch->bos_written =
377 rerzalloc(NULL, batch->bos_written, BITSET_WORD,
379 BITSET_WORDS(batch->exec_array_size));
384 add_bo_to_batch(struct iris_batch *batch, struct iris_bo *bo, bool writable)
386 assert(batch->exec_array_size > batch->exec_count);
390 batch->exec_bos[batch->exec_count] = bo;
393 BITSET_SET(batch->bos_written, batch->exec_count);
395 bo->index = batch->exec_count;
396 batch->exec_count++;
397 batch->aperture_space += bo->size;
399 batch->max_gem_handle =
400 MAX2(batch->max_gem_handle, iris_get_backing_bo(bo)->gem_handle);
404 flush_for_cross_batch_dependencies(struct iris_batch *batch,
408 if (batch->measure && bo == batch->measure->bo)
411 /* When a batch uses a buffer for the first time, or newly writes a buffer
415 for (int b = 0; b < batch->num_other_batches; b++) {
416 struct iris_batch *other_batch = batch->other_batches[b];
419 /* If the buffer is referenced by another batch, and either batch
420 * intends to write it, then flush the other batch and synchronize.
440 * Add a buffer to the current batch's validation list.
442 * You must call this on any BO you wish to use in this batch, to ensure
446 iris_use_pinned_bo(struct iris_batch *batch,
451 assert(bo != batch->bo);
456 * the buffer. It is added directly to the batch using add_bo_to_batch()
457 * during batch reset time.
459 if (bo == batch->screen->workaround_bo)
463 assert(batch->sync_region_depth);
464 iris_bo_bump_seqno(bo, batch->next_seqno, access);
467 int existing_index = find_exec_index(batch, bo);
470 flush_for_cross_batch_dependencies(batch, bo, writable);
472 ensure_exec_obj_space(batch, 1);
473 add_bo_to_batch(batch, bo, writable);
474 } else if (writable && !BITSET_TEST(batch->bos_written, existing_index)) {
475 flush_for_cross_batch_dependencies(batch, bo, writable);
478 BITSET_SET(batch->bos_written, existing_index);
483 create_batch(struct iris_batch *batch)
485 struct iris_screen *screen = batch->screen;
489 batch->bo = iris_bo_alloc(bufmgr, "command buffer",
492 iris_get_backing_bo(batch->bo)->real.kflags |= EXEC_OBJECT_CAPTURE;
493 batch->map = iris_bo_map(NULL, batch->bo, MAP_READ | MAP_WRITE);
494 batch->map_next = batch->map;
496 ensure_exec_obj_space(batch, 1);
497 add_bo_to_batch(batch, batch->bo, false);
501 iris_batch_maybe_noop(struct iris_batch *batch)
503 /* We only insert the NOOP at the beginning of the batch. */
504 assert(iris_batch_bytes_used(batch) == 0);
506 if (batch->noop_enabled) {
510 uint32_t *map = batch->map_next;
514 batch->map_next += 4;
519 iris_batch_reset(struct iris_batch *batch)
521 struct iris_screen *screen = batch->screen;
525 u_trace_fini(&batch->trace);
527 iris_bo_unreference(batch->bo);
528 batch->primary_batch_size = 0;
529 batch->total_chained_batch_size = 0;
530 batch->contains_draw = false;
531 batch->contains_fence_signal = false;
533 batch->decoder.surface_base = batch->last_binder_address;
535 batch->decoder.bt_pool_base = batch->last_binder_address;
537 create_batch(batch);
538 assert(batch->bo->index == 0);
540 memset(batch->bos_written, 0,
541 sizeof(BITSET_WORD) * BITSET_WORDS(batch->exec_array_size));
544 iris_batch_add_syncobj(batch, syncobj, I915_EXEC_FENCE_SIGNAL);
547 assert(!batch->sync_region_depth);
548 iris_batch_sync_boundary(batch);
549 iris_batch_mark_reset_sync(batch);
554 add_bo_to_batch(batch, screen->workaround_bo, false);
556 iris_batch_maybe_noop(batch);
558 u_trace_init(&batch->trace, &batch->ice->ds.trace_context);
559 batch->begin_trace_recorded = false;
563 iris_batch_free(struct iris_batch *batch)
565 struct iris_screen *screen = batch->screen;
568 for (int i = 0; i < batch->exec_count; i++) {
569 iris_bo_unreference(batch->exec_bos[i]);
571 free(batch->exec_bos);
572 ralloc_free(batch->bos_written);
574 ralloc_free(batch->exec_fences.mem_ctx);
576 pipe_resource_reference(&batch->fine_fences.ref.res, NULL);
578 util_dynarray_foreach(&batch->syncobjs, struct iris_syncobj *, s)
580 ralloc_free(batch->syncobjs.mem_ctx);
582 iris_fine_fence_reference(batch->screen, &batch->last_fence, NULL);
583 u_upload_destroy(batch->fine_fences.uploader);
585 iris_bo_unreference(batch->bo);
586 batch->bo = NULL;
587 batch->map = NULL;
588 batch->map_next = NULL;
591 if (!batch->has_engines_context)
592 iris_destroy_kernel_context(bufmgr, batch->ctx_id);
594 iris_destroy_batch_measure(batch->measure);
595 batch->measure = NULL;
597 u_trace_fini(&batch->trace);
599 _mesa_hash_table_destroy(batch->cache.render, NULL);
602 intel_batch_decode_ctx_finish(&batch->decoder);
610 * the context on the first batch.
617 iris_foreach_batch(ice, batch)
618 iris_batch_free(batch);
622 * If we've chained to a secondary batch, or are getting near to the end,
626 iris_batch_maybe_flush(struct iris_batch *batch, unsigned estimate)
628 if (batch->bo != batch->exec_bos[0] ||
629 iris_batch_bytes_used(batch) + estimate >= BATCH_SZ) {
630 iris_batch_flush(batch);
635 record_batch_sizes(struct iris_batch *batch)
637 unsigned batch_size = iris_batch_bytes_used(batch);
639 VG(VALGRIND_CHECK_MEM_IS_DEFINED(batch->map, batch_size));
641 if (batch->bo == batch->exec_bos[0])
642 batch->primary_batch_size = batch_size;
644 batch->total_chained_batch_size += batch_size;
648 iris_chain_to_new_batch(struct iris_batch *batch)
650 uint32_t *cmd = batch->map_next;
651 uint64_t *addr = batch->map_next + 4;
652 batch->map_next += 12;
654 record_batch_sizes(batch);
656 /* No longer held by batch->bo, still held by validation list */
657 iris_bo_unreference(batch->bo);
658 create_batch(batch);
660 /* Emit MI_BATCH_BUFFER_START to chain to another batch. */
662 *addr = batch->bo->address;
666 add_aux_map_bos_to_batch(struct iris_batch *batch)
668 void *aux_map_ctx = iris_bufmgr_get_aux_map_context(batch->screen->bufmgr);
673 ensure_exec_obj_space(batch, count);
675 (void**)&batch->exec_bos[batch->exec_count], count);
677 struct iris_bo *bo = batch->exec_bos[batch->exec_count];
678 add_bo_to_batch(batch, bo, false);
683 finish_seqno(struct iris_batch *batch)
685 struct iris_fine_fence *sq = iris_fine_fence_new(batch, IRIS_FENCE_END);
689 iris_fine_fence_reference(batch->screen, &batch->last_fence, sq);
690 iris_fine_fence_reference(batch->screen, &sq, NULL);
694 * Terminate a batch with MI_BATCH_BUFFER_END.
697 iris_finish_batch(struct iris_batch *batch)
699 const struct intel_device_info *devinfo = &batch->screen->devinfo;
701 if (devinfo->ver == 12 && batch->name == IRIS_BATCH_RENDER) {
702 /* We re-emit constants at the beginning of every batch as a hardware
705 * the next render batch is executed.
707 iris_emit_pipe_control_flush(batch, "ISP invalidate at batch end",
713 add_aux_map_bos_to_batch(batch);
715 finish_seqno(batch);
717 trace_intel_end_batch(&batch->trace, batch->name);
719 /* Emit MI_BATCH_BUFFER_END to finish our batch. */
720 uint32_t *map = batch->map_next;
724 batch->map_next += 4;
726 record_batch_sizes(batch);
733 replace_kernel_ctx(struct iris_batch *batch)
735 struct iris_screen *screen = batch->screen;
738 if (batch->has_engines_context) {
739 struct iris_context *ice = batch->ice;
740 int priority = iris_kernel_context_get_priority(bufmgr, batch->ctx_id);
741 uint32_t old_ctx = batch->ctx_id;
752 uint32_t new_ctx = iris_clone_hw_context(bufmgr, batch->ctx_id);
756 iris_destroy_kernel_context(bufmgr, batch->ctx_id);
757 batch->ctx_id = new_ctx;
760 iris_lost_context_state(batch);
767 iris_batch_check_for_reset(struct iris_batch *batch)
769 struct iris_screen *screen = batch->screen;
771 struct drm_i915_reset_stats stats = { .ctx_id = batch->ctx_id };
777 /* A reset was observed while a batch from this hardware context was
782 /* A reset was observed while a batch from this context was in progress,
783 * but the batch was not executing. In this case, assume that the
794 replace_kernel_ctx(batch);
801 move_syncobj_to_batch(struct iris_batch *batch,
805 struct iris_bufmgr *bufmgr = batch->screen->bufmgr;
811 util_dynarray_foreach(&batch->syncobjs, struct iris_syncobj *, s) {
819 iris_batch_add_syncobj(batch, *p_syncobj, flags);
825 update_bo_syncobjs(struct iris_batch *batch, struct iris_bo *bo, bool write)
827 struct iris_screen *screen = batch->screen;
829 struct iris_context *ice = batch->ice;
844 * own batch, although we need to track them. Just note that other places of
845 * our code may need to care about all the operations done by every batch
849 int batch_idx = batch->name;
851 /* Make our batch depend on additional syncobjs depending on what other
854 * We also look at the dependencies set by our own batch since those could
863 move_syncobj_to_batch(batch, &bo_deps->write_syncobjs[i],
868 move_syncobj_to_batch(batch, &bo_deps->read_syncobjs[i],
873 iris_batch_get_signal_syncobj(batch);
875 /* Update bo_deps depending on what we're doing with the bo in this batch
876 * by putting the batch's syncobj in the bo_deps lists accordingly. Only
889 update_batch_syncobjs(struct iris_batch *batch)
891 for (int i = 0; i < batch->exec_count; i++) {
892 struct iris_bo *bo = batch->exec_bos[i];
893 bool write = BITSET_TEST(batch->bos_written, i);
895 if (bo == batch->screen->workaround_bo)
898 update_bo_syncobjs(batch, bo, write);
903 * Submit the batch to the GPU via execbuffer2.
906 submit_batch(struct iris_batch *batch)
908 struct iris_bufmgr *bufmgr = batch->screen->bufmgr;
911 iris_bo_unmap(batch->bo);
914 malloc(batch->exec_count * sizeof(*validation_list));
917 calloc(batch->max_gem_handle + 1, sizeof(unsigned));
920 for (int i = 0; i < batch->exec_count; i++) {
921 struct iris_bo *bo = iris_get_backing_bo(batch->exec_bos[i]);
924 bool written = BITSET_TEST(batch->bos_written, i);
944 /* The decode operation may map and wait on the batch buffer, which could
949 decode_batch(batch);
953 update_batch_syncobjs(batch);
956 dump_fence_list(batch);
957 dump_bo_list(batch);
966 * Any render targets written to in the batch must be flagged with
977 .batch_len = ALIGN(batch->primary_batch_size, 8),
978 .flags = batch->exec_flags |
982 .rsvd1 = batch->ctx_id, /* rsvd1 is actually the context ID */
985 if (num_fences(batch)) {
987 execbuf.num_cliprects = num_fences(batch);
989 (uintptr_t)util_dynarray_begin(&batch->exec_fences);
993 if (!batch->screen->devinfo.no_hw &&
994 intel_ioctl(batch->screen->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf))
999 for (int i = 0; i < batch->exec_count; i++) {
1000 struct iris_bo *bo = batch->exec_bos[i];
1027 * Flush the batch buffer, submitting it to the GPU and resetting it so
1028 * we're ready to emit the next batch.
1031 _iris_batch_flush(struct iris_batch *batch, const char *file, int line)
1033 struct iris_screen *screen = batch->screen;
1034 struct iris_context *ice = batch->ice;
1037 if (iris_batch_bytes_used(batch) == 0 && !batch->contains_fence_signal)
1040 iris_measure_batch_end(ice, batch);
1042 iris_finish_batch(batch);
1049 fprintf(stderr, "%19s:%-3d: %s batch [%u] flush with %5db (%0.1f%%) "
1051 file, line, iris_batch_name_to_string(batch->name), batch->ctx_id,
1052 batch->total_chained_batch_size,
1053 100.0f * batch->total_chained_batch_size / BATCH_SZ,
1054 batch->exec_count,
1055 (float) batch->aperture_space / (1024 * 1024));
1059 uint64_t start_ts = intel_ds_begin_submit(batch->ds);
1060 uint64_t submission_id = batch->ds->submission_id;
1061 int ret = submit_batch(batch);
1062 intel_ds_end_submit(batch->ds, start_ts);
1064 /* When batch submission fails, our end-of-batch syncobj remains
1069 * dubiously claiming that this batch completed, because future batches may
1073 * the failing batch's syncobj to try and allow further progress to be
1077 iris_syncobj_signal(screen->bufmgr, iris_batch_get_signal_syncobj(batch));
1079 batch->exec_count = 0;
1080 batch->max_gem_handle = 0;
1081 batch->aperture_space = 0;
1083 util_dynarray_foreach(&batch->syncobjs, struct iris_syncobj *, s)
1085 util_dynarray_clear(&batch->syncobjs);
1087 util_dynarray_clear(&batch->exec_fences);
1091 iris_bo_wait_rendering(batch->bo); /* if execbuf failed; this is a nop */
1095 iris_utrace_flush(batch, submission_id);
1097 /* Start a new batch buffer. */
1098 iris_batch_reset(batch);
1106 if ((ret == -EIO || ret == -ENOMEM) && replace_kernel_ctx(batch)) {
1107 if (batch->reset->reset) {
1109 batch->reset->reset(batch->reset->data, PIPE_GUILTY_CONTEXT_RESET);
1126 * Does the current batch refer to the given BO?
1128 * (In other words, is the BO in the current batch's validation list?)
1131 iris_batch_references(struct iris_batch *batch, struct iris_bo *bo)
1133 return find_exec_index(batch, bo) != -1;
1141 iris_batch_prepare_noop(struct iris_batch *batch, bool noop_enable)
1143 if (batch->noop_enabled == noop_enable)
1146 batch->noop_enabled = noop_enable;
1148 iris_batch_flush(batch);
1150 /* If the batch was empty, flush had no effect, so insert our noop. */
1151 if (iris_batch_bytes_used(batch) == 0)
1152 iris_batch_maybe_noop(batch);
1157 return !batch->noop_enabled;