st: play it safe for now and check _NEW_PROGRAM for shader const buffer atom
[mesa.git] / src / mesa / state_tracker / st_atom_shader.c
index a62ea8161c5b581c80d192525926e9330c000938..fc1ff5be04a59cc6d43b8c0885ea8512cdbddef1 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "main/imports.h"
 #include "main/mtypes.h"
+#include "main/macros.h"
 #include "shader/program.h"
 
 #include "pipe/p_context.h"
@@ -71,6 +72,8 @@ struct translated_vertex_program
 
    /** Maps VERT_RESULT_x to slot */
    GLuint output_to_slot[VERT_RESULT_MAX];
+   ubyte output_to_semantic_name[VERT_RESULT_MAX];
+   ubyte output_to_semantic_index[VERT_RESULT_MAX];
 
    /** Pointer to the translated vertex program */
    struct st_vertex_program *vp;
@@ -162,7 +165,7 @@ find_translated_vp(struct st_context *st,
 
    /* No?  Allocate translated vp object now */
    if (!xvp) {
-      xvp = CALLOC_STRUCT(translated_vertex_program);
+      xvp = ST_CALLOC_STRUCT(translated_vertex_program);
       xvp->frag_inputs = fragInputsRead;
       xvp->master = stvp;
 
@@ -175,17 +178,23 @@ find_translated_vp(struct st_context *st,
       GLuint outAttr, dummySlot;
       const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
       GLuint numVpOuts = 0;
+      GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
+      GLint maxGeneric;
 
       /* Compute mapping of vertex program outputs to slots, which depends
        * on the fragment program's input->slot mapping.
        */
       for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
-         /* set default: */
+         /* set defaults: */
          xvp->output_to_slot[outAttr] = UNUSED;
+         xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
+         xvp->output_to_semantic_index[outAttr] = 99;
 
          if (outAttr == VERT_RESULT_HPOS) {
             /* always put xformed position into slot zero */
             xvp->output_to_slot[VERT_RESULT_HPOS] = 0;
+            xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
+            xvp->output_to_semantic_index[outAttr] = 0;
             numVpOuts++;
          }
          else if (outputsWritten & (1 << outAttr)) {
@@ -194,22 +203,42 @@ find_translated_vp(struct st_context *st,
             if (fpInAttrib >= 0) {
                GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
                if (fpInSlot != ~0) {
+                  /* match this vp output to the fp input */
                   GLuint vpOutSlot = stfp->input_map[fpInSlot];
                   xvp->output_to_slot[outAttr] = vpOutSlot;
+                  xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
+                  xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
                   numVpOuts++;
                }
             }
-            else if (outAttr == VERT_RESULT_PSIZ ||
-                     outAttr == VERT_RESULT_BFC0 ||
-                     outAttr == VERT_RESULT_BFC1) {
-               /* backface colors go into last slots */
-               xvp->output_to_slot[outAttr] = numVpOuts++;
-            }
+            else if (outAttr == VERT_RESULT_PSIZ)
+               emitPntSize = GL_TRUE;
+            else if (outAttr == VERT_RESULT_BFC0)
+               emitBFC0 = GL_TRUE;
+            else if (outAttr == VERT_RESULT_BFC1)
+               emitBFC1 = GL_TRUE;
          }
-         /*
-         printf("output_to_slot[%d] = %d\n", outAttr, 
+#if 0 /*debug*/
+         printf("assign vp output_to_slot[%d] = %d\n", outAttr, 
                 xvp->output_to_slot[outAttr]);
-         */
+#endif
+      }
+
+      /* must do these last */
+      if (emitPntSize) {
+         xvp->output_to_slot[VERT_RESULT_PSIZ] = numVpOuts++;
+         xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
+         xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
+      }
+      if (emitBFC0) {
+         xvp->output_to_slot[VERT_RESULT_BFC0] = numVpOuts++;
+         xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
+         xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
+      }
+      if (emitBFC1) {
+         xvp->output_to_slot[VERT_RESULT_BFC1] = numVpOuts++;
+         xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
+         xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 1;
       }
 
       /* Unneeded vertex program outputs will go to this slot.
@@ -218,17 +247,38 @@ find_translated_vp(struct st_context *st,
        */
       dummySlot = numVpOuts;
 
-      /* Map vert program outputs that aren't used to the dummy slot */
+      /* find max GENERIC slot index */
+      maxGeneric = -1;
+      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
+         if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
+            maxGeneric = MAX2(maxGeneric,
+                              xvp->output_to_semantic_index[outAttr]);
+         }
+      }
+
+      /* Map vert program outputs that aren't used to the dummy slot
+       * (and an unused generic attribute slot).
+       */
       for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
          if (outputsWritten & (1 << outAttr)) {
-            if (xvp->output_to_slot[outAttr] == UNUSED)
+            if (xvp->output_to_slot[outAttr] == UNUSED) {
                xvp->output_to_slot[outAttr] = dummySlot;
+               xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
+               xvp->output_to_semantic_index[outAttr] = maxGeneric + 1;
+            }
          }
+
+#if 0 /*debug*/
+         printf("vp output_to_slot[%d] = %d\n", outAttr, 
+                xvp->output_to_slot[outAttr]);
+#endif
       }
 
       assert(stvp->Base.Base.NumInstructions > 1);
 
-      st_translate_vertex_program(st, stvp, xvp->output_to_slot);
+      st_translate_vertex_program(st, stvp, xvp->output_to_slot,
+                                  xvp->output_to_semantic_name,
+                                  xvp->output_to_semantic_index);
 
       xvp->vp = stvp;
 
@@ -248,7 +298,7 @@ st_free_translated_vertex_programs(struct st_context *st,
 
    while (xvp) {
       next = xvp->next;
-      free(xvp);
+      _mesa_free(xvp);
       xvp = next;
    }
 }
@@ -257,14 +307,9 @@ st_free_translated_vertex_programs(struct st_context *st,
 static void *
 get_passthrough_fs(struct st_context *st)
 {
-   struct pipe_shader_state shader;
-
    if (!st->passthrough_fs) {
       st->passthrough_fs =
-         util_make_fragment_passthrough_shader(st->pipe, &shader);
-#if 0      /* We actually need to keep the tokens around at this time */
-      free((void *) shader.tokens);
-#endif
+         util_make_fragment_passthrough_shader(st->pipe);
    }
 
    return st->passthrough_fs;