source: OGRE/trunk/ogrenew/RenderSystems/GL/src/atifs/include/ps_1_4.h @ 692

Revision 692, 11.6 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.stevestreeting.com/ogre/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/gpl.html.
23-----------------------------------------------------------------------------
24*/
25
26
27/**
28        A number of invaluable references were used to put together this ps.1.x compiler for ATI_fragment_shader execution
29
30        References:
31                1. MSDN: DirectX 8.1 Reference
32                2. Wolfgang F. Engel "Fundamentals of Pixel Shaders - Introduction to Shader Programming Part III" on gamedev.net
33                3. Martin Ecker - XEngine
34                4. Shawn Kirst - ps14toATIfs
35                5. Jason L. Mitchell "Real-Time 3D Graphics With Pixel Shaders"
36                6. Jason L. Mitchell "1.4 Pixel Shaders"
37                7. Jason L. Mitchell and Evan Hart "Hardware Shading with EXT_vertex_shader and ATI_fragment_shader"
38                6. ATI 8500 SDK
39                7. GL_ATI_fragment_shader extension reference
40
41*/
42//---------------------------------------------------------------------------
43#ifndef ps_1_4H
44#define ps_1_4H
45
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49
50#include "OgreGLPrerequisites.h"
51#include "Compiler2Pass.h"
52
53
54//---------------------------------------------------------------------------
55// macro to get the size of a static array
56#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
57
58#define ALPHA_BIT 0x08
59#define RGB_BITS 0x07
60
61// Context key patterns
62#define ckp_PS_BASE 0x1
63#define ckp_PS_1_1  0x2
64#define ckp_PS_1_2  0x4
65#define ckp_PS_1_3  0x8
66#define ckp_PS_1_4  0x10
67
68#define ckp_PS_1_4_BASE (ckp_PS_BASE + ckp_PS_1_4)
69
70
71
72
73/** Subclasses Compiler2Pass to provide a ps_1_x compiler that takes DirectX pixel shader assembly
74        and converts it to a form that can be used by ATI_fragment_shader OpenGL API
75@remarks
76        all ps_1_1, ps_1_2, ps_1_3, ps_1_4 assembly instructions are recognized but not all are passed
77        on to ATI_fragment_shader.      ATI_fragment_shader does not have an equivelant directive for
78        texkill or texdepth instructions.
79
80        The user must provide the GL binding interfaces.
81
82        A Test method is provided to verify the basic operation of the compiler which outputs the test
83        results to a file.
84
85
86*/
87class PS_1_4 : public Compiler2Pass{
88private:
89        enum RWAflags {rwa_NONE = 0, rwa_READ = 1, rwa_WRITE = 2};
90
91        enum MachineInstID {mi_COLOROP1, mi_COLOROP2, mi_COLOROP3, mi_ALPHAOP1, mi_ALPHAOP2,
92                                                mi_ALPHAOP3, mi_SETCONSTANTS, mi_PASSTEXCOORD, mi_SAMPLEMAP, mi_TEX,
93                                                mi_TEXCOORD, mi_TEXREG2RGB, mi_NOP
94        };
95
96        struct  TokenInstType{
97          char* Name;
98          GLuint ID;
99
100        };
101
102        struct RegisterUsage {
103                bool Phase1Write;
104                bool Phase2Write;
105        };
106
107        // Token ID enumeration
108        enum SymbolID {
109                // Terminal Tokens section
110
111                // DirectX pixel shader source formats
112                sid_PS_1_4, sid_PS_1_1, sid_PS_1_2, sid_PS_1_3,
113                                       
114                // PS_BASE
115                sid_C0, sid_C1, sid_C2, sid_C3, sid_C4, sid_C5, sid_C6, sid_C7,
116                sid_V0, sid_V1,
117                sid_ADD, sid_SUB, sid_MUL, sid_MAD, sid_LRP, sid_MOV, sid_CMP, sid_CND,
118                sid_DP3, sid_DP4, sid_DEF,
119                sid_R, sid_RA, sid_G, sid_GA, sid_B, sid_BA, sid_A, sid_RGBA, sid_RGB,
120                sid_RG, sid_RGA, sid_RB, sid_RBA, sid_GB, sid_GBA,
121                sid_RRRR, sid_GGGG, sid_BBBB, sid_AAAA,
122                sid_X2, sid_X4, sid_D2, sid_SAT,
123                sid_BIAS, sid_INVERT, sid_NEGATE, sid_BX2,
124                sid_COMMA, sid_VALUE,
125
126                //PS_1_4 sid
127                sid_R0, sid_R1, sid_R2, sid_R3, sid_R4, sid_R5,
128                sid_T0, sid_T1, sid_T2, sid_T3, sid_T4, sid_T5,
129                sid_DP2ADD,
130                sid_X8, sid_D8, sid_D4,
131                sid_TEXCRD, sid_TEXLD,
132                sid_STR, sid_STQ,
133                sid_STRDR, sid_STQDQ,
134                sid_BEM,
135                sid_PHASE,
136
137                //PS_1_1 sid
138                sid_1R0, sid_1R1, sid_1T0, sid_1T1, sid_1T2, sid_1T3,
139                sid_TEX, sid_TEXCOORD, sid_TEXM3X2PAD,
140                sid_TEXM3X2TEX, sid_TEXM3X3PAD, sid_TEXM3X3TEX, sid_TEXM3X3SPEC, sid_TEXM3X3VSPEC,
141                sid_TEXREG2AR, sid_TEXREG2GB,
142               
143                //PS_1_2 side
144                sid_TEXREG2RGB, sid_TEXDP3, sid_TEXDP3TEX,
145
146                // common
147                sid_SKIP, sid_PLUS,
148
149                // non-terminal tokens section
150                sid_PROGRAM, sid_PROGRAMTYPE, sid_DECLCONSTS, sid_DEFCONST,
151                sid_CONSTANT, sid_COLOR,
152                sid_TEXSWIZZLE, sid_UNARYOP,
153                sid_NUMVAL, sid_SEPERATOR, sid_ALUOPS, sid_TEXMASK, sid_TEXOP_PS1_1_3,
154                sid_TEXOP_PS1_4,
155                sid_ALU_STATEMENT, sid_DSTMODSAT, sid_UNARYOP_ARGS, sid_REG_PS1_4,
156                sid_TEX_PS1_4, sid_REG_PS1_1_3, sid_TEX_PS1_1_3, sid_DSTINFO,
157                sid_SRCINFO, sid_BINARYOP_ARGS, sid_TERNARYOP_ARGS, sid_TEMPREG,
158                sid_DSTMASK, sid_PRESRCMOD, sid_SRCNAME, sid_SRCREP, sid_POSTSRCMOD,
159                sid_DSTMOD, sid_DSTSAT, sid_BINARYOP,  sid_TERNARYOP,
160                sid_TEXOPS_PHASE1, sid_COISSUE, sid_PHASEMARKER, sid_TEXOPS_PHASE2,
161                sid_TEXREG_PS1_4, sid_TEXOPS_PS1_4, sid_TEXOPS_PS1_1_3, sid_TEXCISCOP_PS1_1_3,
162
163
164                // last token
165                sid_INVALID = BAD_TOKEN // must be last in enumeration
166        };
167
168        /// structure used to keep track of arguments and instruction parameters
169        struct OpParram {
170          GLuint Arg;           // type of argument
171          bool Filled;          // has it been filled yet
172          GLuint MaskRep;       // Mask/Replicator flags
173          GLuint Mod;           // argument modifier
174        };
175
176        typedef std::vector<uint> MachineInstContainer;
177        //typedef MachineInstContainer::iterator MachineInstIterator;
178
179
180        // there are 2 phases with 2 subphases each
181        enum PhaseType {ptPHASE1TEX, ptPHASE1ALU, ptPHASE2TEX, ptPHASE2ALU };
182
183        struct RegModOffset {
184                uint MacroOffset;
185                uint RegisterBase;
186                uint OpParramsIndex;
187        };
188
189        struct MacroRegModify {
190                TokenInst *             Macro;
191                uint                    MacroSize;
192                RegModOffset *  RegMods;
193                uint                    RegModSize;
194
195        };
196
197        #define R_BASE  (sid_R0 - GL_REG_0_ATI)
198        #define C_BASE  (sid_C0 - GL_CON_0_ATI)
199        #define T_BASE  (sid_1T0 - GL_REG_0_ATI)
200
201        // static library database for tokens and BNF rules
202        static SymbolDef PS_1_4_SymbolTypeLib[];
203        static TokenRule PS_1_x_RulePath[];
204        static bool LibInitialized;
205
206        // Static Macro database for ps.1.1 ps.1.2 ps.1.3 instructions
207
208        static TokenInst texreg2ar[];
209        static RegModOffset texreg2xx_RegMods[];
210        static MacroRegModify texreg2ar_MacroMods;
211
212        static TokenInst texreg2gb[];
213        static MacroRegModify texreg2gb_MacroMods;
214
215        static TokenInst texdp3[];
216        static RegModOffset texdp3_RegMods[];
217        static MacroRegModify texdp3_MacroMods;
218
219        static TokenInst texdp3tex[];
220        static RegModOffset texdp3tex_RegMods[];
221        static MacroRegModify texdp3tex_MacroMods;
222
223        static TokenInst texm3x2pad[];
224        static RegModOffset texm3xxpad_RegMods[];
225        static MacroRegModify texm3x2pad_MacroMods;
226
227        static TokenInst texm3x2tex[];
228        static RegModOffset texm3xxtex_RegMods[];
229        static MacroRegModify texm3x2tex_MacroMods;
230
231        static TokenInst texm3x3pad[];
232        static MacroRegModify texm3x3pad_MacroMods;
233
234        static TokenInst texm3x3tex[];
235        static MacroRegModify texm3x3tex_MacroMods;
236
237        static TokenInst texm3x3spec[];
238        static RegModOffset texm3x3spec_RegMods[];
239        static MacroRegModify texm3x3spec_MacroMods;
240
241        static TokenInst texm3x3vspec[];
242        static RegModOffset texm3x3vspec_RegMods[];
243        static MacroRegModify texm3x3vspec_MacroMods;
244
245
246        MachineInstContainer mPhase1TEX_mi; /// machine instructions for phase one texture section
247        MachineInstContainer mPhase1ALU_mi; /// machine instructions for phase one ALU section
248        MachineInstContainer mPhase2TEX_mi; /// machine instructions for phase two texture section
249        MachineInstContainer mPhase2ALU_mi; /// machine instructions for phase two ALU section
250
251        MachineInstContainer* mActivePhaseMachineInstructions;
252        // vars used during pass 2
253        MachineInstID mOpType;
254        uint mOpInst;
255        bool mDo_Alpha;
256        PhaseType mInstructionPhase;
257        int mArgCnt;
258        int mConstantsPos;
259
260        #define MAXOPPARRAMS 5 // max number of parrams bound to an instruction
261       
262        OpParram mOpParrams[MAXOPPARRAMS];
263
264        /// keeps track of which registers are written to in each phase
265        /// if a register is read from but has not been written to in phase 2
266        /// then if it was written to in phase 1 perform a register pass function
267        /// at the begining of phase2 so that the register has something worthwhile in it
268        /// NB: check ALU and TEX section of phase 1 and phase 2
269        /// there are 6 temp registers r0 to r5 to keep track off
270        /// checks are performed in pass 2 when building machine instructions
271        RegisterUsage Phase_RegisterUsage[6];
272
273        bool mMacroOn; // if true then put all ALU instructions in phase 1
274
275        uint mTexm3x3padCount; // keep track of how many texm3x3pad instructions are used so know which mask to use
276
277        size_t mLastInstructionPos; // keep track of last phase 2 ALU instruction to check for R0 setting
278        size_t mSecondLastInstructionPos;
279
280        // keep track if phase marker found: determines which phase the ALU instructions go into
281        bool mPhaseMarkerFound;
282
283#ifdef _DEBUG
284        FILE* fp;
285        // full compiler test with output results going to a text file
286        void testCompile(char* testname, char* teststr, SymbolID* testresult,
287                uint testresultsize, GLuint* MachinInstResults = NULL, uint MachinInstResultsSize = 0);
288#endif // _DEBUG
289
290
291        /** attempt to build a machine instruction using current tokens
292                determines what phase machine insturction should be in and if an Alpha Op is required
293                calls expandMachineInstruction() to expand the token into machine instructions
294        */
295        bool BuildMachineInst();
296       
297        void clearMachineInstState();
298
299        bool setOpParram(const SymbolDef* symboldef);
300
301        /** optimizes machine instructions depending on pixel shader context
302                only applies to ps.1.1 ps.1.2 and ps.1.3 since they use CISC instructions
303                that must be transformed into RISC instructions
304        */
305        void optimize();
306
307        // the method is expected to be recursive to allow for inline expansion of instructions if required
308        bool Pass2scan(const TokenInst * Tokens, const size_t size);
309
310        // supply virtual functions for Compiler2Pass
311        /// Pass 1 is completed so now take tokens generated and build machine instructions
312        bool doPass2();
313
314        /** Build a machine instruction from token and ready it for expansion
315                will expand CISC tokens using macro database
316
317        */
318        bool bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions);
319
320        /** Expand CISC tokens into PS1_4 token equivalents
321
322        */
323        bool expandMacro(const MacroRegModify & MacroMod);
324
325        /** Expand Machine instruction into operation type and arguments and put into proper machine
326                instruction container
327                also expands scaler alpha machine instructions if required
328
329        */
330        bool expandMachineInstruction();
331
332        // mainly used by tests - too slow for use in binding
333        size_t getMachineInst(size_t Idx);
334
335        size_t getMachineInstCount();
336
337        void addMachineInst(PhaseType phase, const uint inst);
338
339        void clearAllMachineInst();
340
341        void updateRegisterWriteState(const PhaseType phase);
342
343        bool isRegisterReadValid(const PhaseType phase, const int param);
344
345public:
346
347        /// constructor
348        PS_1_4();
349
350        /// binds machine instructions generated in Pass 2 to the ATI GL fragment shader
351        bool bindAllMachineInstToFragmentShader();
352
353#ifdef _DEBUG
354        /// perform compiler tests - only available in _DEBUG mode
355        void test();
356        void testbinder();
357
358#endif
359};
360
361
362#endif
363
Note: See TracBrowser for help on using the repository browser.