file == PROGRAM_STATE_VAR ||
file == PROGRAM_NAMED_PARAM ||
file == PROGRAM_CONSTANT ||
+ file == PROGRAM_SAMPLER ||
file == PROGRAM_UNIFORM);
}
{
GLuint *map, i;
+#if 0
+ printf("================ pre link uniforms ===============\n");
+ _mesa_print_parameter_list(shProg->Uniforms);
+#endif
+
map = (GLuint *) malloc(prog->Parameters->NumParameters * sizeof(GLuint));
if (!map)
return GL_FALSE;
- for (i = 0; i < prog->Parameters->NumParameters; i++) {
+ for (i = 0; i < prog->Parameters->NumParameters; /* incr below*/) {
/* see if this uniform is in the linked uniform list */
const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
const GLfloat *pVals = prog->Parameters->ParameterValues[i];
GLint j;
+ GLint size;
/* sanity check */
assert(is_uniform(p->Type));
if (j >= 0) {
/* already in list, check size XXX check this */
+#if 0
assert(p->Size == shProg->Uniforms->Parameters[j].Size);
+#endif
}
else {
/* not already in linked list */
switch (p->Type) {
case PROGRAM_ENV_PARAM:
j = _mesa_add_named_parameter(shProg->Uniforms, p->Name, pVals);
+ break;
case PROGRAM_CONSTANT:
j = _mesa_add_named_constant(shProg->Uniforms, p->Name, pVals, p->Size);
break;
case PROGRAM_UNIFORM:
j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size);
break;
+ case PROGRAM_SAMPLER:
+ j = _mesa_add_sampler(shProg->Uniforms, p->Name);
+ break;
default:
abort();
}
}
ASSERT(j >= 0);
- map[i] = j;
+ size = p->Size;
+ while (size > 0) {
+ map[i] = j;
+ i++;
+ j++;
+ size -= 4;
+ }
+
}
+#if 0
+ printf("================ post link uniforms ===============\n");
+ _mesa_print_parameter_list(shProg->Uniforms);
+#endif
- /* OK, now scan the program/shader instructions looking for varying vars,
+#if 0
+ {
+ GLuint i;
+ for (i = 0; i < prog->Parameters->NumParameters; i++) {
+ printf("map[%d] = %d\n", i, map[i]);
+ }
+ _mesa_print_parameter_list(shProg->Uniforms);
+ }
+#endif
+
+ /* OK, now scan the program/shader instructions looking for uniform vars,
* replacing the old index with the new index.
*/
for (i = 0; i < prog->NumInstructions; i++) {
inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ];
}
}
- /* XXX update program OutputsWritten, InputsRead */
+
+ if (inst->Opcode == OPCODE_TEX ||
+ inst->Opcode == OPCODE_TXB ||
+ inst->Opcode == OPCODE_TXP) {
+ printf("====== remap sampler from %d to %d\n",
+ inst->Sampler, map[ inst->Sampler ]);
+ inst->Sampler = map[ inst->Sampler ];
+ }
}
free(map);
* XXX Temporary
*/
static void
-slang_resolve_branches(struct gl_program *prog)
+_slang_resolve_branches(struct gl_program *prog)
{
struct target {
const char *Name;
}
+/**
+ * Scan program for texture instructions, lookup sampler/uniform's value
+ * to determine which texture unit to use.
+ * Also, update the program's TexturesUsed[] array.
+ */
+void
+_slang_resolve_samplers(struct gl_shader_program *shProg,
+ struct gl_program *prog)
+{
+ GLuint i;
+
+ for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+ prog->TexturesUsed[i] = 0;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->Opcode == OPCODE_TEX ||
+ inst->Opcode == OPCODE_TXB ||
+ inst->Opcode == OPCODE_TXP) {
+ GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0];
+ assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS);
+ inst->TexSrcUnit = sampleUnit;
+
+ prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget);
+ }
+ }
+}
+
+
+/**
+ * Scan program instructions to update the program's InputsRead and
+ * OutputsWritten fields.
+ */
+static void
+_slang_update_inputs_outputs(struct gl_program *prog)
+{
+ GLuint i, j;
+
+ prog->InputsRead = 0x0;
+ prog->OutputsWritten = 0x0;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_INPUT) {
+ prog->InputsRead |= 1 << inst->SrcReg[j].Index;
+ }
+ }
+ if (inst->DstReg.File == PROGRAM_OUTPUT) {
+ prog->OutputsWritten |= 1 << inst->DstReg.Index;
+ }
+ }
+}
+
+
+
/** cast wrapper */
static struct gl_vertex_program *
vertex_program(struct gl_program *prog)
shProg->VertexProgram->Base.Parameters = shProg->Uniforms;
shProg->FragmentProgram->Base.Parameters = shProg->Uniforms;
- slang_resolve_branches(&shProg->VertexProgram->Base);
- slang_resolve_branches(&shProg->FragmentProgram->Base);
+ _slang_resolve_branches(&shProg->VertexProgram->Base);
+ _slang_resolve_branches(&shProg->FragmentProgram->Base);
+#if 1
+ _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
+ _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
+#endif
+ _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
+ _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
#if 1
printf("************** original fragment program\n");