i965/vec4: Generate URB writes using a loop.
[mesa.git] / src / mesa / drivers / dri / r200 / r200_vertprog.c
index 5d268319f3f76cddcbfcd92b8154f7f891940eaa..461b7cb55a84d805d7c7dab4230d52327acb0be9 100644 (file)
@@ -95,12 +95,11 @@ static struct{
    OPN(SUB, 2),
    OPN(SWZ, 1),
    OPN(XPD, 2),
-   OPN(PRINT, 0),
    OPN(END, 0),
 };
 #undef OPN
 
-static GLboolean r200VertexProgUpdateParams(GLcontext *ctx, struct r200_vertex_program *vp)
+static GLboolean r200VertexProgUpdateParams(struct gl_context *ctx, struct r200_vertex_program *vp)
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    GLfloat *fcmd = (GLfloat *)&rmesa->hw.vpp[0].cmd[VPP_CMD_0 + 1];
@@ -123,13 +122,12 @@ static GLboolean r200VertexProgUpdateParams(GLcontext *ctx, struct r200_vertex_p
    for(pi = 0; pi < paramList->NumParameters; pi++) {
       switch(paramList->Parameters[pi].Type) {
       case PROGRAM_STATE_VAR:
-      case PROGRAM_NAMED_PARAM:
       //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);
       case PROGRAM_CONSTANT:
-        *fcmd++ = paramList->ParameterValues[pi][0];
-        *fcmd++ = paramList->ParameterValues[pi][1];
-        *fcmd++ = paramList->ParameterValues[pi][2];
-        *fcmd++ = paramList->ParameterValues[pi][3];
+        *fcmd++ = paramList->ParameterValues[pi][0].f;
+        *fcmd++ = paramList->ParameterValues[pi][1].f;
+        *fcmd++ = paramList->ParameterValues[pi][2].f;
+        *fcmd++ = paramList->ParameterValues[pi][3].f;
         break;
       default:
         _mesa_problem(NULL, "Bad param type in %s", __FUNCTION__);
@@ -168,24 +166,24 @@ static unsigned long t_dst(struct prog_dst_register *dst)
         | R200_VSF_OUT_CLASS_TMP);
    case PROGRAM_OUTPUT:
       switch (dst->Index) {
-      case VERT_RESULT_HPOS:
+      case VARYING_SLOT_POS:
         return R200_VSF_OUT_CLASS_RESULT_POS;
-      case VERT_RESULT_COL0:
+      case VARYING_SLOT_COL0:
         return R200_VSF_OUT_CLASS_RESULT_COLOR;
-      case VERT_RESULT_COL1:
+      case VARYING_SLOT_COL1:
         return ((1 << R200_VPI_OUT_REG_INDEX_SHIFT)
            | R200_VSF_OUT_CLASS_RESULT_COLOR);
-      case VERT_RESULT_FOGC:
+      case VARYING_SLOT_FOGC:
         return R200_VSF_OUT_CLASS_RESULT_FOGC;
-      case VERT_RESULT_TEX0:
-      case VERT_RESULT_TEX1:
-      case VERT_RESULT_TEX2:
-      case VERT_RESULT_TEX3:
-      case VERT_RESULT_TEX4:
-      case VERT_RESULT_TEX5:
-        return (((dst->Index - VERT_RESULT_TEX0) << R200_VPI_OUT_REG_INDEX_SHIFT)
+      case VARYING_SLOT_TEX0:
+      case VARYING_SLOT_TEX1:
+      case VARYING_SLOT_TEX2:
+      case VARYING_SLOT_TEX3:
+      case VARYING_SLOT_TEX4:
+      case VARYING_SLOT_TEX5:
+        return (((dst->Index - VARYING_SLOT_TEX0) << R200_VPI_OUT_REG_INDEX_SHIFT)
            | R200_VSF_OUT_CLASS_RESULT_TEXC);
-      case VERT_RESULT_PSIZ:
+      case VARYING_SLOT_PSIZ:
         return R200_VSF_OUT_CLASS_RESULT_POINTSIZE;
       default:
         fprintf(stderr, "problem in %s, unknown dst output reg %d\n", __FUNCTION__, dst->Index);
@@ -214,13 +212,11 @@ static unsigned long t_src_class(gl_register_file file)
 
    case PROGRAM_LOCAL_PARAM:
    case PROGRAM_ENV_PARAM:
-   case PROGRAM_NAMED_PARAM:
    case PROGRAM_CONSTANT:
    case PROGRAM_STATE_VAR:
       return VSF_IN_CLASS_PARAM;
    /*
    case PROGRAM_OUTPUT:
-   case PROGRAM_WRITE_ONLY:
    case PROGRAM_ADDRESS:
    */
    default:
@@ -396,7 +392,7 @@ static unsigned long op_operands(enum prog_opcode opcode)
  *
  * \return  GL_TRUE for success, GL_FALSE for failure.
  */
-static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_vertex_program *vp)
+static GLboolean r200_translate_vertex_program(struct gl_context *ctx, struct r200_vertex_program *vp)
 {
    struct gl_vertex_program *mesa_vp = &vp->mesa_program;
    struct prog_instruction *vpi;
@@ -432,22 +428,17 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
 #endif
 
    if ((mesa_vp->Base.OutputsWritten &
-      ~((1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_COL0) | (1 << VERT_RESULT_COL1) |
-      (1 << VERT_RESULT_FOGC) | (1 << VERT_RESULT_TEX0) | (1 << VERT_RESULT_TEX1) |
-      (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) |
-      (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) {
+      ~((1 << VARYING_SLOT_POS) | (1 << VARYING_SLOT_COL0) | (1 << VARYING_SLOT_COL1) |
+      (1 << VARYING_SLOT_FOGC) | (1 << VARYING_SLOT_TEX0) | (1 << VARYING_SLOT_TEX1) |
+      (1 << VARYING_SLOT_TEX2) | (1 << VARYING_SLOT_TEX3) | (1 << VARYING_SLOT_TEX4) |
+      (1 << VARYING_SLOT_TEX5) | (1 << VARYING_SLOT_PSIZ))) != 0) {
       if (R200_DEBUG & RADEON_FALLBACKS) {
         fprintf(stderr, "can't handle vert prog outputs 0x%llx\n",
-           mesa_vp->Base.OutputsWritten);
+                 (unsigned long long) mesa_vp->Base.OutputsWritten);
       }
       return GL_FALSE;
    }
 
-   if (mesa_vp->IsNVProgram) {
-   /* subtle differences in spec like guaranteed initialized regs could cause
-      headaches. Might want to remove the driconf option to enable it completely */
-      return GL_FALSE;
-   }
    /* Initial value should be last tmp reg that hw supports.
       Strangely enough r300 doesnt mind even though these would be out of range.
       Smart enough to realize that it doesnt need it? */
@@ -458,13 +449,13 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
 /* FIXME: is changing the prog safe to do here? */
    if (mesa_vp->IsPositionInvariant &&
       /* make sure we only do this once */
-       !(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
+       !(mesa_vp->Base.OutputsWritten & (1 << VARYING_SLOT_POS))) {
         _mesa_insert_mvp_code(ctx, mesa_vp);
       }
 
    /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with
       base e isn't directly available neither. */
-   if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) {
+   if ((mesa_vp->Base.OutputsWritten & (1 << VARYING_SLOT_FOGC)) && !vp->fogpidx) {
       struct gl_program_parameter_list *paramList;
       gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 };
       paramList = mesa_vp->Base.Parameters;
@@ -535,20 +526,29 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
       vp->inputmap_rev[3] = VERT_ATTRIB_FOG;
       array_count++;
    }
-   for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) {
-      if (mesa_vp->Base.InputsRead & (1 << i)) {
-        vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6;
-        vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i;
-        free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6));
+   /* VERT_ATTRIB_TEX0-5 */
+   for (i = 0; i <= 5; i++) {
+      if (mesa_vp->Base.InputsRead & VERT_BIT_TEX(i)) {
+        vp->inputs[VERT_ATTRIB_TEX(i)] = i + 6;
+        vp->inputmap_rev[8 + i] = VERT_ATTRIB_TEX(i);
+        free_inputs &= ~(1 << (i + 6));
         array_count++;
       }
    }
    /* using VERT_ATTRIB_TEX6/7 would be illegal */
+   for (; i < VERT_ATTRIB_TEX_MAX; i++) {
+      if (mesa_vp->Base.InputsRead & VERT_BIT_TEX(i)) {
+          if (R200_DEBUG & RADEON_FALLBACKS) {
+              fprintf(stderr, "texture attribute %d in vert prog\n", i);
+          }
+          return GL_FALSE;
+      }
+   }
    /* completely ignore aliasing? */
-   for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
+   for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
       int j;
    /* completely ignore aliasing? */
-      if (mesa_vp->Base.InputsRead & (1 << i)) {
+      if (mesa_vp->Base.InputsRead & VERT_BIT_GENERIC(i)) {
         array_count++;
         if (array_count > 12) {
            if (R200_DEBUG & RADEON_FALLBACKS) {
@@ -560,17 +560,24 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
            /* will always find one due to limited array_count */
            if (free_inputs & (1 << j)) {
               free_inputs &= ~(1 << j);
-              vp->inputs[i] = j;
-              if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */
-              else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */
-              else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */
+              vp->inputs[VERT_ATTRIB_GENERIC(i)] = j;
+              if (j == 0) {
+                  /* mapped to pos */
+                  vp->inputmap_rev[j] = VERT_ATTRIB_GENERIC(i);
+              } else if (j < 12) {
+                  /* mapped to col/tex */
+                  vp->inputmap_rev[j + 2] = VERT_ATTRIB_GENERIC(i);
+              } else {
+                  /* mapped to pos1 */
+                  vp->inputmap_rev[j + 1] = VERT_ATTRIB_GENERIC(i);
+               }
               break;
            }
         }
       }
    }
 
-   if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
+   if (!(mesa_vp->Base.OutputsWritten & (1 << VARYING_SLOT_POS))) {
       if (R200_DEBUG & RADEON_FALLBACKS) {
         fprintf(stderr, "can't handle vert prog without position output\n");
       }
@@ -676,7 +683,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
 
       dst = vpi->DstReg;
       if (dst.File == PROGRAM_OUTPUT &&
-         dst.Index == VERT_RESULT_FOGC &&
+         dst.Index == VARYING_SLOT_FOGC &&
          dst.WriteMask & WRITEMASK_X) {
          fog_temp_i = u_temp_i;
          dst.File = PROGRAM_TEMPORARY;
@@ -1098,7 +1105,7 @@ else {
    return GL_TRUE;
 }
 
-void r200SetupVertexProg( GLcontext *ctx ) {
+void r200SetupVertexProg( struct gl_context *ctx ) {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    struct r200_vertex_program *vp = (struct r200_vertex_program *)ctx->VertexProgram.Current;
    GLboolean fallback;
@@ -1109,8 +1116,7 @@ void r200SetupVertexProg( GLcontext *ctx ) {
       r200_translate_vertex_program(ctx, vp);
    }
    /* could optimize setting up vertex progs away for non-tcl hw */
-   fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp) &&
-      rmesa->radeon.radeonScreen->drmSupportsVertexProgram);
+   fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp));
    TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, fallback);
    if (rmesa->radeon.TclFallback) return;
 
@@ -1179,7 +1185,7 @@ void r200SetupVertexProg( GLcontext *ctx ) {
 
 
 static void
-r200BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
+r200BindProgram(struct gl_context *ctx, GLenum target, struct gl_program *prog)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
@@ -1194,7 +1200,7 @@ r200BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
 }
 
 static struct gl_program *
-r200NewProgram(GLcontext *ctx, GLenum target, GLuint id)
+r200NewProgram(struct gl_context *ctx, GLenum target, GLuint id)
 {
    struct r200_vertex_program *vp;
 
@@ -1203,7 +1209,6 @@ r200NewProgram(GLcontext *ctx, GLenum target, GLuint id)
       vp = CALLOC_STRUCT(r200_vertex_program);
       return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
    case GL_FRAGMENT_PROGRAM_ARB:
-   case GL_FRAGMENT_PROGRAM_NV:
       return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(gl_fragment_program), target, id );
    default:
       _mesa_problem(ctx, "Bad target in r200NewProgram");
@@ -1213,13 +1218,13 @@ r200NewProgram(GLcontext *ctx, GLenum target, GLuint id)
 
 
 static void
-r200DeleteProgram(GLcontext *ctx, struct gl_program *prog)
+r200DeleteProgram(struct gl_context *ctx, struct gl_program *prog)
 {
    _mesa_delete_program(ctx, prog);
 }
 
 static GLboolean
-r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
+r200ProgramStringNotify(struct gl_context *ctx, GLenum target, struct gl_program *prog)
 {
    struct r200_vertex_program *vp = (void *)prog;
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -1244,12 +1249,11 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
 }
 
 static GLboolean
-r200IsProgramNative(GLcontext *ctx, GLenum target, struct gl_program *prog)
+r200IsProgramNative(struct gl_context *ctx, GLenum target, struct gl_program *prog)
 {
    struct r200_vertex_program *vp = (void *)prog;
 
    switch(target){
-   case GL_VERTEX_STATE_PROGRAM_NV:
    case GL_VERTEX_PROGRAM_ARB:
       if (!vp->translated) {
         r200_translate_vertex_program(ctx, vp);