static int batch_flush(struct intel_info *info) { int size, ret; batch_dword(info, MI_BATCH_BUFFER_END); size = batch_count(info); if (size & 1) { batch_dword(info, MI_NOOP); size = batch_count(info); } size *= sizeof(info->batch[0]); ret = drm_intel_bo_subdata(info->batch_ibo, 0, size, info->batch); if (ret) { ALOGE("failed to subdata batch"); goto fail; } ret = drm_intel_bo_mrb_exec(info->batch_ibo, size, NULL, 0, 0, info->exec_blt); if (ret) { ALOGE("failed to exec batch"); goto fail; } return batch_next(info); fail: info->cur = info->batch; return ret; }
static void gen6_render_flush(struct intel_batchbuffer *batch, uint32_t batch_end) { int ret; ret = drm_intel_bo_subdata(batch->bo, 0, 4096, batch->buffer); if (ret == 0) ret = drm_intel_bo_mrb_exec(batch->bo, batch_end, NULL, 0, 0, 0); assert(ret == 0); }
void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring) { unsigned int used = flush_on_ring_common(batch, ring); if (used == 0) return; do_or_die(drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer)); batch->ptr = NULL; do_or_die(drm_intel_bo_mrb_exec(batch->bo, used, NULL, 0, 0, ring)); intel_batchbuffer_reset(batch); }
int intel_winsys_submit_bo(struct intel_winsys *winsys, enum intel_ring_type ring, struct intel_bo *bo, int used, struct intel_context *ctx, unsigned long flags) { const unsigned long exec_flags = (unsigned long) ring | flags; /* logical contexts are only available for the render ring */ if (ring != INTEL_RING_RENDER) ctx = NULL; if (ctx) { return drm_intel_gem_bo_context_exec(gem_bo(bo), (drm_intel_context *) ctx, used, exec_flags); } else { return drm_intel_bo_mrb_exec(gem_bo(bo), used, NULL, 0, 0, exec_flags); } }
void intel_batch_submit(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int ret; assert (!intel->in_batch_atomic); if (intel->vertex_flush) intel->vertex_flush(intel); intel_end_vertex(intel); if (intel->batch_flush) intel->batch_flush(intel); if (intel->batch_used == 0) return; /* Mark the end of the batchbuffer. */ OUT_BATCH(MI_BATCH_BUFFER_END); /* Emit a padding dword if we aren't going to be quad-word aligned. */ if (intel->batch_used & 1) OUT_BATCH(MI_NOOP); if (DUMP_BATCHBUFFERS) { FILE *file = fopen(DUMP_BATCHBUFFERS, "a"); if (file) { fwrite (intel->batch_ptr, intel->batch_used*4, 1, file); fclose(file); } } ret = dri_bo_subdata(intel->batch_bo, 0, intel->batch_used*4, intel->batch_ptr); if (ret == 0) { ret = drm_intel_bo_mrb_exec(intel->batch_bo, intel->batch_used*4, NULL, 0, 0xffffffff, (HAS_BLT(intel) ? intel->current_batch: I915_EXEC_DEFAULT)); } if (ret != 0) { static int once; if (!once) { if (ret == -EIO) { /* The GPU has hung and unlikely to recover by this point. */ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Detected a hung GPU, disabling acceleration.\n"); xf86DrvMsg(scrn->scrnIndex, X_ERROR, "When reporting this, please include i915_error_state from debugfs and the full dmesg.\n"); } else { /* The driver is broken. */ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to submit batch buffer, expect rendering corruption: %s.\n ", strerror(-ret)); } uxa_set_force_fallback(xf86ScrnToScreen(scrn), TRUE); intel->force_fallback = TRUE; once = 1; } } while (!list_is_empty(&intel->batch_pixmaps)) { struct intel_pixmap *entry; entry = list_first_entry(&intel->batch_pixmaps, struct intel_pixmap, batch); entry->busy = -1; entry->dirty = 0; list_del(&entry->batch); } if (intel->debug_flush & DEBUG_FLUSH_WAIT) drm_intel_bo_wait_rendering(intel->batch_bo); intel_next_batch(scrn, intel->current_batch == I915_EXEC_BLT); if (intel->batch_commit_notify) intel->batch_commit_notify(intel); intel->current_batch = 0; }