📄 vs1.0_inst.cpp
字号:
#ifdef WIN32
#pragma warning(disable:4786)
#endif
#include "vs1.0_inst.h"
#include <stdio.h>
#include <string>
#include <map>
#include "nvparse_errors.h"
#include "nvparse_externs.h"
std::string vs10_transstring;
#if 0
VS10Reg::VS10Reg()
{
type = 0;
index = 0;
sign = 0;
mask = 0;
}
VS10Reg::VS10Reg(const VS10Reg &r)
{
type = r.type;
index = r.index;
sign = r.sign;
mask = r.mask;
}
VS10Reg& VS10Reg::operator=(const VS10Reg &r)
{
if ( this != &r )
{
type = r.type;
index = r.index;
sign = r.sign;
mask = r.mask;
}
return *this;
}
#endif
void VS10Reg::Init()
{
type = 0;
index = -1;
sign = 0;
mask[0] = 'j';
mask[1] = 'j';
mask[2] = 'j';
mask[3] = 'j';
}
int VS10Reg::ValidateIndex()
{
switch( type )
{
case TYPE_TEMPORARY_REG:
if ( index < 0 || index > 11 ) return 0;
else return 1;
break;
case TYPE_VERTEX_ATTRIB_REG:
if ( index < 0 || index > 15 ) return 0;
else return 1;
break;
case TYPE_ADDRESS_REG:
if ( index != 0 ) return 0;
else return 1;
break;
case TYPE_CONSTANT_MEM_REG:
if ( index < 0 || index > 95 ) return 0;
else return 1;
break;
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
return 1;
break;
case TYPE_POSITION_RESULT_REG:
return 1;
break;
case TYPE_COLOR_RESULT_REG:
if ( index < 0 || index > 1 ) return 0;
else return 1;
break;
case TYPE_TEXTURE_RESULT_REG:
if ( index < 0 || index > 3 ) return 0;
else return 1;
break;
case TYPE_FOG_RESULT_REG:
return 1;
break;
case TYPE_POINTS_RESULT_REG:
return 1;
break;
default:
errors.set( "VS10Reg::ValidateIndex() Internal Error: unknown register type\n" );
return 1;
}
}
void VS10Reg::Translate()
{
char str[16];
if ( sign == -1 )
vs10_transstring.append( "-" );
switch ( type )
{
case TYPE_TEMPORARY_REG:
sprintf( str, "R%d", index );
vs10_transstring.append( str );
break;
case TYPE_VERTEX_ATTRIB_REG:
sprintf( str, "v[%d]", index );
vs10_transstring.append( str );
break;
case TYPE_ADDRESS_REG:
sprintf( str, "A%d", index );
vs10_transstring.append( str );
break;
case TYPE_CONSTANT_MEM_REG:
sprintf( str, "c[%d]", index );
vs10_transstring.append( str );
break;
case TYPE_CONSTANT_A0_REG:
vs10_transstring.append( "c[ A0.x ]" );
break;
case TYPE_CONSTANT_A0_OFFSET_REG:
sprintf( str, "c[ A0.x + %d ]", index );
vs10_transstring.append( str );
break;
case TYPE_POSITION_RESULT_REG:
vs10_transstring.append( "o[HPOS]" );
break;
case TYPE_COLOR_RESULT_REG:
sprintf( str, "o[COL%d]", index );
vs10_transstring.append( str );
break;
case TYPE_TEXTURE_RESULT_REG:
sprintf( str, "o[TEX%d]", index );
vs10_transstring.append( str );
break;
case TYPE_FOG_RESULT_REG:
vs10_transstring.append( "o[FOGC]" );
break;
case TYPE_POINTS_RESULT_REG:
vs10_transstring.append( "o[PSIZ]" );
break;
default:
errors.set( "VS10Reg::Translate() Internal Error: unknown register type\n" );
}
if ( mask[0] != 0 )
{
str[0] = '.';
strncpy( str+1, mask, 4 );
str[5] = 0;
vs10_transstring.append( str );
}
}
VS10Inst::~VS10Inst()
{
if (comment != NULL ) delete [] comment;
}
VS10Inst::VS10Inst()
{
line = -1;
instid = -1;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst( int currline )
{
line = currline;
instid = -1;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst( const VS10Inst &inst )
{
line = inst.line;
instid = inst.instid;
dst = inst.dst;
src[0] = inst.src[0];
src[1] = inst.src[1];
src[2] = inst.src[2];
if ( inst.comment == NULL )
comment = NULL;
else
{
comment = new char[strlen(inst.comment)+1];
strcpy( comment, inst.comment );
}
}
VS10Inst& VS10Inst::operator=(const VS10Inst &inst)
{
if ( this != &inst )
{
line = inst.line;
instid = inst.instid;
dst = inst.dst;
src[0] = inst.src[0];
src[1] = inst.src[1];
src[2] = inst.src[2];
if ( inst.comment == NULL )
comment = NULL;
else
{
comment = new char[strlen(inst.comment)+1];
strcpy( comment, inst.comment );
}
}
return *this;
}
VS10Inst::VS10Inst(int currline, int inst)
{
line = currline;
instid = inst;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst(int currline, int inst, char *cmt)
{
line = currline;
instid = inst;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = cmt;
}
VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0)
{
line = currline;
instid = inst;
dst = dreg;
src[0] = src0;
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1)
{
line = currline;
instid = inst;
dst = dreg;
src[0] = src0;
src[1] = src1;
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2)
{
line = currline;
instid = inst;
dst = dreg;
src[0] = src0;
src[1] = src1;
src[2] = src2;
comment = NULL;
}
void VS10Inst::Validate( int &vsflag )
{
// Handle comments, noops, and newlines.
if ( instid == VS10_COMMENT || instid == VS10_NOP || instid == -1 ) return;
// Handle the header case.
if ( instid == VS10_HEADER )
{
if ( vsflag == 0 )
{
vsflag = 1;
return;
}
else
{
char temp[128];
sprintf( temp, "(%d) Error: vs.1.0 token already encountered\n", line );
errors.set( temp );
return;
}
}
// Validate register indices are valid.
ValidateRegIndices();
// Verify destination masking is valid.
ValidateDestMask();
// Verify source swizzling is valid.
ValidateSrcMasks();
// Verify destination register is writable.
ValidateDestWritable();
// Verify source registers are readable.
ValidateSrcReadable();
// Verify not reading from multiple vertex attributes or constants
ValidateReadPorts();
}
void VS10Inst::ValidateRegIndices()
{
char temp[256];
int result;
// Destination register.
result = dst.ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: destination register index out of range\n", line );
errors.set( temp );
}
// Source register.
result = src[0].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: source register index out of range\n", line );
errors.set( temp );
}
switch( instid )
{
// Vector operations.
case VS10_MOV:
case VS10_LIT:
break;
// Unary operations.
case VS10_FRC:
break;
// Scalar operations.
case VS10_EXP:
case VS10_EXPP:
case VS10_LOG:
case VS10_LOGP:
case VS10_RCP:
case VS10_RSQ:
break;
// Binary operations.
case VS10_ADD:
case VS10_DP3:
case VS10_DP4:
case VS10_DST:
case VS10_SGE:
case VS10_SLT:
case VS10_SUB:
case VS10_MAX:
case VS10_MIN:
case VS10_MUL:
result = src[1].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: second source register index out of range\n", line );
errors.set( temp );
}
break;
case VS10_M3X2:
case VS10_M3X3:
case VS10_M3X4:
case VS10_M4X3:
case VS10_M4X4:
{
result = src[1].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: second source register index out of range\n", line );
errors.set( temp );
}
int orig;
orig = src[1].index;
switch( instid )
{
case VS10_M3X2:
src[1].index = src[1].index + 1;
break;
case VS10_M3X3:
case VS10_M4X3:
src[1].index = src[1].index + 2;
break;
case VS10_M3X4:
case VS10_M4X4:
src[1].index = src[1].index + 3;
break;
}
result = src[1].ValidateIndex();
src[1].index = orig;
if ( !result )
{
sprintf( temp, "(%d) Error: macro expansion produces source register index out of range\n", line );
errors.set( temp );
}
}
break;
// Trinary operations.
case VS10_MAD:
result = src[1].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: second source register index out of range\n", line );
errors.set( temp );
}
result = src[2].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: third source register index out of range\n", line );
errors.set( temp );
}
break;
default:
errors.set( "VS10Inst::ValidateRegIndices() Internal Error: unknown instruction type\n" );
break;
}
}
void VS10Inst::ValidateDestMask()
{
char temp[256];
typedef std::map<char, int> MyMap;
typedef MyMap::value_type MyPair;
static const MyPair pairs[] =
{
MyPair('x',1),
MyPair('y',2),
MyPair('z',3),
MyPair('w',4),
};
static const MyMap swizzleMap(pairs, pairs+(sizeof(pairs)/sizeof(pairs[0])));
if ( dst.mask[0] == 0 ) return;
int i = 1;
while ( i < 4 && dst.mask[i] != 0 )
{
MyMap::const_iterator lastMaskIt = swizzleMap.find(dst.mask[i-1]);
MyMap::const_iterator curMaskIt = swizzleMap.find(dst.mask[i]);
if (lastMaskIt == swizzleMap.end() || curMaskIt == swizzleMap.end() ||
lastMaskIt->second >= curMaskIt->second)
// if ( dst.mask[i-1] >= dst.mask[i] )
{
char mask[5];
strncpy( mask, dst.mask, 4 );
mask[4] = 0;
sprintf( temp, "(%d) Error: destination register has invalid mask: %s\n", line, mask );
errors.set( temp );
break;
}
i++;
}
}
void VS10Inst::ValidateSrcMasks()
{
char temp[256];
char mask[5];
int len;
int i;
switch( instid )
{
// Vector operations.
case VS10_MOV:
case VS10_LIT:
strncpy( mask, src[0].mask, 4 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -