On Fri, Aug 7, 2015 at 2:59 PM, Ilia Mirkin <imir...@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 <ja...@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.jus...@intel.com> wrote: >>> We lower this based on the extension spec formula: >>> gl_GlobalInvocationID = >>> gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID >>> >>> Suggested-by: Kenneth Graunke <kenn...@whitecape.org> >>> Signed-off-by: Jordan Justen <jordan.l.jus...@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@lists.freedesktop.org >>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev >> _______________________________________________ >> mesa-dev mailing list >> mesa-dev@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev