glsl: Remove the ir_binop_cross opcode.
[mesa.git] / src / mesa / program / program.c
index a6ada8a048b859c14c86c47a69a1347a9b4ff1db..4cacde9aed14a7815cdcc01b3fabc10b357d91fe 100644 (file)
@@ -49,19 +49,27 @@ struct gl_program _mesa_DummyProgram;
  * Init context's vertex/fragment program state
  */
 void
-_mesa_init_program(GLcontext *ctx)
+_mesa_init_program(struct gl_context *ctx)
 {
    GLuint i;
 
    /*
     * If this assertion fails, we need to increase the field
-    * size for register indexes.
+    * size for register indexes (see INST_INDEX_BITS).
     */
    ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4
           <= (1 << INST_INDEX_BITS));
    ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4
           <= (1 << INST_INDEX_BITS));
 
+   ASSERT(ctx->Const.VertexProgram.MaxTemps <= (1 << INST_INDEX_BITS));
+   ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= (1 << INST_INDEX_BITS));
+   ASSERT(ctx->Const.FragmentProgram.MaxTemps <= (1 << INST_INDEX_BITS));
+   ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= (1 << INST_INDEX_BITS));
+
+   ASSERT(ctx->Const.VertexProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS);
+   ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS);
+
    /* If this fails, increase prog_instruction::TexSrcUnit size */
    ASSERT(MAX_TEXTURE_UNITS < (1 << 5));
 
@@ -98,6 +106,13 @@ _mesa_init_program(GLcontext *ctx)
    ctx->FragmentProgram.Cache = _mesa_new_program_cache();
 #endif
 
+#if FEATURE_ARB_geometry_shader4
+   ctx->GeometryProgram.Enabled = GL_FALSE;
+   /* right now by default we don't have a geometry program */
+   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+                            NULL);
+   ctx->GeometryProgram.Cache = _mesa_new_program_cache();
+#endif
 
    /* XXX probably move this stuff */
 #if FEATURE_ATI_fragment_shader
@@ -113,7 +128,7 @@ _mesa_init_program(GLcontext *ctx)
  * Free a context's vertex/fragment program state
  */
 void
-_mesa_free_program_data(GLcontext *ctx)
+_mesa_free_program_data(struct gl_context *ctx)
 {
 #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
@@ -122,6 +137,10 @@ _mesa_free_program_data(GLcontext *ctx)
 #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
    _mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache);
+#endif
+#if FEATURE_ARB_geometry_shader4
+   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
+   _mesa_delete_program_cache(ctx, ctx->GeometryProgram.Cache);
 #endif
    /* XXX probably move this stuff */
 #if FEATURE_ATI_fragment_shader
@@ -142,7 +161,7 @@ _mesa_free_program_data(GLcontext *ctx)
  * shared state.
  */
 void
