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

Jason Ekstrand jason at jlekstrand.net
Fri Aug 7 15:01:53 PDT 2015


On Fri, Aug 7, 2015 at 2:59 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> 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).

That's why you should start using nir_to_tgsi in st/mesa. :-P

> 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