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