From d2acd673135318585fb956a2723a9a1ba89577d7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 6 Sep 2014 12:20:55 +0800 Subject: [PATCH] ilo: use ilo_builder for kernels and STATE_BASE_ADDRESS 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 | 70 +--------- src/gallium/drivers/ilo/ilo_3d.h | 5 - .../drivers/ilo/ilo_3d_pipeline_gen6.c | 16 +-- .../drivers/ilo/ilo_3d_pipeline_gen7.c | 8 +- src/gallium/drivers/ilo/ilo_context.c | 2 +- src/gallium/drivers/ilo/ilo_cp.c | 16 ++- src/gallium/drivers/ilo/ilo_cp.h | 6 +- src/gallium/drivers/ilo/ilo_shader.c | 130 ++++-------------- src/gallium/drivers/ilo/ilo_shader.h | 9 +- 9 files changed, 61 insertions(+), 201 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c index e6c72d35484..47b05caf2cf 100644 --- a/src/gallium/drivers/ilo/ilo_3d.c +++ b/src/gallium/drivers/ilo/ilo_3d.c @@ -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); diff --git a/src/gallium/drivers/ilo/ilo_3d.h b/src/gallium/drivers/ilo/ilo_3d.h index 369594affaa..2ea3d99e884 100644 --- a/src/gallium/drivers/ilo/ilo_3d.h +++ b/src/gallium/drivers/ilo/ilo_3d.h @@ -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; diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c index 3bff8961ce8..0a629f0625c 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c @@ -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); diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c index f8c335aac78..6fde9ec1099 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c @@ -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); diff --git a/src/gallium/drivers/ilo/ilo_context.c b/src/gallium/drivers/ilo/ilo_context.c index 119d940e3f9..9e6a0681bd2 100644 --- a/src/gallium/drivers/ilo/ilo_context.c +++ b/src/gallium/drivers/ilo/ilo_context.c @@ -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); diff --git a/src/gallium/drivers/ilo/ilo_cp.c b/src/gallium/drivers/ilo/ilo_cp.c index 4f65d443f49..d6bdfcaea2a 100644 --- a/src/gallium/drivers/ilo/ilo_cp.c +++ b/src/gallium/drivers/ilo/ilo_cp.c @@ -27,11 +27,14 @@ #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); diff --git a/src/gallium/drivers/ilo/ilo_cp.h b/src/gallium/drivers/ilo/ilo_cp.h index bdc75c63d87..7935a529522 100644 --- a/src/gallium/drivers/ilo/ilo_cp.h +++ b/src/gallium/drivers/ilo/ilo_cp.h @@ -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); diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c index b7e7a0a1439..ee796da7788 100644 --- a/src/gallium/drivers/ilo/ilo_shader.c +++ b/src/gallium/drivers/ilo/ilo_shader.c @@ -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; } /** diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h index d12b086ec81..45e6af2090e 100644 --- a/src/gallium/drivers/ilo/ilo_shader.h +++ b/src/gallium/drivers/ilo/ilo_shader.h @@ -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, -- 2.30.2