[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