i965: use pack/unpackDouble lowering
[mesa.git] / src / gallium / drivers / ilo / ilo_draw.c
index 19ea6a7d080f52b8841fd9fbedc86b34dc48950c..6831d2c4eff381b5050b86daad171f59a0ba0e89 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #include "util/u_prim.h"
-#include "intel_winsys.h"
+#include "core/intel_winsys.h"
 
 #include "ilo_render.h"
 #include "ilo_blit.h"
 #include "ilo_draw.h"
 
 static void
-ilo_3d_own_render_ring(struct ilo_3d *hw3d)
+ilo_draw_set_owner(struct ilo_context *ilo)
 {
-   ilo_cp_set_owner(hw3d->cp, INTEL_RING_RENDER, &hw3d->owner);
+   ilo_cp_set_owner(ilo->cp, INTEL_RING_RENDER, &ilo->draw.cp_owner);
 }
 
 static uint64_t
-query_timestamp_to_ns(const struct ilo_3d *hw3d, uint64_t timestamp)
+query_timestamp_to_ns(const struct ilo_context *ilo, uint64_t timestamp)
 {
    /* see ilo_get_timestamp() */
    return (timestamp & 0xffffffff) * 80;
@@ -54,7 +54,7 @@ query_timestamp_to_ns(const struct ilo_3d *hw3d, uint64_t timestamp)
  * Process the bo and accumulate the result.  The bo is emptied.
  */
 static void
-query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q)
+query_process_bo(const struct ilo_context *ilo, struct ilo_query *q)
 {
    const uint64_t *vals;
    uint64_t tmp;
@@ -71,6 +71,7 @@ query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q)
 
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
+   case PIPE_QUERY_OCCLUSION_PREDICATE:
    case PIPE_QUERY_TIME_ELAPSED:
    case PIPE_QUERY_PRIMITIVES_GENERATED:
    case PIPE_QUERY_PRIMITIVES_EMITTED:
@@ -81,14 +82,14 @@ query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q)
          tmp += vals[2 * i + 1] - vals[2 * i];
 
       if (q->type == PIPE_QUERY_TIME_ELAPSED)
-         tmp = query_timestamp_to_ns(hw3d, tmp);
+         tmp = query_timestamp_to_ns(ilo, tmp);
 
       q->result.u64 += tmp;
       break;
    case PIPE_QUERY_TIMESTAMP:
       assert(q->stride == sizeof(*vals));
 
-      q->result.u64 = query_timestamp_to_ns(hw3d, vals[q->used - 1]);
+      q->result.u64 = query_timestamp_to_ns(ilo, vals[q->used - 1]);
       break;
    case PIPE_QUERY_PIPELINE_STATISTICS:
       assert(q->stride == sizeof(*vals) * 22);
@@ -122,19 +123,19 @@ query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q)
 }
 
 static void
-query_begin_bo(struct ilo_3d *hw3d, struct ilo_query *q)
+query_begin_bo(struct ilo_context *ilo, struct ilo_query *q)
 {
    /* bo is full */
    if (q->used >= q->count)
-      query_process_bo(hw3d, q);
+      query_process_bo(ilo, q);
 
    /* write the beginning value to the bo */
    if (q->in_pairs)
-      ilo_3d_pipeline_emit_query(hw3d->pipeline, q, q->stride * q->used);
+      ilo_render_emit_query(ilo->render, q, q->stride * q->used);
 }
 
 static void
-query_end_bo(struct ilo_3d *hw3d, struct ilo_query *q)
+query_end_bo(struct ilo_context *ilo, struct ilo_query *q)
 {
    uint32_t offset;
 
@@ -147,17 +148,17 @@ query_end_bo(struct ilo_3d *hw3d, struct ilo_query *q)
    q->used++;
 
    /* write the ending value to the bo */
-   ilo_3d_pipeline_emit_query(hw3d->pipeline, q, offset);
+   ilo_render_emit_query(ilo->render, q, offset);
 }
 
 bool
-ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q)
+ilo_init_draw_query(struct ilo_context *ilo, struct ilo_query *q)
 {
-   struct ilo_context *ilo = ilo_context(pipe);
    unsigned bo_size;
 
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
+   case PIPE_QUERY_OCCLUSION_PREDICATE:
    case PIPE_QUERY_TIME_ELAPSED:
    case PIPE_QUERY_PRIMITIVES_GENERATED:
    case PIPE_QUERY_PRIMITIVES_EMITTED:
@@ -177,15 +178,14 @@ ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q)
       break;
    }
 
-   q->cmd_len = ilo_3d_pipeline_estimate_size(ilo->hw3d->pipeline,
-         ILO_3D_PIPELINE_QUERY, q);
+   q->cmd_len = ilo_render_get_query_len(ilo->render, q->type);
 
    /* double cmd_len and stride if in pairs */
    q->cmd_len <<= q->in_pairs;
    q->stride <<= q->in_pairs;
 
    bo_size = (q->stride > 4096) ? q->stride : 4096;
-   q->bo = intel_winsys_alloc_buffer(ilo->winsys, "query", bo_size, false);
+   q->bo = intel_winsys_alloc_bo(ilo->winsys, "query", bo_size, false);
    if (!q->bo)
       return false;
 
@@ -195,44 +195,40 @@ ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q)
 }
 
 void
-ilo_3d_begin_query(struct pipe_context *pipe, struct ilo_query *q)
+ilo_begin_draw_query(struct ilo_context *ilo, struct ilo_query *q)
 {
-   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
-
-   ilo_3d_own_render_ring(hw3d);
+   ilo_draw_set_owner(ilo);
 
    /* need to submit first */
-   if (!ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo) ||
-         ilo_cp_space(hw3d->cp) < q->cmd_len) {
-      ilo_cp_submit(hw3d->cp, "out of aperture or space");
+   if (!ilo_builder_validate(&ilo->cp->builder, 1, &q->bo) ||
+         ilo_cp_space(ilo->cp) < q->cmd_len) {
+      ilo_cp_submit(ilo->cp, "out of aperture or space");
 
-      assert(ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo));
-      assert(ilo_cp_space(hw3d->cp) >= q->cmd_len);
+      assert(ilo_builder_validate(&ilo->cp->builder, 1, &q->bo));
+      assert(ilo_cp_space(ilo->cp) >= q->cmd_len);
 
-      ilo_3d_own_render_ring(hw3d);
+      ilo_draw_set_owner(ilo);
    }
 
    /* reserve the space for ending/pausing the query */
-   hw3d->owner.reserve += q->cmd_len >> q->in_pairs;
+   ilo->draw.cp_owner.reserve += q->cmd_len >> q->in_pairs;
 
-   query_begin_bo(hw3d, q);
+   query_begin_bo(ilo, q);
 
    if (q->in_pairs)
-      list_add(&q->list, &hw3d->queries);
+      list_add(&q->list, &ilo->draw.queries);
 }
 
 void
-ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q)
+ilo_end_draw_query(struct ilo_context *ilo, struct ilo_query *q)
 {
-   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
-
-   ilo_3d_own_render_ring(hw3d);
+   ilo_draw_set_owner(ilo);
 
    /* reclaim the reserved space */
-   hw3d->owner.reserve -= q->cmd_len >> q->in_pairs;
-   assert(hw3d->owner.reserve >= 0);
+   ilo->draw.cp_owner.reserve -= q->cmd_len >> q->in_pairs;
+   assert(ilo->draw.cp_owner.reserve >= 0);
 
-   query_end_bo(hw3d, q);
+   query_end_bo(ilo, q);
 
    list_delinit(&q->list);
 }
@@ -241,39 +237,37 @@ ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q)
  * Process the raw query data.
  */
 void
-ilo_3d_process_query(struct pipe_context *pipe, struct ilo_query *q)
+ilo_process_draw_query(struct ilo_context *ilo, struct ilo_query *q)
 {
-   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
-
-   query_process_bo(hw3d, q);
+   query_process_bo(ilo, q);
 }
 
 static void
-ilo_3d_own_cp(struct ilo_cp *cp, void *data)
+ilo_draw_own_cp(struct ilo_cp *cp, void *data)
 {
-   struct ilo_3d *hw3d = data;
+   struct ilo_context *ilo = data;
 
    /* multiply by 2 for both resuming and pausing */
-   if (ilo_cp_space(hw3d->cp) < hw3d->owner.reserve * 2) {
-      ilo_cp_submit(hw3d->cp, "out of space");
-      assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve * 2);
+   if (ilo_cp_space(ilo->cp) < ilo->draw.cp_owner.reserve * 2) {
+      ilo_cp_submit(ilo->cp, "out of space");
+      assert(ilo_cp_space(ilo->cp) >= ilo->draw.cp_owner.reserve * 2);
    }
 
    while (true) {
       struct ilo_builder_snapshot snapshot;
       struct ilo_query *q;
 
-      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
+      ilo_builder_batch_snapshot(&ilo->cp->builder, &snapshot);
 
       /* resume queries */
-      LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list)
-         query_begin_bo(hw3d, q);
+      LIST_FOR_EACH_ENTRY(q, &ilo->draw.queries, list)
+         query_begin_bo(ilo, q);
 
-      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
-         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
+      if (!ilo_builder_validate(&ilo->cp->builder, 0, NULL)) {
+         ilo_builder_batch_restore(&ilo->cp->builder, &snapshot);
 
-         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
-            ilo_cp_submit(hw3d->cp, "out of aperture");
+         if (ilo_builder_batch_used(&ilo->cp->builder)) {
+            ilo_cp_submit(ilo->cp, "out of aperture");
             continue;
          }
       }
@@ -281,96 +275,39 @@ ilo_3d_own_cp(struct ilo_cp *cp, void *data)
       break;
    }
 
-   assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve);
+   assert(ilo_cp_space(ilo->cp) >= ilo->draw.cp_owner.reserve);
 }
 
 static void
-ilo_3d_release_cp(struct ilo_cp *cp, void *data)
+ilo_draw_release_cp(struct ilo_cp *cp, void *data)
 {
-   struct ilo_3d *hw3d = data;
+   struct ilo_context *ilo = data;
    struct ilo_query *q;
 
-   assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve);
+   assert(ilo_cp_space(ilo->cp) >= ilo->draw.cp_owner.reserve);
 
    /* pause queries */
