ilo: add support for scratch spaces
authorChia-I Wu <olvaffe@gmail.com>
Thu, 22 Oct 2015 16:45:49 +0000 (00:45 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Fri, 23 Oct 2015 09:29:58 +0000 (17:29 +0800)
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
src/gallium/drivers/ilo/ilo_render.c
src/gallium/drivers/ilo/ilo_render.h
src/gallium/drivers/ilo/ilo_render_gen.h
src/gallium/drivers/ilo/ilo_render_gen6.c
src/gallium/drivers/ilo/ilo_render_gen7.c
src/gallium/drivers/ilo/ilo_render_gen8.c
src/gallium/drivers/ilo/ilo_shader.c
src/gallium/drivers/ilo/ilo_shader.h
src/gallium/drivers/ilo/shader/ilo_shader_internal.h

index 433348d932690a8bbe094a244899d3fdaf113349..69f36ae5df60213d6892c29e65cb60a684b52dd0 100644 (file)
@@ -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. */
index 21f75de11a05b5c4da5a3a4fdbeab93662a24412..8bc04df4fabb6e485171de4539e8b1b83eeac33d 100644 (file)
@@ -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,
index 098af73ec9b5195869255ea6a501a3e80210d471..31fd1e6f859255ddfde0178c47b054000a282857 100644 (file)
@@ -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,
index 6b1337500438f61619ccb1bd17bf09ed6b10b07d..f227d6bf4da27fc0bfcead1c30ca6e9f59b19046 100644 (file)
@@ -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;
index c81514f9b4c3a9467828ad9af514956bb94d2131..910e6c0fb7ae3404878a2b70e88cc74fed99aad7 100644 (file)
@@ -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);
    }
 }
 
index 97d9d058fdfa21d6eecd70e0d183ab8c347b4cfc..330ba6c88d6e16208c2e6e02b30b80a2c34e4bd8 100644 (file)
@@ -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 */
index 1f750a2bfed50342a624a6aa956c9bf106665f1c..efe0e0d501b6ec33786b2a6aa37bd160728dc7f6 100644 (file)
@@ -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))
index c78d0e0b6027419a7a81630efe5c573528a04d6f..c61716dc7916e5940fde7e936479be57ee1c854e 100644 (file)
 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;
index 01de54146b174180521866c7eafd9ab97faf1e77..10dcf739430a9a9fa931dbf400f6f8f444703ea3 100644 (file)
@@ -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,
index 01c86675202da082187cff34338fc70452f09be5..1f0cda174e8d59a67da74c07ea01d7f3fa2e9ad0 100644 (file)
@@ -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;