Enable texture sampling for vertex programs/shaders.
authorBrian <brian@yutani.localnet.net>
Tue, 17 Apr 2007 21:56:46 +0000 (15:56 -0600)
committerBrian <brian@yutani.localnet.net>
Tue, 17 Apr 2007 21:56:46 +0000 (15:56 -0600)
This is a bit of a hack for now because the tnl module is using the swrast
module to fetch texels.  The texture fetch/filter code should probably be
moved into the main/ module since it doesn't really depend upon other
swrast code.

src/mesa/main/texstate.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/tnl/t_vb_program.c

index 51e19b7f4e7a589dea938c4dad9f2d1f98a12548..197e8212ad0b26934621fc1006883e79c6bd0ac4 100644 (file)
@@ -2921,17 +2921,24 @@ static void
 update_texture_state( GLcontext *ctx )
 {
    GLuint unit;
-   struct gl_fragment_program *fprog;
+   struct gl_fragment_program *fprog = NULL;
+   struct gl_vertex_program *vprog = NULL;
 
    if (ctx->Shader.CurrentProgram &&
        ctx->Shader.CurrentProgram->LinkStatus) {
       fprog = ctx->Shader.CurrentProgram->FragmentProgram;
-   }
-   else if (ctx->FragmentProgram._Enabled) {
-      fprog = ctx->FragmentProgram.Current;
+      vprog = ctx->Shader.CurrentProgram->VertexProgram;
    }
    else {
-      fprog = NULL;
+      if (ctx->FragmentProgram._Enabled) {
+         fprog = ctx->FragmentProgram.Current;
+      }
+      if (ctx->VertexProgram._Enabled) {
+         /* XXX enable this if/when non-shader vertex programs get
+          * texture fetches:
+         vprog = ctx->VertexProgram.Current;
+         */
+      }
    }
 
    ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 
@@ -2960,8 +2967,12 @@ update_texture_state( GLcontext *ctx )
        * by a fragment shader/program.  When multiple flags are set, we'll
        * settle on the one with highest priority (see texture_override below).
        */
-      if (fprog) {
-         enableBits = fprog->Base.TexturesUsed[unit];
+      if (fprog || vprog) {
+         enableBits = 0x0;
+         if (fprog)
+            enableBits |= fprog->Base.TexturesUsed[unit];
+         if (vprog)
+            enableBits |= vprog->Base.TexturesUsed[unit];
       }
       else {
          if (!texUnit->Enabled)
index e113adb68928bfc89238e665c621e67ef7d4438c..c8efb962d0336d793b453a8fd4872b592d99a655 100644 (file)
@@ -488,7 +488,7 @@ _swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state )
 }
 
 
-static void
+void
 _swrast_update_texture_samplers(GLcontext *ctx)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
@@ -617,7 +617,7 @@ _swrast_validate_derived( GLcontext *ctx )
                               _NEW_PROGRAM))
         _swrast_update_fragment_program( ctx, swrast->NewState );
 
-      if (swrast->NewState & _NEW_TEXTURE)
+      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
          _swrast_update_texture_samplers( ctx );
 
       if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
index 3a9a48922ef08e92b378d7ee3dcf562d4d407fba..1cf3813fd360844f9c838cc20309de34612ac9b9 100644 (file)
@@ -228,6 +228,9 @@ typedef struct
 extern void
 _swrast_validate_derived( GLcontext *ctx );
 
+extern void
+_swrast_update_texture_samplers(GLcontext *ctx);
+
 
 #define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context)
 
index 3d7ea3a06abad622f6461e94378efe0d126c9cb6..81e166bde50ed3092b9980dad171a58adcb313c0 100644 (file)
 
 /**
  * \file tnl/t_vb_program.c
- * \brief Pipeline stage for executing NVIDIA vertex programs.
+ * \brief Pipeline stage for executing vertex programs.
  * \author Brian Paul,  Keith Whitwell
  */
 
 
 #include "glheader.h"
+#include "colormac.h"
 #include "context.h"
 #include "macros.h"
 #include "imports.h"
 #include "t_context.h"
 #include "t_pipeline.h"
 
+#include "swrast/s_context.h"
+#include "swrast/s_texfilter.h"
+
+/**
+ * XXX the texture sampling code in this module is a bit of a hack.
+ * The texture sampling code is in swrast, though it doesn't have any
+ * real dependencies on the rest of swrast.  It should probably be
+ * moved into main/ someday.
+ */
+
+static void
+vp_fetch_texel(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
+               GLuint unit, GLfloat color[4])
+{
+   GLchan rgba[4];
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+   /* XXX use a float-valued TextureSample routine here!!! */
+   swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,
+                               1, (const GLfloat (*)[4]) texcoord,
+                               &lambda, &rgba);
+   color[0] = CHAN_TO_FLOAT(rgba[0]);
+   color[1] = CHAN_TO_FLOAT(rgba[1]);
+   color[2] = CHAN_TO_FLOAT(rgba[2]);
+   color[3] = CHAN_TO_FLOAT(rgba[3]);
+}
 
 
 /**
@@ -107,6 +134,9 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine)
 
    /* init call stack */
    machine->StackDepth = 0;
+
+   machine->FetchTexelLod = vp_fetch_texel;
+   machine->FetchTexelDeriv = NULL; /* not used by vertex programs */
 }
 
 
@@ -216,19 +246,14 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
    GLuint outputs[VERT_RESULT_MAX], numOutputs;
    GLuint i, j;
 
-#define FORCE_PROG_EXECUTE_C 1
-#if FORCE_PROG_EXECUTE_C
    if (!program)
       return GL_TRUE;
-#else
-   if (!program || !program->IsNVProgram)
-      return GL_TRUE;
-#endif
 
    if (program->IsNVProgram) {
       _mesa_load_tracked_matrices(ctx);
    }
    else {
+      /* ARB program or vertex shader */
       _mesa_load_state_parameters(ctx, program->Base.Parameters);
    }
 
@@ -380,8 +405,8 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
  * Called the first time stage->run is called.  In effect, don't
  * allocate data until the first time the stage is run.
  */
-static GLboolean init_vp( GLcontext *ctx,
-                         struct tnl_pipeline_stage *stage )
+static GLboolean
+init_vp(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &(tnl->vb);
@@ -411,7 +436,8 @@ static GLboolean init_vp( GLcontext *ctx,
 /**
  * Destructor for this pipeline stage.
  */
-static void dtr( struct tnl_pipeline_stage *stage )
+static void
+dtr(struct tnl_pipeline_stage *stage)
 {
    struct vp_stage_data *store = VP_STAGE_DATA(stage);
 
@@ -432,6 +458,16 @@ static void dtr( struct tnl_pipeline_stage *stage )
 }
 
 
+static void
+validate_vp_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
+{
+   if (ctx->VertexProgram._Current) {
+      _swrast_update_texture_samplers(ctx);
+   }
+}
+
+
+
 /**
  * Public description of this pipeline stage.
  */
@@ -441,6 +477,6 @@ const struct tnl_pipeline_stage _tnl_vertex_program_stage =
    NULL,                       /* private_data */
    init_vp,                    /* create */
    dtr,                                /* destroy */
-   NULL,                       /* validate */
+   validate_vp_stage,          /* validate */
    run_vp                      /* run -- initially set to ctr */
 };