-   LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list)
-      query_end_bo(hw3d, q);
-}
-
-/**
- * Hook for CP new-batch.
- */
-void
-ilo_3d_cp_submitted(struct ilo_3d *hw3d)
-{
-   /* invalidate the pipeline */
-   ilo_3d_pipeline_invalidate(hw3d->pipeline,
-         ILO_3D_PIPELINE_INVALIDATE_BATCH_BO |
-         ILO_3D_PIPELINE_INVALIDATE_STATE_BO |
-         ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
-
-   hw3d->new_batch = true;
-}
-
-/**
- * Create a 3D context.
- */
-struct ilo_3d *
-ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
-{
-   struct ilo_3d *hw3d;
-
-   hw3d = CALLOC_STRUCT(ilo_3d);
-   if (!hw3d)
-      return NULL;
-
-   hw3d->cp = cp;
-   hw3d->owner.own = ilo_3d_own_cp;
-   hw3d->owner.release = ilo_3d_release_cp;
-   hw3d->owner.data = hw3d;
-   hw3d->owner.reserve = 0;
-
-   hw3d->new_batch = true;
-
-   list_inithead(&hw3d->queries);
-
-   hw3d->pipeline = ilo_3d_pipeline_create(&cp->builder);
-   if (!hw3d->pipeline) {
-      FREE(hw3d);
-      return NULL;
-   }
-
-   return hw3d;
-}
-
-/**
- * Destroy a 3D context.
- */
-void
-ilo_3d_destroy(struct ilo_3d *hw3d)
-{
-   ilo_3d_pipeline_destroy(hw3d->pipeline);
-   FREE(hw3d);
+   LIST_FOR_EACH_ENTRY(q, &ilo->draw.queries, list)
+      query_end_bo(ilo, q);
 }
 
 static bool
-draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec)
+draw_vbo(struct ilo_context *ilo, const struct ilo_state_vector *vec)
 {
    bool need_flush = false;
    bool success = true;
    int max_len, before_space;
 
-   /* on GEN7+, we need SOL_RESET to reset the SO write offsets */
-   if (ilo_dev_gen(hw3d->pipeline->dev) >= ILO_GEN(7) &&
+   /* on Gen7 and Gen7.5, we need SOL_RESET to reset the SO write offsets */
+   if (ilo_dev_gen(ilo->dev) >= ILO_GEN(7) &&
+       ilo_dev_gen(ilo->dev) <= ILO_GEN(7.5) &&
        (vec->dirty & ILO_DIRTY_SO) && vec->so.enabled &&
        !vec->so.append_bitmask) {
-      ilo_cp_submit(hw3d->cp, "SOL_RESET");
-      ilo_cp_set_one_off_flags(hw3d->cp, INTEL_EXEC_GEN7_SOL_RESET);
+      ilo_cp_submit(ilo->cp, "SOL_RESET");
+      ilo_cp_set_one_off_flags(ilo->cp, INTEL_EXEC_GEN7_SOL_RESET);
    }
 
-   ilo_3d_own_render_ring(hw3d);
-
-   if (!hw3d->new_batch) {
+   if (ilo_builder_batch_used(&ilo->cp->builder)) {
       /*
        * Without a better tracking mechanism, when the framebuffer changes, we
        * have to assume that the old framebuffer may be sampled from.  If that
@@ -383,39 +320,38 @@ draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec)
       need_flush |= (vec->dirty & ILO_DIRTY_SO);
    }
 
+   ilo_draw_set_owner(ilo);
+
    /* make sure there is enough room first */
-   max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-         ILO_3D_PIPELINE_DRAW, vec);
-   if (need_flush) {
-      max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-            ILO_3D_PIPELINE_FLUSH, NULL);
-   }
+   max_len = ilo_render_get_draw_len(ilo->render, vec);
+   if (need_flush)
+      max_len += ilo_render_get_flush_len(ilo->render);
 
-   if (max_len > ilo_cp_space(hw3d->cp)) {
-      ilo_cp_submit(hw3d->cp, "out of space");
+   if (max_len > ilo_cp_space(ilo->cp)) {
+      ilo_cp_submit(ilo->cp, "out of space");
       need_flush = false;
-      assert(max_len <= ilo_cp_space(hw3d->cp));
+      assert(max_len <= ilo_cp_space(ilo->cp));
    }
 
    /* space available before emission */
-   before_space = ilo_cp_space(hw3d->cp);
+   before_space = ilo_cp_space(ilo->cp);
 
    if (need_flush)
-      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+      ilo_render_emit_flush(ilo->render);
 
    while (true) {
       struct ilo_builder_snapshot snapshot;
 
-      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
+      ilo_builder_batch_snapshot(&ilo->cp->builder, &snapshot);
 
-      ilo_3d_pipeline_emit_draw(hw3d->pipeline, vec);
+      ilo_render_emit_draw(ilo->render, vec);
 
-      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
-         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
+      if (!ilo_builder_validate(&ilo->cp->builder, 0, NULL)) {
+         ilo_builder_batch_restore(&ilo->cp->builder, &snapshot);
 
          /* flush and try again */
-         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
-            ilo_cp_submit(hw3d->cp, "out of aperture");
+         if (ilo_builder_batch_used(&ilo->cp->builder)) {
+            ilo_cp_submit(ilo->cp, "out of aperture");
             continue;
          }
 
@@ -425,32 +361,32 @@ draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec)
       break;
    }
 
-   hw3d->pipeline->invalidate_flags = 0x0;
-
    /* sanity check size estimation */
-   assert(before_space - ilo_cp_space(hw3d->cp) <= max_len);
+   assert(before_space - ilo_cp_space(ilo->cp) <= max_len);
 
    return success;
 }
 
 void
-ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter)
+ilo_draw_rectlist(struct ilo_context *ilo)
 {
    int max_len, before_space;
+   bool need_flush;
+
+   need_flush = ilo_builder_batch_used(&ilo->cp->builder);
 
-   ilo_3d_own_render_ring(hw3d);
+   ilo_draw_set_owner(ilo);
 
-   max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-         ILO_3D_PIPELINE_RECTLIST, blitter);
-   max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-         ILO_3D_PIPELINE_FLUSH, NULL) * 2;
+   max_len = ilo_render_get_rectlist_len(ilo->render, ilo->blitter);
+   max_len += ilo_render_get_flush_len(ilo->render) * 2;
 
