From 582ecb3b9132ff3690900e5426c982187d640c87 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 23 Oct 2015 00:45:49 +0800 Subject: [PATCH] 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 433348d9326..69f36ae5df6 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 21f75de11a0..8bc04df4fab 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 098af73ec9b..31fd1e6f859 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 6b133750043..f227d6bf4da 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 c81514f9b4c..910e6c0fb7a 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 97d9d058fdf..330ba6c88d6 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 1f750a2bfed..efe0e0d501b 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 c78d0e0b602..c61716dc791 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 01de54146b1..10dcf739430 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 01c86675202..1f0cda174e8 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; -- 2.30.2