summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/ilo_3d.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-06-19 09:56:05 +0800
committerChia-I Wu <[email protected]>2013-06-19 16:46:42 +0800
commitcf41fae96b3d796ce80b2d1ad76b5c84a0669314 (patch)
tree372220327ee720cd763cfcd241ccee4bf846abc7 /src/gallium/drivers/ilo/ilo_3d.c
parent7f7b05d6b324c15b6573dfe1e90d4d5cf416a59b (diff)
ilo: rework shader cache
The new code makes the shader cache manages all shaders and be able to upload all of them to a caller-provided bo as a whole. Previously, we uploaded only the bound shaders. When a different set of shaders is bound, we had to allocate a new kernel bo to upload if the current one is busy.
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_3d.c')
-rw-r--r--src/gallium/drivers/ilo/ilo_3d.c76
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);