-_mesa_update_default_objects_program(GLcontext *ctx)
+_mesa_update_default_objects_program(struct gl_context *ctx)
 {
 #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
@@ -158,6 +177,12 @@ _mesa_update_default_objects_program(GLcontext *ctx)
    assert(ctx->FragmentProgram.Current);
 #endif
 
+#if FEATURE_ARB_geometry_shader4
+   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+                            (struct gl_geometry_program *)
+                            ctx->Shared->DefaultGeometryProgram);
+#endif
+
    /* XXX probably move this stuff */
 #if FEATURE_ATI_fragment_shader
    if (ctx->ATIFragmentShader.Current) {
@@ -178,7 +203,7 @@ _mesa_update_default_objects_program(GLcontext *ctx)
  * This is generally called from within the parsers.
  */
 void
-_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string)
+_mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
 {
    ctx->Program.ErrorPos = pos;
    free((void *) ctx->Program.ErrorString);
@@ -235,7 +260,7 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
  * Initialize a new vertex/fragment program object.
  */
 static struct gl_program *
-_mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
+_mesa_init_program_struct( struct gl_context *ctx, struct gl_program *prog,
                            GLenum target, GLuint id)
 {
    (void) ctx;
@@ -261,7 +286,7 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
  * Initialize a new fragment program object.
  */
 struct gl_program *
-_mesa_init_fragment_program( GLcontext *ctx, struct gl_fragment_program *prog,
+_mesa_init_fragment_program( struct gl_context *ctx, struct gl_fragment_program *prog,
                              GLenum target, GLuint id)
 {
    if (prog)
@@ -275,7 +300,7 @@ _mesa_init_fragment_program( GLcontext *ctx, struct gl_fragment_program *prog,
  * Initialize a new vertex program object.
  */
 struct gl_program *
-_mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
+_mesa_init_vertex_program( struct gl_context *ctx, struct gl_vertex_program *prog,
                            GLenum target, GLuint id)
 {
    if (prog)
@@ -285,6 +310,20 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
 }
 
 
+/**
+ * Initialize a new geometry program object.
+ */
+struct gl_program *
+_mesa_init_geometry_program( struct gl_context *ctx, struct gl_geometry_program *prog,
+                             GLenum target, GLuint id)
+{
+   if (prog)
+      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+   else
+      return NULL;
+}
+
+
 /**
  * Allocate and initialize a new fragment/vertex program object but
  * don't put it into the program hash table.  Called via
@@ -298,7 +337,7 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
  * \return  pointer to new program object
  */
 struct gl_program *
-_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
+_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
 {
    struct gl_program *prog;
    switch (target) {
@@ -313,6 +352,11 @@ _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
                                          CALLOC_STRUCT(gl_fragment_program),
                                          target, id );
       break;
+   case MESA_GEOMETRY_PROGRAM:
+      prog = _mesa_init_geometry_program(ctx,
+                                         CALLOC_STRUCT(gl_geometry_program),
+                                         target, id);
+      break;
    default:
       _mesa_problem(ctx, "bad target in _mesa_new_program");
       prog = NULL;
@@ -328,7 +372,7 @@ _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
  * by a device driver function.
  */
 void
-_mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
+_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
 {
    (void) ctx;
    ASSERT(prog);
@@ -362,7 +406,7 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
  * casts elsewhere.
  */
 struct gl_program *
-_mesa_lookup_program(GLcontext *ctx, GLuint id)
+_mesa_lookup_program(struct gl_context *ctx, GLuint id)
 {
    if (id)
       return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
@@ -375,7 +419,7 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id)
  * Reference counting for vertex/fragment programs
  */
 void
-_mesa_reference_program(GLcontext *ctx,
+_mesa_reference_program(struct gl_context *ctx,
                         struct gl_program **ptr,
                         struct gl_program *prog)
 {
@@ -387,6 +431,8 @@ _mesa_reference_program(GLcontext *ctx,
       else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
          ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
                 prog->Target == GL_FRAGMENT_PROGRAM_NV);
+      else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
+         ASSERT(prog->Target == MESA_GEOMETRY_PROGRAM);
    }
    if (*ptr == prog) {
       return;  /* no change */
@@ -398,7 +444,8 @@ _mesa_reference_program(GLcontext *ctx,
 #if 0
       printf("Program %p ID=%u Target=%s  Refcount-- to %d\n",
              *ptr, (*ptr)->Id,
-             ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
+             ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+              ((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
              (*ptr)->RefCount - 1);
 #endif
       ASSERT((*ptr)->RefCount > 0);
@@ -422,7 +469,8 @@ _mesa_reference_program(GLcontext *ctx,
 #if 0
       printf("Program %p ID=%u Target=%s  Refcount++ to %d\n",
              prog, prog->Id,
-             (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
+             (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+              (prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
              prog->RefCount);
 #endif
       /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
@@ -438,7 +486,7 @@ _mesa_reference_program(GLcontext *ctx,
  * made by a device driver.
  */
 struct gl_program *
-_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
+_mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
 {
    struct gl_program *clone;
 
@@ -472,6 +520,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
    if (prog->Attributes)
       clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);
    memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+   clone->IndirectRegisterFiles = prog->IndirectRegisterFiles;
    clone->NumInstructions = prog->NumInstructions;
    clone->NumTemporaries = prog->NumTemporaries;
    clone->NumParameters = prog->NumParameters;
@@ -510,6 +559,16 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
          fpc->PixelCenterInteger = fp->PixelCenterInteger;
       }
       break;
+   case MESA_GEOMETRY_PROGRAM:
+      {
+         const struct gl_geometry_program *gp
+            = (const struct gl_geometry_program *) prog;
+         struct gl_geometry_program *gpc = (struct gl_geometry_program *) clone;
+         gpc->VerticesOut = gp->VerticesOut;
+         gpc->InputType = gp->InputType;
+         gpc->OutputType = gp->OutputType;
+      }
+      break;
    default:
       _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
    }
@@ -670,7 +729,7 @@ adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
  * the first program go to the inputs of the second program.
  */
 struct gl_program *
-_mesa_combine_programs(GLcontext *ctx,
+_mesa_combine_programs(struct gl_context *ctx,
                        const struct gl_program *progA,
                        const struct gl_program *progB)
 {
@@ -737,7 +796,7 @@ _mesa_combine_programs(GLcontext *ctx,
          if (p->Type == PROGRAM_STATE_VAR &&
              p->StateIndexes[0] == STATE_INTERNAL &&
              p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
-             p->StateIndexes[2] == VERT_ATTRIB_COLOR0) {
+             (int) p->StateIndexes[2] == (int) VERT_ATTRIB_COLOR0) {
             progB_inputsRead |= FRAG_BIT_COL0;
             progB_colorFile = PROGRAM_STATE_VAR;
             progB_colorIndex = i;
@@ -817,12 +876,16 @@ _mesa_find_used_registers(const struct gl_program *prog,
       const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
 
       if (inst->DstReg.File == file) {
-         used[inst->DstReg.Index] = GL_TRUE;
+         ASSERT(inst->DstReg.Index < usedSize);
+         if(inst->DstReg.Index < usedSize)
+            used[inst->DstReg.Index] = GL_TRUE;
       }
 
       for (j = 0; j < n; j++) {
          if (inst->SrcReg[j].File == file) {
-            used[inst->SrcReg[j].Index] = GL_TRUE;
+            ASSERT(inst->SrcReg[j].Index < usedSize);
+            if(inst->SrcReg[j].Index < usedSize)
+               used[inst->SrcReg[j].Index] = GL_TRUE;
          }
       }
    }
@@ -860,7 +923,7 @@ _mesa_find_free_register(const GLboolean used[],
  * behaviour.
  */
 void
-_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog)
+_mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog)
 {
    static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
    GLuint i;