summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2004-12-18 16:18:00 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2004-12-18 16:18:00 +0000
commit2a5afe3ab8d4c3624ed72b99a11b6a9017078d1c (patch)
tree77c8b5ba0ac5fa4f941f060c3e4252ecf20b1153 /src/mesa
parent6cec977773c87ac95ca66089eb50850c9f0a27ed (diff)
Added PRINT instruction for GL_NV_fragment_program.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/shader/nvfragparse.c79
-rw-r--r--src/mesa/shader/nvfragprog.h6
-rw-r--r--src/mesa/shader/nvvertparse.c2
-rw-r--r--src/mesa/shader/program.c8
-rw-r--r--src/mesa/swrast/s_nvfragprog.c27
5 files changed, 107 insertions, 15 deletions
diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c
index 5c71b4b4dfe..bf1196cbf7f 100644
--- a/src/mesa/shader/nvfragparse.c
+++ b/src/mesa/shader/nvfragparse.c
@@ -58,6 +58,7 @@
#define INPUT_1V_T 7 /* one source vector, plus textureId */
#define INPUT_3V_T 8 /* one source vector, plus textureId */
#define INPUT_NONE 9
+#define INPUT_1V_S 10 /* a string and a vector register */
#define OUTPUT_V 20
#define OUTPUT_S 21
#define OUTPUT_NONE 22
@@ -95,7 +96,7 @@ static const struct instruction_pattern Instructions[] = {
{ "EX2", FP_OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "FLR", FP_OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "FRC", FP_OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "KIL", FP_OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 },
+ { "KIL", FP_OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 },
{ "LG2", FP_OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "LIT", FP_OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
{ "LRP", FP_OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
@@ -124,12 +125,13 @@ static const struct instruction_pattern Instructions[] = {
{ "SUB", FP_OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "TEX", FP_OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S },
{ "TXD", FP_OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S },
- { "TXP", FP_OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S },
+ { "TXP", FP_OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S },
{ "UP2H", FP_OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S },
{ "UP2US", FP_OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S },
{ "UP4B", FP_OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S },
{ "UP4UB", FP_OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S },
{ "X2D", FP_OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S },
+ { "PRINT", FP_OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 },
{ NULL, (enum fp_opcode) -1, 0, 0, 0 }
};
@@ -1190,6 +1192,60 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
}
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState,
+ struct fp_instruction *inst)
+{
+ const GLubyte *str;
+ GLubyte *msg;
+ GLuint len;
+
+ /* The first argument is a literal string 'just like this' */
+ if (!Parse_String(parseState, "'"))
+ RETURN_ERROR1("Expected '");
+
+ str = parseState->pos;
+ for (len = 0; str[len] != '\''; len++) /* find closing quote */
+ ;
+ parseState->pos += len + 1;
+ msg = _mesa_malloc(len + 1);
+
+ _mesa_memcpy(msg, str, len);
+ msg[len] = 0;
+ inst->Data = msg;
+
+ if (Parse_String(parseState, ",")) {
+ /* got an optional register to print */
+ GLubyte token[100];
+ GetToken(parseState, token);
+ if (token[0] == 'o') {
+ /* dst reg */
+ if (!Parse_OutputReg(parseState, &inst->SrcReg[0].Index))
+ RETURN_ERROR;
+ inst->SrcReg[0].File = PROGRAM_OUTPUT;
+ }
+ else {
+ /* src reg */
+ if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+ }
+ }
+ else {
+ /* File = 0 indicates no register to print */
+ inst->SrcReg[0].File = -1;
+ }
+
+ inst->SrcReg[0].Swizzle[0] = 0;
+ inst->SrcReg[0].Swizzle[1] = 1;
+ inst->SrcReg[0].Swizzle[2] = 2;
+ inst->SrcReg[0].Swizzle[3] = 3;
+ inst->SrcReg[0].NegateBase = GL_FALSE;
+ inst->SrcReg[0].Abs = GL_FALSE;
+ inst->SrcReg[0].NegateAbs = GL_FALSE;
+
+ return GL_TRUE;
+}
+
static GLboolean
Parse_InstructionSequence(struct parse_state *parseState,
@@ -1209,6 +1265,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
inst->DstReg.CondSwizzle[1] = 1;
inst->DstReg.CondSwizzle[2] = 2;
inst->DstReg.CondSwizzle[3] = 3;
+ inst->Data = NULL;
/* special instructions */
if (Parse_String(parseState, "DEFINE")) {
@@ -1291,10 +1348,16 @@ Parse_InstructionSequence(struct parse_state *parseState,
RETURN_ERROR1("Expected ,");
}
else if (instMatch.outputs == OUTPUT_NONE) {
- ASSERT(instMatch.opcode == FP_OPCODE_KIL_NV);
- /* This is a little weird, the cond code info is in the dest register */
- if (!Parse_CondCodeMask(parseState, &inst->DstReg))
- RETURN_ERROR;
+ if (instMatch.opcode == FP_OPCODE_KIL_NV) {
+ /* This is a little weird, the cond code info is in
+ * the dest register.
+ */
+ if (!Parse_CondCodeMask(parseState, &inst->DstReg))
+ RETURN_ERROR;
+ }
+ else {
+ ASSERT(instMatch.opcode == FP_OPCODE_PRINT);
+ }
}
if (instMatch.inputs == INPUT_1V) {
@@ -1362,6 +1425,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
&inst->TexSrcBit))
RETURN_ERROR;
}
+ else if (instMatch.inputs == INPUT_1V_S) {
+ if (!Parse_PrintInstruction(parseState, inst))
+ RETURN_ERROR;
+ }
/* end of statement semicolon */
if (!Parse_String(parseState, ";"))
diff --git a/src/mesa/shader/nvfragprog.h b/src/mesa/shader/nvfragprog.h
index 8f02f228770..ddfc4993ed5 100644
--- a/src/mesa/shader/nvfragprog.h
+++ b/src/mesa/shader/nvfragprog.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.3
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -117,6 +117,7 @@ enum fp_opcode {
FP_OPCODE_UP4UB, /* NV_f_p only */
FP_OPCODE_X2D, /* NV_f_p only - 2d mat mul */
FP_OPCODE_XPD, /* ARB_f_p only - cross product */
+ FP_OPCODE_PRINT, /* Mesa only */
FP_OPCODE_END /* private opcode */
};
@@ -158,6 +159,7 @@ struct fp_instruction
#if FEATURE_MESA_program_debug
GLint StringPos;
#endif
+ void *Data; /* some arbitrary data, only used for PRINT instruction now */
};
diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c
index e84cf9d5049..b02143a2e66 100644
--- a/src/mesa/shader/nvvertparse.c
+++ b/src/mesa/shader/nvvertparse.c
@@ -1402,7 +1402,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
program->IsPositionInvariant = parseState.isPositionInvariant;
program->IsNVProgram = GL_TRUE;
-#ifdef DEBUG
+#ifdef DEBUG_foo
_mesa_printf("--- glLoadProgramNV result ---\n");
_mesa_print_nv_vertex_program(program);
_mesa_printf("------------------------------\n");
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index ca0421181ce..307736f79ca 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -278,8 +278,14 @@ _mesa_delete_program(GLcontext *ctx, struct program *prog)
else if (prog->Target == GL_FRAGMENT_PROGRAM_NV ||
prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
struct fragment_program *fprog = (struct fragment_program *) prog;
- if (fprog->Instructions)
+ if (fprog->Instructions) {
+ GLuint i;
+ for (i = 0; i < fprog->Base.NumInstructions; i++) {
+ if (fprog->Instructions[i].Data)
+ _mesa_free(fprog->Instructions[i].Data);
+ }
_mesa_free(fprog->Instructions);
+ }
if (fprog->Parameters)
_mesa_free_parameter_list(fprog->Parameters);
}
diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c
index d083f83645d..5d9979c5c62 100644
--- a/src/mesa/swrast/s_nvfragprog.c
+++ b/src/mesa/swrast/s_nvfragprog.c
@@ -120,6 +120,11 @@ get_register_pointer( GLcontext *ctx,
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
src = machine->Inputs[source->Index];
break;
+ case PROGRAM_OUTPUT:
+ /* This is only for PRINT */
+ ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
+ src = machine->Outputs[source->Index];
+ break;
case PROGRAM_LOCAL_PARAM:
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
src = program->Base.LocalParams[source->Index];
@@ -128,10 +133,8 @@ get_register_pointer( GLcontext *ctx,
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS);
src = ctx->FragmentProgram.Parameters[source->Index];
break;
-
case PROGRAM_STATE_VAR:
- /* Fallthrough */
-
+ /* Fallthrough */
case PROGRAM_NAMED_PARAM:
ASSERT(source->Index < (GLint) program->Parameters->NumParameters);
src = program->Parameters->Parameters[source->Index].Values;
@@ -342,7 +345,7 @@ fetch_vector1( GLcontext *ctx,
}
-/*
+/**
* Test value against zero and return GT, LT, EQ or UN if NaN.
*/
static INLINE GLuint
@@ -357,7 +360,8 @@ generate_cc( float value )
return COND_EQ;
}
-/*
+
+/**
* Test if the ccMaskRule is satisfied by the given condition code.
* Used to mask destination writes according to the current condition codee.
*/
@@ -1306,6 +1310,19 @@ execute_program( GLcontext *ctx,
store_vector4( inst, machine, result );
}
break;
+ case FP_OPCODE_PRINT:
+ {
+ if (inst->SrcReg[0].File != -1) {
+ GLfloat a[4];
+ fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a);
+ _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
+ a[0], a[1], a[2], a[3]);
+ }
+ else {
+ _mesa_printf("%s\n", (const char *) inst->Data);
+ }
+ }
+ break;
case FP_OPCODE_END:
return GL_TRUE;
default: