📄 ps_1_4.h
字号:
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.stevestreeting.com/ogre/
Copyright © 2000-2004 The OGRE Team
Also see acknowledgements in Readme.html
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/gpl.html.
-----------------------------------------------------------------------------
*/
/**
A number of invaluable references were used to put together this ps.1.x compiler for ATI_fragment_shader execution
References:
1. MSDN: DirectX 8.1 Reference
2. Wolfgang F. Engel "Fundamentals of Pixel Shaders - Introduction to Shader Programming Part III" on gamedev.net
3. Martin Ecker - XEngine
4. Shawn Kirst - ps14toATIfs
5. Jason L. Mitchell "Real-Time 3D Graphics With Pixel Shaders"
6. Jason L. Mitchell "1.4 Pixel Shaders"
7. Jason L. Mitchell and Evan Hart "Hardware Shading with EXT_vertex_shader and ATI_fragment_shader"
6. ATI 8500 SDK
7. GL_ATI_fragment_shader extension reference
*/
//---------------------------------------------------------------------------
#ifndef ps_1_4H
#define ps_1_4H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "OgreGLPrerequisites.h"
#include "Compiler2Pass.h"
//---------------------------------------------------------------------------
// macro to get the size of a static array
#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
#define ALPHA_BIT 0x08
#define RGB_BITS 0x07
// Context key patterns
#define ckp_PS_BASE 0x1
#define ckp_PS_1_1 0x2
#define ckp_PS_1_2 0x4
#define ckp_PS_1_3 0x8
#define ckp_PS_1_4 0x10
#define ckp_PS_1_4_BASE (ckp_PS_BASE + ckp_PS_1_4)
/** Subclasses Compiler2Pass to provide a ps_1_x compiler that takes DirectX pixel shader assembly
and converts it to a form that can be used by ATI_fragment_shader OpenGL API
@remarks
all ps_1_1, ps_1_2, ps_1_3, ps_1_4 assembly instructions are recognized but not all are passed
on to ATI_fragment_shader. ATI_fragment_shader does not have an equivelant directive for
texkill or texdepth instructions.
The user must provide the GL binding interfaces.
A Test method is provided to verify the basic operation of the compiler which outputs the test
results to a file.
*/
class PS_1_4 : public Compiler2Pass{
private:
enum RWAflags {rwa_NONE = 0, rwa_READ = 1, rwa_WRITE = 2};
enum MachineInstID {mi_COLOROP1, mi_COLOROP2, mi_COLOROP3, mi_ALPHAOP1, mi_ALPHAOP2,
mi_ALPHAOP3, mi_SETCONSTANTS, mi_PASSTEXCOORD, mi_SAMPLEMAP, mi_TEX,
mi_TEXCOORD, mi_TEXREG2RGB, mi_NOP
};
struct TokenInstType{
char* Name;
GLuint ID;
};
struct RegisterUsage {
bool Phase1Write;
bool Phase2Write;
};
// Token ID enumeration
enum SymbolID {
// Terminal Tokens section
// DirectX pixel shader source formats
sid_PS_1_4, sid_PS_1_1, sid_PS_1_2, sid_PS_1_3,
// PS_BASE
sid_C0, sid_C1, sid_C2, sid_C3, sid_C4, sid_C5, sid_C6, sid_C7,
sid_V0, sid_V1,
sid_ADD, sid_SUB, sid_MUL, sid_MAD, sid_LRP, sid_MOV, sid_CMP, sid_CND,
sid_DP3, sid_DP4, sid_DEF,
sid_R, sid_RA, sid_G, sid_GA, sid_B, sid_BA, sid_A, sid_RGBA, sid_RGB,
sid_RG, sid_RGA, sid_RB, sid_RBA, sid_GB, sid_GBA,
sid_RRRR, sid_GGGG, sid_BBBB, sid_AAAA,
sid_X2, sid_X4, sid_D2, sid_SAT,
sid_BIAS, sid_INVERT, sid_NEGATE, sid_BX2,
sid_COMMA, sid_VALUE,
//PS_1_4 sid
sid_R0, sid_R1, sid_R2, sid_R3, sid_R4, sid_R5,
sid_T0, sid_T1, sid_T2, sid_T3, sid_T4, sid_T5,
sid_DP2ADD,
sid_X8, sid_D8, sid_D4,
sid_TEXCRD, sid_TEXLD,
sid_STR, sid_STQ,
sid_STRDR, sid_STQDQ,
sid_BEM,
sid_PHASE,
//PS_1_1 sid
sid_1R0, sid_1R1, sid_1T0, sid_1T1, sid_1T2, sid_1T3,
sid_TEX, sid_TEXCOORD, sid_TEXM3X2PAD,
sid_TEXM3X2TEX, sid_TEXM3X3PAD, sid_TEXM3X3TEX, sid_TEXM3X3SPEC, sid_TEXM3X3VSPEC,
sid_TEXREG2AR, sid_TEXREG2GB,
//PS_1_2 side
sid_TEXREG2RGB, sid_TEXDP3, sid_TEXDP3TEX,
// common
sid_SKIP, sid_PLUS,
// non-terminal tokens section
sid_PROGRAM, sid_PROGRAMTYPE, sid_DECLCONSTS, sid_DEFCONST,
sid_CONSTANT, sid_COLOR,
sid_TEXSWIZZLE, sid_UNARYOP,
sid_NUMVAL, sid_SEPERATOR, sid_ALUOPS, sid_TEXMASK, sid_TEXOP_PS1_1_3,
sid_TEXOP_PS1_4,
sid_ALU_STATEMENT, sid_DSTMODSAT, sid_UNARYOP_ARGS, sid_REG_PS1_4,
sid_TEX_PS1_4, sid_REG_PS1_1_3, sid_TEX_PS1_1_3, sid_DSTINFO,
sid_SRCINFO, sid_BINARYOP_ARGS, sid_TERNARYOP_ARGS, sid_TEMPREG,
sid_DSTMASK, sid_PRESRCMOD, sid_SRCNAME, sid_SRCREP, sid_POSTSRCMOD,
sid_DSTMOD, sid_DSTSAT, sid_BINARYOP, sid_TERNARYOP,
sid_TEXOPS_PHASE1, sid_COISSUE, sid_PHASEMARKER, sid_TEXOPS_PHASE2,
sid_TEXREG_PS1_4, sid_TEXOPS_PS1_4, sid_TEXOPS_PS1_1_3, sid_TEXCISCOP_PS1_1_3,
// last token
sid_INVALID = BAD_TOKEN // must be last in enumeration
};
/// structure used to keep track of arguments and instruction parameters
struct OpParram {
GLuint Arg; // type of argument
bool Filled; // has it been filled yet
GLuint MaskRep; // Mask/Replicator flags
GLuint Mod; // argument modifier
};
typedef std::vector<uint> MachineInstContainer;
//typedef MachineInstContainer::iterator MachineInstIterator;
// there are 2 phases with 2 subphases each
enum PhaseType {ptPHASE1TEX, ptPHASE1ALU, ptPHASE2TEX, ptPHASE2ALU };
struct RegModOffset {
uint MacroOffset;
uint RegisterBase;
uint OpParramsIndex;
};
struct MacroRegModify {
TokenInst * Macro;
uint MacroSize;
RegModOffset * RegMods;
uint RegModSize;
};
#define R_BASE (sid_R0 - GL_REG_0_ATI)
#define C_BASE (sid_C0 - GL_CON_0_ATI)
#define T_BASE (sid_1T0 - GL_REG_0_ATI)
// static library database for tokens and BNF rules
static SymbolDef PS_1_4_SymbolTypeLib[];
static TokenRule PS_1_x_RulePath[];
static bool LibInitialized;
// Static Macro database for ps.1.1 ps.1.2 ps.1.3 instructions
static TokenInst texreg2ar[];
static RegModOffset texreg2xx_RegMods[];
static MacroRegModify texreg2ar_MacroMods;
static TokenInst texreg2gb[];
static MacroRegModify texreg2gb_MacroMods;
static TokenInst texdp3[];
static RegModOffset texdp3_RegMods[];
static MacroRegModify texdp3_MacroMods;
static TokenInst texdp3tex[];
static RegModOffset texdp3tex_RegMods[];
static MacroRegModify texdp3tex_MacroMods;
static TokenInst texm3x2pad[];
static RegModOffset texm3xxpad_RegMods[];
static MacroRegModify texm3x2pad_MacroMods;
static TokenInst texm3x2tex[];
static RegModOffset texm3xxtex_RegMods[];
static MacroRegModify texm3x2tex_MacroMods;
static TokenInst texm3x3pad[];
static MacroRegModify texm3x3pad_MacroMods;
static TokenInst texm3x3tex[];
static MacroRegModify texm3x3tex_MacroMods;
static TokenInst texm3x3spec[];
static RegModOffset texm3x3spec_RegMods[];
static MacroRegModify texm3x3spec_MacroMods;
static TokenInst texm3x3vspec[];
static RegModOffset texm3x3vspec_RegMods[];
static MacroRegModify texm3x3vspec_MacroMods;
MachineInstContainer mPhase1TEX_mi; /// machine instructions for phase one texture section
MachineInstContainer mPhase1ALU_mi; /// machine instructions for phase one ALU section
MachineInstContainer mPhase2TEX_mi; /// machine instructions for phase two texture section
MachineInstContainer mPhase2ALU_mi; /// machine instructions for phase two ALU section
MachineInstContainer* mActivePhaseMachineInstructions;
// vars used during pass 2
MachineInstID mOpType;
uint mOpInst;
bool mDo_Alpha;
PhaseType mInstructionPhase;
int mArgCnt;
int mConstantsPos;
#define MAXOPPARRAMS 5 // max number of parrams bound to an instruction
OpParram mOpParrams[MAXOPPARRAMS];
/// keeps track of which registers are written to in each phase
/// if a register is read from but has not been written to in phase 2
/// then if it was written to in phase 1 perform a register pass function
/// at the begining of phase2 so that the register has something worthwhile in it
/// NB: check ALU and TEX section of phase 1 and phase 2
/// there are 6 temp registers r0 to r5 to keep track off
/// checks are performed in pass 2 when building machine instructions
RegisterUsage Phase_RegisterUsage[6];
bool mMacroOn; // if true then put all ALU instructions in phase 1
uint mTexm3x3padCount; // keep track of how many texm3x3pad instructions are used so know which mask to use
size_t mLastInstructionPos; // keep track of last phase 2 ALU instruction to check for R0 setting
size_t mSecondLastInstructionPos;
// keep track if phase marker found: determines which phase the ALU instructions go into
bool mPhaseMarkerFound;
#ifdef _DEBUG
FILE* fp;
// full compiler test with output results going to a text file
void testCompile(char* testname, char* teststr, SymbolID* testresult,
uint testresultsize, GLuint* MachinInstResults = NULL, uint MachinInstResultsSize = 0);
#endif // _DEBUG
/** attempt to build a machine instruction using current tokens
determines what phase machine insturction should be in and if an Alpha Op is required
calls expandMachineInstruction() to expand the token into machine instructions
*/
bool BuildMachineInst();
void clearMachineInstState();
bool setOpParram(const SymbolDef* symboldef);
/** optimizes machine instructions depending on pixel shader context
only applies to ps.1.1 ps.1.2 and ps.1.3 since they use CISC instructions
that must be transformed into RISC instructions
*/
void optimize();
// the method is expected to be recursive to allow for inline expansion of instructions if required
bool Pass2scan(const TokenInst * Tokens, const size_t size);
// supply virtual functions for Compiler2Pass
/// Pass 1 is completed so now take tokens generated and build machine instructions
bool doPass2();
/** Build a machine instruction from token and ready it for expansion
will expand CISC tokens using macro database
*/
bool bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions);
/** Expand CISC tokens into PS1_4 token equivalents
*/
bool expandMacro(const MacroRegModify & MacroMod);
/** Expand Machine instruction into operation type and arguments and put into proper machine
instruction container
also expands scaler alpha machine instructions if required
*/
bool expandMachineInstruction();
// mainly used by tests - too slow for use in binding
size_t getMachineInst(size_t Idx);
size_t getMachineInstCount();
void addMachineInst(PhaseType phase, const uint inst);
void clearAllMachineInst();
void updateRegisterWriteState(const PhaseType phase);
bool isRegisterReadValid(const PhaseType phase, const int param);
public:
/// constructor
PS_1_4();
/// binds machine instructions generated in Pass 2 to the ATI GL fragment shader
bool bindAllMachineInstToFragmentShader();
#ifdef _DEBUG
/// perform compiler tests - only available in _DEBUG mode
void test();
void testbinder();
#endif
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -