Merge branch 'glsl-to-tgsi'
[mesa.git] / src / mesa / program / ir_to_mesa.cpp
index f27492749bd170fa86c3bbd1918e35c9fd9a452a..debadb9a398cea81c2009ba173a6afe7e8077a5e 100644 (file)
@@ -134,7 +134,7 @@ src_reg::src_reg(dst_reg reg)
    this->index = reg.index;
    this->swizzle = SWIZZLE_XYZW;
    this->negate = 0;
-   this->reladdr = NULL;
+   this->reladdr = reg.reladdr;
 }
 
 dst_reg::dst_reg(src_reg reg)
@@ -331,20 +331,6 @@ dst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP);
 
 dst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X);
 
-static void
-fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
-
-static void
-fail_link(struct gl_shader_program *prog, const char *fmt, ...)
-{
-   va_list args;
-   va_start(args, fmt);
-   ralloc_vasprintf_append(&prog->InfoLog, fmt, args);
-   va_end(args);
-
-   prog->LinkStatus = GL_FALSE;
-}
-
 static int
 swizzle_for_size(int size)
 {
@@ -789,10 +775,11 @@ ir_to_mesa_visitor::visit(ir_variable *ir)
 
       if (storage->file == PROGRAM_TEMPORARY &&
          dst.index != storage->index + (int) ir->num_state_slots) {
-        fail_link(this->shader_program,
-                  "failed to load builtin uniform `%s'  (%d/%d regs loaded)\n",
-                  ir->name, dst.index - storage->index,
-                  type_size(ir->type));
+        linker_error(this->shader_program,
+                     "failed to load builtin uniform `%s' "
+                     "(%d/%d regs loaded)\n",
+                     ir->name, dst.index - storage->index,
+                     type_size(ir->type));
       }
    }
 }
@@ -803,48 +790,44 @@ ir_to_mesa_visitor::visit(ir_loop *ir)
    ir_dereference_variable *counter = NULL;
 
    if (ir->counter != NULL)
-      counter = new(ir) ir_dereference_variable(ir->counter);
+      counter = new(mem_ctx) ir_dereference_variable(ir->counter);
 
    if (ir->from != NULL) {
       assert(ir->counter != NULL);
 
-      ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL);
+      ir_assignment *a =
+       new(mem_ctx) ir_assignment(counter, ir->from, NULL);
 
       a->accept(this);
-      delete a;
    }
 
    emit(NULL, OPCODE_BGNLOOP);
 
    if (ir->to) {
       ir_expression *e =
-        new(ir) ir_expression(ir->cmp, glsl_type::bool_type,
-                              counter, ir->to);
-      ir_if *if_stmt =  new(ir) ir_if(e);
+        new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type,
+                                         counter, ir->to);
+      ir_if *if_stmt =  new(mem_ctx) ir_if(e);
 
-      ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break);
+      ir_loop_jump *brk =
+       new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break);
 
       if_stmt->then_instructions.push_tail(brk);
 
       if_stmt->accept(this);
-
-      delete if_stmt;
-      delete e;
-      delete brk;
    }
 
    visit_exec_list(&ir->body_instructions, this);
 
    if (ir->increment) {
       ir_expression *e =
-        new(ir) ir_expression(ir_binop_add, counter->type,
-                              counter, ir->increment);
+        new(mem_ctx) ir_expression(ir_binop_add, counter->type,
+                                         counter, ir->increment);
 
-      ir_assignment *a = new(ir) ir_assignment(counter, e, NULL);
+      ir_assignment *a =
+       new(mem_ctx) ir_assignment(counter, e, NULL);
 
       a->accept(this);
-      delete a;
-      delete e;
    }
 
    emit(NULL, OPCODE_ENDLOOP);
@@ -1296,8 +1279,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]);
       break;
    case ir_unop_i2f:
+   case ir_unop_u2f:
    case ir_unop_b2f:
    case ir_unop_b2i:
+   case ir_unop_i2u:
+   case ir_unop_u2i:
       /* Mesa IR lacks types, ints are stored as truncated floats. */
       result_src = op[0];
       break;
@@ -1335,7 +1321,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       break;
 
    case ir_unop_bit_not:
-   case ir_unop_u2f:
    case ir_binop_lshift:
    case ir_binop_rshift:
    case ir_binop_bit_and:
@@ -1417,9 +1402,9 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
       case ir_var_in:
       case ir_var_inout:
         /* The linker assigns locations for varyings and attributes,
-         * including deprecated builtins (like gl_Color), user-assign
-         * generic attributes (glBindVertexLocation), and
-         * user-defined varyings.
+         * including deprecated builtins (like gl_Color),
+         * user-assigned generic attributes (glBindVertexLocation),
+         * and user-defined varyings.
          *
          * FINISHME: We would hit this path for function arguments.  Fix!
          */
@@ -1498,6 +1483,18 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
              this->result, src_reg_for_float(element_size));
       }
 
+      /* If there was already a relative address register involved, add the
+       * new and the old together to get the new offset.
+       */
+      if (src.reladdr != NULL)  {
+        src_reg accum_reg = get_temp(glsl_type::float_type);
+
+        emit(ir, OPCODE_ADD, dst_reg(accum_reg),
+             index_reg, *src.reladdr);
+
+        index_reg = accum_reg;
+      }
+
       src.reladdr = ralloc(mem_ctx, src_reg);
       memcpy(src.reladdr, &index_reg, sizeof(index_reg));
    }
@@ -2403,29 +2400,32 @@ check_resources(const struct gl_context *ctx,
    case GL_VERTEX_PROGRAM_ARB:
       if (_mesa_bitcount(prog->SamplersUsed) >
           ctx->Const.MaxVertexTextureImageUnits) {
-         fail_link(shader_program, "Too many vertex shader texture samplers");
+         linker_error(shader_program,
+                     "Too many vertex shader texture samplers");
       }
       if (prog->Parameters->NumParameters > MAX_UNIFORMS) {
-         fail_link(shader_program, "Too many vertex shader constants");
+         linker_error(shader_program, "Too many vertex shader constants");
       }
       break;
    case MESA_GEOMETRY_PROGRAM:
       if (_mesa_bitcount(prog->SamplersUsed) >
           ctx->Const.MaxGeometryTextureImageUnits) {
-         fail_link(shader_program, "Too many geometry shader texture samplers");
+         linker_error(shader_program,
+                     "Too many geometry shader texture samplers");
       }
       if (prog->Parameters->NumParameters >
           MAX_GEOMETRY_UNIFORM_COMPONENTS / 4) {
-         fail_link(shader_program, "Too many geometry shader constants");
+         linker_error(shader_program, "Too many geometry shader constants");
       }
       break;
    case GL_FRAGMENT_PROGRAM_ARB:
       if (_mesa_bitcount(prog->SamplersUsed) >
           ctx->Const.MaxTextureImageUnits) {
-         fail_link(shader_program, "Too many fragment shader texture samplers");
+         linker_error(shader_program,
+                     "Too many fragment shader texture samplers");
       }
       if (prog->Parameters->NumParameters > MAX_UNIFORMS) {
-         fail_link(shader_program, "Too many fragment shader constants");
+         linker_error(shader_program, "Too many fragment shader constants");
       }
       break;
    default:
@@ -2540,9 +2540,10 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
          * from _mesa_add_uniform) has to match what the linker chose.
          */
         if (index != parameter_index) {
-           fail_link(shader_program, "Allocation of uniform `%s' to target "
-                     "failed (%d vs %d)\n",
-                     uniform->Name, index, parameter_index);
+           linker_error(shader_program,
+                        "Allocation of uniform `%s' to target failed "
+                        "(%d vs %d)\n",
+                        uniform->Name, index, parameter_index);
         }
       }
    }
@@ -2575,8 +2576,8 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx,
    int loc = _mesa_get_uniform_location(ctx, shader_program, name);
 
    if (loc == -1) {
-      fail_link(shader_program,
-               "Couldn't find uniform for initializer %s\n", name);
+      linker_error(shader_program,
+                  "Couldn't find uniform for initializer %s\n", name);
       return;
    }
 
@@ -2976,11 +2977,31 @@ get_mesa_program(struct gl_context *ctx,
          if (mesa_inst->SrcReg[src].RelAddr)
             prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File;
 
-      if (options->EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
-        fail_link(shader_program, "Couldn't flatten if statement\n");
-      }
-
       switch (mesa_inst->Opcode) {
+      case OPCODE_IF:
+        if (options->EmitNoIfs) {
+           linker_warning(shader_program,
+                          "Couldn't flatten if-statement.  "
+                          "This will likely result in software "
+                          "rasterization.\n");
+        }
+        break;
+      case OPCODE_BGNLOOP:
+        if (options->EmitNoLoops) {
+           linker_warning(shader_program,
+                          "Couldn't unroll loop.  "
+                          "This will likely result in software "
+                          "rasterization.\n");
+        }
+        break;
+      case OPCODE_CONT:
+        if (options->EmitNoCont) {
+           linker_warning(shader_program,
+                          "Couldn't lower continue-statement.  "
+                          "This will likely result in software "
+                          "rasterization.\n");
+        }
+        break;
       case OPCODE_BGNSUB:
         inst->function->inst = i;
         mesa_inst->Comment = strdup(inst->function->sig->function_name());
@@ -3248,7 +3269,7 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
    for (i = 0; i < prog->NumShaders; i++) {
       if (!prog->Shaders[i]->CompileStatus) {
-        fail_link(prog, "linking with uncompiled shader");
+        linker_error(prog, "linking with uncompiled shader");
         prog->LinkStatus = GL_FALSE;
       }
    }