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#include <unordered_map>
22
23namespace sw
24{
25 class PixelProgram : public PixelRoutine
26 {
27 public:
28 PixelProgram(const PixelProcessor::State &state, const PixelShader *shader);
29 virtual ~PixelProgram() {}
30
31 protected:
32 virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);
33 virtual void applyShader(Int cMask[4]);
34 virtual Bool alphaTest(Int cMask[4]);
35 virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
36
37 private:
38 // Temporary registers
39 RegisterArray<NUM_TEMPORARY_REGISTERS> r;
40
41 // Color outputs
42 Vector4f c[RENDERTARGETS];
43 RegisterArray<RENDERTARGETS, true> oC;
44
45 // Shader variables
46 Vector4f vPos;
47 Vector4f vFace;
48
49 // DX9 specific variables
50 Vector4f p0;
51 Array<Int> aL; // loop counter register
52 Array<Int> increment; // increment value per loop
53 Array<Int> iteration; // iteration count
54
55 Int loopDepth; // FIXME: Add support for switch
56 Int stackIndex; // FIXME: Inc/decrement callStack
57 Array<UInt> callStack;
58
59 // Per pixel based on conditions reached
60 Int enableIndex;
61 Array<Int4, MAX_SHADER_ENABLE_STACK_SIZE> enableStack;
62 Int4 enableBreak;
63 Int4 enableContinue;
64 Int4 enableLeave;
65
66 Vector4f sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
67 Vector4f sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
68
69 // Raster operations
70 void clampColor(Vector4f oC[RENDERTARGETS]);
71
72 Int4 enableMask(const Shader::Instruction *instruction);
73
74 Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
75 Vector4f readConstant(const Src &src, unsigned int offset = 0);
76 RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
77 RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);
78 Int relativeAddress(const Shader::Relative &rel, int bufferIndex = -1);
79 Int4 dynamicAddress(const Shader::Relative &rel);
80
81 Float4 linearToSRGB(const Float4 &x);
82
83 // Instructions
84 typedef Shader::Control Control;
85
86 void M3X2(Vector4f &dst, Vector4f &src0, const Src &src1);
87 void M3X3(Vector4f &dst, Vector4f &src0, const Src &src1);
88 void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);
89 void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
90 void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
91 void TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
92 void TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod);
93 void TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias);
94 void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
95 void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
96 void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset);
97 void TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias);
98 void TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod);
99 void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src &, Float4 &lod);
100 void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &offset, Float4 &lod);
101 void TEXGRAD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &dsx, Vector4f &dsy);
102 void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
103 void DISCARD(Int cMask[4], const Shader::Instruction *instruction);
104 void DFDX(Vector4f &dst, Vector4f &src);
105 void DFDY(Vector4f &dst, Vector4f &src);
106 void FWIDTH(Vector4f &dst, Vector4f &src);
107 void BREAK();
108 void BREAKC(Vector4f &src0, Vector4f &src1, Control);
109 void BREAKP(const Src &predicateRegister);
110 void BREAK(Int4 &condition);
111 void CONTINUE();
112 void TEST();
113 void SCALAR();
114 void CALL(int labelIndex, int callSiteIndex);
115 void CALLNZ(int labelIndex, int callSiteIndex, const Src &src);
116 void CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister);
117 void CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister);
118 void ELSE();
119 void ENDIF();
120 void ENDLOOP();
121 void ENDREP();
122 void ENDWHILE();
123 void ENDSWITCH();
124 void IF(const Src &src);
125 void IFb(const Src &boolRegister);
126 void IFp(const Src &predicateRegister);
127 void IFC(Vector4f &src0, Vector4f &src1, Control);
128 void IF(Int4 &condition);
129 void LABEL(int labelIndex);
130 void LOOP(const Src &integerRegister);
131 void REP(const Src &integerRegister);
132 void WHILE(const Src &temporaryRegister);
133 void SWITCH();
134 void RET();
135 void LEAVE();
136
137 int ifDepth = 0;
138 int loopRepDepth = 0;
139 int currentLabel = -1;
140 bool scalar = false;
141
142 std::vector<BasicBlock*> ifFalseBlock;
143 std::vector<BasicBlock*> loopRepTestBlock;
144 std::vector<BasicBlock*> loopRepEndBlock;
145 std::vector<BasicBlock*> labelBlock;
146 std::unordered_map<unsigned int, std::vector<BasicBlock*>> callRetBlock; // label -> list of call sites
147 BasicBlock *returnBlock;
148 std::vector<bool> isConditionalIf;
149 std::vector<Int4> restoreContinue;
150 };
151}
152
153#endif
154