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 <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