ilo: use ilo_builder for kernels and STATE_BASE_ADDRESS
authorChia-I Wu <olvaffe@gmail.com>
Sat, 6 Sep 2014 04:20:55 +0000 (12:20 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Tue, 9 Sep 2014 05:31:37 +0000 (13:31 +0800)
Remove instruction buffer management from ilo_3d and adapt ilo_shader_cache to
upload kernels to ilo_builder.  To be able to do that, we also let ilo_builder
manage STATE_BASE_ADDRESS.

src/gallium/drivers/ilo/ilo_3d.c
src/gallium/drivers/ilo/ilo_3d.h
src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
src/gallium/drivers/ilo/ilo_context.c
src/gallium/drivers/ilo/ilo_cp.c
src/gallium/drivers/ilo/ilo_cp.h
src/gallium/drivers/ilo/ilo_shader.c
src/gallium/drivers/ilo/ilo_shader.h

index e6c72d35484b267b0aec233ba03ba0ef6d8e80cf..47b05caf2cf7400bfb01ab2c9dfb36588c7fef33 100644 (file)
@@ -401,7 +401,8 @@ ilo_3d_cp_flushed(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_STATE_BO |
+         ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
 
    hw3d->new_batch = true;
 }
@@ -446,10 +447,6 @@ void
 ilo_3d_destroy(struct ilo_3d *hw3d)
 {
    ilo_3d_pipeline_destroy(hw3d->pipeline);
-
-   if (hw3d->kernel.bo)
-      intel_bo_unreference(hw3d->kernel.bo);
-
    FREE(hw3d);
 }
 
@@ -717,66 +714,6 @@ ilo_draw_vbo_with_sw_restart(struct pipe_context *pipe,
    FREE(restart_info);
 }
 
-static bool
-upload_shaders(struct ilo_3d *hw3d, struct ilo_shader_cache *shc)
-{
-   bool incremental = true;
-   int upload;
-
-   upload = ilo_shader_cache_upload(shc,
-         NULL, hw3d->kernel.used, incremental);
-   if (!upload)
-      return true;
-
-   /*
-    * Allocate a new bo.  When this is a new batch, assume the bo is still in
-    * use by the previous batch and force allocation.
-    *
-    * Does it help to make shader cache upload with unsynchronized mapping,
-    * and remove the check for new batch here?
-    */
-   if (hw3d->kernel.used + upload > hw3d->kernel.size || hw3d->new_batch) {
-      unsigned new_size = (hw3d->kernel.size) ?
-         hw3d->kernel.size : (8 * 1024);
-
-      while (hw3d->kernel.used + upload > new_size)
-         new_size *= 2;
-
-      if (hw3d->kernel.bo)
-         intel_bo_unreference(hw3d->kernel.bo);
-
-      hw3d->kernel.bo = intel_winsys_alloc_buffer(hw3d->cp->winsys,
-            "kernel bo", new_size, true);
-      if (!hw3d->kernel.bo) {
-         ilo_err("failed to allocate kernel bo\n");
-         return false;
-      }
-
-      hw3d->kernel.used = 0;
-      hw3d->kernel.size = new_size;
-      incremental = false;
-
-      assert(new_size >= ilo_shader_cache_upload(shc,
-            NULL, hw3d->kernel.used, incremental));
-
-      ilo_3d_pipeline_invalidate(hw3d->pipeline,
-            ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
-   }
-
-   upload = ilo_shader_cache_upload(shc,
-         hw3d->kernel.bo, hw3d->kernel.used, incremental);
-   if (upload < 0) {
-      ilo_err("failed to upload shaders\n");
-      return false;
-   }
-
-   hw3d->kernel.used += upload;
-
-   assert(hw3d->kernel.used <= hw3d->kernel.size);
-
-   return true;
-}
-
 static void
 ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
@@ -816,8 +753,7 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    ilo_finalize_3d_states(ilo, info);
 
-   if (!upload_shaders(hw3d, ilo->shader_cache))
-      return;
+   ilo_shader_cache_upload(ilo->shader_cache, &hw3d->cp->builder);
 
    ilo_blit_resolve_framebuffer(ilo);
 
index 369594affaad767d691e23cd5a0f0b2e35cd72de..2ea3d99e884597c922904098afbf12288f1eb9d1 100644 (file)
@@ -45,11 +45,6 @@ struct ilo_3d {
 
    bool new_batch;
 
-   struct {
-      struct intel_bo *bo;
-      unsigned used, size;
-   } kernel;
-
    struct {
       struct pipe_query *query;
       unsigned mode;
index 3bff8961ce8279269310b20b6ecfb720e607fc0f..0a629f0625ce438d9d38d421165d081d94c5801d 100644 (file)
@@ -215,15 +215,11 @@ gen6_pipeline_common_base_address(struct ilo_3d_pipeline *p,
    /* STATE_BASE_ADDRESS */
    if (session->state_bo_changed || session->kernel_bo_changed ||
        session->batch_bo_changed) {
-      const struct ilo_builder_writer *bat =
-         &p->cp->builder.writers[ILO_BUILDER_WRITER_BATCH];
-
       if (p->dev->gen == ILO_GEN(6))
          gen6_wa_pipe_control_post_sync(p, false);
 
-      gen6_emit_STATE_BASE_ADDRESS(p->dev,
-            NULL, bat->bo, bat->bo, NULL, ilo->hw3d->kernel.bo,
-            0, 0, 0, 0, p->cp);
+      ilo_builder_batch_state_base_address(&p->cp->builder,
+            session->hw_ctx_changed);
 
       /*
        * From the Sandy Bridge PRM, volume 1 part 1, page 28:
@@ -1634,13 +1630,7 @@ gen6_rectlist_commands(struct ilo_3d_pipeline *p,
 
    gen6_rectlist_wm_multisample(p, blitter, session);
 
-   gen6_emit_STATE_BASE_ADDRESS(p->dev,
-         NULL,                /* General State Base */
-         p->cp->builder.writers[0].bo,           /* Surface State Base */
-         p->cp->builder.writers[0].bo,           /* Dynamic State Base */
-         NULL,                /* Indirect Object Base */
-         NULL,                /* Instruction Base */
-         0, 0, 0, 0, p->cp);
+   ilo_builder_batch_state_base_address(&p->cp->builder, true);
 
    gen6_emit_3DSTATE_VERTEX_BUFFERS(p->dev,
          &blitter->ve, &blitter->vb, p->cp);
index f8c335aac78c86e0a8ba1b1dc00fbe9eb314b3f8..6fde9ec1099dd0ff4a90283a7fafdd9539522db6 100644 (file)
@@ -800,13 +800,7 @@ gen7_rectlist_commands(struct ilo_3d_pipeline *p,
 {
    gen7_rectlist_wm_multisample(p, blitter, session);
 
-   gen6_emit_STATE_BASE_ADDRESS(p->dev,
-         NULL,                /* General State Base */
-         p->cp->builder.writers[0].bo,           /* Surface State Base */
-         p->cp->builder.writers[0].bo,           /* Dynamic State Base */
-         NULL,                /* Indirect Object Base */
-         NULL,                /* Instruction Base */
-         0, 0, 0, 0, p->cp);
+   ilo_builder_batch_state_base_address(&p->cp->builder, true);
 
    gen6_emit_3DSTATE_VERTEX_BUFFERS(p->dev,
          &blitter->ve, &blitter->vb, p->cp);
index 119d940e3f9e27b749655bb9f6026270df8d12dd..9e6a0681bd21315f203a8fa30e685f6dbcf4de21 100644 (file)
@@ -109,8 +109,8 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
    util_slab_create(&ilo->transfer_mempool,
          sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED);
 
-   ilo->cp = ilo_cp_create(ilo->dev, ilo->winsys);
    ilo->shader_cache = ilo_shader_cache_create();
+   ilo->cp = ilo_cp_create(ilo->dev, ilo->winsys, ilo->shader_cache);
    if (ilo->cp)
       ilo->hw3d = ilo_3d_create(ilo->cp, ilo->dev);
 
index 4f65d443f494d22a28aa09e4ce3e660026bef208..d6bdfcaea2a82b736a6c7b037c80d9c1c0ff899a 100644 (file)
 
 #include "intel_winsys.h"
 
+#include "ilo_shader.h"
 #include "ilo_cp.h"
 
 static struct intel_bo *
 ilo_cp_end_batch(struct ilo_cp *cp, unsigned *used)
 {
+   struct intel_bo *bo;
+
    ilo_cp_set_owner(cp, NULL, 0);
 
    if (!ilo_builder_batch_used(&cp->builder)) {
@@ -43,7 +46,13 @@ ilo_cp_end_batch(struct ilo_cp *cp, unsigned *used)
    assert(ilo_builder_batch_space(&cp->builder) >= 2);
    ilo_builder_batch_mi_batch_buffer_end(&cp->builder);
 
-   return ilo_builder_end(&cp->builder, used);
+   bo = ilo_builder_end(&cp->builder, used);
+
+   /* we have to assume that kernel uploads also failed */
+   if (!bo)
+      ilo_shader_cache_invalidate(cp->shader_cache);
+
+   return bo;
 }
 
 /**
@@ -101,7 +110,9 @@ ilo_cp_destroy(struct ilo_cp *cp)
  * Create a command parser.
  */
 struct ilo_cp *
-ilo_cp_create(const struct ilo_dev_info *dev, struct intel_winsys *winsys)
+ilo_cp_create(const struct ilo_dev_info *dev,
+              struct intel_winsys *winsys,
+              struct ilo_shader_cache *shc)
 {
    struct ilo_cp *cp;
 
@@ -110,6 +121,7 @@ ilo_cp_create(const struct ilo_dev_info *dev, struct intel_winsys *winsys)
       return NULL;
 
    cp->winsys = winsys;
+   cp->shader_cache = shc;
    cp->render_ctx = intel_winsys_create_context(winsys);
    if (!cp->render_ctx) {
       FREE(cp);
index bdc75c63d8716115bf7626d079f670ca9ee45dde..7935a529522ca65186587bbc90866058bffdff11 100644 (file)
@@ -34,6 +34,7 @@
 #include "ilo_common.h"
 
 struct ilo_cp;
+struct ilo_shader_cache;
 
 typedef void (*ilo_cp_callback)(struct ilo_cp *cp, void *data);
 
@@ -47,6 +48,7 @@ struct ilo_cp_owner {
  */
 struct ilo_cp {
    struct intel_winsys *winsys;
+   struct ilo_shader_cache *shader_cache;
    struct intel_context *render_ctx;
 
    ilo_cp_callback flush_callback;
@@ -68,7 +70,9 @@ struct ilo_cp {
 };
 
 struct ilo_cp *
-ilo_cp_create(const struct ilo_dev_info *dev, struct intel_winsys *winsys);
+ilo_cp_create(const struct ilo_dev_info *dev,
+              struct intel_winsys *winsys,
+              struct ilo_shader_cache *shc);
 
 void
 ilo_cp_destroy(struct ilo_cp *cp);
index b7e7a0a14396af0b0f45bd0a78d967523faf3245..ee796da778827007c5674ea50380f662ecf43b5e 100644 (file)
@@ -30,6 +30,7 @@
 #include "intel_winsys.h"
 
 #include "shader/ilo_shader_internal.h"
+#include "ilo_builder.h"
 #include "ilo_state.h"
 #include "ilo_shader.h"
 
@@ -107,128 +108,53 @@ ilo_shader_cache_notify_change(struct ilo_shader_cache *shc,
 }
 
 /**
- * Upload a managed shader to the bo.
+ * Upload managed shaders to the bo.  Only shaders that are changed or added
+ * after the last upload are uploaded.
  */
-static int
-ilo_shader_cache_upload_shader(struct ilo_shader_cache *shc,
-                               struct ilo_shader_state *shader,
-                               struct intel_bo *bo, unsigned offset,
-                               bool incremental)
+void
+ilo_shader_cache_upload(struct ilo_shader_cache *shc,
+                        struct ilo_builder *builder)
 {
-   const unsigned base = offset;
-   struct ilo_shader *sh;
-
-   LIST_FOR_EACH_ENTRY(sh, &shader->variants, list) {
-      int err;
-
-      if (incremental && sh->uploaded)
-         continue;
-
-      /* kernels must be aligned to 64-byte */
-      offset = align(offset, 64);
-
-      err = intel_bo_pwrite(bo, offset, sh->kernel_size, sh->kernel);
-      if (unlikely(err))
-         return -1;
-
-      sh->uploaded = true;
-      sh->cache_offset = offset;
-
-      offset += sh->kernel_size;
-   }
+   struct ilo_shader_state *shader, *next;
 
-   return (int) (offset - base);
-}
+   LIST_FOR_EACH_ENTRY_SAFE(shader, next, &shc->changed, list) {
+      struct ilo_shader *sh;
 
-/**
- * Similar to ilo_shader_cache_upload(), except no upload happens.
- */
-static int
-ilo_shader_cache_get_upload_size(struct ilo_shader_cache *shc,
-                                 unsigned offset,
-                                 bool incremental)
-{
-   const unsigned base = offset;
-   struct ilo_shader_state *shader;
+      LIST_FOR_EACH_ENTRY(sh, &shader->variants, list) {
+         if (sh->uploaded)
+            continue;
 
-   if (!incremental) {
-      LIST_FOR_EACH_ENTRY(shader, &shc->shaders, list) {
-         struct ilo_shader *sh;
+         sh->cache_offset = ilo_builder_instruction_write(builder,
+               sh->kernel_size, sh->kernel);
 
-         /* see ilo_shader_cache_upload_shader() */
-         LIST_FOR_EACH_ENTRY(sh, &shader->variants, list) {
-            if (!incremental || !sh->uploaded)
-               offset = align(offset, 64) + sh->kernel_size;
-         }
+         sh->uploaded = true;
       }
-   }
-
-   LIST_FOR_EACH_ENTRY(shader, &shc->changed, list) {
-      struct ilo_shader *sh;
 
-      /* see ilo_shader_cache_upload_shader() */
-      LIST_FOR_EACH_ENTRY(sh, &shader->variants, list) {
-         if (!incremental || !sh->uploaded)
-            offset = align(offset, 64) + sh->kernel_size;
-      }
+      list_del(&shader->list);
+      list_add(&shader->list, &shc->shaders);
    }
-
-   /*
-    * From the Sandy Bridge PRM, volume 4 part 2, page 112:
-    *
-    *     "Due to prefetch of the instruction stream, the EUs may attempt to
-    *      access up to 8 instructions (128 bytes) beyond the end of the
-    *      kernel program - possibly into the next memory page.  Although
-    *      these instructions will not be executed, software must account for
-    *      the prefetch in order to avoid invalid page access faults."
-    */
-   if (offset > base)
-      offset += 128;
-
-   return (int) (offset - base);
 }
 
 /**
- * Upload managed shaders to the bo.  When incremental is true, only shaders
- * that are changed or added after the last upload are uploaded.
+ * Invalidate all shaders so that they get uploaded in next
+ * ilo_shader_cache_upload().
  */
-int
-ilo_shader_cache_upload(struct ilo_shader_cache *shc,
-                        struct intel_bo *bo, unsigned offset,
-                        bool incremental)
+void
+ilo_shader_cache_invalidate(struct ilo_shader_cache *shc)
 {
    struct ilo_shader_state *shader, *next;
-   int size = 0, s;
 
-   if (!bo)
-      return ilo_shader_cache_get_upload_size(shc, offset, incremental);
-
-   if (!incremental) {
-      LIST_FOR_EACH_ENTRY(shader, &shc->shaders, list) {
-         s = ilo_shader_cache_upload_shader(shc, shader,
-               bo, offset, incremental);
-         if (unlikely(s < 0))
-            return s;
-
-         size += s;
-         offset += s;
-      }
+   LIST_FOR_EACH_ENTRY_SAFE(shader, next, &shc->shaders, list) {
+      list_del(&shader->list);
+      list_add(&shader->list, &shc->changed);
    }
 
-   LIST_FOR_EACH_ENTRY_SAFE(shader, next, &shc->changed, list) {
-      s = ilo_shader_cache_upload_shader(shc, shader,
-            bo, offset, incremental);
-      if (unlikely(s < 0))
-         return s;
-
-      size += s;
-      offset += s;
+   LIST_FOR_EACH_ENTRY(shader, &shc->changed, list) {
+      struct ilo_shader *sh;
 
-      list_del(&shader->list);
-      list_add(&shader->list, &shc->shaders);
+      LIST_FOR_EACH_ENTRY(sh, &shader->variants, list)
+         sh->uploaded = false;
    }
-
-   return size;
 }
 
 /**
index d12b086ec8140588690819c952fcff555d7716a9..45e6af2090e6a8ae39f0782af51cf058e1cfcd15 100644 (file)
@@ -70,6 +70,7 @@ struct ilo_kernel_routing {
 };
 
 struct intel_bo;
+struct ilo_builder;
 struct ilo_context;
 struct ilo_rasterizer_state;
 struct ilo_shader_cache;
@@ -90,10 +91,12 @@ void
 ilo_shader_cache_remove(struct ilo_shader_cache *shc,
                         struct ilo_shader_state *shader);
 
-int
+void
 ilo_shader_cache_upload(struct ilo_shader_cache *shc,
-                        struct intel_bo *bo, unsigned offset,
-                        bool incremental);
+                        struct ilo_builder *builder);
+
+void
+ilo_shader_cache_invalidate(struct ilo_shader_cache *shc);
 
 struct ilo_shader_state *
 ilo_shader_create_vs(const struct ilo_dev_info *dev,