⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vs1.0_inst.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#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 + -