diff options
Diffstat (limited to 'src/mesa/shader')
-rw-r--r-- | src/mesa/shader/arbprogparse.c | 19 | ||||
-rw-r--r-- | src/mesa/shader/descrip.mms | 6 | ||||
-rw-r--r-- | src/mesa/shader/prog_cache.c | 29 | ||||
-rw-r--r-- | src/mesa/shader/prog_cache.h | 2 | ||||
-rw-r--r-- | src/mesa/shader/prog_statevars.c | 27 | ||||
-rw-r--r-- | src/mesa/shader/prog_statevars.h | 1 | ||||
-rw-r--r-- | src/mesa/shader/program.c | 47 | ||||
-rw-r--r-- | src/mesa/shader/shader_api.c | 33 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 6 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_link.c | 2 |
10 files changed, 124 insertions, 48 deletions
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index f499499eb3a..536404bf978 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -64,12 +64,6 @@ having three separate program parameter arrays. #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 @@ -2609,7 +2603,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, /* 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 < Program->Base.Parameters->NumParameters); + assert(*Index < (GLint) Program->Base.Parameters->NumParameters); file = Program->Base.Parameters->Parameters[*Index].Type; if (file == PROGRAM_CONSTANT) *File = PROGRAM_CONSTANT; @@ -3443,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++; @@ -3798,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 = @@ -3843,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; @@ -3901,6 +3895,9 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, program->FogOption = ap.FogOption; program->UsesKill = ap.UsesKill; + if (program->FogOption) + program->Base.InputsRead |= FRAG_BIT_FOGC; + if (program->Base.Instructions) _mesa_free(program->Base.Instructions); program->Base.Instructions = ap.Base.Instructions; diff --git a/src/mesa/shader/descrip.mms b/src/mesa/shader/descrip.mms index bdac946efe2..19bafd48302 100644 --- a/src/mesa/shader/descrip.mms +++ b/src/mesa/shader/descrip.mms @@ -1,6 +1,6 @@ # Makefile for core library for VMS # contributed by Jouk Jansen [email protected] -# Last revision : 27 May 2008 +# Last revision : 29 September 2008 .first define gl [---.include.gl] define math [-.math] @@ -34,6 +34,7 @@ SOURCES = \ prog_instruction.c \ prog_parameter.c \ prog_print.c \ + prog_cache.c \ prog_statevars.c \ shader_api.c prog_uniform.c @@ -52,7 +53,7 @@ OBJECTS = \ prog_parameter.obj,\ prog_print.obj,\ prog_statevars.obj,\ - shader_api.obj,prog_uniform.obj + shader_api.obj,prog_uniform.obj,prog_cache.obj ##### RULES ##### @@ -91,3 +92,4 @@ prog_print.obj : prog_print.c prog_statevars.obj : prog_statevars.c shader_api.obj : shader_api.c prog_uniform.obj : prog_uniform.c +prog_cache.obj : prog_cache.c diff --git a/src/mesa/shader/prog_cache.c b/src/mesa/shader/prog_cache.c index 36a25377c55..9437e596138 100644 --- a/src/mesa/shader/prog_cache.c +++ b/src/mesa/shader/prog_cache.c @@ -44,6 +44,7 @@ struct cache_item struct gl_program_cache { struct cache_item **items; + struct cache_item *last; GLuint size, n_items; }; @@ -83,6 +84,8 @@ rehash(struct gl_program_cache *cache) struct cache_item *c, *next; GLuint size, i; + cache->last = NULL; + size = cache->size * 3; items = (struct cache_item**) _mesa_malloc(size * sizeof(*items)); _mesa_memset(items, 0, size * sizeof(*items)); @@ -105,6 +108,8 @@ clear_cache(GLcontext *ctx, struct gl_program_cache *cache) { struct cache_item *c, *next; GLuint i; + + cache->last = NULL; for (i = 0; i < cache->size; i++) { for (c = cache->items[i]; c; c = next) { @@ -149,18 +154,26 @@ _mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache) struct gl_program * -_mesa_search_program_cache(const struct gl_program_cache *cache, +_mesa_search_program_cache(struct gl_program_cache *cache, const void *key, GLuint keysize) { - const GLuint hash = hash_key(key, keysize); - struct cache_item *c; - - for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->hash == hash && memcmp(c->key, key, keysize) == 0) - return c->program; + if (cache->last && + memcmp(cache->last->key, key, keysize) == 0) { + return cache->last->program; } + else { + const GLuint hash = hash_key(key, keysize); + struct cache_item *c; + + for (c = cache->items[hash % cache->size]; c; c = c->next) { + if (c->hash == hash && memcmp(c->key, key, keysize) == 0) { + cache->last = c; + return c->program; + } + } - return NULL; + return NULL; + } } diff --git a/src/mesa/shader/prog_cache.h b/src/mesa/shader/prog_cache.h index a8c91fba011..4e1ccac03ff 100644 --- a/src/mesa/shader/prog_cache.h +++ b/src/mesa/shader/prog_cache.h @@ -42,7 +42,7 @@ _mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *pc); extern struct gl_program * -_mesa_search_program_cache(const struct gl_program_cache *cache, +_mesa_search_program_cache(struct gl_program_cache *cache, const void *key, GLuint keysize); extern void diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index d4e31207e84..34c47413506 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -395,6 +395,12 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], case STATE_INTERNAL: switch (state[1]) { + case STATE_CURRENT_ATTRIB: { + const GLuint idx = (GLuint) state[2]; + COPY_4V(value, ctx->Current.Attrib[idx]); + return; + } + case STATE_NORMAL_SCALE: ASSIGN_4V(value, ctx->_ModelViewInvScale, @@ -501,6 +507,9 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], } return; + /* XXX: make sure new tokens added here are also handled in the + * _mesa_program_state_flags() switch, below. + */ default: /* unknown state indexes are silently ignored * should be handled by the driver. @@ -574,11 +583,29 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) case STATE_INTERNAL: switch (state[1]) { + case STATE_CURRENT_ATTRIB: + return _NEW_CURRENT_ATTRIB; + + case STATE_NORMAL_SCALE: + return _NEW_MODELVIEW; + case STATE_TEXRECT_SCALE: case STATE_SHADOW_AMBIENT: return _NEW_TEXTURE; case STATE_FOG_PARAMS_OPTIMIZED: return _NEW_FOG; + case STATE_LIGHT_SPOT_DIR_NORMALIZED: + case STATE_LIGHT_POSITION: + case STATE_LIGHT_POSITION_NORMALIZED: + case STATE_LIGHT_HALF_VECTOR: + return _NEW_LIGHT; + + case STATE_PT_SCALE: + case STATE_PT_BIAS: + case STATE_PCM_SCALE: + case STATE_PCM_BIAS: + return _NEW_PIXEL; + default: /* unknown state indexes are silently ignored and * no flag set, since it is handled by the driver. diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 20643ca7947..72e51f40314 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h @@ -104,6 +104,7 @@ typedef enum gl_state_index_ { STATE_LOCAL, STATE_INTERNAL, /* Mesa additions */ + STATE_CURRENT_ATTRIB, /* ctx->Current vertex attrib value */ STATE_NORMAL_SCALE, STATE_TEXRECT_SCALE, STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index f120c20bdf2..37962f0e9bb 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -372,7 +372,11 @@ _mesa_reference_program(GLcontext *ctx, assert(ptr); if (*ptr && prog) { /* sanity check */ - ASSERT((*ptr)->Target == prog->Target); + if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB) + ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB); + else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB) + ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB || + prog->Target == GL_FRAGMENT_PROGRAM_NV); } if (*ptr == prog) { return; /* no change */ @@ -686,17 +690,47 @@ _mesa_combine_programs(GLcontext *ctx, if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprogA, *fprogB, *newFprog; + GLbitfield progB_inputsRead = progB->InputsRead; + GLint progB_colorFile, progB_colorIndex; + fprogA = (struct gl_fragment_program *) progA; fprogB = (struct gl_fragment_program *) progB; newFprog = (struct gl_fragment_program *) newProg; newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill; + /* We'll do a search and replace for instances + * of progB_colorFile/progB_colorIndex below... + */ + progB_colorFile = PROGRAM_INPUT; + progB_colorIndex = FRAG_ATTRIB_COL0; + + /* + * The fragment program may get color from a state var rather than + * a fragment input (vertex output) if it's constant. + * See the texenvprogram.c code. + * So, search the program's parameter list now to see if the program + * gets color from a state var instead of a conventional fragment + * input register. + */ + for (i = 0; i < progB->Parameters->NumParameters; i++) { + struct gl_program_parameter *p = &progB->Parameters->Parameters[i]; + if (p->Type == PROGRAM_STATE_VAR && + p->StateIndexes[0] == STATE_INTERNAL && + p->StateIndexes[1] == STATE_CURRENT_ATTRIB && + p->StateIndexes[2] == VERT_ATTRIB_COLOR0) { + progB_inputsRead |= FRAG_BIT_COL0; + progB_colorFile = PROGRAM_STATE_VAR; + progB_colorIndex = i; + break; + } + } + /* Connect color outputs of fprogA to color inputs of fprogB, via a * new temporary register. */ if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) && - (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) { + (progB_inputsRead & FRAG_BIT_COL0)) { GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY); if (tempReg < 0) { _mesa_problem(ctx, "No free temp regs found in " @@ -707,13 +741,14 @@ _mesa_combine_programs(GLcontext *ctx, replace_registers(newInst, lenA, PROGRAM_OUTPUT, FRAG_RESULT_COLR, PROGRAM_TEMPORARY, tempReg); - /* replace reads from input.color[0] with tempReg */ + /* replace reads from the input color with tempReg */ replace_registers(newInst + lenA, lenB, - PROGRAM_INPUT, FRAG_ATTRIB_COL0, - PROGRAM_TEMPORARY, tempReg); + progB_colorFile, progB_colorIndex, /* search for */ + PROGRAM_TEMPORARY, tempReg /* replace with */ ); } - inputsB = progB->InputsRead; + /* compute combined program's InputsRead */ + inputsB = progB_inputsRead; if (progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) { inputsB &= ~(1 << FRAG_ATTRIB_COL0); } diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 854f8bfdaa6..266ecc4ef21 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -47,7 +47,7 @@ #include "shader/shader_api.h" #include "shader/slang/slang_compile.h" #include "shader/slang/slang_link.h" - +#include "glapi/dispatch.h" #ifndef GL_PROGRAM_BINARY_LENGTH_OES @@ -455,7 +455,13 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) n = shProg->NumShaders; for (i = 0; i < n; i++) { if (shProg->Shaders[i] == sh) { - /* already attached */ + /* The shader is already attched to this program. The + * GL_ARB_shader_objects spec says: + * + * "The error INVALID_OPERATION is generated by AttachObjectARB + * if <obj> is already attached to <containerObj>." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); return; } } @@ -919,24 +925,15 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, static GLuint _mesa_get_handle(GLcontext *ctx, GLenum pname) { -#if 0 - GET_CURRENT_CONTEXT(ctx); - - switch (pname) { - case GL_PROGRAM_OBJECT_ARB: - { - struct gl2_program_intf **pro = ctx->Shader.CurrentProgram; - - if (pro != NULL) - return (**pro)._container._generic. - GetName((struct gl2_generic_intf **) (pro)); - } - break; - default: + GLint handle = 0; + + if (pname == GL_PROGRAM_OBJECT_ARB) { + CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle)); + } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); } -#endif - return 0; + + return handle; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 9e8daa10517..f3c3fa6c5b3 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1579,13 +1579,17 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) else { /* Variable array index */ struct prog_instruction *inst; + slang_ir_storage dstStore = *n->Store; /* do codegen for array index expression */ emit(emitInfo, n->Children[1]); inst = new_instruction(emitInfo, OPCODE_ARL); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + if (dstStore.Size > 4) + dstStore.Size = 4; /* only emit one instruction */ + + storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); inst->DstReg.File = PROGRAM_ADDRESS; diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index d884be2a75d..00e89537685 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -408,7 +408,7 @@ _slang_update_inputs_outputs(struct gl_program *prog) } } else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { - maxAddrReg = MAX2(maxAddrReg, inst->SrcReg[j].Index + 1); + maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1)); } } if (inst->DstReg.File == PROGRAM_OUTPUT) { |