Added PRINT instruction for GL_NV_fragment_program.
This commit is contained in:
@@ -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
|
||||
@@ -130,6 +131,7 @@ static const struct instruction_pattern Instructions[] = {
|
||||
{ "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,11 +1348,17 @@ 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 (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) {
|
||||
if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
|
||||
@@ -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, ";"))
|
||||
|
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
@@ -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");
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
||||
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:
|
||||
|
Reference in New Issue
Block a user