-   if (max_len > ilo_cp_space(hw3d->cp)) {
-      ilo_cp_submit(hw3d->cp, "out of space");
-      assert(max_len <= ilo_cp_space(hw3d->cp));
+   if (max_len > ilo_cp_space(ilo->cp)) {
+      ilo_cp_submit(ilo->cp, "out of space");
+      need_flush = false;
+      assert(max_len <= ilo_cp_space(ilo->cp));
    }
 
-   before_space = ilo_cp_space(hw3d->cp);
+   before_space = ilo_cp_space(ilo->cp);
 
    /*
     * From the Sandy Bridge PRM, volume 2 part 1, page 313:
@@ -474,22 +410,22 @@ ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter)
     *
     * Skip checking blitter->op and do the flushes.
     */
-   if (!hw3d->new_batch)
-      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+   if (need_flush)
+      ilo_render_emit_flush(ilo->render);
 
    while (true) {
       struct ilo_builder_snapshot snapshot;
 
-      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
+      ilo_builder_batch_snapshot(&ilo->cp->builder, &snapshot);
 
-      ilo_3d_pipeline_emit_rectlist(hw3d->pipeline, blitter);
+      ilo_render_emit_rectlist(ilo->render, ilo->blitter);
 
-      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
-         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
+      if (!ilo_builder_validate(&ilo->cp->builder, 0, NULL)) {
+         ilo_builder_batch_restore(&ilo->cp->builder, &snapshot);
 
          /* flush and try again */
-         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
-            ilo_cp_submit(hw3d->cp, "out of aperture");
+         if (ilo_builder_batch_used(&ilo->cp->builder)) {
+            ilo_cp_submit(ilo->cp, "out of aperture");
             continue;
          }
       }
@@ -497,14 +433,12 @@ ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter)
       break;
    }
 
-   ilo_3d_pipeline_invalidate(hw3d->pipeline, ILO_3D_PIPELINE_INVALIDATE_HW);
+   ilo_render_invalidate_hw(ilo->render);
 
-   ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+   ilo_render_emit_flush(ilo->render);
 
    /* sanity check size estimation */
-   assert(before_space - ilo_cp_space(hw3d->cp) <= max_len);
-
-   hw3d->new_batch = false;
+   assert(before_space - ilo_cp_space(ilo->cp) <= max_len);
 }
 
 static void
