From c90f221e0a1f89332189dd5ec79dccf6b251ecf5 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 28 Jun 2018 19:16:19 -0700 Subject: [PATCH] nir: Add a concept of constant data associated with a shader This commit adds a concept to NIR of having a blob of constant data associated with a shader. Instead of being a UBO or uniform that can be manipulated by the client, this constant data considered part of the shader and remains constant across all invocations of the given shader until the end of time. To access this constant data from the shader, we add a new load_constant intrinsic. The intention is that drivers will eventually lower load_constant intrinsics to load_ubo, load_uniform, or something similar. Constant data will be used by the optimization pass in the next commit but this concept may also be useful for OpenCL. v2 (Jason Ekstrand): - Rename num_constants to constant_data_size (anholt) Reviewed-by: Timothy Arceri Reviewed-by: Iago Toral Quiroga Reviewed-by: Kenneth Graunke --- src/compiler/nir/nir.h | 8 ++++++++ src/compiler/nir/nir_clone.c | 6 ++++++ src/compiler/nir/nir_intrinsics.py | 2 ++ src/compiler/nir/nir_serialize.c | 12 ++++++++++++ src/compiler/nir/nir_sweep.c | 2 ++ 5 files changed, 30 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index e35bef612df..cc5f88d6f54 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2067,6 +2067,14 @@ typedef struct nir_shader { * access plus one */ unsigned num_inputs, num_uniforms, num_outputs, num_shared; + + /** Constant data associated with this shader. + * + * Constant data is loaded through load_constant intrinsics. See also + * nir_opt_large_constants. + */ + void *constant_data; + unsigned constant_data_size; } nir_shader; static inline nir_function_impl * diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index 23bb17eeba3..989c5051a54 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -734,6 +734,12 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s) ns->num_outputs = s->num_outputs; ns->num_shared = s->num_shared; + ns->constant_data_size = s->constant_data_size; + if (s->constant_data_size > 0) { + ns->constant_data = ralloc_size(ns, s->constant_data_size); + memcpy(ns->constant_data, s->constant_data, s->constant_data_size); + } + free_clone_state(&state); return ns; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index d9d0bbdfccf..44a5b76beb6 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -532,6 +532,8 @@ load("per_vertex_output", 2, [BASE, COMPONENT], [CAN_ELIMINATE]) load("shared", 1, [BASE], [CAN_ELIMINATE]) # src[] = { offset }. const_index[] = { base, range } load("push_constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER]) +# src[] = { offset }. const_index[] = { base, range } +load("constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER]) # Stores work the same way as loads, except now the first source is the value # to store and the second (and possibly third) source specify where to store diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index cc4bf23aa0f..6a30738c2d7 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -1116,6 +1116,10 @@ nir_serialize(struct blob *blob, const nir_shader *nir) write_function_impl(&ctx, fxn->impl); } + blob_write_uint32(blob, nir->constant_data_size); + if (nir->constant_data_size > 0) + blob_write_bytes(blob, nir->constant_data, nir->constant_data_size); + *(uintptr_t *)(blob->data + idx_size_offset) = ctx.next_idx; _mesa_hash_table_destroy(ctx.remap_table, NULL); @@ -1169,6 +1173,14 @@ nir_deserialize(void *mem_ctx, nir_foreach_function(fxn, ctx.nir) fxn->impl = read_function_impl(&ctx, fxn); + ctx.nir->constant_data_size = blob_read_uint32(blob); + if (ctx.nir->constant_data_size > 0) { + ctx.nir->constant_data = + ralloc_size(ctx.nir, ctx.nir->constant_data_size); + blob_copy_bytes(blob, ctx.nir->constant_data, + ctx.nir->constant_data_size); + } + free(ctx.idx_table); return ctx.nir; diff --git a/src/compiler/nir/nir_sweep.c b/src/compiler/nir/nir_sweep.c index b14bf139c1b..aab641388db 100644 --- a/src/compiler/nir/nir_sweep.c +++ b/src/compiler/nir/nir_sweep.c @@ -167,6 +167,8 @@ nir_sweep(nir_shader *nir) sweep_function(nir, func); } + ralloc_steal(nir, nir->constant_data); + /* Free everything we didn't steal back. */ ralloc_free(rubbish); } -- 2.30.2