Plug in selection/feedback code.
[mesa.git] / src / mesa / state_tracker / st_atom_fs.c
index 9ca1807913cc7c223962fc3174724f5afa4ae4a1..d06654761681d37b09b164f24ce3e63bcf247393 100644 (file)
   * Authors:
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
-                   
+
 #include "shader/prog_parameter.h"
-#include "st_context.h"
+
 #include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_winsys.h"
+#include "pipe/tgsi/mesa/mesa_to_tgsi.h"
+#include "pipe/tgsi/exec/tgsi_dump.h"
+
+#include "st_context.h"
 #include "st_atom.h"
 #include "st_program.h"
-#include "pipe/tgsi/mesa/mesa_to_tgsi.h"
-#include "pipe/tgsi/core/tgsi_dump.h"
 
-static void compile_fs( struct st_context *st,
-                       struct st_fragment_program *fs )
+#define TGSI_DEBUG 0
+
+static void compile_fs( struct st_context *st )
 {
+   struct st_fragment_program *fp = st->fp;
+
    /* XXX: fix static allocation of tokens:
     */
-   tgsi_mesa_compile_fp_program( &fs->Base, fs->tokens, ST_FP_MAX_TOKENS );
+   tgsi_mesa_compile_fp_program( &fp->Base, fp->tokens, ST_FP_MAX_TOKENS );
+
+   fp->fs.inputs_read
+      = tgsi_mesa_translate_fragment_input_mask(fp->Base.Base.InputsRead);
+   fp->fs.outputs_written
+      = tgsi_mesa_translate_fragment_output_mask(fp->Base.Base.OutputsWritten);
+   fp->fs.tokens = &fp->tokens[0];
 
-   tgsi_dump( fs->tokens, TGSI_DUMP_VERBOSE );
+   if (TGSI_DEBUG)
+      tgsi_dump( fp->tokens, TGSI_DUMP_VERBOSE );
+
+   fp->dirty = 0;
 }
 
 
+
 static void update_fs( struct st_context *st )
 {
-   struct pipe_fs_state fs;
    struct st_fragment_program *fp = NULL;
-   struct gl_program_parameter_list *params = NULL;
 
+   /* find active shader and params.  Changes to this Mesa state
+    * should be covered by ST_NEW_FRAGMENT_PROGRAM, thanks to the
+    * logic in st_cb_program.c
+    */
    if (st->ctx->Shader.CurrentProgram &&
        st->ctx->Shader.CurrentProgram->LinkStatus &&
        st->ctx->Shader.CurrentProgram->FragmentProgram) {
       struct gl_fragment_program *f
          = st->ctx->Shader.CurrentProgram->FragmentProgram;
       fp = st_fragment_program(f);
-      params = f->Base.Parameters;
    }
-   else if (st->ctx->FragmentProgram._Current) {
+   else {
+      assert(st->ctx->FragmentProgram._Current);
       fp = st_fragment_program(st->ctx->FragmentProgram._Current);
-      params = st->ctx->FragmentProgram._Current->Base.Parameters;
    }
 
-   if (fp && params) {
-      /* load program's constants array */
-      fp->constants.nr_constants = params->NumParameters;
-      memcpy(fp->constants.constant, 
-             params->ParameterValues,
-             params->NumParameters * sizeof(GLfloat) * 4);
-   }
+   /* translate shader to TGSI format */
+   if (st->fp != fp || fp->dirty) {
+      st->fp = fp;
+
+      if (fp->dirty)
+        compile_fs( st );
 
-   if (fp->dirty)
-      compile_fs( st, fp );
-
-   memset( &fs, 0, sizeof(fs) );
-   fs.inputs_read = fp->Base.Base.InputsRead;
-   fs.tokens = &fp->tokens[0];
-   fs.constants = &fp->constants;
-   
-   if (memcmp(&fs, &st->state.fs, sizeof(fs)) != 0 ||
-       fp->dirty) 
-   {
-      fp->dirty = 0;
-      st->state.fs = fs;
-      st->pipe->set_fs_state(st->pipe, &fs);
+      st->state.fs = fp->fs;
+      st->pipe->set_fs_state(st->pipe, &st->state.fs);
    }
 }
 
 
 const struct st_tracked_state st_update_fs = {
+   .name = "st_update_fs",
    .dirty = {
-      .mesa  = _NEW_PROGRAM,
+      .mesa  = 0,
       .st   = ST_NEW_FRAGMENT_PROGRAM,
    },
    .update = update_fs