aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/shader/program.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/shader/program.c')
-rw-r--r--mesalib/src/mesa/shader/program.c96
1 files changed, 59 insertions, 37 deletions
diff --git a/mesalib/src/mesa/shader/program.c b/mesalib/src/mesa/shader/program.c
index 6b8d94e66..f4f701b54 100644
--- a/mesalib/src/mesa/shader/program.c
+++ b/mesalib/src/mesa/shader/program.c
@@ -127,11 +127,11 @@ _mesa_free_program_data(GLcontext *ctx)
if (ctx->ATIFragmentShader.Current) {
ctx->ATIFragmentShader.Current->RefCount--;
if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
- _mesa_free(ctx->ATIFragmentShader.Current);
+ free(ctx->ATIFragmentShader.Current);
}
}
#endif
- _mesa_free((void *) ctx->Program.ErrorString);
+ free((void *) ctx->Program.ErrorString);
}
@@ -162,7 +162,7 @@ _mesa_update_default_objects_program(GLcontext *ctx)
if (ctx->ATIFragmentShader.Current) {
ctx->ATIFragmentShader.Current->RefCount--;
if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
- _mesa_free(ctx->ATIFragmentShader.Current);
+ free(ctx->ATIFragmentShader.Current);
}
}
ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
@@ -180,7 +180,7 @@ void
_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string)
{
ctx->Program.ErrorPos = pos;
- _mesa_free((void *) ctx->Program.ErrorString);
+ free((void *) ctx->Program.ErrorString);
if (!string)
string = "";
ctx->Program.ErrorString = _mesa_strdup(string);
@@ -190,7 +190,7 @@ _mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string)
/**
* Find the line number and column for 'pos' within 'string'.
* Return a copy of the line which contains 'pos'. Free the line with
- * _mesa_free().
+ * free().
* \param string the program string
* \param pos the position within the string
* \param line returns the line number corresponding to 'pos'.
@@ -222,8 +222,8 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
while (*p != 0 && *p != '\n')
p++;
len = p - lineStart;
- s = (GLubyte *) _mesa_malloc(len + 1);
- _mesa_memcpy(s, lineStart, len);
+ s = (GLubyte *) malloc(len + 1);
+ memcpy(s, lineStart, len);
s[len] = 0;
return s;
@@ -240,7 +240,7 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
(void) ctx;
if (prog) {
GLuint i;
- _mesa_bzero(prog, sizeof(*prog));
+ memset(prog, 0, sizeof(*prog));
prog->Id = id;
prog->Target = target;
prog->Resident = GL_TRUE;
@@ -337,7 +337,7 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
return;
if (prog->String)
- _mesa_free(prog->String);
+ free(prog->String);
_mesa_free_instructions(prog->Instructions, prog->NumInstructions);
@@ -351,7 +351,7 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
_mesa_free_parameter_list(prog->Attributes);
}
- _mesa_free(prog);
+ free(prog);
}
@@ -505,6 +505,8 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
fpc->FogOption = fp->FogOption;
fpc->UsesKill = fp->UsesKill;
+ fpc->OriginUpperLeft = fp->OriginUpperLeft;
+ fpc->PixelCenterInteger = fp->PixelCenterInteger;
}
break;
default:
@@ -580,7 +582,7 @@ _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
for (i = 0; i < prog->NumInstructions; i++) {
struct prog_instruction *inst = prog->Instructions + i;
if (inst->BranchTarget > 0) {
- if (inst->BranchTarget > start) {
+ if (inst->BranchTarget > (GLint) start) {
inst->BranchTarget -= count;
}
}
@@ -677,6 +679,8 @@ _mesa_combine_programs(GLcontext *ctx,
const GLuint lenB = progB->NumInstructions;
const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
const GLuint newLength = lenA + lenB;
+ GLboolean usedTemps[MAX_PROGRAM_TEMPS];
+ GLuint firstTemp = 0;
GLbitfield inputsB;
GLuint i;
@@ -698,6 +702,10 @@ _mesa_combine_programs(GLcontext *ctx,
newProg->Instructions = newInst;
newProg->NumInstructions = newLength;
+ /* find used temp regs (we may need new temps below) */
+ _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY,
+ usedTemps, MAX_PROGRAM_TEMPS);
+
if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
struct gl_fragment_program *fprogA, *fprogB, *newFprog;
GLbitfield progB_inputsRead = progB->InputsRead;
@@ -741,12 +749,15 @@ _mesa_combine_programs(GLcontext *ctx,
*/
if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) &&
(progB_inputsRead & FRAG_BIT_COL0)) {
- GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
+ GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS,
+ firstTemp);
if (tempReg < 0) {
_mesa_problem(ctx, "No free temp regs found in "
"_mesa_combine_programs(), using 31");
tempReg = 31;
}
+ firstTemp = tempReg + 1;
+
/* replace writes to result.color[0] with tempReg */
replace_registers(newInst, lenA,
PROGRAM_OUTPUT, FRAG_RESULT_COLOR,
@@ -784,53 +795,64 @@ _mesa_combine_programs(GLcontext *ctx,
}
-
-
/**
- * Scan the given program to find a free register of the given type.
- * \param regFile - PROGRAM_INPUT, PROGRAM_OUTPUT or PROGRAM_TEMPORARY
+ * Populate the 'used' array with flags indicating which registers (TEMPs,
+ * INPUTs, OUTPUTs, etc, are used by the given program.
+ * \param file type of register to scan for
+ * \param used returns true/false flags for in use / free
+ * \param usedSize size of the 'used' array
*/
-GLint
-_mesa_find_free_register(const struct gl_program *prog, GLuint regFile)
+void
+_mesa_find_used_registers(const struct gl_program *prog,
+ gl_register_file file,
+ GLboolean used[], GLuint usedSize)
{
- GLboolean used[MAX_PROGRAM_TEMPS];
- GLuint i, k;
-
- assert(regFile == PROGRAM_INPUT ||
- regFile == PROGRAM_OUTPUT ||
- regFile == PROGRAM_TEMPORARY);
+ GLuint i, j;
- _mesa_memset(used, 0, sizeof(used));
+ memset(used, 0, usedSize);
for (i = 0; i < prog->NumInstructions; i++) {
const struct prog_instruction *inst = prog->Instructions + i;
const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
- /* check dst reg first */
- if (inst->DstReg.File == regFile) {
+ if (inst->DstReg.File == file) {
used[inst->DstReg.Index] = GL_TRUE;
}
- else {
- /* check src regs otherwise */
- for (k = 0; k < n; k++) {
- if (inst->SrcReg[k].File == regFile) {
- used[inst->SrcReg[k].Index] = GL_TRUE;
- break;
- }
+
+ for (j = 0; j < n; j++) {
+ if (inst->SrcReg[j].File == file) {
+ used[inst->SrcReg[j].Index] = GL_TRUE;
}
}
}
+}
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+
+/**
+ * Scan the given 'used' register flag array for the first entry
+ * that's >= firstReg.
+ * \param used vector of flags indicating registers in use (as returned
+ * by _mesa_find_used_registers())
+ * \param usedSize size of the 'used' array
+ * \param firstReg first register to start searching at
+ * \return index of unused register, or -1 if none.
+ */
+GLint
+_mesa_find_free_register(const GLboolean used[],
+ GLuint usedSize, GLuint firstReg)
+{
+ GLuint i;
+
+ assert(firstReg < usedSize);
+
+ for (i = firstReg; i < usedSize; i++)
if (!used[i])
return i;
- }
return -1;
}
-
/**
* "Post-process" a GPU program. This is intended to be used for debugging.
* Example actions include no-op'ing instructions or changing instruction