Mesa (master): ilo: add support for scratch spaces

Chia-I Wu olv at kemper.freedesktop.org
Fri Oct 23 09:30:29 UTC 2015


Module: Mesa
Branch: master
Commit: 582ecb3b9132ff3690900e5426c982187d640c87
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=582ecb3b9132ff3690900e5426c982187d640c87

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Fri Oct 23 00:45:49 2015 +0800

ilo: add support for scratch spaces

When a kernel reports a non-zero per-thread scratch space size, make sure the
hardware state is correctly set up, and a scratch bo is allocated.

---

 src/gallium/drivers/ilo/ilo_draw.c                 |    8 ++++
 src/gallium/drivers/ilo/ilo_render.c               |   39 +++++++++++++++
 src/gallium/drivers/ilo/ilo_render.h               |    6 +++
 src/gallium/drivers/ilo/ilo_render_gen.h           |    5 ++
 src/gallium/drivers/ilo/ilo_render_gen6.c          |   19 +++++---
 src/gallium/drivers/ilo/ilo_render_gen7.c          |   13 +++--
 src/gallium/drivers/ilo/ilo_render_gen8.c          |    2 +-
 src/gallium/drivers/ilo/ilo_shader.c               |   50 ++++++++++++++++++--
 src/gallium/drivers/ilo/ilo_shader.h               |    6 +++
 .../drivers/ilo/shader/ilo_shader_internal.h       |    1 +
 10 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/ilo/ilo_draw.c b/src/gallium/drivers/ilo/ilo_draw.c
index 433348d..69f36ae 100644
--- a/src/gallium/drivers/ilo/ilo_draw.c
+++ b/src/gallium/drivers/ilo/ilo_draw.c
@@ -547,6 +547,7 @@ static void
 ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct ilo_context *ilo = ilo_context(pipe);
+   int vs_scratch_size, gs_scratch_size, fs_scratch_size;
 
    if (ilo_debug & ILO_DEBUG_DRAW) {
       if (info->indexed) {
@@ -574,8 +575,15 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    ilo_finalize_3d_states(ilo, info);
 
+   /* 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. */
diff --git a/src/gallium/drivers/ilo/ilo_render.c b/src/gallium/drivers/ilo/ilo_render.c
index 21f75de..8bc04df 100644
--- a/src/gallium/drivers/ilo/ilo_render.c
+++ b/src/gallium/drivers/ilo/ilo_render.c
@@ -67,10 +67,49 @@ ilo_render_create(struct ilo_builder *builder)
 void
 ilo_render_destroy(struct ilo_render *render)
 {
+   intel_bo_unref(render->vs_scratch.bo);
+   intel_bo_unref(render->gs_scratch.bo);
+   intel_bo_unref(render->fs_scratch.bo);
+
    intel_bo_unref(render->workaround_bo);
    FREE(render);
 }
 
+static bool
+resize_scratch_space(struct ilo_render *render,
+                     struct ilo_render_scratch_space *scratch,
+                     const char *name, int new_size)
+{
+   struct intel_bo *bo;
+
+   if (scratch->size >= new_size)
+      return true;
+
+   bo = intel_winsys_alloc_bo(render->builder->winsys, name, new_size, false);
+   if (!bo)
+      return false;
+
+   intel_bo_unref(scratch->bo);
+   scratch->bo = bo;
+   scratch->size = new_size;
+
+   return true;
+}
+
+bool
+ilo_render_prepare_scratch_spaces(struct ilo_render *render,
+                                  int vs_scratch_size,
+                                  int gs_scratch_size,
+                                  int fs_scratch_size)
+{
+   return (resize_scratch_space(render, &render->vs_scratch,
+            "vs scratch", vs_scratch_size) &&
+           resize_scratch_space(render, &render->gs_scratch,
+            "gs scratch", gs_scratch_size) &&
+           resize_scratch_space(render, &render->fs_scratch,
+            "fs scratch", fs_scratch_size));
+}
+
 void
 ilo_render_get_sample_position(const struct ilo_render *render,
                                unsigned sample_count,
diff --git a/src/gallium/drivers/ilo/ilo_render.h b/src/gallium/drivers/ilo/ilo_render.h
index 098af73..31fd1e6 100644
--- a/src/gallium/drivers/ilo/ilo_render.h
+++ b/src/gallium/drivers/ilo/ilo_render.h
@@ -43,6 +43,12 @@ ilo_render_create(struct ilo_builder *builder);
 void
 ilo_render_destroy(struct ilo_render *render);
 
+bool
+ilo_render_prepare_scratch_spaces(struct ilo_render *render,
+                                  int vs_scratch_size,
+                                  int gs_scratch_size,
+                                  int fs_scratch_size);
+
 void
 ilo_render_get_sample_position(const struct ilo_render *render,
                                unsigned sample_count,
diff --git a/src/gallium/drivers/ilo/ilo_render_gen.h b/src/gallium/drivers/ilo/ilo_render_gen.h
index 6b13375..f227d6b 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen.h
+++ b/src/gallium/drivers/ilo/ilo_render_gen.h
@@ -51,6 +51,11 @@ struct ilo_render {
 
    struct intel_bo *workaround_bo;
 
+   struct ilo_render_scratch_space {
+      struct intel_bo *bo;
+      int size;
+   } vs_scratch, gs_scratch, fs_scratch;
+
    struct ilo_state_sample_pattern sample_pattern;
 
    bool hw_ctx_changed;
diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c
index c81514f..910e6c0 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen6.c
@@ -475,10 +475,13 @@ gen6_draw_vs(struct ilo_render *r,
          gen6_wa_pre_3dstate_vs_toggle(r);
 
       if (ilo_dev_gen(r->dev) == ILO_GEN(6) &&
-          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO))
-         gen6_3DSTATE_VS(r->builder, &cso->vs_sol.vs, kernel_offset, NULL);
-      else
-         gen6_3DSTATE_VS(r->builder, &cso->vs, kernel_offset, NULL);
+          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)) {
+         gen6_3DSTATE_VS(r->builder, &cso->vs_sol.vs,
+               kernel_offset, r->vs_scratch.bo);
+      } else {
+         gen6_3DSTATE_VS(r->builder, &cso->vs,
+               kernel_offset, r->vs_scratch.bo);
+      }
    }
 }
 
@@ -501,7 +504,8 @@ gen6_draw_gs(struct ilo_render *r,
          cso = ilo_shader_get_kernel_cso(vec->gs);
          kernel_offset = ilo_shader_get_kernel_offset(vec->gs);
 
-         gen6_3DSTATE_GS(r->builder, &cso->gs, kernel_offset, NULL);
+         gen6_3DSTATE_GS(r->builder, &cso->gs,
+               kernel_offset, r->gs_scratch.bo);
       } else if (ilo_dev_gen(r->dev) == ILO_GEN(6) &&
             ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)) {
          const int verts_per_prim =
@@ -524,7 +528,8 @@ gen6_draw_gs(struct ilo_render *r,
          kernel_offset = ilo_shader_get_kernel_offset(vec->vs) +
             ilo_shader_get_kernel_param(vec->vs, param);
 
-         gen6_3DSTATE_GS(r->builder, &cso->vs_sol.sol, kernel_offset, NULL);
+         gen6_3DSTATE_GS(r->builder, &cso->vs_sol.sol,
+               kernel_offset, r->gs_scratch.bo);
       } else {
          gen6_3DSTATE_GS(r->builder, &vec->disabled_gs, 0, NULL);
       }
@@ -672,7 +677,7 @@ gen6_draw_wm(struct ilo_render *r,
          gen6_wa_pre_3dstate_wm_max_threads(r);
 
       gen6_3DSTATE_WM(r->builder, &vec->rasterizer->rs,
-            &cso->ps, kernel_offset, NULL);
+            &cso->ps, kernel_offset, r->fs_scratch.bo);
    }
 }
 