@@ -512,6 +446,7 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
                          const struct pipe_draw_info *info)
 {
    const struct ilo_ib_state *ib = &ilo->state_vector.ib;
+   const struct ilo_vma *vma;
    union {
       const void *ptr;
       const uint8_t *u8;
@@ -520,12 +455,14 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
    } u;
 
    /* we will draw with IB mapped */
-   if (ib->buffer) {
-      u.ptr = intel_bo_map(ilo_buffer(ib->buffer)->bo, false);
+   if (ib->state.buffer) {
+      vma = ilo_resource_get_vma(ib->state.buffer);
+      u.ptr = intel_bo_map(vma->bo, false);
       if (u.ptr)
-         u.u8 += ib->offset;
+         u.u8 += vma->bo_offset + ib->state.offset;
    } else {
-      u.ptr = ib->user_buffer;
+      vma = NULL;
+      u.ptr = ib->state.user_buffer;
    }
 
    if (!u.ptr)
@@ -551,7 +488,7 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
       (pipe)->draw_vbo(pipe, &subinfo);                  \
 } while (0)
 
-   switch (ib->index_size) {
+   switch (ib->state.index_size) {
    case 1:
       DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u8);
       break;
@@ -568,8 +505,8 @@ draw_vbo_with_sw_restart(struct ilo_context *ilo,
 
 #undef DRAW_VBO_WITH_SW_RESTART
 
-   if (ib->buffer)
-      intel_bo_unmap(ilo_buffer(ib->buffer)->bo);
+   if (vma)
+      intel_bo_unmap(vma->bo);
 }
 
 static bool
@@ -579,9 +516,9 @@ draw_vbo_need_sw_restart(const struct ilo_context *ilo,
    /* the restart index is fixed prior to GEN7.5 */
    if (ilo_dev_gen(ilo->dev) < ILO_GEN(7.5)) {
       const unsigned cut_index =
-         (ilo->state_vector.ib.index_size == 1) ? 0xff :
-         (ilo->state_vector.ib.index_size == 2) ? 0xffff :
-         (ilo->state_vector.ib.index_size == 4) ? 0xffffffff : 0;
+         (ilo->state_vector.ib.state.index_size == 1) ? 0xff :
+         (ilo->state_vector.ib.state.index_size == 2) ? 0xffff :
+         (ilo->state_vector.ib.state.index_size == 4) ? 0xffffffff : 0;
 
       if (info->restart_index < cut_index)
          return true;
@@ -612,7 +549,7 @@ static void
 ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct ilo_context *ilo = ilo_context(pipe);
-   struct ilo_3d *hw3d = ilo->hw3d;
+   int vs_scratch_size, gs_scratch_size, fs_scratch_size;
 
    if (ilo_debug & ILO_DEBUG_DRAW) {
       if (info->indexed) {
@@ -640,39 +577,44 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    ilo_finalize_3d_states(ilo, info);
 
-   ilo_shader_cache_upload(ilo->shader_cache, &hw3d->cp->builder);
+   /* upload kernels */
+   ilo_shader_cache_upload(ilo->shader_cache, &ilo->cp->builder);
+
+   /* prepare scratch spaces */
+   ilo_shader_cache_get_max_scratch_sizes(ilo->shader_cache,
+         &vs_scratch_size, &gs_scratch_size, &fs_scratch_size);
+   ilo_render_prepare_scratch_spaces(ilo->render,
+         vs_scratch_size, gs_scratch_size, fs_scratch_size);
 
    ilo_blit_resolve_framebuffer(ilo);
 
    /* If draw_vbo ever fails, return immediately. */
-   if (!draw_vbo(hw3d, &ilo->state_vector))
+   if (!draw_vbo(ilo, &ilo->state_vector))
       return;
 
    /* clear dirty status */
    ilo->state_vector.dirty = 0x0;
-   hw3d->new_batch = false;
 
    /* avoid dangling pointer reference */
    ilo->state_vector.draw = NULL;
 
    if (ilo_debug & ILO_DEBUG_NOCACHE)
-      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+      ilo_render_emit_flush(ilo->render);
 }
 
 static void
 ilo_texture_barrier(struct pipe_context *pipe)
 {
    struct ilo_context *ilo = ilo_context(pipe);
-   struct ilo_3d *hw3d = ilo->hw3d;
 
    if (ilo->cp->ring != INTEL_RING_RENDER)
       return;
 
-   ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+   ilo_render_emit_flush(ilo->render);
 
    /* don't know why */
    if (ilo_dev_gen(ilo->dev) >= ILO_GEN(7))
-      ilo_cp_submit(hw3d->cp, "texture barrier");
+      ilo_cp_submit(ilo->cp, "texture barrier");
 }
 
 static void
@@ -682,18 +624,28 @@ ilo_get_sample_position(struct pipe_context *pipe,
                         float *out_value)
 {
    struct ilo_context *ilo = ilo_context(pipe);
-   struct ilo_3d *hw3d = ilo->hw3d;
 
-   ilo_3d_pipeline_get_sample_position(hw3d->pipeline,
+   ilo_render_get_sample_position(ilo->render,
          sample_count, sample_index,
          &out_value[0], &out_value[1]);
 }
 
+void
+ilo_init_draw(struct ilo_context *ilo)
+{
+   ilo->draw.cp_owner.own = ilo_draw_own_cp;
+   ilo->draw.cp_owner.release = ilo_draw_release_cp;
+   ilo->draw.cp_owner.data = (void *) ilo;
+   ilo->draw.cp_owner.reserve = 0;
+
+   list_inithead(&ilo->draw.queries);
+}
+
 /**
  * Initialize 3D-related functions.
  */
 void
-ilo_init_3d_functions(struct ilo_context *ilo)
+ilo_init_draw_functions(struct ilo_context *ilo)
 {
    ilo->base.draw_vbo = ilo_draw_vbo;
    ilo->base.texture_barrier = ilo_texture_barrier;