[Mesa-dev] [PATCH 10/13] glsl: Add a lowering pass for gl_VertexID
Tapani Pälli
tapani.palli at intel.com
Tue Jul 29 23:51:36 PDT 2014
On 06/21/2014 04:01 AM, Ian Romanick 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)
> + {
This loop could be optimized a bit (?) by having shader as the
constructor parameter, initializing ir_list(shader->ir) and figuring out
variable from the symbol table:
var = shader->symbols->get_variable("gl_BaseVertex");
(would also need to add this variable to the symbol table when/if adding
it to IR below)
> + 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);
(with my proposal wouild need to
shader->symbols_add_variable("gl_BaseVertex"); here)
> + }
> +
> + 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.)
> */
More information about the mesa-dev
mailing list