Unify vertex/fragment program instuctions.

Based on patch by Ian (#4967) but also unify instruction opcodes.
This commit is contained in:
Brian Paul
2005-11-05 17:10:45 +00:00
parent 73347516be
commit 7e807510d8
31 changed files with 1170 additions and 1067 deletions

View File

@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.1
* Version: 6.5
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2005 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"),
@@ -43,7 +43,7 @@
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "nvfragprog.h"
#include "program_instruction.h"
#include "nvfragparse.h"
#include "nvprogram.h"
#include "program.h"
@@ -79,60 +79,60 @@
struct instruction_pattern {
const char *name;
enum fp_opcode opcode;
enum prog_opcode opcode;
GLuint inputs;
GLuint outputs;
GLuint suffixes;
};
static const struct instruction_pattern Instructions[] = {
{ "ADD", FP_OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "COS", FP_OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "DDX", FP_OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
{ "DDY", FP_OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
{ "DP3", FP_OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
{ "DP4", FP_OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
{ "DST", FP_OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
{ "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 },
{ "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 },
{ "MAD", FP_OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MAX", FP_OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MIN", FP_OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MOV", FP_OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MUL", FP_OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "PK2H", FP_OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 },
{ "PK2US", FP_OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 },
{ "PK4B", FP_OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 },
{ "PK4UB", FP_OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 },
{ "POW", FP_OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S },
{ "RCP", FP_OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "RFL", FP_OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
{ "RSQ", FP_OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "SEQ", FP_OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SFL", FP_OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SGE", FP_OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SGT", FP_OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SIN", FP_OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "SLE", FP_OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SLT", FP_OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SNE", FP_OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "STR", FP_OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "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 },
{ "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 }
{ "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
{ "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
{ "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
{ "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
{ "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
{ "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 },
{ "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
{ "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "PK2H", OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 },
{ "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 },
{ "PK4B", OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 },
{ "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 },
{ "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S },
{ "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
{ "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
{ "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
{ "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S },
{ "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S },
{ "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S },
{ "UP2H", OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S },
{ "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S },
{ "UP4B", OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S },
{ "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S },
{ "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S },
{ "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 },
{ NULL, (enum prog_opcode) -1, 0, 0, 0 }
};
@@ -248,7 +248,7 @@ MatchInstruction(const GLubyte *token)
return result;
}
}
result.opcode = (enum fp_opcode) -1;
result.opcode = (enum prog_opcode) -1;
return result;
}
@@ -668,7 +668,7 @@ Parse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
static GLboolean
Parse_CondCodeMask(struct parse_state *parseState,
struct fp_dst_register *dstReg)
struct prog_dst_register *dstReg)
{
if (Parse_String(parseState, "EQ"))
dstReg->CondMask = COND_EQ;
@@ -865,7 +865,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
static GLboolean
Parse_MaskedDstReg(struct parse_state *parseState,
struct fp_dst_register *dstReg)
struct prog_dst_register *dstReg)
{
GLubyte token[100];
GLint idx;
@@ -964,7 +964,7 @@ Parse_MaskedDstReg(struct parse_state *parseState,
*/
static GLboolean
Parse_VectorSrc(struct parse_state *parseState,
struct fp_src_register *srcReg)
struct prog_src_register *srcReg)
{
GLfloat sign = 1.0F;
GLubyte token[100];
@@ -1087,7 +1087,7 @@ Parse_VectorSrc(struct parse_state *parseState,
static GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState,
struct fp_src_register *srcReg)
struct prog_src_register *srcReg)
{
GLubyte token[100];
GLfloat sign = 1.0F;
@@ -1198,7 +1198,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
static GLboolean
Parse_PrintInstruction(struct parse_state *parseState,
struct fp_instruction *inst)
struct prog_instruction *inst)
{
const GLubyte *str;
GLubyte *msg;
@@ -1251,15 +1251,15 @@ Parse_PrintInstruction(struct parse_state *parseState,
static GLboolean
Parse_InstructionSequence(struct parse_state *parseState,
struct fp_instruction program[])
struct prog_instruction program[])
{
while (1) {
struct fp_instruction *inst = program + parseState->numInst;
struct prog_instruction *inst = program + parseState->numInst;
struct instruction_pattern instMatch;
GLubyte token[100];
/* Initialize the instruction */
_mesa_init_fp_instruction(inst);
_mesa_init_instruction(inst);
/* special instructions */
if (Parse_String(parseState, "DEFINE")) {
@@ -1301,7 +1301,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
(const char *) id, value);
}
else if (Parse_String(parseState, "END")) {
inst->Opcode = FP_OPCODE_END;
inst->Opcode = OPCODE_END;
inst->StringPos = parseState->curLine - parseState->start;
assert(inst->StringPos >= 0);
parseState->numInst++;
@@ -1328,7 +1328,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
inst->Opcode = instMatch.opcode;
inst->Precision = instMatch.suffixes & (_R | _H | _X);
inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE;
inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
inst->StringPos = parseState->curLine - parseState->start;
assert(inst->StringPos >= 0);
@@ -1342,7 +1342,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
RETURN_ERROR1("Expected ,");
}
else if (instMatch.outputs == OUTPUT_NONE) {
if (instMatch.opcode == FP_OPCODE_KIL_NV) {
if (instMatch.opcode == OPCODE_KIL_NV) {
/* This is a little weird, the cond code info is in
* the dest register.
*/
@@ -1350,7 +1350,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
RETURN_ERROR;
}
else {
ASSERT(instMatch.opcode == FP_OPCODE_PRINT);
ASSERT(instMatch.opcode == OPCODE_PRINT);
}
}
@@ -1402,7 +1402,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
if (!Parse_TextureImageId(parseState, &unit, &idx))
RETURN_ERROR;
inst->TexSrcUnit = unit;
inst->TexSrcIdx = idx;
inst->TexSrcTarget = idx;
}
else if (instMatch.inputs == INPUT_3V_T) {
GLubyte unit, idx;
@@ -1421,7 +1421,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
if (!Parse_TextureImageId(parseState, &unit, &idx))
RETURN_ERROR;
inst->TexSrcUnit = unit;
inst->TexSrcIdx = idx;
inst->TexSrcTarget = idx;
}
else if (instMatch.inputs == INPUT_1V_S) {
if (!Parse_PrintInstruction(parseState, inst))
@@ -1454,8 +1454,8 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
struct fragment_program *program)
{
struct parse_state parseState;
struct fp_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
struct fp_instruction *newInst;
struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
struct prog_instruction *newInst;
GLenum target;
GLubyte *programString;
@@ -1519,14 +1519,14 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
/* copy the compiled instructions */
assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
newInst = (struct fp_instruction *)
MALLOC(parseState.numInst * sizeof(struct fp_instruction));
newInst = (struct prog_instruction *)
MALLOC(parseState.numInst * sizeof(struct prog_instruction));
if (!newInst) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
return; /* out of memory */
}
MEMCPY(newInst, instBuffer,
parseState.numInst * sizeof(struct fp_instruction));
parseState.numInst * sizeof(struct prog_instruction));
/* install the program */
program->Base.Target = target;
@@ -1568,7 +1568,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
static void
PrintSrcReg(const struct fragment_program *program,
const struct fp_src_register *src)
const struct prog_src_register *src)
{
static const char comps[5] = "xyzw";
@@ -1635,10 +1635,10 @@ PrintSrcReg(const struct fragment_program *program,
}
static void
PrintTextureSrc(const struct fp_instruction *inst)
PrintTextureSrc(const struct prog_instruction *inst)
{
_mesa_printf("TEX%d, ", inst->TexSrcUnit);
switch (inst->TexSrcIdx) {
switch (inst->TexSrcTarget) {
case TEXTURE_1D_INDEX:
_mesa_printf("1D");
break;
@@ -1660,7 +1660,7 @@ PrintTextureSrc(const struct fp_instruction *inst)
}
static void
PrintCondCode(const struct fp_dst_register *dst)
PrintCondCode(const struct prog_dst_register *dst)
{
static const char *comps = "xyzw";
static const char *ccString[] = {
@@ -1684,7 +1684,7 @@ PrintCondCode(const struct fp_dst_register *dst)
static void
PrintDstReg(const struct fp_dst_register *dst)
PrintDstReg(const struct prog_dst_register *dst)
{
if (dst->File == PROGRAM_OUTPUT) {
_mesa_printf("o[%s]", OutputRegisters[dst->Index]);
@@ -1732,9 +1732,9 @@ PrintDstReg(const struct fp_dst_register *dst)
void
_mesa_print_nv_fragment_program(const struct fragment_program *program)
{
const struct fp_instruction *inst;
const struct prog_instruction *inst;
for (inst = program->Instructions; inst->Opcode != FP_OPCODE_END; inst++) {
for (inst = program->Instructions; inst->Opcode != OPCODE_END; inst++) {
int i;
for (i = 0; Instructions[i].name; i++) {
if (inst->Opcode == Instructions[i].opcode) {
@@ -1744,7 +1744,7 @@ _mesa_print_nv_fragment_program(const struct fragment_program *program)
_mesa_printf("H");
else if (inst->Precision == FIXED12)
_mesa_printf("X");
if (inst->UpdateCondRegister)
if (inst->CondUpdate)
_mesa_printf("C");
if (inst->Saturate)
_mesa_printf("_SAT");
@@ -1818,24 +1818,3 @@ _mesa_nv_fragment_output_register_name(GLuint i)
ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
return OutputRegisters[i];
}
/**
* Initialize fragment program instruction fields to defaults.
*/
void
_mesa_init_fp_instruction(struct fp_instruction *inst)
{
_mesa_bzero(inst, sizeof(struct fp_instruction));
inst->SrcReg[0].File = PROGRAM_UNDEFINED;
inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[1].File = PROGRAM_UNDEFINED;
inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[2].File = PROGRAM_UNDEFINED;
inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
inst->DstReg.File = PROGRAM_UNDEFINED;
inst->DstReg.WriteMask = WRITEMASK_XYZW;
inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
inst->Precision = FLOAT32;
inst->DstReg.CondMask = COND_TR;
}