glsl/cs: Initialize gl_GlobalInvocationID in main()
authorJordan Justen <jordan.l.justen@intel.com>
Mon, 17 Aug 2015 21:35:44 +0000 (14:35 -0700)
committerJordan Justen <jordan.l.justen@intel.com>
Sun, 13 Sep 2015 16:53:16 +0000 (09:53 -0700)
We initialize gl_GlobalInvocationID based on the extension spec
formula:

    gl_GlobalInvocationID =
        gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID

https://www.opengl.org/registry/specs/ARB/compute_shader.txt

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
src/glsl/builtin_variables.cpp
src/glsl/glsl_parser_extras.cpp
src/glsl/ir.h

index fbcec353a4af96cde8b22ddce7649dea1efad985..34d4006f86f3c9e9e53d1b3c8c0db636269c718a 100644 (file)
@@ -22,6 +22,8 @@
  */
 
 #include "ir.h"
+#include "ir_builder.h"
+#include "linker.h"
 #include "glsl_parser_extras.h"
 #include "glsl_symbol_table.h"
 #include "main/core.h"
@@ -29,6 +31,8 @@
 #include "program/prog_statevars.h"
 #include "program/prog_instruction.h"
 
+using namespace ir_builder;
+
 static const struct gl_builtin_uniform_element gl_NumSamples_elements[] = {
    {NULL, {STATE_NUM_SAMPLES, 0, 0}, SWIZZLE_XXXX}
 };
@@ -1056,6 +1060,7 @@ builtin_variable_generator::generate_cs_special_vars()
    add_system_value(SYSTEM_VALUE_LOCAL_INVOCATION_ID, uvec3_t,
                     "gl_LocalInvocationID");
    add_system_value(SYSTEM_VALUE_WORK_GROUP_ID, uvec3_t, "gl_WorkGroupID");
+   add_variable("gl_GlobalInvocationID", uvec3_t, ir_var_auto, 0);
    /* TODO: finish this. */
 }
 
@@ -1207,3 +1212,65 @@ _mesa_glsl_initialize_variables(exec_list *instructions,
       break;
    }
 }
+
+
+/**
+ * Initialize compute shader variables with values that are derived from other
+ * compute shader variable.
+ */
+static void
+initialize_cs_derived_variables(gl_shader *shader,
+                                ir_function_signature *const main_sig)
+{
+   assert(shader->Stage == MESA_SHADER_COMPUTE);
+
+   ir_variable *gl_GlobalInvocationID =
+      shader->symbols->get_variable("gl_GlobalInvocationID");
+   assert(gl_GlobalInvocationID);
+   ir_variable *gl_WorkGroupID =
+      shader->symbols->get_variable("gl_WorkGroupID");
+   assert(gl_WorkGroupID);
+   ir_variable *gl_WorkGroupSize =
+      shader->symbols->get_variable("gl_WorkGroupSize");
+   if (gl_WorkGroupSize == NULL) {
+      void *const mem_ctx = ralloc_parent(shader->ir);
+      gl_WorkGroupSize = new(mem_ctx) ir_variable(glsl_type::uvec3_type,
+                                                  "gl_WorkGroupSize",
+                                                  ir_var_auto);
+      gl_WorkGroupSize->data.how_declared = ir_var_declared_implicitly;
+      gl_WorkGroupSize->data.read_only = true;
+      shader->ir->push_head(gl_WorkGroupSize);
+   }
+   ir_variable *gl_LocalInvocationID =
+      shader->symbols->get_variable("gl_LocalInvocationID");
+   assert(gl_LocalInvocationID);
+
+   /* gl_GlobalInvocationID =
+    *    gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID
+    */
+   ir_instruction *inst =
+      assign(gl_GlobalInvocationID,
+             add(mul(gl_WorkGroupID, gl_WorkGroupSize),
+                 gl_LocalInvocationID));
+   main_sig->body.push_head(inst);
+}
+
+
+/**
+ * Initialize builtin variables with values based on other builtin variables.
+ * These are initialized in the main function.
+ */
+void
+_mesa_glsl_initialize_derived_variables(gl_shader *shader)
+{
+   /* We only need to set CS variables currently. */
+   if (shader->Stage != MESA_SHADER_COMPUTE)
+      return;
+
+   ir_function_signature *const main_sig =
+      _mesa_get_main_function_signature(shader);
+   if (main_sig == NULL)
+      return;
+
+   initialize_cs_derived_variables(shader, main_sig);
+}
index fb76614133d2b8b041c7bbb1bd72d03f2b517fc6..dae5261dacac49d51ab543cb45d7a3d7e5fb4b6b 100644 (file)
@@ -1694,6 +1694,8 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
       }
    }
 
+   _mesa_glsl_initialize_derived_variables(shader);
+
    delete state->symbols;
    ralloc_free(state);
 }
index fce72a2d3c41975e1af7a9871a81fda8ef2809c1..f9ddf7442b0ddf815477b4068cc6ecdbdffb491c 100644 (file)
@@ -2513,6 +2513,9 @@ extern void
 _mesa_glsl_initialize_variables(exec_list *instructions,
                                struct _mesa_glsl_parse_state *state);
 
+extern void
+_mesa_glsl_initialize_derived_variables(gl_shader *shader);
+
 extern void
 _mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state);