/** * "Post-process" a GPU program. This is intended to be used for debugging. * Example actions include no-op'ing instructions or changing instruction * behaviour. */ void _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog) { static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 }; GLuint i; GLuint whiteSwizzle; GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters, (gl_constant_value *) white, 4, &whiteSwizzle); (void) whiteIndex; for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); (void) n; if (_mesa_is_tex_instruction(inst->Opcode)) { #if 0 /* replace TEX/TXP/TXB with MOV */ inst->Opcode = OPCODE_MOV; inst->DstReg.WriteMask = WRITEMASK_XYZW; inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; inst->SrcReg[0].Negate = NEGATE_NONE; #endif #if 0 /* disable shadow texture mode */ inst->TexShadow = 0; #endif } if (inst->Opcode == OPCODE_TXP) { #if 0 inst->Opcode = OPCODE_MOV; inst->DstReg.WriteMask = WRITEMASK_XYZW; inst->SrcReg[0].File = PROGRAM_CONSTANT; inst->SrcReg[0].Index = whiteIndex; inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; inst->SrcReg[0].Negate = NEGATE_NONE; #endif #if 0 inst->TexShadow = 0; #endif #if 0 inst->Opcode = OPCODE_TEX; inst->TexShadow = 0; #endif } } }
/** * Build the shProg->Uniforms list. * This is basically a list/index of all uniforms found in either/both of * the vertex and fragment shaders. * * About uniforms: * Each uniform has two indexes, one that points into the vertex * program's parameter array and another that points into the fragment * program's parameter array. When the user changes a uniform's value * we have to change the value in the vertex and/or fragment program's * parameter array. * * This function will be called twice to set up the two uniform->parameter * mappings. * * If a uniform is only present in the vertex program OR fragment program * then the fragment/vertex parameter index, respectively, will be -1. */ static GLboolean link_uniform_vars(GLcontext *ctx, struct gl_shader_program *shProg, struct gl_program *prog, GLuint *numSamplers) { GLuint samplerMap[200]; /* max number of samplers declared, not used */ GLuint i; for (i = 0; i < prog->Parameters->NumParameters; i++) { const struct gl_program_parameter *p = prog->Parameters->Parameters + i; /* * XXX FIX NEEDED HERE * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR. * For example, modelview matrix, light pos, etc. * Also, we need to update the state-var name-generator code to * generate GLSL-style names, like "gl_LightSource[0].position". * Furthermore, we'll need to fix the state-var's size/datatype info. */ if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) && p->Used) { /* add this uniform, indexing into the target's Parameters list */ struct gl_uniform *uniform = _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i); if (uniform) uniform->Initialized = p->Initialized; } /* The samplerMap[] table we build here is used to remap/re-index * sampler references by TEX instructions. */ if (p->Type == PROGRAM_SAMPLER && p->Used) { /* Allocate a new sampler index */ GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0]; GLuint newSampNum = *numSamplers; if (newSampNum >= ctx->Const.MaxTextureImageUnits) { char s[100]; sprintf(s, "Too many texture samplers (%u, max is %u)", newSampNum, ctx->Const.MaxTextureImageUnits); link_error(shProg, s); return GL_FALSE; } /* save old->new mapping in the table */ if (oldSampNum < Elements(samplerMap)) samplerMap[oldSampNum] = newSampNum; /* update parameter's sampler index */ prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum; (*numSamplers)++; } } /* OK, now scan the program/shader instructions looking for texture * instructions using sampler vars. Replace old sampler indexes with * new ones. */ prog->SamplersUsed = 0x0; for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; if (_mesa_is_tex_instruction(inst->Opcode)) { /* here, inst->TexSrcUnit is really the sampler unit */ const GLint oldSampNum = inst->TexSrcUnit; #if 0 printf("====== remap sampler from %d to %d\n", inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]); #endif if (oldSampNum < Elements(samplerMap)) { const GLuint newSampNum = samplerMap[oldSampNum]; inst->TexSrcUnit = newSampNum; prog->SamplerTargets[newSampNum] = inst->TexSrcTarget; prog->SamplersUsed |= (1 << newSampNum); if (inst->TexShadow) { prog->ShadowSamplers |= (1 << newSampNum); } } } } return GL_TRUE; }