[Mesa-dev] [PATCH 2/3] glsl/cs: Lower gl_GlobalInvocationID variable

Ilia Mirkin imirkin at alum.mit.edu
Fri Aug 7 14:59:26 PDT 2015


FWIW I would very much prefer that things like this stay at the GLSL
IR level, otherwise we'll have to duplicate it in st/mesa (or do it at
the GLSL IR level).

On Fri, Aug 7, 2015 at 5:56 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> Out of pure curiosity, why did you choose to do this at the GLSL IR
> level?  Why not pass it through to NIR and do the lowering there?  Not
> that you *should* do it there, but I'm curious as to what motivated
> the choice.  I'm honestly not sure which would have been easier.
> --Jason
>
> On Thu, Aug 6, 2015 at 11:01 AM, Jordan Justen
> <jordan.l.justen at intel.com> wrote:
>> We lower this based on the extension spec formula:
>>     gl_GlobalInvocationID =
>>         gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID
>>
>> Suggested-by: Kenneth Graunke <kenneth at whitecape.org>
>> Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
>> ---
>>  src/glsl/Makefile.sources       |   1 +
>>  src/glsl/ir_optimization.h      |   1 +
>>  src/glsl/linker.cpp             |   2 +
>>  src/glsl/lower_cs_global_id.cpp | 177 ++++++++++++++++++++++++++++++++++++++++
>>  4 files changed, 181 insertions(+)
>>  create mode 100644 src/glsl/lower_cs_global_id.cpp
>>
>> diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources
>> index a0e85ed..8b1aaae 100644
>> --- a/src/glsl/Makefile.sources
>> +++ b/src/glsl/Makefile.sources
>> @@ -144,6 +144,7 @@ LIBGLSL_FILES = \
>>         loop_unroll.cpp \
>>         lower_clip_distance.cpp \
>>         lower_const_arrays_to_uniforms.cpp \
>> +       lower_cs_global_id.cpp \
>>         lower_discard.cpp \
>>         lower_discard_flow.cpp \
>>         lower_if_to_cond_assign.cpp \
>> diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
>> index eef107e..7fb657c 100644
>> --- a/src/glsl/ir_optimization.h
>> +++ b/src/glsl/ir_optimization.h
>> @@ -136,6 +136,7 @@ void optimize_dead_builtin_variables(exec_list *instructions,
>>  bool lower_tess_level(gl_shader *shader);
>>
>>  bool lower_vertex_id(gl_shader *shader);
>> +bool lower_cs_global_id(gl_shader *shader);
>>
>>  bool lower_subroutine(exec_list *instructions, struct _mesa_glsl_parse_state *state);
>>
>> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
>> index e2da0af..f628198 100644
>> --- a/src/glsl/linker.cpp
>> +++ b/src/glsl/linker.cpp
>> @@ -2153,6 +2153,8 @@ link_intrastage_shaders(void *mem_ctx,
>>        }
>>     }
>>
>> +   lower_cs_global_id(linked);
>> +
>>     /* Make a pass over all variable declarations to ensure that arrays with
>>      * unspecified sizes have a size specified.  The size is inferred from the
>>      * max_array_access field.
>> diff --git a/src/glsl/lower_cs_global_id.cpp b/src/glsl/lower_cs_global_id.cpp
>> new file mode 100644
>> index 0000000..606b43c
>> --- /dev/null
>> +++ b/src/glsl/lower_cs_global_id.cpp
>> @@ -0,0 +1,177 @@
>> +/*
>> + * Copyright (c) 2014 Intel Corporation
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a
>> + * copy of this software and associated documentation files (the "Software"),
>> + * to deal in the Software without restriction, including without limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including the next
>> + * paragraph) shall be included in all copies or substantial portions of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> + * DEALINGS IN THE SOFTWARE.
>> + */
>> +
>> +/**
>> + * \file lower_cs_global_id.cpp
>> + *
>> + *  We lower this based on the extension spec formula:
>> + *      gl_GlobalInvocationID =
>> + *          gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID
>> + */
>> +
>> +#include "glsl_symbol_table.h"
>> +#include "ir_hierarchical_visitor.h"
>> +#include "ir.h"
>> +#include "ir_builder.h"
>> +#include "linker.h"
>> +#include "program/prog_statevars.h"
>> +
>> +namespace {
>> +
>> +class lower_cs_global_id_visitor : public ir_hierarchical_visitor {
>> +public:
>> +   explicit lower_cs_global_id_visitor(ir_function_signature *main_sig,
>> +                                    exec_list *ir_list)
>> +      : progress(false), GlobalInvocationID(NULL), gl_WorkGroupID(NULL),
>> +        gl_WorkGroupSize(NULL), gl_LocalInvocationID(NULL),
>> +        main_sig(main_sig), ir_list(ir_list)
>> +   {
>> +      foreach_in_list(ir_instruction, ir, ir_list) {
>> +         ir_variable *const var = ir->as_variable();
>> +
>> +         if (var == NULL)
>> +            continue;
>> +
>> +         if (var->data.mode == ir_var_system_value) {
>> +            if (var->data.location == SYSTEM_VALUE_WORK_GROUP_ID)
>> +               gl_WorkGroupID = var;
>> +            if (var->data.location == SYSTEM_VALUE_LOCAL_INVOCATION_ID)
>> +               gl_LocalInvocationID = var;
>> +         } else if (gl_WorkGroupSize == NULL &&
>> +                    var->data.mode == ir_var_auto &&
>> +                    var->data.read_only &&
>> +                    var->data.how_declared == ir_var_declared_implicitly &&
>> +                    var->name != NULL &&
>> +                    strcmp(var->name, "gl_WorkGroupSize") == 0) {
>> +            gl_WorkGroupSize = var;
>> +         } else
>> +            continue;
>> +         if (gl_WorkGroupID != NULL && gl_LocalInvocationID != NULL &&
>> +             gl_WorkGroupSize != NULL)
>> +            break;
>> +      }
>> +   }
>> +
>> +   virtual ir_visitor_status visit(ir_dereference_variable *);
>> +
>> +   bool progress;
>> +
>> +private:
>> +   ir_variable *GlobalInvocationID;
>> +   ir_variable *gl_WorkGroupID;
>> +   ir_variable *gl_WorkGroupSize;
>> +   ir_variable *gl_LocalInvocationID;
>> +
>> +   ir_function_signature *main_sig;
>> +   exec_list *ir_list;
>> +};
>> +
>> +} /* anonymous namespace */
>> +
>> +ir_visitor_status
>> +lower_cs_global_id_visitor::visit(ir_dereference_variable *ir)
>> +{
>> +   if (ir->var->data.mode != ir_var_system_value ||
>> +       ir->var->data.location != SYSTEM_VALUE_GLOBAL_INVOCATION_ID)
>> +      return visit_continue;
>> +
>> +   if (GlobalInvocationID == NULL) {
>> +      const glsl_type *const uvec3_t = glsl_type::uvec3_type;
>> +      void *const mem_ctx = ralloc_parent(ir);
>> +
>> +      GlobalInvocationID =
>> +         new(mem_ctx) ir_variable(uvec3_t, "__GlobalInvocationID",
>> +                                  ir_var_temporary);
>> +      ir_list->push_head(GlobalInvocationID);
>> +
>> +      if (gl_WorkGroupID == NULL) {
>> +         gl_WorkGroupID = new(mem_ctx) ir_variable(uvec3_t, "gl_WorkGroupID",
>> +                                                   ir_var_system_value);
>> +         gl_WorkGroupID->data.how_declared = ir_var_declared_implicitly;
>> +         gl_WorkGroupID->data.read_only = true;
>> +         gl_WorkGroupID->data.location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
>> +         gl_WorkGroupID->data.explicit_location = true;
>> +         gl_WorkGroupID->data.explicit_index = 0;
>> +         ir_list->push_head(gl_WorkGroupID);
>> +      }
>> +
>> +      if (gl_WorkGroupSize == NULL) {
>> +         gl_WorkGroupSize = new(mem_ctx) ir_variable(uvec3_t, "gl_WorkGroupSize",
>> +                                                     ir_var_auto);
>> +         gl_WorkGroupSize->data.how_declared = ir_var_declared_implicitly;
>> +         gl_WorkGroupSize->data.read_only = true;
>> +         ir_list->push_head(gl_WorkGroupSize);
>> +      }
>> +
>> +      if (gl_LocalInvocationID == NULL) {
>> +         gl_LocalInvocationID =
>> +            new(mem_ctx) ir_variable(uvec3_t, "gl_LocalInvocationID",
>> +                                     ir_var_system_value);
>> +         gl_LocalInvocationID->data.how_declared = ir_var_declared_implicitly;
>> +         gl_LocalInvocationID->data.read_only = true;
>> +         gl_LocalInvocationID->data.location = SYSTEM_VALUE_LOCAL_INVOCATION_ID;
>> +         gl_LocalInvocationID->data.explicit_location = true;
>> +         gl_LocalInvocationID->data.explicit_index = 0;
>> +         ir_list->push_head(gl_LocalInvocationID);
>> +      }
>> +
>> +      /**
>> +       *  gl_GlobalInvocationID =
>> +       *     gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID
>> +       */
>> +      ir_instruction *const inst =
>> +         ir_builder::assign(GlobalInvocationID,
>> +                            ir_builder::add(ir_builder::mul(gl_WorkGroupID,
>> +                                                            gl_WorkGroupSize),
>> +                                            gl_LocalInvocationID));
>> +
>> +      main_sig->body.push_head(inst);
>> +   }
>> +
>> +   ir->var = GlobalInvocationID;
>> +   progress = true;
>> +
>> +   return visit_continue;
>> +}
>> +
>> +bool
>> +lower_cs_global_id(gl_shader *shader)
>> +{
>> +   /* gl_GlobalInvocationID only exists in the compute shader.
>> +    */
>> +   if (shader->Stage != MESA_SHADER_COMPUTE)
>> +      return false;
>> +
>> +   ir_function_signature *const main_sig =
>> +      link_get_main_function_signature(shader);
>> +   if (main_sig == NULL) {
>> +      assert(main_sig != NULL);
>> +      return false;
>> +   }
>> +
>> +   lower_cs_global_id_visitor v(main_sig, shader->ir);
>> +
>> +   v.run(shader->ir);
>> +
>> +   return v.progress;
>> +}
>> --
>> 2.1.4
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list