mesa: consistantly use mesa memory-functions in gallium state tracker
[mesa.git] / src / mesa / state_tracker / st_program.c
index 59314a32322d3eb812d74a085d7516d8aa01e4aa..d2535b6a2fa51f571ff4569eee29a8bc09984be1 100644 (file)
 #define TGSI_DEBUG 0
 
 
-/** XXX we should use the version of this from p_util.h but including
+/** XXX we should use the version of this from u_memory.h but including
  * that header causes symbol collisions.
  */
 static INLINE void *
 mem_dup(const void *src, uint size)
 {
-   void *dup = MALLOC(size);
+   void *dup = _mesa_malloc(size);
    if (dup)
-      memcpy(dup, src, size);
+      _mesa_memcpy(dup, src, size);
    return dup;
 }
 
@@ -71,15 +71,17 @@ mem_dup(const void *src, uint size)
 
 /**
  * Translate a Mesa vertex shader into a TGSI shader.
- * \param outputMapping  to map vertex program output registers to TGSI
- *                       output slots
+ * \param outputMapping  to map vertex program output registers (VERT_RESULT_x)
+ *       to TGSI output slots
  * \param tokensOut  destination for TGSI tokens
  * \return  pointer to cached pipe_shader object.
  */
 void
 st_translate_vertex_program(struct st_context *st,
                             struct st_vertex_program *stvp,
-                            const GLuint outputMapping[])
+                            const GLuint outputMapping[],
+                            const ubyte *outputSemanticName,
+                            const ubyte *outputSemanticIndex)
 {
    struct pipe_context *pipe = st->pipe;
    struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
@@ -97,7 +99,12 @@ st_translate_vertex_program(struct st_context *st,
    ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
    uint vs_num_outputs = 0;
 
+   GLbitfield input_flags[MAX_PROGRAM_INPUTS];
+   GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
+
    memset(&vs, 0, sizeof(vs));
+   memset(input_flags, 0, sizeof(input_flags));
+   memset(output_flags, 0, sizeof(output_flags));
 
    if (stvp->Base.IsPositionInvariant)
       _mesa_insert_mvp_code(st->ctx, &stvp->Base);
@@ -169,13 +176,30 @@ st_translate_vertex_program(struct st_context *st,
          default:
             assert(0);
          }
+
+         input_flags[slot] = stvp->Base.Base.InputFlags[attr];
+      }
+   }
+
+#if 0
+   if (outputMapping && outputSemanticName) {
+      printf("VERT_RESULT  written  out_slot  semantic_name  semantic_index\n");
+      for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
+         printf("    %-2d          %c       %3d          %2d              %2d\n",
+                attr, 
+                ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
+                outputMapping[attr],
+                outputSemanticName[attr],
+                outputSemanticIndex[attr]);
       }
    }
+#endif
 
    /* initialize output semantics to defaults */
    for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
       vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
       vs_output_semantic_index[i] = 0;
+      output_flags[i] = 0x0;
    }
 
    num_generic = 0;
@@ -203,10 +227,6 @@ st_translate_vertex_program(struct st_context *st,
             defaultOutputMapping[attr] = slot;
          }
 
-         /*
-         printf("Output %u -> slot %u\n", attr, slot);
-         */
-
          switch (attr) {
          case VERT_RESULT_HPOS:
             assert(slot == 0);
@@ -248,16 +268,24 @@ st_translate_vertex_program(struct st_context *st,
          case VERT_RESULT_TEX5:
          case VERT_RESULT_TEX6:
          case VERT_RESULT_TEX7:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            vs_output_semantic_index[slot] = num_generic++;
-            break;
+            /* fall-through */
          case VERT_RESULT_VAR0:
             /* fall-through */
          default:
-            assert(attr - VERT_RESULT_VAR0 < MAX_VARYING);
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            vs_output_semantic_index[slot] = num_generic++;
+            if (outputSemanticName) {
+               /* use provided semantic into */
+               assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
+               vs_output_semantic_name[slot] = outputSemanticName[attr];
+               vs_output_semantic_index[slot] = outputSemanticIndex[attr];
+            }
+            else {
+               /* use default semantic info */
+               vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+               vs_output_semantic_index[slot] = num_generic++;
+            }
          }
+
+         output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
       }
    }
 
