r300: Fix emit size prediction to know about primitive splitting.
[mesa.git] / src / mesa / state_tracker / st_program.c
index d66f45d13eacf87cfb4cccf0a38e6b8936420c77..21ad6fef2b47788f65a73f17ae1b6b273fac5eb8 100644 (file)
 
 #include "st_debug.h"
 #include "st_context.h"
-#include "st_atom.h"
 #include "st_program.h"
 #include "st_mesa_to_tgsi.h"
 #include "cso_cache/cso_context.h"
 
-   /* Clean out any old compilations:
-    */
+
+
+/**
+ * Clean out any old compilations:
+ */
 void
 st_vp_release_varients( struct st_context *st,
                         struct st_vertex_program *stvp )
@@ -99,6 +101,8 @@ st_prepare_vertex_program(struct st_context *st,
    if (stvp->Base.IsPositionInvariant)
       _mesa_insert_mvp_code(st->ctx, &stvp->Base);
 
+   assert(stvp->Base.Base.NumInstructions > 1);
+
    /*
     * Determine number of inputs, the mappings between VERT_ATTRIB_x
     * and TGSI generic input indexes, plus input attrib semantic info.
@@ -110,6 +114,9 @@ st_prepare_vertex_program(struct st_context *st,
          stvp->num_inputs++;
       }
    }
+   /* bit of a hack, presetup potentially unused edgeflag input */
+   stvp->input_to_index[VERT_ATTRIB_EDGEFLAG] = stvp->num_inputs;
+   stvp->index_to_input[stvp->num_inputs] = VERT_ATTRIB_EDGEFLAG;
 
    /* Compute mapping of vertex program outputs to slots.
     */
@@ -179,6 +186,10 @@ st_prepare_vertex_program(struct st_context *st,
          }
       }
    }
+   /* similar hack to above, presetup potentially unused edgeflag output */
+   stvp->result_to_output[VERT_RESULT_EDGE] = stvp->num_outputs;
+   stvp->output_semantic_name[stvp->num_outputs] = TGSI_SEMANTIC_EDGEFLAG;
+   stvp->output_semantic_index[stvp->num_outputs] = 0;
 }
 
 
@@ -189,22 +200,47 @@ st_translate_vertex_program(struct st_context *st,
 {
    struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient);
    struct pipe_context *pipe = st->pipe;
+   struct ureg_program *ureg;
+   enum pipe_error error;
+   unsigned num_outputs;
+
+   ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+   if (ureg == NULL)
+      return NULL;
+
+   vpv->num_inputs = stvp->num_inputs;
+   num_outputs = stvp->num_outputs;
+   if (key->passthrough_edgeflags) {
+      vpv->num_inputs++;
+      num_outputs++;
+   }
 
-   vpv->state.tokens = 
+   error = 
       st_translate_mesa_program(st->ctx,
                                 TGSI_PROCESSOR_VERTEX,
+                                ureg,
                                 &stvp->Base.Base,
                                 /* inputs */
-                                stvp->num_inputs,
+                                vpv->num_inputs,
                                 stvp->input_to_index,
                                 NULL, /* input semantic name */
                                 NULL, /* input semantic index */
                                 NULL,
                                 /* outputs */
-                                stvp->num_outputs,
+                                num_outputs,
                                 stvp->result_to_output,
                                 stvp->output_semantic_name,
-                                stvp->output_semantic_index );
+                                stvp->output_semantic_index,
+                                key->passthrough_edgeflags );
+
+   if (error)
+      goto fail;
+
+   vpv->state.tokens = ureg_get_tokens( ureg, NULL );
+   if (!vpv->state.tokens)
+      goto fail;
+
+   ureg_destroy( ureg );
 
    vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
 
@@ -219,28 +255,34 @@ st_translate_vertex_program(struct st_context *st,
    }
 
    return vpv;
