Пример #1
0
ir_visitor_status
ir_constant_folding_visitor::visit_enter(ir_assignment *ir)
{
   ir->rhs->accept(this);
   handle_rvalue(&ir->rhs);

   if (ir->condition) {
      ir->condition->accept(this);
      handle_rvalue(&ir->condition);

      ir_constant *const_val = ir->condition->as_constant();
      /* If the condition is constant, either remove the condition or
       * remove the never-executed assignment.
       */
      if (const_val) {
	 if (const_val->value.b[0])
	    ir->condition = NULL;
	 else
	    ir->remove();
	 this->progress = true;
      }
   }

   /* Don't descend into the LHS because we want it to stay as a
    * variable dereference.  FINISHME: We probably should to get array
    * indices though.
    */
   return visit_continue_with_parent;
}
Пример #2
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
{
   handle_rvalue(&ir->coordinate);
   handle_rvalue(&ir->projector);
   handle_rvalue(&ir->shadow_comparitor);
   handle_rvalue(&ir->offset);

   switch (ir->op) {
   case ir_tex:
   case ir_lod:
   case ir_query_levels:
      break;
   case ir_txb:
      handle_rvalue(&ir->lod_info.bias);
      break;
   case ir_txf:
   case ir_txl:
   case ir_txs:
      handle_rvalue(&ir->lod_info.lod);
      break;
   case ir_txf_ms:
      handle_rvalue(&ir->lod_info.sample_index);
      break;
   case ir_txd:
      handle_rvalue(&ir->lod_info.grad.dPdx);
      handle_rvalue(&ir->lod_info.grad.dPdy);
      break;
   case ir_tg4:
      handle_rvalue(&ir->lod_info.component);
      break;
   }

   return visit_continue;
}
Пример #3
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir)
{
   handle_rvalue(&ir->rhs);
   handle_rvalue(&ir->condition);

   return visit_continue;
}
Пример #4
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_dereference_array *ir)
{
   /* The array index is not the target of the assignment, so clear the
    * 'in_assignee' flag.  Restore it after returning from the array index.
    */
   const bool was_in_assignee = this->in_assignee;
   this->in_assignee = false;
   handle_rvalue(&ir->array_index);
   this->in_assignee = was_in_assignee;

   handle_rvalue(&ir->array);
   return visit_continue;
}
Пример #5
0
ir_visitor_status
ir_rvalue_visitor::visit_leave(ir_texture *ir)
{
   handle_rvalue(&ir->coordinate);
   handle_rvalue(&ir->projector);
   handle_rvalue(&ir->shadow_comparitor);
   handle_rvalue(&ir->offset);

   switch (ir->op) {
   case ir_tex:
      break;
   case ir_txb:
      handle_rvalue(&ir->lod_info.bias);
      break;
   case ir_txf:
   case ir_txl:
      handle_rvalue(&ir->lod_info.lod);
      break;
   case ir_txd:
      handle_rvalue(&ir->lod_info.grad.dPdx);
      handle_rvalue(&ir->lod_info.grad.dPdy);
      break;
   }

   return visit_continue;
}
Пример #6
0
/**
 * Replace any assignment having gl_ClipDistance (undereferenced) as its LHS
 * or RHS with a sequence of assignments, one for each component of the array.
 * Each of these assignments is lowered to refer to gl_ClipDistanceMESA as
 * appropriate.
 */