@@ -279,7 +307,7 @@ st_translate_vertex_program(struct st_context *st,
 
    /* free old shader state, if any */
    if (stvp->state.tokens) {
-      FREE((void *) stvp->state.tokens);
+      _mesa_free((void *) stvp->state.tokens);
       stvp->state.tokens = NULL;
    }
    if (stvp->driver_shader) {
@@ -289,21 +317,24 @@ st_translate_vertex_program(struct st_context *st,
 
    /* XXX: fix static allocation of tokens:
     */
-   num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,
-                                &stvp->Base.Base,
-                                /* inputs */
-                                vs_num_inputs,
-                                stvp->input_to_index,
-                                vs_input_semantic_name,
-                                vs_input_semantic_index,
-                                NULL,
-                                /* outputs */
-                                vs_num_outputs,
-                                outputMapping,
-                                vs_output_semantic_name,
-                                vs_output_semantic_index,
-                                /* tokenized result */
-                                tokens, ST_MAX_SHADER_TOKENS);
+   num_tokens = st_translate_mesa_program(st->ctx,
+                                          TGSI_PROCESSOR_VERTEX,
+                                          &stvp->Base.Base,
+                                          /* inputs */
+                                          vs_num_inputs,
+                                          stvp->input_to_index,
+                                          vs_input_semantic_name,
+                                          vs_input_semantic_index,
+                                          NULL,
+                                          input_flags,
+                                          /* outputs */
+                                          vs_num_outputs,
+                                          outputMapping,
+                                          vs_output_semantic_name,
+                                          vs_output_semantic_index,
+                                          output_flags,
+                                          /* tokenized result */
+                                          tokens, ST_MAX_SHADER_TOKENS);
 
    assert(num_tokens < ST_MAX_SHADER_TOKENS);
 
@@ -347,15 +378,18 @@ st_translate_fragment_program(struct st_context *st,
    GLuint num_generic = 0;
    GLuint num_tokens;
 
-   ubyte fs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
-   ubyte fs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
    uint fs_num_inputs = 0;
 
    ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
    ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
    uint fs_num_outputs = 0;
 
+   GLbitfield input_flags[MAX_PROGRAM_INPUTS];
+   GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
+
    memset(&fs, 0, sizeof(fs));
+   memset(input_flags, 0, sizeof(input_flags));
+   memset(output_flags, 0, sizeof(output_flags));
 
    /* which vertex output goes to the first fragment input: */
    if (inputsRead & FRAG_BIT_WPOS)
@@ -378,23 +412,26 @@ st_translate_fragment_program(struct st_context *st,
 
          switch (attr) {
          case FRAG_ATTRIB_WPOS:
-            fs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
-            fs_input_semantic_index[slot] = 0;
+            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+            stfp->input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case FRAG_ATTRIB_COL0:
-            fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            fs_input_semantic_index[slot] = 0;
+            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            stfp->input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case FRAG_ATTRIB_COL1:
-            fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            fs_input_semantic_index[slot] = 1;
+            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            stfp->input_semantic_index[slot] = 1;
             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case FRAG_ATTRIB_FOGC:
-            fs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
-            fs_input_semantic_index[slot] = 0;
+            if (stfp->Base.UsesPointCoord)
+               stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            else
+               stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+            stfp->input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
          case FRAG_ATTRIB_TEX0:
@@ -405,17 +442,19 @@ st_translate_fragment_program(struct st_context *st,
          case FRAG_ATTRIB_TEX5:
          case FRAG_ATTRIB_TEX6:
          case FRAG_ATTRIB_TEX7:
-            fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            fs_input_semantic_index[slot] = num_generic++;
+            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stfp->input_semantic_index[slot] = num_generic++;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
          case FRAG_ATTRIB_VAR0:
             /* fall-through */
          default:
-            fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            fs_input_semantic_index[slot] = num_generic++;
+            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stfp->input_semantic_index[slot] = num_generic++;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
          }
+
+         input_flags[slot] = stfp->Base.Base.InputFlags[attr];
       }
    }
 
@@ -452,6 +491,9 @@ st_translate_fragment_program(struct st_context *st,
             default:
                assert(0);
             }
+
+            output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
+
             fs_num_outputs++;
          }
       }
@@ -462,21 +504,24 @@ st_translate_fragment_program(struct st_context *st,
 
    /* XXX: fix static allocation of tokens:
     */
-   num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_FRAGMENT,
-                                &stfp->Base.Base,
-                                /* inputs */
-                                fs_num_inputs,
-                                inputMapping,
-                                fs_input_semantic_name,
-                                fs_input_semantic_index,
-                                interpMode,
-                                /* outputs */
-                                fs_num_outputs,
-                                outputMapping,
-                                fs_output_semantic_name,
-                                fs_output_semantic_index,
-                                /* tokenized result */
-                                tokens, ST_MAX_SHADER_TOKENS);
+   num_tokens = st_translate_mesa_program(st->ctx,
+                                          TGSI_PROCESSOR_FRAGMENT,
+                                          &stfp->Base.Base,
+                                          /* inputs */
+                                          fs_num_inputs,
+                                          inputMapping,
+                                          stfp->input_semantic_name,
+                                          stfp->input_semantic_index,
+                                          interpMode,
+                                          input_flags,
+                                          /* outputs */
+                                          fs_num_outputs,
+                                          outputMapping,
+                                          fs_output_semantic_name,
+                                          fs_output_semantic_index,
+                                          output_flags,
+                                          /* tokenized result */
+                                          tokens, ST_MAX_SHADER_TOKENS);
 
    assert(num_tokens < ST_MAX_SHADER_TOKENS);
 
@@ -493,3 +538,19 @@ st_translate_fragment_program(struct st_context *st,
       tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
 }
 
+
+/**
+ * Debug- print current shader text
+ */
+void
+st_print_shaders(GLcontext *ctx)
+{
+   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+   if (shProg) {
+      GLuint i;
+      for (i = 0; i < shProg->NumShaders; i++) {
+         printf("GLSL shader %u of %u:\n", i, shProg->NumShaders);
+         printf("%s\n", shProg->Shaders[i]->Source);
+      }
+   }
+}