+
+fail:
+   debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
+   _mesa_print_program(&stvp->Base.Base);
+   debug_assert(0);
+
+   ureg_destroy( ureg );
+   return NULL;
 }
 
 
 
 /**
  * Translate a Mesa fragment shader into a TGSI shader.
- * \param inputMapping  to map fragment program input registers to TGSI
- *                      input slots
  * \return  pointer to cached pipe_shader object.
  */
 void
 st_translate_fragment_program(struct st_context *st,
-                              struct st_fragment_program *stfp,
-                              const GLuint inputMapping[])
+                              struct st_fragment_program *stfp )
 {
    struct pipe_context *pipe = st->pipe;
    GLuint outputMapping[FRAG_RESULT_MAX];
-   GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
+   GLuint inputMapping[FRAG_ATTRIB_MAX];
    GLuint interpMode[16];  /* XXX size? */
    GLuint attr;
+   enum pipe_error error;
    const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
-   GLuint vslot = 0;
+   struct ureg_program *ureg;
 
    uint fs_num_inputs = 0;
 
@@ -248,24 +290,14 @@ st_translate_fragment_program(struct st_context *st,
    ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
    uint fs_num_outputs = 0;
 
-   /* which vertex output goes to the first fragment input: */
-   if (inputsRead & FRAG_BIT_WPOS)
-      vslot = 0;
-   else
-      vslot = 1;
-
    /*
     * Convert Mesa program inputs to TGSI input register semantics.
     */
    for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
       if (inputsRead & (1 << attr)) {
-         const GLuint slot = fs_num_inputs;
+         const GLuint slot = fs_num_inputs++;
 
-         defaultInputMapping[attr] = slot;
-
-         stfp->input_map[slot] = vslot++;
-
-         fs_num_inputs++;
+         inputMapping[attr] = slot;
 
          switch (attr) {
          case FRAG_ATTRIB_WPOS:
@@ -293,6 +325,16 @@ st_translate_fragment_program(struct st_context *st,
             stfp->input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
             break;
+         case FRAG_ATTRIB_PNTC:
+            /* This is a hack.  We really need a new semantic label for
+             * point coord.  The draw module needs to know which fragment
+             * shader input is the point coord attribute so that it can set
+             * up the right vertex attribute values.
+             */
+            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stfp->input_semantic_index[slot] = 0;
+            interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
+            break;
 
             /* In most cases, there is nothing special about these
              * inputs, so adopt a convention to use the generic
@@ -317,7 +359,6 @@ st_translate_fragment_program(struct st_context *st,
          case FRAG_ATTRIB_TEX5:
          case FRAG_ATTRIB_TEX6:
          case FRAG_ATTRIB_TEX7:
-         case FRAG_ATTRIB_PNTC:
          case FRAG_ATTRIB_VAR0:
          default:
             /* Actually, let's try and zero-base this just for
@@ -330,6 +371,9 @@ st_translate_fragment_program(struct st_context *st,
             break;
          }
       }
+      else {
+        inputMapping[attr] = -1;
+      }
    }
 
    /*
@@ -371,12 +415,15 @@ st_translate_fragment_program(struct st_context *st,
       }
    }
 
-   if (!inputMapping)
-      inputMapping = defaultInputMapping;
+   ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+   if (ureg == NULL)
+      return;
+
 
-   stfp->state.tokens = 
+   error = 
       st_translate_mesa_program(st->ctx,
                                 TGSI_PROCESSOR_FRAGMENT,
+                                ureg,
                                 &stfp->Base.Base,
                                 /* inputs */
                                 fs_num_inputs,
@@ -388,8 +435,10 @@ st_translate_fragment_program(struct st_context *st,
                                 fs_num_outputs,
                                 outputMapping,
                                 fs_output_semantic_name,
-                                fs_output_semantic_index );
+                                fs_output_semantic_index, FALSE );
 
+   stfp->state.tokens = ureg_get_tokens( ureg, NULL );
+   ureg_destroy( ureg );
    stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
 
    if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {