From b730d0d3e9b202b17a0815cb820fc9905f35cb98 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Nov 2008 13:04:04 -0700 Subject: [PATCH] mesa: add gl_program::Input/OutputFlags[] array These arrays will indicate per-input or per-output options for vertex/fragment programs such as centroid-sampling and invariance. --- src/mesa/main/config.h | 2 ++ src/mesa/main/mtypes.h | 3 +++ src/mesa/shader/prog_execute.h | 6 ++--- src/mesa/shader/slang/slang_link.c | 42 ++++++++++++++++++------------ 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 882e2f224ae..f1f12b8a0ed 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -193,6 +193,8 @@ #define MAX_UNIFORMS 128 /**< number of float components */ #define MAX_VARYING 8 /**< number of float[4] vectors */ #define MAX_SAMPLERS 8 +#define MAX_PROGRAM_INPUTS 32 +#define MAX_PROGRAM_OUTPUTS 32 /*@}*/ /** For GL_NV_vertex_program */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 284f81b7cf8..9b40d8fb6cc 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1873,10 +1873,13 @@ struct gl_program GLbitfield InputsRead; /**< Bitmask of which input regs are read */ GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */ + GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */ + GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */ GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */ GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */ GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */ + /** Named parameters, constants, etc. from program text */ struct gl_program_parameter_list *Parameters; /** Numbered local parameters */ diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h index 18b13e11a41..8ceb7b092e8 100644 --- a/src/mesa/shader/prog_execute.h +++ b/src/mesa/shader/prog_execute.h @@ -25,6 +25,8 @@ #ifndef PROG_EXECUTE_H #define PROG_EXECUTE_H +#include "main/config.h" + typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, GLuint unit, GLfloat color[4]); @@ -36,10 +38,6 @@ typedef void (*FetchTexelDerivFunc)(GLcontext *ctx, const GLfloat texcoord[4], GLuint unit, GLfloat color[4]); -/** The larger of VERT_RESULT_MAX, FRAG_RESULT_MAX */ -#define MAX_PROGRAM_OUTPUTS VERT_RESULT_MAX - - /** * Virtual machine state used during execution of vertex/fragment programs. */ diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 6b895013afe..08d75403723 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -89,16 +89,39 @@ bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit) * Linking varying vars involves rearranging varying vars so that the * vertex program's output varyings matches the order of the fragment * program's input varyings. + * We'll then rewrite instructions to replace PROGRAM_VARYING with either + * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or + * fragment shader. + * This is also where we set program Input/OutputFlags to indicate + * which inputs are centroid-sampled, invariant, etc. */ static GLboolean link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) { GLuint *map, i, firstVarying, newFile; + GLbitfield *inOutFlags; map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint)); if (!map) return GL_FALSE; + /* Varying variables are treated like other vertex program outputs + * (and like other fragment program inputs). The position of the + * first varying differs for vertex/fragment programs... + * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT. + */ + if (prog->Target == GL_VERTEX_PROGRAM_ARB) { + firstVarying = VERT_RESULT_VAR0; + newFile = PROGRAM_OUTPUT; + inOutFlags = prog->OutputFlags; + } + else { + assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); + firstVarying = FRAG_ATTRIB_VAR0; + newFile = PROGRAM_INPUT; + inOutFlags = prog->InputFlags; + } + for (i = 0; i < prog->Varying->NumParameters; i++) { /* see if this varying is in the linked varying list */ const struct gl_program_parameter *var = prog->Varying->Parameters + i; @@ -132,12 +155,14 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) var->Flags); } - /* map varying[i] to varying[j]. + /* Map varying[i] to varying[j]. + * Plus, set prog->Input/OutputFlags[] as described above. * Note: the loop here takes care of arrays or large (sz>4) vars. */ { GLint sz = var->Size; while (sz > 0) { + inOutFlags[firstVarying + j] = var->Flags; /*printf("Link varying from %d to %d\n", i, j);*/ map[i++] = j++; sz -= 4; @@ -147,21 +172,6 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) } - /* Varying variables are treated like other vertex program outputs - * (and like other fragment program inputs). The position of the - * first varying differs for vertex/fragment programs... - * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT. - */ - if (prog->Target == GL_VERTEX_PROGRAM_ARB) { - firstVarying = VERT_RESULT_VAR0; - newFile = PROGRAM_OUTPUT; - } - else { - assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); - firstVarying = FRAG_ATTRIB_VAR0; - newFile = PROGRAM_INPUT; - } - /* OK, now scan the program/shader instructions looking for varying vars, * replacing the old index with the new index. */ -- 2.30.2