diff --git a/src/gallium/drivers/ilo/ilo_render_gen7.c b/src/gallium/drivers/ilo/ilo_render_gen7.c
index 97d9d05..330ba6c 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen7.c
@@ -318,10 +318,13 @@ gen7_draw_vs(struct ilo_render *r,
       const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->vs);
       const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->vs);
 
-      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
-         gen8_3DSTATE_VS(r->builder, &cso->vs, kernel_offset, NULL);
-      else
-         gen6_3DSTATE_VS(r->builder, &cso->vs, kernel_offset, NULL);
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
+         gen8_3DSTATE_VS(r->builder, &cso->vs,
+               kernel_offset, r->vs_scratch.bo);
+      } else {
+         gen6_3DSTATE_VS(r->builder, &cso->vs,
+               kernel_offset, r->vs_scratch.bo);
+      }
    }
 }
 
@@ -534,7 +537,7 @@ gen7_draw_wm(struct ilo_render *r,
       if (r->hw_ctx_changed)
          gen7_wa_pre_3dstate_ps_max_threads(r);
 
-      gen7_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, NULL);
+      gen7_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, r->fs_scratch.bo);
    }
 
    /* 3DSTATE_SCISSOR_STATE_POINTERS */
diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c
index 1f750a2..efe0e0d 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen8.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen8.c
@@ -125,7 +125,7 @@ gen8_draw_wm(struct ilo_render *r,
 
    /* 3DSTATE_PS */
    if (DIRTY(FS) || r->instruction_bo_changed)
-      gen8_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, NULL);
+      gen8_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, r->fs_scratch.bo);
 
    /* 3DSTATE_PS_EXTRA */
    if (DIRTY(FS))
diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c
index c78d0e0..c61716d 100644
--- a/src/gallium/drivers/ilo/ilo_shader.c
+++ b/src/gallium/drivers/ilo/ilo_shader.c
@@ -37,6 +37,10 @@
 struct ilo_shader_cache {
    struct list_head shaders;
    struct list_head changed;
+
+   int max_vs_scratch_size;
+   int max_gs_scratch_size;
+   int max_fs_scratch_size;
 };
 
 /**
@@ -121,6 +125,8 @@ ilo_shader_cache_upload(struct ilo_shader_cache *shc,
       struct ilo_shader *sh;
 
       LIST_FOR_EACH_ENTRY(sh, &shader->variants, list) {
+         int scratch_size, *cur_max;
+
          if (sh->uploaded)
             continue;
 
@@ -128,6 +134,29 @@ ilo_shader_cache_upload(struct ilo_shader_cache *shc,
                sh->kernel_size, sh->kernel);
 
          sh->uploaded = true;
+
+         switch (shader->info.type) {
+         case PIPE_SHADER_VERTEX:
+            scratch_size = ilo_state_vs_get_scratch_size(&sh->cso.vs);
+            cur_max = &shc->max_vs_scratch_size;
+            break;
+         case PIPE_SHADER_GEOMETRY:
+            scratch_size = ilo_state_gs_get_scratch_size(&sh->cso.gs);
+            cur_max = &shc->max_gs_scratch_size;
+            break;
+         case PIPE_SHADER_FRAGMENT:
+            scratch_size = ilo_state_ps_get_scratch_size(&sh->cso.ps);
+            cur_max = &shc->max_fs_scratch_size;
+            break;
+         default:
+            assert(!"unknown shader type");
+            scratch_size = 0;
+            cur_max = &shc->max_vs_scratch_size;
+            break;
+         }
+
+         if (*cur_max < scratch_size)
+            *cur_max = scratch_size;
       }
 
       list_del(&shader->list);
@@ -155,6 +184,21 @@ ilo_shader_cache_invalidate(struct ilo_shader_cache *shc)
       LIST_FOR_EACH_ENTRY(sh, &shader->variants, list)
          sh->uploaded = false;
    }
+
+   shc->max_vs_scratch_size = 0;
+   shc->max_gs_scratch_size = 0;
+   shc->max_fs_scratch_size = 0;
+}
+
+void
+ilo_shader_cache_get_max_scratch_sizes(const struct ilo_shader_cache *shc,
+                                       int *vs_scratch_size,
+                                       int *gs_scratch_size,
+                                       int *fs_scratch_size)
+{
+   *vs_scratch_size = shc->max_vs_scratch_size;
+   *gs_scratch_size = shc->max_gs_scratch_size;
+   *fs_scratch_size = shc->max_fs_scratch_size;
 }
 
 /**
@@ -601,7 +645,7 @@ init_vs(struct ilo_shader *kernel,
    init_shader_urb(kernel, state, &info.urb);
    init_shader_kernel(kernel, state, &info.kernel);
    init_shader_resource(kernel, state, &info.resource);
-   info.per_thread_scratch_size = 0;
+   info.per_thread_scratch_size = kernel->per_thread_scratch_size;
    info.dispatch_enable = true;
    info.stats_enable = true;
 
@@ -640,7 +684,7 @@ init_gs(struct ilo_shader *kernel,
    init_shader_urb(kernel, state, &info.urb);
    init_shader_kernel(kernel, state, &info.kernel);
    init_shader_resource(kernel, state, &info.resource);
-   info.per_thread_scratch_size = 0;
+   info.per_thread_scratch_size = kernel->per_thread_scratch_size;
    info.dispatch_enable = true;
    info.stats_enable = true;
 
@@ -665,7 +709,7 @@ init_ps(struct ilo_shader *kernel,
    init_shader_kernel(kernel, state, &info.kernel_8);
    init_shader_resource(kernel, state, &info.resource);
 
-   info.per_thread_scratch_size = 0;
+   info.per_thread_scratch_size = kernel->per_thread_scratch_size;
    info.io.has_rt_write = true;
    info.io.posoffset = GEN6_POSOFFSET_NONE;
    info.io.attr_count = kernel->in.count;
diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h
index 01de541..10dcf73 100644
--- a/src/gallium/drivers/ilo/ilo_shader.h
+++ b/src/gallium/drivers/ilo/ilo_shader.h
@@ -120,6 +120,12 @@ ilo_shader_cache_upload(struct ilo_shader_cache *shc,
 void
 ilo_shader_cache_invalidate(struct ilo_shader_cache *shc);
 
+void
+ilo_shader_cache_get_max_scratch_sizes(const struct ilo_shader_cache *shc,
+                                       int *vs_scratch_size,
+                                       int *gs_scratch_size,
+                                       int *fs_scratch_size);
+
 struct ilo_shader_state *
 ilo_shader_create_vs(const struct ilo_dev *dev,
                      const struct pipe_shader_state *state,
diff --git a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h
index 01c8667..1f0cda1 100644
--- a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h
+++ b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h
@@ -139,6 +139,7 @@ struct ilo_shader {
 
    void *kernel;
    int kernel_size;
+   int per_thread_scratch_size;
 
    struct ilo_kernel_routing routing;
    struct ilo_state_ps_params_info ps_params;




More information about the mesa-commit mailing list