Enable texture sampling for vertex programs/shaders.

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.
This commit is contained in:
Brian
2007-04-17 15:56:46 -06:00
parent d2d86a3f0b
commit 04bda46739
4 changed files with 70 additions and 20 deletions

View File

@@ -2921,17 +2921,24 @@ static void
update_texture_state( GLcontext *ctx ) update_texture_state( GLcontext *ctx )
{ {
GLuint unit; GLuint unit;
struct gl_fragment_program *fprog; struct gl_fragment_program *fprog = NULL;
struct gl_vertex_program *vprog = NULL;
if (ctx->Shader.CurrentProgram && if (ctx->Shader.CurrentProgram &&
ctx->Shader.CurrentProgram->LinkStatus) { ctx->Shader.CurrentProgram->LinkStatus) {
fprog = ctx->Shader.CurrentProgram->FragmentProgram; fprog = ctx->Shader.CurrentProgram->FragmentProgram;
} vprog = ctx->Shader.CurrentProgram->VertexProgram;
else if (ctx->FragmentProgram._Enabled) {
fprog = ctx->FragmentProgram.Current;
} }
else { 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 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 * by a fragment shader/program. When multiple flags are set, we'll
* settle on the one with highest priority (see texture_override below). * settle on the one with highest priority (see texture_override below).
*/ */
if (fprog) { if (fprog || vprog) {
enableBits = fprog->Base.TexturesUsed[unit]; enableBits = 0x0;
if (fprog)
enableBits |= fprog->Base.TexturesUsed[unit];
if (vprog)
enableBits |= vprog->Base.TexturesUsed[unit];
} }
else { else {
if (!texUnit->Enabled) if (!texUnit->Enabled)

View File

@@ -488,7 +488,7 @@ _swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state )
} }
static void void
_swrast_update_texture_samplers(GLcontext *ctx) _swrast_update_texture_samplers(GLcontext *ctx)
{ {
SWcontext *swrast = SWRAST_CONTEXT(ctx); SWcontext *swrast = SWRAST_CONTEXT(ctx);
@@ -617,7 +617,7 @@ _swrast_validate_derived( GLcontext *ctx )
_NEW_PROGRAM)) _NEW_PROGRAM))
_swrast_update_fragment_program( ctx, swrast->NewState ); _swrast_update_fragment_program( ctx, swrast->NewState );
if (swrast->NewState & _NEW_TEXTURE) if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
_swrast_update_texture_samplers( ctx ); _swrast_update_texture_samplers( ctx );
if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))

View File

@@ -228,6 +228,9 @@ typedef struct
extern void extern void
_swrast_validate_derived( GLcontext *ctx ); _swrast_validate_derived( GLcontext *ctx );
extern void
_swrast_update_texture_samplers(GLcontext *ctx);
#define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context) #define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context)

View File

@@ -25,12 +25,13 @@
/** /**
* \file tnl/t_vb_program.c * \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 * \author Brian Paul, Keith Whitwell
*/ */
#include "glheader.h" #include "glheader.h"
#include "colormac.h"
#include "context.h" #include "context.h"
#include "macros.h" #include "macros.h"
#include "imports.h" #include "imports.h"
@@ -42,6 +43,32 @@
#include "t_context.h" #include "t_context.h"
#include "t_pipeline.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 */ /* init call stack */
machine->StackDepth = 0; 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 outputs[VERT_RESULT_MAX], numOutputs;
GLuint i, j; GLuint i, j;
#define FORCE_PROG_EXECUTE_C 1
#if FORCE_PROG_EXECUTE_C
if (!program) if (!program)
return GL_TRUE; return GL_TRUE;
#else
if (!program || !program->IsNVProgram)
return GL_TRUE;
#endif
if (program->IsNVProgram) { if (program->IsNVProgram) {
_mesa_load_tracked_matrices(ctx); _mesa_load_tracked_matrices(ctx);
} }
else { else {
/* ARB program or vertex shader */
_mesa_load_state_parameters(ctx, program->Base.Parameters); _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 * Called the first time stage->run is called. In effect, don't
* allocate data until the first time the stage is run. * allocate data until the first time the stage is run.
*/ */
static GLboolean init_vp( GLcontext *ctx, static GLboolean
struct tnl_pipeline_stage *stage ) init_vp(GLcontext *ctx, struct tnl_pipeline_stage *stage)
{ {
TNLcontext *tnl = TNL_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &(tnl->vb); struct vertex_buffer *VB = &(tnl->vb);
@@ -411,7 +436,8 @@ static GLboolean init_vp( GLcontext *ctx,
/** /**
* Destructor for this pipeline stage. * 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); 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. * Public description of this pipeline stage.
*/ */
@@ -441,6 +477,6 @@ const struct tnl_pipeline_stage _tnl_vertex_program_stage =
NULL, /* private_data */ NULL, /* private_data */
init_vp, /* create */ init_vp, /* create */
dtr, /* destroy */ dtr, /* destroy */
NULL, /* validate */ validate_vp_stage, /* validate */
run_vp /* run -- initially set to ctr */ run_vp /* run -- initially set to ctr */
}; };