Ejemplo n.º 1
0
ir_visitor_status
ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
{
   /* Note: for geometry shader inputs, lower_named_interface_blocks may
    * create 2D arrays, so we need to be able to handle those.  2D arrays
    * shouldn't be able to crop up for any other reason.
    */
   if (ir_dereference_array * const inner_array =
       ir->array->as_dereference_array()) {
      /*          ir => foo[i][j]
       * inner_array => foo[i]
       */
      if (ir_dereference_variable * const deref_var =
          inner_array->array->as_dereference_variable()) {
         if (this->shader_type == GL_GEOMETRY_SHADER &&
             deref_var->var->mode == ir_var_shader_in) {
            /* foo is a geometry shader input, so i is the vertex, and j the
             * part of the input we're accessing.
             */
            if (try_mark_partial_variable(deref_var->var, ir->array_index))
            {
               /* We've now taken care of foo and j, but i might contain a
                * subexpression that accesses shader inputs.  So manually
                * visit i and then continue with the parent.
                */
               inner_array->array_index->accept(this);
               return visit_continue_with_parent;
            }
         }
      }
   } else if (ir_dereference_variable * const deref_var =
              ir->array->as_dereference_variable()) {
      /* ir => foo[i], where foo is a variable. */
      if (this->shader_type == GL_GEOMETRY_SHADER &&
          deref_var->var->mode == ir_var_shader_in) {
         /* foo is a geometry shader input, so i is the vertex, and we're
          * accessing the entire input.
          */
         mark_whole_variable(deref_var->var);
         /* We've now taken care of foo, but i might contain a subexpression
          * that accesses shader inputs.  So manually visit i and then
          * continue with the parent.
          */
         ir->array_index->accept(this);
         return visit_continue_with_parent;
      } else if (is_shader_inout(deref_var->var)) {
         /* foo is a shader input/output, but not a geometry shader input,
          * so i is the part of the input we're accessing.
          */
         if (try_mark_partial_variable(deref_var->var, ir->array_index))
            return visit_continue_with_parent;
      }
   }

   /* The expression is something we don't recognize.  Just visit its
    * subexpressions.
    */
   return visit_continue;
}
/* Default handler: Mark all the locations in the variable as used. */
ir_visitor_status
ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
{
   if (!is_shader_inout(ir->var))
      return visit_continue;

   mark_whole_variable(ir->var);

   return visit_continue;
}