r300: Fix emit size prediction to know about primitive splitting.
[mesa.git] / src / mesa / state_tracker / st_program.c
index 876d92539e900ab1c8a56be7fef2d43d43770e29..21ad6fef2b47788f65a73f17ae1b6b273fac5eb8 100644 (file)
@@ -44,7 +44,6 @@
 
 #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"
@@ -102,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.
@@ -113,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.
     */
@@ -182,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;
 }
 
 
@@ -193,40 +201,45 @@ 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++;
+   }
+
    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 (ret)
+   if (error)
       goto fail;
 
-   /* Edgeflags will be the last input:
-    */
-   if (key.passthrough_edgeflags) {
-      ureg_MOV( ureg,
-                ureg_DECL_output( ureg, TGSI_SEMANTIC_EDGEFLAG, 0 ),
-                ureg_DECL_next_vs_input(ureg));
-   }
+   vpv->state.tokens = ureg_get_tokens( ureg, NULL );
+   if (!vpv->state.tokens)
+      goto fail;
 
-   tokens = ureg_get_tokens( ureg, NULL );
    ureg_destroy( ureg );
 
    vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
@@ -244,6 +257,10 @@ 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;
 }
@@ -252,23 +269,20 @@ fail:
 
 /**
  * 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;
    struct ureg_program *ureg;
-   GLuint vslot = 0;
 
    uint fs_num_inputs = 0;
 
@@ -276,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;
-
-         defaultInputMapping[attr] = slot;
+         const GLuint slot = fs_num_inputs++;
 
-         stfp->input_map[slot] = vslot++;
-
-         fs_num_inputs++;
+         inputMapping[attr] = slot;
 
          switch (attr) {
          case FRAG_ATTRIB_WPOS:
@@ -321,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
@@ -345,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
@@ -358,6 +371,9 @@ st_translate_fragment_program(struct st_context *st,
             break;
          }
       }
+      else {
+        inputMapping[attr] = -1;
+      }
    }
 
    /*
@@ -399,17 +415,15 @@ st_translate_fragment_program(struct st_context *st,
       }
    }
 
-   if (!inputMapping)
-      inputMapping = defaultInputMapping;
-
    ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
    if (ureg == NULL)
-      return NULL;
+      return;
 
 
-   stfp->state.tokens = 
+   error = 
       st_translate_mesa_program(st->ctx,
                                 TGSI_PROCESSOR_FRAGMENT,
+                                ureg,
                                 &stfp->Base.Base,
                                 /* inputs */
                                 fs_num_inputs,
@@ -421,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)) {