mesa: add & use a new driver flag for UBO updates instead of _NEW_BUFFER_OBJECT
[mesa.git] / src / mesa / drivers / dri / i915 / i915_fragprog.c
index b67ebb9a1ec2879b4d88b1ed477b68b78638838c..930c2b876bc9cb4ba50bebafe00ff05ec817112c 100644 (file)
@@ -97,43 +97,43 @@ src_vector(struct i915_fragment_program *p,
       break;
    case PROGRAM_INPUT:
       switch (source->Index) {
-      case FRAG_ATTRIB_WPOS:
+      case VARYING_SLOT_POS:
          src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL);
          break;
-      case FRAG_ATTRIB_COL0:
+      case VARYING_SLOT_COL0:
          src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
          break;
-      case FRAG_ATTRIB_COL1:
+      case VARYING_SLOT_COL1:
          src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ);
          src = swizzle(src, X, Y, Z, ONE);
          break;
-      case FRAG_ATTRIB_FOGC:
+      case VARYING_SLOT_FOGC:
          src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W);
          src = swizzle(src, W, ZERO, ZERO, ONE);
          break;
-      case FRAG_ATTRIB_TEX0:
-      case FRAG_ATTRIB_TEX1:
-      case FRAG_ATTRIB_TEX2:
-      case FRAG_ATTRIB_TEX3:
-      case FRAG_ATTRIB_TEX4:
-      case FRAG_ATTRIB_TEX5:
-      case FRAG_ATTRIB_TEX6:
-      case FRAG_ATTRIB_TEX7:
+      case VARYING_SLOT_TEX0:
+      case VARYING_SLOT_TEX1:
+      case VARYING_SLOT_TEX2:
+      case VARYING_SLOT_TEX3:
+      case VARYING_SLOT_TEX4:
+      case VARYING_SLOT_TEX5:
+      case VARYING_SLOT_TEX6:
+      case VARYING_SLOT_TEX7:
          src = i915_emit_decl(p, REG_TYPE_T,
-                              T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0),
+                              T_TEX0 + (source->Index - VARYING_SLOT_TEX0),
                               D0_CHANNEL_ALL);
         break;
 
-      case FRAG_ATTRIB_VAR0:
-      case FRAG_ATTRIB_VAR0 + 1:
-      case FRAG_ATTRIB_VAR0 + 2:
-      case FRAG_ATTRIB_VAR0 + 3:
-      case FRAG_ATTRIB_VAR0 + 4:
-      case FRAG_ATTRIB_VAR0 + 5:
-      case FRAG_ATTRIB_VAR0 + 6:
-      case FRAG_ATTRIB_VAR0 + 7:
+      case VARYING_SLOT_VAR0:
+      case VARYING_SLOT_VAR0 + 1:
+      case VARYING_SLOT_VAR0 + 2:
+      case VARYING_SLOT_VAR0 + 3:
+      case VARYING_SLOT_VAR0 + 4:
+      case VARYING_SLOT_VAR0 + 5:
+      case VARYING_SLOT_VAR0 + 6:
+      case VARYING_SLOT_VAR0 + 7:
          src = i915_emit_decl(p, REG_TYPE_T,
-                              T_TEX0 + (source->Index - FRAG_ATTRIB_VAR0),
+                              T_TEX0 + (source->Index - VARYING_SLOT_VAR0),
                               D0_CHANNEL_ALL);
          break;
 
@@ -173,12 +173,9 @@ src_vector(struct i915_fragment_program *p,
 
    case PROGRAM_CONSTANT:
    case PROGRAM_STATE_VAR:
-   case PROGRAM_NAMED_PARAM:
    case PROGRAM_UNIFORM:
-      src =
-         i915_emit_param4fv(p,
-                            program->Base.Parameters->ParameterValues[source->
-                                                                      Index]);
+      src = i915_emit_param4fv(p,
+        &program->Base.Parameters->ParameterValues[source->Index][0].f);
       break;
 
    default:
@@ -210,6 +207,7 @@ get_result_vector(struct i915_fragment_program *p,
    case PROGRAM_OUTPUT:
       switch (inst->DstReg.Index) {
       case FRAG_RESULT_COLOR:
+      case FRAG_RESULT_DATA0:
          return UREG(REG_TYPE_OC, 0);
       case FRAG_RESULT_DEPTH:
          p->depth_written = 1;
@@ -302,11 +300,11 @@ do {                                                                      \
 /* 
  * TODO: consider moving this into core 
  */
-static void calc_live_regs( struct i915_fragment_program *p )
+static bool calc_live_regs( struct i915_fragment_program *p )
 {
     const struct gl_fragment_program *program = &p->FragProg;
-    GLuint regsUsed = 0xffff0000;
-    uint8_t live_components[16] = { 0, };
+    GLuint regsUsed = ~((1 << I915_MAX_TEMPORARY) - 1);
+    uint8_t live_components[I915_MAX_TEMPORARY] = { 0, };
     GLint i;
    
     for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
@@ -316,6 +314,9 @@ static void calc_live_regs( struct i915_fragment_program *p )
 
         /* Register is written to: unmark as live for this and preceeding ops */ 
         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+           if (inst->DstReg.Index >= I915_MAX_TEMPORARY)
+              return false;
+
             live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask;
             if (live_components[inst->DstReg.Index] == 0)
                 regsUsed &= ~(1 << inst->DstReg.Index);
@@ -326,6 +327,9 @@ static void calc_live_regs( struct i915_fragment_program *p )
             if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) {
                 unsigned c;
 
+               if (inst->SrcReg[a].Index >= I915_MAX_TEMPORARY)
+                  return false;
+
                 regsUsed |= 1 << inst->SrcReg[a].Index;
 
                 for (c = 0; c < 4; c++) {
@@ -339,6 +343,8 @@ static void calc_live_regs( struct i915_fragment_program *p )
 
         p->usedRegs[i] = regsUsed;
     }
+
+    return true;
 }
 
 static GLuint get_live_regs( struct i915_fragment_program *p, 
@@ -393,7 +399,10 @@ upload_program(struct i915_fragment_program *p)
 
    /* Not always needed:
     */
-   calc_live_regs(p);
+   if (!calc_live_regs(p)) {
+      i915_program_error(p, "Could not allocate registers");
+      return;
+   }
 
    while (1) {
       GLuint src0, src1, src2, flags;
@@ -1078,7 +1087,6 @@ upload_program(struct i915_fragment_program *p)
 
       case OPCODE_BGNLOOP:
       case OPCODE_BGNSUB:
-      case OPCODE_BRA:
       case OPCODE_BRK:
       case OPCODE_CAL:
       case OPCODE_CONT:
@@ -1138,21 +1146,21 @@ fixup_depth_write(struct i915_fragment_program *p)
 static void
 check_wpos(struct i915_fragment_program *p)
 {
-   GLuint inputs = p->FragProg.Base.InputsRead;
+   GLbitfield64 inputs = p->FragProg.Base.InputsRead;
    GLint i;
 
    p->wpos_tex = -1;
 
    for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
-      if (inputs & (FRAG_BIT_TEX(i) | FRAG_BIT_VAR(i)))
+      if (inputs & (VARYING_BIT_TEX(i) | VARYING_BIT_VAR(i)))
          continue;
-      else if (inputs & FRAG_BIT_WPOS) {
+      else if (inputs & VARYING_BIT_POS) {
          p->wpos_tex = i;
-         inputs &= ~FRAG_BIT_WPOS;
+         inputs &= ~VARYING_BIT_POS;
       }
    }
 
-   if (inputs & FRAG_BIT_WPOS) {
+   if (inputs & VARYING_BIT_POS) {
       i915_program_error(p, "No free texcoord for wpos value");
    }
 }
@@ -1275,7 +1283,7 @@ i915IsProgramNative(struct gl_context * ctx, GLenum target, struct gl_program *p
       return !p->error;
    }
    else
-      return GL_TRUE;
+      return true;
 }
 
 static GLboolean
@@ -1290,7 +1298,14 @@ i915ProgramStringNotify(struct gl_context * ctx,
    (void) _tnl_program_string(ctx, target, prog);
 
    /* XXX check if program is legal, within limits */
-   return GL_TRUE;
+   return true;
+}
+
+static void
+i915SamplerUniformChange(struct gl_context *ctx,
+                         GLenum target, struct gl_program *prog)
+{
+   i915ProgramStringNotify(ctx, target, prog);
 }
 
 void
@@ -1327,7 +1342,7 @@ i915ValidateFragmentProgram(struct i915_context *i915)
    struct i915_fragment_program *p =
       (struct i915_fragment_program *) ctx->FragmentProgram._Current;
 
-   const GLuint inputsRead = p->FragProg.Base.InputsRead;
+   const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead;
    GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
    GLuint s2 = S2_TEXCOORD_NONE;
    int i, offset = 0;
@@ -1341,33 +1356,36 @@ i915ValidateFragmentProgram(struct i915_context *i915)
 
    intel->vertex_attr_count = 0;
    intel->wpos_offset = 0;
-   intel->wpos_size = 0;
    intel->coloroffset = 0;
    intel->specoffset = 0;
 
-   if (inputsRead & FRAG_BITS_TEX_ANY) {
+   if (inputsRead & VARYING_BITS_TEX_ANY || p->wpos_tex != -1) {
       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16);
    }
    else {
       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12);
    }
 
-   if (inputsRead & FRAG_BIT_COL0) {
+   /* Handle gl_PointSize builtin var here */
+   if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled)
+      EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4);
+
+   if (inputsRead & VARYING_BIT_COL0) {
       intel->coloroffset = offset / 4;
       EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4);
    }
 
-   if (inputsRead & FRAG_BIT_COL1) {
+   if (inputsRead & VARYING_BIT_COL1) {
        intel->specoffset = offset / 4;
        EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_4UB_4F_BGRA, S4_VFMT_SPEC_FOG, 4);
    }
 
-   if ((inputsRead & FRAG_BIT_FOGC)) {
+   if ((inputsRead & VARYING_BIT_FOGC)) {
       EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
    }
 
    for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
-      if (inputsRead & FRAG_BIT_TEX(i)) {
+      if (inputsRead & VARYING_BIT_TEX(i)) {
          int sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
 
          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
@@ -1375,7 +1393,7 @@ i915ValidateFragmentProgram(struct i915_context *i915)
 
          EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
       }
-      else if (inputsRead & FRAG_BIT_VAR(i)) {
+      else if (inputsRead & VARYING_BIT_VAR(i)) {
          int sz = VB->AttribPtr[_TNL_ATTRIB_GENERIC0 + i]->size;
 
          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
@@ -1384,17 +1402,15 @@ i915ValidateFragmentProgram(struct i915_context *i915)
          EMIT_ATTR(_TNL_ATTRIB_GENERIC0 + i, EMIT_SZ(sz), 0, sz * 4);
       }
       else if (i == p->wpos_tex) {
-
+        int wpos_size = 4 * sizeof(float);
          /* If WPOS is required, duplicate the XYZ position data in an
           * unused texture coordinate:
           */
          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
-         s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3));
+         s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(wpos_size));
 
          intel->wpos_offset = offset;
-         intel->wpos_size = 3 * sizeof(GLuint);
-
-         EMIT_PAD(intel->wpos_size);
+         EMIT_PAD(wpos_size);
       }
    }
 
@@ -1445,4 +1461,5 @@ i915InitFragProgFuncs(struct dd_function_table *functions)
    functions->DeleteProgram = i915DeleteProgram;
    functions->IsProgramNative = i915IsProgramNative;
    functions->ProgramStringNotify = i915ProgramStringNotify;
+   functions->SamplerUniformChange = i915SamplerUniformChange;
 }