summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2014-09-06 12:20:55 +0800
committerChia-I Wu <olvaffe@gmail.com>2014-09-09 13:31:37 +0800
commitd2acd673135318585fb956a2723a9a1ba89577d7 (patch)
tree97f5be7cf4bde77d96e7d95b454ddf7f3e6602f4
parent55f80a3290cb0e07db780265369eb504573b4e62 (diff)
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.
-rw-r--r--src/gallium/drivers/ilo/ilo_3d.c70
-rw-r--r--src/gallium/drivers/ilo/ilo_3d.h5
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c16
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c8
-rw-r--r--src/gallium/drivers/ilo/ilo_context.c2
-rw-r--r--src/gallium/drivers/ilo/ilo_cp.c16
-rw-r--r--src/gallium/drivers/ilo/ilo_cp.h6
-rw-r--r--src/gallium/drivers/ilo/ilo_shader.c130
-rw-r--r--src/gallium/drivers/ilo/ilo_shader.h9
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
@@ -46,11 +46,6 @@ struct ilo_3d {
bool new_batch;
struct {
- struct intel_bo *bo;
- unsigned used, size;
- } kernel;
-
- struct {
struct pipe_query *query;
unsigned mode;
bool cond;
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,