gallium: add some temporary code for testing draw module vertex passthrough
[mesa.git] / src / mesa / state_tracker / st_cb_program.c
index b84f552404fb0e3974d122f18ec80762961974bd..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 "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"
-
-
-/* Counter to track program string changes:
- */
-static GLuint program_id = 0;
+#include "st_program.h"
+#include "st_atom_shader.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 )
@@ -64,22 +70,33 @@ 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: {
       struct st_vertex_program *prog = CALLOC_STRUCT(st_vertex_program);
 
-      prog->id = program_id++;
-      prog->dirty = 1;
-
-#if defined(USE_X86_ASM) || defined(SLANG_X86)
-      x86_init_func( &prog->sse2_program );
-#endif
+      prog->serialNo = SerialNo++;
 
       return _mesa_init_vertex_program( ctx, 
                                        &prog->Base,
@@ -88,12 +105,10 @@ static struct gl_program *st_new_program( GLcontext *ctx,
    }
 
    case GL_FRAGMENT_PROGRAM_ARB:
-   case GL_FRAGMENT_PROGRAM_NV:
-   {
+   case GL_FRAGMENT_PROGRAM_NV: {
       struct st_fragment_program *prog = CALLOC_STRUCT(st_fragment_program);
 
-      prog->id = program_id++;
-      prog->dirty = 1;
+      prog->serialNo = SerialNo++;
 
       return _mesa_init_fragment_program( ctx, 
                                          &prog->Base,
@@ -106,21 +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:
-   {
-#if defined(USE_X86_ASM) || defined(SLANG_X86)
-      struct st_vertex_program *p = (struct st_vertex_program *) prog;
-
-      x86_release_func( &p->sse2_program );
-#endif
+      {
+         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 );
 }
 
@@ -132,6 +156,7 @@ 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 )
@@ -139,26 +164,45 @@ static void st_program_string_notify( GLcontext *ctx,
    struct st_context *st = st_context(ctx);
 
    if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      struct st_fragment_program *p = (struct st_fragment_program *)prog;
+      struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
 
-      if (prog == &ctx->FragmentProgram._Current->Base)
-        st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+      stfp->serialNo++;
+
+#if 0
+      if (stfp->cso) {
+         /* free the TGSI code */
+         // cso_delete(stfp->vs);
+         stfp->cso = NULL;
+      }
+#endif
+
+      stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
 
-      p->id = program_id++;      
-      p->param_state = p->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 *p = (struct st_vertex_program *)prog;
+      struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
 
-      if (prog == &ctx->VertexProgram._Current->Base)
-        st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+      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;
+      }
 
-      p->id = program_id++;      
-      p->param_state = p->Base.Base.Parameters->StateFlags;
+      stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
 
-      /* Also tell tnl about it:
-       */
-      _tnl_program_string(ctx, target, prog);
+      if (st->vp == stvp)
+        st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
    }
 }
 
@@ -166,10 +210,8 @@ static void st_program_string_notify( GLcontext *ctx,
 
 void st_init_program_functions(struct dd_function_table *functions)
 {
-#if 0
-   assert(functions->ProgramStringNotify == _tnl_program_string); 
-#endif
    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;