ir_visitor_status
lower_clip_distance_visitor::visit_leave(ir_assignment *ir)
{
   ir_dereference_variable *lhs_var = ir->lhs->as_dereference_variable();
   ir_dereference_variable *rhs_var = ir->rhs->as_dereference_variable();
   if ((lhs_var && lhs_var->var == this->old_clip_distance_var)
       || (rhs_var && rhs_var->var == this->old_clip_distance_var)) {
      /* LHS or RHS of the assignment is the entire gl_ClipDistance array.
       * Since we are reshaping gl_ClipDistance from an array of floats to an
       * array of vec4's, this isn't going to work as a bulk assignment
       * anymore, so unroll it to element-by-element assignments and lower
       * each of them.
       *
       * Note: to unroll into element-by-element assignments, we need to make
       * clones of the LHS and RHS.  This is safe because expressions and
       * l-values are side-effect free.
       */
      void *ctx = ralloc_parent(ir);
      int array_size = this->old_clip_distance_var->type->array_size();
      for (int i = 0; i < array_size; ++i) {
         ir_dereference_array *new_lhs = new(ctx) ir_dereference_array(
            ir->lhs->clone(ctx, NULL), new(ctx) ir_constant(i));
         ir_dereference_array *new_rhs = new(ctx) ir_dereference_array(
            ir->rhs->clone(ctx, NULL), new(ctx) ir_constant(i));
         this->handle_rvalue((ir_rvalue **) &new_rhs);

         /* Handle the LHS after creating the new assignment.  This must
          * happen in this order because handle_rvalue may replace the old LHS
          * with an ir_expression of ir_binop_vector_extract.  Since this is
          * not a valide l-value, this will cause an assertion in the
          * ir_assignment constructor to fail.
          *
          * If this occurs, replace the mangled LHS with a dereference of the
          * vector, and replace the RHS with an ir_triop_vector_insert.
          */
         ir_assignment *const assign = new(ctx) ir_assignment(new_lhs, new_rhs);
         this->handle_rvalue((ir_rvalue **) &assign->lhs);
         this->fix_lhs(assign);

         this->base_ir->insert_before(assign);
      }
      ir->remove();

      return visit_continue;
   }

   /* Handle the LHS as if it were an r-value.  Normally
    * rvalue_visit(ir_assignment *) only visits the RHS, but we need to lower
    * expressions in the LHS as well.
    *
    * This may cause the LHS to get replaced with an ir_expression of
    * ir_binop_vector_extract.  If this occurs, replace it with a dereference
    * of the vector, and replace the RHS with an ir_triop_vector_insert.
    */
   handle_rvalue((ir_rvalue **)&ir->lhs);
   this->fix_lhs(ir);

   return rvalue_visit(ir);
}
Пример #7
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
{
   handle_rvalue(&ir->coordinate);
   handle_rvalue(&ir->offset);

   switch (ir->op) {
   case ir_tex:
   case ir_lod:
      break;
   case ir_txb:
      handle_rvalue(&ir->lod_info.bias);
      break;
   case ir_txf:
   case ir_txl:
   case ir_txs:
      handle_rvalue(&ir->lod_info.lod);
      break;
   case ir_txf_ms:
      handle_rvalue(&ir->lod_info.sample_index);
      break;
   case ir_txd:
      handle_rvalue(&ir->lod_info.grad.dPdx);
      handle_rvalue(&ir->lod_info.grad.dPdy);
      break;
   }

   return visit_continue;
}
Пример #8
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_expression *ir)
{
   unsigned int operand;

   for (operand = 0; operand < ir->get_num_operands(); operand++) {
      handle_rvalue(&ir->operands[operand]);
   }

   return visit_continue;
}
Пример #9
0
ir_visitor_status
ir_constant_folding_visitor::visit_enter(ir_discard *ir)
{
   if (ir->condition) {
      ir->condition->accept(this);
      handle_rvalue(&ir->condition);

      ir_constant *const_val = ir->condition->as_constant();
      /* If the condition is constant, either remove the condition or
       * remove the never-executed assignment.
       */
      if (const_val) {
         if (const_val->value.b[0])
            ir->condition = NULL;
         else
            ir->remove();
         this->progress = true;
      }
   }

   return visit_continue_with_parent;
}
Пример #10
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_swizzle *ir)
{
   handle_rvalue(&ir->val);
   return visit_continue;
}
Пример #11
0
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_dereference_record *ir)
{
   handle_rvalue(&ir->record);
   return visit_continue;
}