From 2a5afe3ab8d4c3624ed72b99a11b6a9017078d1c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 18 Dec 2004 16:18:00 +0000 Subject: [PATCH] Added PRINT instruction for GL_NV_fragment_program. --- src/mesa/shader/nvfragparse.c | 79 ++++++++++++++++++++++++++++++++++++++---- src/mesa/shader/nvfragprog.h | 6 ++-- src/mesa/shader/nvvertparse.c | 2 +- src/mesa/shader/program.c | 8 ++++- src/mesa/swrast/s_nvfragprog.c | 27 ++++++++++++--- 5 files changed, 107 insertions(+), 15 deletions(-) diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index 5c71b4b..bf1196c 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 8f02f22..ddfc499 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 e84cf9d..b02143a 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 ca04211..307736f 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 d083f83..5d9979c 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: -- 2.7.4