diff options
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_3d.c')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_3d.c | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c index 17dd5b125e9..6223de98c0f 100644 --- a/src/gallium/drivers/ilo/ilo_3d.c +++ b/src/gallium/drivers/ilo/ilo_3d.c @@ -363,6 +363,10 @@ 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); } @@ -627,6 +631,66 @@ 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, 0); + 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) { @@ -649,17 +713,10 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } } - /* assume the cache is still in use by the previous batch */ - if (hw3d->new_batch) - ilo_shader_cache_mark_busy(ilo->shader_cache); - ilo_finalize_states(ilo); - /* the shaders may be uploaded to a new shader cache */ - if (hw3d->shader_cache_seqno != ilo->shader_cache->seqno) { - ilo_3d_pipeline_invalidate(hw3d->pipeline, - ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO); - } + if (!upload_shaders(hw3d, ilo->shader_cache)) + return; /* If draw_vbo ever fails, return immediately. */ if (!draw_vbo(hw3d, ilo, info, &prim_generated, &prim_emitted)) @@ -668,7 +725,6 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* clear dirty status */ ilo->dirty = 0x0; hw3d->new_batch = false; - hw3d->shader_cache_seqno = ilo->shader_cache->seqno; update_prim_count(hw3d, prim_generated, prim_emitted); |