gallium: add some temporary code for testing draw module vertex passthrough
[mesa.git] / src / mesa / state_tracker / st_cb_program.c
index 327b627722fd4e31205b3a72afb9548a6934d825..4dc76f19b10abb0814a2af4455aff8fd3a59f5ec 100644 (file)
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
 
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/program.h"
+#include "shader/programopt.h"
+#include "shader/shader_api.h"
+
+#include "cso_cache/cso_cache.h"
+#include "draw/draw_context.h"
+
 #include "st_context.h"
-#include "st_program.h"    
+#include "st_program.h"
+#include "st_atom_shader.h"
+
 
-#include "glheader.h"
-#include "macros.h"
-#include "enums.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "program.h"
-#include "programopt.h"
-#include "tnl/tnl.h"
-#include "pipe/tgsi/mesa/tgsi_mesa.h"
+static GLuint SerialNo = 1;
 
 
+/**
+ * Called via ctx->Driver.BindProgram() to bind an ARB vertex or
+ * fragment program.
+ */
 static void st_bind_program( GLcontext *ctx,
                             GLenum target, 
                             struct gl_program *prog )
@@ -52,6 +62,7 @@ static void st_bind_program( GLcontext *ctx,
 
    switch (target) {
    case GL_VERTEX_PROGRAM_ARB: 
+      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
       break;
    case GL_FRAGMENT_PROGRAM_ARB:
       st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
@@ -59,23 +70,45 @@ static void st_bind_program( GLcontext *ctx,
    }
 }
 
+
+/**
+ * Called via ctx->Driver.UseProgram() to bind a linked GLSL program
+ * (vertex shader + fragment shader).
+ */
+static void st_use_program( GLcontext *ctx,
+                           GLuint program )
+{
+   struct st_context *st = st_context(ctx);
+
+   st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+   st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+
+   _mesa_use_program(ctx, program);
+}
+
+
+
 static struct gl_program *st_new_program( GLcontext *ctx,
                                          GLenum target, 
                                          GLuint id )
 {
-   struct st_context *st = st_context(ctx);
-
    switch (target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      return _mesa_init_vertex_program(ctx, 
-                                      CALLOC_STRUCT(gl_vertex_program),
-                                       target, 
-                                      id);
+   case GL_VERTEX_PROGRAM_ARB: {
+      struct st_vertex_program *prog = CALLOC_STRUCT(st_vertex_program);
 
-   case GL_FRAGMENT_PROGRAM_ARB: {
+      prog->serialNo = SerialNo++;
+
+      return _mesa_init_vertex_program( ctx, 
+                                       &prog->Base,
+                                       target, 
+                                       id );
+   }
+
+   case GL_FRAGMENT_PROGRAM_ARB:
+   case GL_FRAGMENT_PROGRAM_NV: {
       struct st_fragment_program *prog = CALLOC_STRUCT(st_fragment_program);
 
-      prog->id = st->program_id++;
+      prog->serialNo = SerialNo++;
 
       return _mesa_init_fragment_program( ctx, 
                                          &prog->Base,
@@ -88,9 +121,30 @@ static struct gl_program *st_new_program( GLcontext *ctx,
    }
 }
 
+
 static void st_delete_program( GLcontext *ctx,
                               struct gl_program *prog )
 {
+   struct st_context *st = st_context(ctx);
+
+   switch( prog->Target ) {
+   case GL_VERTEX_PROGRAM_ARB:
+      {
+         struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
+         st_remove_vertex_program(st, stvp);
+      }
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+      {
+         struct st_fragment_program *stfp
+            = (struct st_fragment_program *) prog;
+         st_remove_fragment_program(st, stfp);
+      }
+      break;
+   default:
+      assert(0); /* problem */
+   }
+
    _mesa_delete_program( ctx, prog );
 }
 
@@ -102,72 +156,64 @@ static GLboolean st_is_program_native( GLcontext *ctx,
    return GL_TRUE;
 }
 
+
 static void st_program_string_notify( GLcontext *ctx,
                                      GLenum target,
                                      struct gl_program *prog )
 {
-   if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      struct st_context *st = st_context(ctx);
+   struct st_context *st = st_context(ctx);
 
-      if (prog == &st->ctx->FragmentProgram._Current->Base) 
-      {
-        struct st_fragment_program *p = 
-           (struct st_fragment_program *) prog;
+   if (target == GL_FRAGMENT_PROGRAM_ARB) {
+      struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
 
-        st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+      stfp->serialNo++;
 
-        p->id = st->program_id++;
 #if 0
-        p->param_state = p->Base.Base.Parameters->StateFlags; 
-        p->translated = 0;
+      if (stfp->cso) {
+         /* free the TGSI code */
+         // cso_delete(stfp->vs);
+         stfp->cso = NULL;
+      }
 #endif
 
-        /* Gack! do this in the compiler: 
-         */
-        if (p->Base.FogOption) {
-           /* add extra instructions to do fog, then turn off FogOption field */
-           _mesa_append_fog_code(ctx, &p->Base);
-           p->Base.FogOption = GL_NONE;
-        }
-
-         /* XXX: Not hooked-up yet. */
-        {
-           struct tgsi_token tokens[1024];
-
-           tgsi_mesa_compile_fp_program( prog, tokens, 1024 );
-           tgsi_dump( tokens, TGSI_DUMP_VERBOSE );
-        }
-      }
+      stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
+
+      if (st->fp == stfp)
+        st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    }
    else if (target == GL_VERTEX_PROGRAM_ARB) {
+      struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
 
-      /* Also tell tnl about it:
-       */
-      _tnl_program_string(ctx, target, prog);
+      stvp->serialNo++;
+
+#if 0
+      if (stvp->cso) {
+         /* free the CSO data */
+         st->pipe->delete_vs_state(st->pipe, stvp->cso->data);
+         FREE((void *) stvp->cso);
+         stvp->cso = NULL;
+      }
+#endif
+      if (stvp->draw_shader) {
+         draw_delete_vertex_shader(st->draw, stvp->draw_shader);
+         stvp->draw_shader = NULL;
+      }
+
+      stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
+
+      if (st->vp == stvp)
+        st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
    }
 }
 
 
 
-void st_init_cb_program( struct st_context *st )
+void st_init_program_functions(struct dd_function_table *functions)
 {
-   struct dd_function_table *functions = &st->ctx->Driver;
-
-   /* Need these flags:
-    */
-   st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
-   st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
-
-   assert(functions->ProgramStringNotify == _tnl_program_string); 
    functions->BindProgram = st_bind_program;
+   functions->UseProgram = st_use_program;
    functions->NewProgram = st_new_program;
    functions->DeleteProgram = st_delete_program;
    functions->IsProgramNative = st_is_program_native;
    functions->ProgramStringNotify = st_program_string_notify;
 }
-
-
-void st_destroy_cb_program( struct st_context *st )
-{
-}
-