aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-12-07 12:18:34 -0800
committerEric Anholt <[email protected]>2018-12-07 16:48:23 -0800
commitb38e4d313fc27a225a36c42f84b2bee9933e62e6 (patch)
treec4cb203d7e79ebc7ace5b7c79772ea9b3efc5247
parent191188876098801edeaaa231f95fed545fbcc08a (diff)
v3d: Create a state uploader for packing our shaders together.
Shaders are usually quite short, and are private to the context. We can save memory and reduce the work the kernel needs to do at exec time by packing them together in a stream uploader for long-lived state.
-rw-r--r--src/gallium/drivers/v3d/v3d_context.c6
-rw-r--r--src/gallium/drivers/v3d/v3d_context.h11
-rw-r--r--src/gallium/drivers/v3d/v3d_program.c22
-rw-r--r--src/gallium/drivers/v3d/v3dx_draw.c9
4 files changed, 35 insertions, 13 deletions
diff --git a/src/gallium/drivers/v3d/v3d_context.c b/src/gallium/drivers/v3d/v3d_context.c
index 12741b578e3..36c8f497824 100644
--- a/src/gallium/drivers/v3d/v3d_context.c
+++ b/src/gallium/drivers/v3d/v3d_context.c
@@ -98,6 +98,8 @@ v3d_context_destroy(struct pipe_context *pctx)
if (v3d->uploader)
u_upload_destroy(v3d->uploader);
+ if (v3d->state_uploader)
+ u_upload_destroy(v3d->state_uploader);
slab_destroy_child(&v3d->transfer_pool);
@@ -159,6 +161,10 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
v3d->uploader = u_upload_create_default(&v3d->base);
v3d->base.stream_uploader = v3d->uploader;
v3d->base.const_uploader = v3d->uploader;
+ v3d->state_uploader = u_upload_create(&v3d->base,
+ 4096,
+ PIPE_BIND_CONSTANT_BUFFER,
+ PIPE_USAGE_STREAM, 0);
v3d->blitter = util_blitter_create(pctx);
if (!v3d->blitter)
diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h
index 8c55eadfa15..ab4756aa76f 100644
--- a/src/gallium/drivers/v3d/v3d_context.h
+++ b/src/gallium/drivers/v3d/v3d_context.h
@@ -143,7 +143,8 @@ struct v3d_uncompiled_shader {
};
struct v3d_compiled_shader {
- struct v3d_bo *bo;
+ struct pipe_resource *resource;
+ uint32_t offset;
union {
struct v3d_prog_data *base;
@@ -368,7 +369,15 @@ struct v3d_context {
/** Sync object that our RCL or TFU job will update as its out_sync. */
uint32_t out_sync;
+ /* Stream uploader used by gallium internals. This could also be used
+ * by driver internals, but we tend to use the v3d_cl.h interfaces
+ * instead.
+ */
struct u_upload_mgr *uploader;
+ /* State uploader used inside the driver. This is for packing bits of
+ * long-term state inside buffers.
+ */
+ struct u_upload_mgr *state_uploader;
/** @{ Current pipeline state objects */
struct pipe_scissor_state scissor;
diff --git a/src/gallium/drivers/v3d/v3d_program.c b/src/gallium/drivers/v3d/v3d_program.c
index 1dceade950a..25b346fd11b 100644
--- a/src/gallium/drivers/v3d/v3d_program.c
+++ b/src/gallium/drivers/v3d/v3d_program.c
@@ -27,6 +27,7 @@
#include "util/u_memory.h"
#include "util/ralloc.h"
#include "util/hash_table.h"
+#include "util/u_upload_mgr.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_parse.h"
#include "compiler/nir/nir.h"
@@ -301,9 +302,8 @@ v3d_get_compiled_shader(struct v3d_context *v3d, struct v3d_key *key)
v3d_set_shader_uniform_dirty_flags(shader);
- shader->bo = v3d_bo_alloc(v3d->screen, shader_size, "shader");
- v3d_bo_map(shader->bo);
- memcpy(shader->bo->map, qpu_insts, shader_size);
+ u_upload_data(v3d->state_uploader, 0, shader_size, 8,
+ qpu_insts, &shader->offset, &shader->resource);
free(qpu_insts);
@@ -331,6 +331,13 @@ v3d_get_compiled_shader(struct v3d_context *v3d, struct v3d_key *key)
}
static void
+v3d_free_compiled_shader(struct v3d_compiled_shader *shader)
+{
+ pipe_resource_reference(&shader->resource, NULL);
+ ralloc_free(shader);
+}
+
+static void
v3d_setup_shared_key(struct v3d_context *v3d, struct v3d_key *key,
struct v3d_texture_stateobj *texstate)
{
@@ -606,12 +613,11 @@ delete_from_cache_if_matches(struct hash_table *ht,
if (key->shader_state == so) {
struct v3d_compiled_shader *shader = entry->data;
_mesa_hash_table_remove(ht, entry);
- v3d_bo_unreference(&shader->bo);
if (shader == *last_compile)
*last_compile = NULL;
- ralloc_free(shader);
+ v3d_free_compiled_shader(shader);
}
}
@@ -677,15 +683,13 @@ v3d_program_fini(struct pipe_context *pctx)
hash_table_foreach(v3d->fs_cache, entry) {
struct v3d_compiled_shader *shader = entry->data;
- v3d_bo_unreference(&shader->bo);
- ralloc_free(shader);
+ v3d_free_compiled_shader(shader);
_mesa_hash_table_remove(v3d->fs_cache, entry);
}
hash_table_foreach(v3d->vs_cache, entry) {
struct v3d_compiled_shader *shader = entry->data;
- v3d_bo_unreference(&shader->bo);
- ralloc_free(shader);
+ v3d_free_compiled_shader(shader);
_mesa_hash_table_remove(v3d->vs_cache, entry);
}
diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c
index 7db1285f11d..2016db7fa81 100644
--- a/src/gallium/drivers/v3d/v3dx_draw.c
+++ b/src/gallium/drivers/v3d/v3dx_draw.c
@@ -192,11 +192,14 @@ v3d_emit_gl_shader_state(struct v3d_context *v3d,
shader.fragment_shader_propagate_nans = true;
shader.coordinate_shader_code_address =
- cl_address(v3d->prog.cs->bo, 0);
+ cl_address(v3d_resource(v3d->prog.cs->resource)->bo,
+ v3d->prog.cs->offset);
shader.vertex_shader_code_address =
- cl_address(v3d->prog.vs->bo, 0);
+ cl_address(v3d_resource(v3d->prog.vs->resource)->bo,
+ v3d->prog.vs->offset);
shader.fragment_shader_code_address =
- cl_address(v3d->prog.fs->bo, 0);
+ cl_address(v3d_resource(v3d->prog.fs->resource)->bo,
+ v3d->prog.fs->offset);
/* XXX: Use combined input/output size flag in the common
* case.