diff options
Diffstat (limited to 'src/mesa/shader/arbprogparse.c')
-rw-r--r-- | src/mesa/shader/arbprogparse.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 39988b5fca6..536404bf978 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -30,6 +30,27 @@ * \author Karl Rasche */ +/** +Notes on program parameters, etc. + +The instructions we emit will use six kinds of source registers: + + PROGRAM_INPUT - input registers + PROGRAM_TEMPORARY - temp registers + PROGRAM_ADDRESS - address/indirect register + PROGRAM_SAMPLER - texture sampler + PROGRAM_CONSTANT - indexes into program->Parameters, a known constant/literal + PROGRAM_STATE_VAR - indexes into program->Parameters, and may actually be: + + a state variable, like "state.fog.color", or + + a pointer to a "program.local[k]" parameter, or + + a pointer to a "program.env[k]" parameter + +Basically, all the program.local[] and program.env[] values will get mapped +into the unified gl_program->Parameters array. This solves the problem of +having three separate program parameter arrays. +*/ + + #include "main/glheader.h" #include "main/imports.h" #include "main/context.h" @@ -38,16 +59,11 @@ #include "shader/grammar/grammar_mesa.h" #include "arbprogparse.h" #include "program.h" +#include "programopt.h" #include "prog_parameter.h" #include "prog_statevars.h" #include "prog_instruction.h" - -/* For ARB programs, use the NV instruction limits */ -#define MAX_INSTRUCTIONS MAX2(MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS, \ - MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) - - /** * This is basically a union of the vertex_program and fragment_program * structs that we can use to parse the program into @@ -1870,7 +1886,11 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, const_values, 4); if (param_var->param_binding_begin == ~0U) param_var->param_binding_begin = idx; - param_var->param_binding_type = PROGRAM_CONSTANT; + param_var->param_binding_type = PROGRAM_STATE_VAR; + /* Note: when we reference this parameter in an instruction later, + * we'll check if it's really a constant/immediate and set the + * instruction register type appropriately. + */ param_var->param_binding_length++; Program->Base.NumParameters++; break; @@ -2577,6 +2597,18 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, return 1; } + if (*File == PROGRAM_STATE_VAR) { + enum register_file file; + + /* If we're referencing the Program->Parameters[] array, check if the + * parameter is really a constant/literal. If so, set File to CONSTANT. + */ + assert(*Index < (GLint) Program->Base.Parameters->NumParameters); + file = Program->Base.Parameters->Parameters[*Index].Type; + if (file == PROGRAM_CONSTANT) + *File = PROGRAM_CONSTANT; + } + /* Add attributes to InputsRead only if they are used the program. * This avoids the handling of unused ATTRIB declarations in the drivers. */ if (*File == PROGRAM_INPUT) @@ -3353,11 +3385,11 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, fprintf (stderr, "%s\n", Program->Base.Parameters->Parameters[a + b].Name); if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) { - const char *s; + char *s; s = _mesa_program_state_string(Program->Base.Parameters->Parameters [a + b].StateIndexes); fprintf(stderr, "%s\n", s); - _mesa_free((char *) s); + _mesa_free(s); } else fprintf (stderr, "%f %f %f %f\n", @@ -3405,7 +3437,7 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst, : ctx->Const.VertexProgram.MaxInstructions; GLint err = 0; - ASSERT(MAX_INSTRUCTIONS >= maxInst); + ASSERT(MAX_PROGRAM_INSTRUCTIONS >= maxInst); Program->MajorVersion = (GLuint) * inst++; Program->MinorVersion = (GLuint) * inst++; @@ -3760,7 +3792,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, /* Initialize the arb_program struct */ program->Base.String = strz; - program->Base.Instructions = _mesa_alloc_instructions(MAX_INSTRUCTIONS); + program->Base.Instructions = _mesa_alloc_instructions(MAX_PROGRAM_INSTRUCTIONS); program->Base.NumInstructions = program->Base.NumTemporaries = program->Base.NumParameters = @@ -3805,12 +3837,12 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, _mesa_free (parsed); - /* Reallocate the instruction array from size [MAX_INSTRUCTIONS] + /* Reallocate the instruction array from size [MAX_PROGRAM_INSTRUCTIONS] * to size [ap.Base.NumInstructions]. */ program->Base.Instructions = _mesa_realloc_instructions(program->Base.Instructions, - MAX_INSTRUCTIONS, + MAX_PROGRAM_INSTRUCTIONS, program->Base.NumInstructions); return !err; @@ -3874,6 +3906,16 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, _mesa_free_parameter_list(program->Base.Parameters); program->Base.Parameters = ap.Base.Parameters; + /* Append fog instructions now if the program has "OPTION ARB_fog_exp" + * or similar. We used to leave this up to drivers, but it appears + * there's no hardware that wants to do fog in a discrete stage separate + * from the fragment shader. + */ + if (program->FogOption != GL_NONE) { + _mesa_append_fog_code(ctx, program); + program->FogOption = GL_NONE; + } + #if DEBUG_FP _mesa_printf("____________Fragment program %u ________\n", program->Base.Id); _mesa_print_program(&program->Base); |