[Mesa-dev] [PATCH 2/6] nir: Add a concept of constant data associated with a shader

Jason Ekstrand jason at jlekstrand.net
Fri Jun 29 20:06:51 UTC 2018


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.
---
 src/compiler/nir/nir.h             |  9 ++++++++-
 src/compiler/nir/nir_clone.c       |  6 ++++++
 src/compiler/nir/nir_intrinsics.py |  2 ++
 src/compiler/nir/nir_serialize.c   | 10 ++++++++++
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index e35bef612df..6c49bce9aaa 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2038,6 +2038,13 @@ typedef struct nir_shader {
    /** list of shared compute variables (nir_variable) */
    struct exec_list shared;
 
+   /** Constant data associated with this shader.
+    *
+    * Constant data is loaded through load_constant intrinsics.  See also
+    * nir_opt_large_constants.
+    */
+   void *constant_data;
+
    /** Set of driver-specific options for the shader.
     *
     * The memory for the options is expected to be kept in a single static
@@ -2066,7 +2073,7 @@ typedef struct nir_shader {
     * the highest index a load_input_*, load_uniform_*, etc. intrinsic can
     * access plus one
     */
-   unsigned num_inputs, num_uniforms, num_outputs, num_shared;
+   unsigned num_inputs, num_uniforms, num_outputs, num_shared, num_constants;
 } 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..1adfaccc54d 100644
--- a/src/compiler/nir/nir_clone.c
+++ b/src/compiler/nir/nir_clone.c
@@ -733,6 +733,12 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s)
    ns->num_uniforms = s->num_uniforms;
    ns->num_outputs = s->num_outputs;
    ns->num_shared = s->num_shared;
+   ns->num_constants = s->num_constants;
+
+   if (s->num_constants > 0) {
+      ns->constant_data = ralloc_size(ns, s->num_constants);
+      memcpy(ns->constant_data, s->constant_data, s->num_constants);
+   }
 
    free_clone_state(&state);
 
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..2f2ecc9b270 100644
--- a/src/compiler/nir/nir_serialize.c
+++ b/src/compiler/nir/nir_serialize.c
@@ -1106,6 +1106,10 @@ nir_serialize(struct blob *blob, const nir_shader *nir)
    blob_write_uint32(blob, nir->num_uniforms);
    blob_write_uint32(blob, nir->num_outputs);
    blob_write_uint32(blob, nir->num_shared);
+   blob_write_uint32(blob, nir->num_constants);
+
+   if (nir->num_constants > 0)
+      blob_write_bytes(blob, nir->constant_data, nir->num_constants);
 
    blob_write_uint32(blob, exec_list_length(&nir->functions));
    nir_foreach_function(fxn, nir) {
@@ -1161,6 +1165,12 @@ nir_deserialize(void *mem_ctx,
    ctx.nir->num_uniforms = blob_read_uint32(blob);
    ctx.nir->num_outputs = blob_read_uint32(blob);
    ctx.nir->num_shared = blob_read_uint32(blob);
+   ctx.nir->num_constants = blob_read_uint32(blob);
+
+   if (ctx.nir->num_constants > 0) {
+      ctx.nir->constant_data = ralloc_size(ctx.nir, ctx.nir->num_constants);
+      blob_copy_bytes(blob, ctx.nir->constant_data, ctx.nir->num_constants);
+   }
 
    unsigned num_functions = blob_read_uint32(blob);
    for (unsigned i = 0; i < num_functions; i++)
-- 
2.17.1



More information about the mesa-dev mailing list