1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef sw_PixelProgram_hpp
16 #define sw_PixelProgram_hpp
17 
18 #include "PixelRoutine.hpp"
19 #include "SamplerCore.hpp"
20 
21 namespace sw
22 {
23 	class PixelProgram : public PixelRoutine
24 	{
25 	public:
PixelProgram(const PixelProcessor::State & state,const PixelShader * shader)26 		PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
27 			PixelRoutine(state, shader), r(shader && shader->dynamicallyIndexedTemporaries),
28 			loopDepth(-1), ifDepth(0), loopRepDepth(0), breakDepth(0), currentLabel(-1), whileTest(false)
29 		{
30 			for(int i = 0; i < 2048; ++i)
31 			{
32 				labelBlock[i] = 0;
33 			}
34 
35 			enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
36 
37 			if(shader && shader->containsBreakInstruction())
38 			{
39 				enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
40 			}
41 
42 			if(shader && shader->containsContinueInstruction())
43 			{
44 				enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
45 			}
46 		}
47 
~PixelProgram()48 		virtual ~PixelProgram() {}
49 
50 	protected:
51 		virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);
52 		virtual void applyShader(Int cMask[4]);
53 		virtual Bool alphaTest(Int cMask[4]);
54 		virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
55 
56 	private:
57 		// Temporary registers
58 		RegisterArray<4096> r;
59 
60 		// Color outputs
61 		Vector4f c[RENDERTARGETS];
62 		RegisterArray<RENDERTARGETS, true> oC;
63 
64 		// Shader variables
65 		Vector4f vPos;
66 		Vector4f vFace;
67 
68 		// DX9 specific variables
69 		Vector4f p0;
70 		Array<Int, 4> aL;
71 		Array<Int, 4> increment;
72 		Array<Int, 4> iteration;
73 
74 		Int loopDepth;    // FIXME: Add support for switch
75 		Int stackIndex;   // FIXME: Inc/decrement callStack
76 		Array<UInt, 16> callStack;
77 
78 		// Per pixel based on conditions reached
79 		Int enableIndex;
80 		Array<Int4, 1 + 24> enableStack;
81 		Int4 enableBreak;
82 		Int4 enableContinue;
83 		Int4 enableLeave;
84 
85 		void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method);
86 		void sampleTexture(Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method);
87 
88 		// Raster operations
89 		void clampColor(Vector4f oC[RENDERTARGETS]);
90 
91 		Int4 enableMask(const Shader::Instruction *instruction);
92 
93 		Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
94 		Vector4f readConstant(const Src &src, unsigned int offset = 0);
95 		RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
96 		RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);
97 		Int relativeAddress(const Shader::Parameter &var, int bufferIndex = -1);
98 
99 		Float4 linearToSRGB(const Float4 &x);
100 
101 		// Instructions
102 		typedef Shader::Control Control;
103 
104 		void M3X2(Vector4f &dst, Vector4f &src0, const Src &src1);
105 		void M3X3(Vector4f &dst, Vector4f &src0, const Src &src1);
106 		void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);
107 		void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
108 		void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
109 		void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
110 		void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project);
111 		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project);
112 		void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
113 		void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
114 		void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, bool project, bool bias);
115 		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias);
116 		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
117 		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
118 		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
119 		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
120 		void DISCARD(Int cMask[4], const Shader::Instruction *instruction);
121 		void DFDX(Vector4f &dst, Vector4f &src);
122 		void DFDY(Vector4f &dst, Vector4f &src);
123 		void FWIDTH(Vector4f &dst, Vector4f &src);
124 		void BREAK();
125 		void BREAKC(Vector4f &src0, Vector4f &src1, Control);
126 		void BREAKP(const Src &predicateRegister);
127 		void BREAK(Int4 &condition);
128 		void CONTINUE();
129 		void TEST();
130 		void CALL(int labelIndex, int callSiteIndex);
131 		void CALLNZ(int labelIndex, int callSiteIndex, const Src &src);
132 		void CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister);
133 		void CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister);
134 		void ELSE();
135 		void ENDIF();
136 		void ENDLOOP();
137 		void ENDREP();
138 		void ENDWHILE();
139 		void ENDSWITCH();
140 		void IF(const Src &src);
141 		void IFb(const Src &boolRegister);
142 		void IFp(const Src &predicateRegister);
143 		void IFC(Vector4f &src0, Vector4f &src1, Control);
144 		void IF(Int4 &condition);
145 		void LABEL(int labelIndex);
146 		void LOOP(const Src &integerRegister);
147 		void REP(const Src &integerRegister);
148 		void WHILE(const Src &temporaryRegister);
149 		void SWITCH();
150 		void RET();
151 		void LEAVE();
152 
153 		int ifDepth;
154 		int loopRepDepth;
155 		int breakDepth;
156 		int currentLabel;
157 		bool whileTest;
158 
159 		// FIXME: Get rid of llvm::
160 		llvm::BasicBlock *ifFalseBlock[24 + 24];
161 		llvm::BasicBlock *loopRepTestBlock[4];
162 		llvm::BasicBlock *loopRepEndBlock[4];
163 		llvm::BasicBlock *labelBlock[2048];
164 		std::vector<llvm::BasicBlock*> callRetBlock[2048];
165 		llvm::BasicBlock *returnBlock;
166 		bool isConditionalIf[24 + 24];
167 	};
168 }
169 
170 #endif
171