diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_render_state.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_render_state.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 6 |
3 files changed, 53 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index b6492fe3722b..5026a6267a88 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -73,6 +73,24 @@ free_gem: return ret; } +/* + * Macro to add commands to auxiliary batch. + * This macro only checks for page overflow before inserting the commands, + * this is sufficient as the null state generator makes the final batch + * with two passes to build command and state separately. At this point + * the size of both are known and it compacts them by relocating the state + * right after the commands taking care of aligment so we should sufficient + * space below them for adding new commands. + */ +#define OUT_BATCH(batch, i, val) \ + do { \ + if (WARN_ON((i) >= PAGE_SIZE / sizeof(u32))) { \ + ret = -ENOSPC; \ + goto err_out; \ + } \ + (batch)[(i)++] = (val); \ + } while(0) + static int render_state_setup(struct render_state *so) { const struct intel_renderstate_rodata *rodata = so->rodata; @@ -110,6 +128,21 @@ static int render_state_setup(struct render_state *so) d[i++] = s; } + + while (i % CACHELINE_DWORDS) + OUT_BATCH(d, i, MI_NOOP); + + so->aux_batch_offset = i * sizeof(u32); + + OUT_BATCH(d, i, MI_BATCH_BUFFER_END); + so->aux_batch_size = (i * sizeof(u32)) - so->aux_batch_offset; + + /* + * Since we are sending length, we need to strictly conform to + * all requirements. For Gen2 this must be a multiple of 8. + */ + so->aux_batch_size = ALIGN(so->aux_batch_size, 8); + kunmap(page); ret = i915_gem_object_set_to_gtt_domain(so->obj, false); @@ -128,6 +161,8 @@ err_out: return ret; } +#undef OUT_BATCH + void i915_gem_render_state_fini(struct render_state *so) { i915_gem_object_ggtt_unpin(so->obj); @@ -176,6 +211,16 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req) if (ret) goto out; + if (so.aux_batch_size > 8) { + ret = req->ring->dispatch_execbuffer(req, + (so.ggtt_offset + + so.aux_batch_offset), + so.aux_batch_size, + I915_DISPATCH_SECURE); + if (ret) + goto out; + } + i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req); out: diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h index 7aa73728178a..e641bb093a90 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.h +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h @@ -37,6 +37,8 @@ struct render_state { struct drm_i915_gem_object *obj; u64 ggtt_offset; int gen; + u32 aux_batch_size; + u32 aux_batch_offset; }; int i915_gem_render_state_init(struct drm_i915_gem_request *req); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9faad82c42ec..99bba8ece464 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1740,6 +1740,12 @@ static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req) if (ret) goto out; + ret = req->ring->emit_bb_start(req, + (so.ggtt_offset + so.aux_batch_offset), + I915_DISPATCH_SECURE); + if (ret) + goto out; + i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req); out: |