[Mesa-dev] [PATCH 10/13] glsl: Add a lowering pass for gl_VertexID

Ian Romanick idr at freedesktop.org
Mon Jun 23 10:47:13 PDT 2014


On 06/22/2014 04:32 AM, Marek Olšák wrote:
> If you define enums in a struct or class, it then works like a
> namespace. E.g. the proper form to use such an enum would be:
> 
> ctx->Const.VertexID = gl_constants::gl_VertexID_native;

I'd swear that I tried that... I know I tried a bunch of other
variations that failed.  Anyway, I'll change it to have the enum inside
the struct.

Thanks for the tip.

> Marek
> 
> On Sat, Jun 21, 2014 at 3:01 AM, Ian Romanick <idr at freedesktop.org> wrote:
>> From: Ian Romanick <ian.d.romanick at intel.com>
>>
>> Converts gl_VertexID to (gl_VertexIDMESA + gl_BaseVertex). gl_VertexIDMESA
>> is backed by SYSTEM_VALUE_VERTEX_ID_ZERO_BASE, and gl_BaseVertex is backed
>> by a built-in uniform from {STATE_INTERNAL, STATE_BASE_VERTEX}.
>>
>> NOTE: The enum has to be declared outside the struct or C++ just cannot
>> find the values.  I tried many variations of scope resolution in
>> linker.cpp, but could not make it do-the-right-thing.
>>
>> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>> Cc: "10.2" <mesa-stable at lists.freedesktop.org>
>> ---
>>  src/glsl/Makefile.sources    |   1 +
>>  src/glsl/ir_optimization.h   |   2 +
>>  src/glsl/linker.cpp          |   7 ++
>>  src/glsl/lower_vertex_id.cpp | 152 +++++++++++++++++++++++++++++++++++++++++++
>>  src/mesa/main/context.c      |   5 ++
>>  src/mesa/main/mtypes.h       |  14 ++++
>>  6 files changed, 181 insertions(+)
>>  create mode 100644 src/glsl/lower_vertex_id.cpp
>>
>> diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources
>> index b54eae7..b884d66 100644
>> --- a/src/glsl/Makefile.sources
>> +++ b/src/glsl/Makefile.sources
>> @@ -77,6 +77,7 @@ LIBGLSL_FILES = \
>>         $(GLSL_SRCDIR)/lower_vec_index_to_swizzle.cpp \
>>         $(GLSL_SRCDIR)/lower_vector.cpp \
>>         $(GLSL_SRCDIR)/lower_vector_insert.cpp \
>> +       $(GLSL_SRCDIR)/lower_vertex_id.cpp \
>>         $(GLSL_SRCDIR)/lower_output_reads.cpp \
>>         $(GLSL_SRCDIR)/lower_ubo_reference.cpp \
>>         $(GLSL_SRCDIR)/opt_algebraic.cpp \
>> diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
>> index b83c225..2892dc2 100644
>> --- a/src/glsl/ir_optimization.h
>> +++ b/src/glsl/ir_optimization.h
>> @@ -125,6 +125,8 @@ bool optimize_redundant_jumps(exec_list *instructions);
>>  bool optimize_split_arrays(exec_list *instructions, bool linked);
>>  bool lower_offset_arrays(exec_list *instructions);
>>
>> +bool lower_vertex_id(gl_shader *shader);
>> +
>>  ir_rvalue *
>>  compare_index_block(exec_list *instructions, ir_variable *index,
>>                     unsigned base, unsigned components, void *mem_ctx);
>> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
>> index 813108c..2e9a0b6 100644
>> --- a/src/glsl/linker.cpp
>> +++ b/src/glsl/linker.cpp
>> @@ -1623,6 +1623,13 @@ link_intrastage_shaders(void *mem_ctx,
>>        }
>>     }
>>
>> +   if (ctx->Const.VertexID != gl_VertexID_native) {
>> +      /* FINISHME: The other lowering method is not yet implemented.
>> +       */
>> +      assert(ctx->Const.VertexID == gl_VertexID_using_uniform_gl_BaseVertex);
>> +      lower_vertex_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_vertex_id.cpp b/src/glsl/lower_vertex_id.cpp
>> new file mode 100644
>> index 0000000..c9cced1
>> --- /dev/null
>> +++ b/src/glsl/lower_vertex_id.cpp
>> @@ -0,0 +1,152 @@
>> +/*
>> + * Copyright © 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_vertex_id.cpp
>> + *
>> + * There exists hardware, such as i965, that does not implement the OpenGL
>> + * semantic for gl_VertexID.  Instead, that hardware does not include the
>> + * value of basevertex in the gl_VertexID value.  To implement the OpenGL
>> + * semantic, we'll have to convert gl_Vertex_ID to
>> + * gl_VertexIDMESA+gl_BaseVertexMESA.
>> + */
>> +
>> +#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_vertex_id_visitor : public ir_hierarchical_visitor {
>> +public:
>> +   explicit lower_vertex_id_visitor(ir_function_signature *main_sig,
>> +                                    exec_list *ir_list)
>> +      : progress(false), VertexID(NULL), gl_VertexID(NULL),
>> +        gl_BaseVertex(NULL), main_sig(main_sig), ir_list(ir_list)
>> +   {
>> +      foreach_list(node, ir_list) {
>> +         ir_instruction *const ir = (ir_instruction *) node;
>> +         ir_variable *const var = ir->as_variable();
>> +
>> +         if (var != NULL && strcmp(var->name, "gl_BaseVertex") == 0) {
>> +            gl_BaseVertex = var;
>> +            break;
>> +         }
>> +      }
>> +   }
>> +
>> +   virtual ir_visitor_status visit(ir_dereference_variable *);
>> +
>> +   bool progress;
>> +
>> +private:
>> +   ir_variable *VertexID;
>> +   ir_variable *gl_VertexID;
>> +   ir_variable *gl_BaseVertex;
>> +
>> +   ir_function_signature *main_sig;
>> +   exec_list *ir_list;
>> +};
>> +
>> +} /* anonymous namespace */
>> +
>> +ir_visitor_status
>> +lower_vertex_id_visitor::visit(ir_dereference_variable *ir)
>> +{
>> +   if (strcmp(ir->var->name, "gl_VertexID") != 0)
>> +      return visit_continue;
>> +
>> +   if (VertexID == NULL) {
>> +      const glsl_type *const int_t = glsl_type::int_type;
>> +      void *const mem_ctx = ralloc_parent(ir);
>> +
>> +      VertexID = new(mem_ctx) ir_variable(int_t, "__VertexID",
>> +                                          ir_var_temporary);
>> +      ir_list->push_head(VertexID);
>> +
>> +      gl_VertexID = new(mem_ctx) ir_variable(int_t, "gl_VertexIDMESA",
>> +                                             ir_var_system_value);
>> +      gl_VertexID->data.how_declared = ir_var_declared_implicitly;
>> +      gl_VertexID->data.read_only = true;
>> +      gl_VertexID->data.location = SYSTEM_VALUE_VERTEX_ID_ZERO_BASE;
>> +      gl_VertexID->data.explicit_location = true;
>> +      gl_VertexID->data.explicit_index = 0;
>> +      ir_list->push_head(gl_VertexID);
>> +
>> +      if (gl_BaseVertex == NULL) {
>> +         static const int slots[STATE_LENGTH] = {
>> +            STATE_INTERNAL,
>> +            STATE_BASE_VERTEX,
>> +            0,
>> +            0,
>> +            0
>> +         };
>> +
>> +         gl_BaseVertex = new(mem_ctx) ir_variable(int_t, "gl_BaseVertex",
>> +                                                  ir_var_uniform);
>> +         gl_BaseVertex->num_state_slots = 1;
>> +         gl_BaseVertex->state_slots =
>> +            ralloc_array(gl_BaseVertex, ir_state_slot,
>> +                         gl_BaseVertex->num_state_slots);
>> +         memcpy(gl_BaseVertex->state_slots, slots, sizeof(slots));
>> +
>> +         ir_list->push_head(gl_BaseVertex);
>> +      }
>> +
>> +      ir_instruction *const inst =
>> +         ir_builder::assign(VertexID,
>> +                            ir_builder::add(gl_VertexID, gl_BaseVertex));
>> +
>> +      main_sig->body.push_head(inst);
>> +   }
>> +
>> +   ir->var = VertexID;
>> +   progress = true;
>> +
>> +   return visit_continue;
>> +}
>> +
>> +bool
>> +lower_vertex_id(gl_shader *shader)
>> +{
>> +   /* gl_VertexID only exists in the vertex shader.
>> +    */
>> +   if (shader->Stage != MESA_SHADER_VERTEX)
>> +      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_vertex_id_visitor v(main_sig, shader->ir);
>> +
>> +   v.run(shader->ir);
>> +
>> +   return v.progress;
>> +}
>> diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
>> index 244e63e..40a3a2c 100644
>> --- a/src/mesa/main/context.c
>> +++ b/src/mesa/main/context.c
>> @@ -622,6 +622,11 @@ _mesa_init_constants(struct gl_context *ctx)
>>     ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
>>     ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
>>
>> +   /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that
>> +    * gl_VertexID is implemented using a native hardware register.
>> +    */
>> +   ctx->Const.VertexID = gl_VertexID_native;
>> +
>>     /* CheckArrayBounds is overriden by drivers/x11 for X server */
>>     ctx->Const.CheckArrayBounds = GL_FALSE;
>>
>> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
>> index c66a16a..e581008 100644
>> --- a/src/mesa/main/mtypes.h
>> +++ b/src/mesa/main/mtypes.h
>> @@ -3335,6 +3335,11 @@ struct gl_program_constants
>>     GLuint MaxImageUniforms;
>>  };
>>
>> +enum _mesa_VertexID_mode {
>> +   gl_VertexID_native,
>> +   gl_VertexID_using_system_gl_BaseVertex,
>> +   gl_VertexID_using_uniform_gl_BaseVertex
>> +};
>>
>>  /**
>>   * Constants which may be overridden by device driver during context creation
>> @@ -3444,6 +3449,15 @@ struct gl_constants
>>     GLboolean NativeIntegers;
>>
>>     /**
>> +    * Method used to implement gl_VertexID
>> +    *
>> +    * \note
>> +    * If desktop GLSL 1.30 or GLSL ES 3.00 are not supported, this field is
>> +    * ignored and need not be set.
>> +    */
>> +   enum _mesa_VertexID_mode VertexID;
>> +
>> +   /**
>>      * If the driver supports real 32-bit integers, what integer value should be
>>      * used for boolean true in uniform uploads?  (Usually 1 or ~0.)
>>      */
>> --
>> 1.8.1.4
>>
>> _______________________________________________
>> 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