summaryrefslogtreecommitdiff
path: root/src/mesa/tnl/t_vb_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/tnl/t_vb_program.c')
-rw-r--r--src/mesa/tnl/t_vb_program.c106
1 files changed, 82 insertions, 24 deletions
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 0a959a04af..9961af70ce 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -25,12 +25,13 @@
/**
* \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"
@@ -42,6 +43,46 @@
#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]);
+}
+
+
+/**
+ * Called via ctx->Driver.ProgramStringNotify() after a new vertex program
+ * string has been parsed.
+ */
+void
+_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
+{
+ /* No-op.
+ * If we had derived anything from the program that was private to this
+ * stage we'd recompute/validate it here.
+ */
+}
/*!
@@ -70,7 +111,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine)
MEMCPY(machine->VertAttribs, ctx->Current.Attrib,
MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat));
- if (ctx->VertexProgram.Current->IsNVProgram) {
+ if (ctx->VertexProgram._Current->IsNVProgram) {
GLuint i;
/* Output/result regs are initialized to [0,0,0,1] */
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
@@ -85,6 +126,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine)
}
}
+ machine->NumDeriv = 0;
+
/* init condition codes */
machine->CondCodes[0] = COND_EQ;
machine->CondCodes[1] = COND_EQ;
@@ -93,6 +136,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 */
}
@@ -202,19 +248,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 (ctx->VertexProgram.Current->IsNVProgram) {
+ if (program->IsNVProgram) {
_mesa_load_tracked_matrices(ctx);
}
else {
+ /* ARB program or vertex shader */
_mesa_load_state_parameters(ctx, program->Base.Parameters);
}
@@ -262,17 +303,6 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
/* execute the program */
_mesa_execute_program(ctx, &program->Base, &machine);
- /* Fixup fog an point size results if needed */
- if (ctx->Fog.Enabled &&
- (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) {
- machine.Outputs[VERT_RESULT_FOGC][0] = 1.0;
- }
-
- if (ctx->VertexProgram.PointSizeEnabled &&
- (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) {
- machine.Outputs[VERT_RESULT_PSIZ][0] = ctx->Point.Size;
- }
-
/* copy the output registers into the VB->attribs arrays */
for (j = 0; j < numOutputs; j++) {
const GLuint attr = outputs[j];
@@ -287,6 +317,23 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
#endif
}
+ /* Fixup fog and point size results if needed */
+ if (program->IsNVProgram) {
+ if (ctx->Fog.Enabled &&
+ (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) {
+ for (i = 0; i < VB->Count; i++) {
+ store->results[VERT_RESULT_FOGC].data[i][0] = 1.0;
+ }
+ }
+
+ if (ctx->VertexProgram.PointSizeEnabled &&
+ (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) {
+ for (i = 0; i < VB->Count; i++) {
+ store->results[VERT_RESULT_PSIZ].data[i][0] = ctx->Point.Size;
+ }
+ }
+ }
+
/* Setup the VB pointers so that the next pipeline stages get
* their data from the right place (the program output arrays).
*/
@@ -360,8 +407,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);
@@ -391,7 +438,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);
@@ -412,6 +460,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.
*/
@@ -421,6 +479,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 */
};