10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
25d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens//
30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// you may not use this file except in compliance with the License.
50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// You may obtain a copy of the License at
65d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens//
70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
85d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens//
90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Unless required by applicable law or agreed to in writing, software
100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// See the License for the specific language governing permissions and
130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// limitations under the License.
145d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens
155d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens#include "PixelProgram.hpp"
16708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens
175d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens#include "SamplerCore.hpp"
18708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Renderer/Primitive.hpp"
19708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Renderer/Renderer.hpp"
205d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens
215d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capensnamespace sw
225d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens{
235d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	extern bool postBlendSRGB;
24f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	extern bool booleanFaceRegister;
25f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	extern bool halfIntegerCoordinates;     // Pixel centers are not at integer coordinates
265d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	extern bool fullPixelPositionRegister;
275d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens
284f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w)
295d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	{
3053ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu		if(shader->getShaderModel() >= 0x0300)
31f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
3202ad0aa756ab6cbfb6ca00b98ac6793536ff9820Alexis Hetu			if(shader->isVPosDeclared())
33f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
34f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(!halfIntegerCoordinates)
35f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
364f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					vPos.x = Float4(Float(x)) + Float4(0, 1, 0, 1);
374f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					vPos.y = Float4(Float(y)) + Float4(0, 0, 1, 1);
38f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
39f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				else
40f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
414f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					vPos.x = Float4(Float(x)) + Float4(0.5f, 1.5f, 0.5f, 1.5f);
424f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					vPos.y = Float4(Float(y)) + Float4(0.5f, 0.5f, 1.5f, 1.5f);
43f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
44f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
45f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(fullPixelPositionRegister)
46f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
474f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					vPos.z = z[0]; // FIXME: Centroid?
484f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					vPos.w = w;    // FIXME: Centroid?
49f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
50f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
51f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
5202ad0aa756ab6cbfb6ca00b98ac6793536ff9820Alexis Hetu			if(shader->isVFaceDeclared())
53f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
544f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				Float4 area = *Pointer<Float>(primitive + OFFSET(Primitive, area));
55f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				Float4 face = booleanFaceRegister ? Float4(As<Float4>(CmpNLT(area, Float4(0.0f)))) : area;
56f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
574f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				vFace.x = face;
584f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				vFace.y = face;
594f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				vFace.z = face;
604f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				vFace.w = face;
61f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
625d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		}
635d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	}
645d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens
654f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::applyShader(Int cMask[4])
665d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	{
674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableIndex = 0;
684f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		stackIndex = 0;
69f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
70f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(shader->containsLeaveInstruction())
71f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
724f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
73f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
74f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
751edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu		for(int i = 0; i < RENDERTARGETS; i++)
761edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu		{
771edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			if(state.targetFormat[i] != FORMAT_NULL)
781edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			{
794f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				oC[i] = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
801edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			}
811edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu		}
82f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
83f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// Create all call site return blocks up front
84f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		for(size_t i = 0; i < shader->getLength(); i++)
85f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
86f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Shader::Instruction *instruction = shader->getInstruction(i);
87f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Shader::Opcode opcode = instruction->opcode;
88f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
89f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(opcode == Shader::OPCODE_CALL || opcode == Shader::OPCODE_CALLNZ)
90f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
91f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				const Dst &dst = instruction->dst;
92f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
93f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				ASSERT(callRetBlock[dst.label].size() == dst.callSite);
94f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				callRetBlock[dst.label].push_back(Nucleus::createBasicBlock());
95f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
96f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
97f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
988b124c10248597cfecd21f7bf385900152467dadNicolas Capens		bool broadcastColor0 = true;
998b124c10248597cfecd21f7bf385900152467dadNicolas Capens
100f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		for(size_t i = 0; i < shader->getLength(); i++)
101f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
102f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Shader::Instruction *instruction = shader->getInstruction(i);
103f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Shader::Opcode opcode = instruction->opcode;
104f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
105f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(opcode == Shader::OPCODE_DCL || opcode == Shader::OPCODE_DEF || opcode == Shader::OPCODE_DEFI || opcode == Shader::OPCODE_DEFB)
106f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
107f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				continue;
108f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
109f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
110f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Dst &dst = instruction->dst;
111f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Src &src0 = instruction->src[0];
112f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Src &src1 = instruction->src[1];
113f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Src &src2 = instruction->src[2];
114f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			const Src &src3 = instruction->src[3];
11525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu			const Src &src4 = instruction->src[4];
116f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
117f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			bool predicate = instruction->predicate;
118f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Control control = instruction->control;
119f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			bool pp = dst.partialPrecision;
120f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			bool project = instruction->project;
121f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			bool bias = instruction->bias;
122f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
123f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Vector4f d;
124f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Vector4f s0;
125f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Vector4f s1;
126f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Vector4f s2;
127f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Vector4f s3;
12825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu			Vector4f s4;
129f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
130f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(opcode == Shader::OPCODE_TEXKILL)   // Takes destination as input
131f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
132f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(dst.type == Shader::PARAMETER_TEXTURE)
133f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
1344f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					d.x = v[2 + dst.index].x;
1354f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					d.y = v[2 + dst.index].y;
1364f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					d.z = v[2 + dst.index].z;
1374f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					d.w = v[2 + dst.index].w;
138f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
139f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				else
140f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
1414f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					d = r[dst.index];
142f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
143f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
144f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
145c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0);
146c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1);
147c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2);
148c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegister(src3);
149c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegister(src4);
150f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
151f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			switch(opcode)
152f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
153f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_PS_2_0:                                                    break;
154f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_PS_2_x:                                                    break;
155f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_PS_3_0:                                                    break;
156f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DEF:                                                       break;
157f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DCL:                                                       break;
158f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_NOP:                                                       break;
159f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_MOV:        mov(d, s0);                                    break;
1608d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_NEG:        neg(d, s0);                                    break;
1618d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_INEG:       ineg(d, s0);                                   break;
162f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_F2B:        f2b(d, s0);                                    break;
163f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_B2F:        b2f(d, s0);                                    break;
1648d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_F2I:        f2i(d, s0);                                    break;
1658d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_I2F:        i2f(d, s0);                                    break;
1668d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_F2U:        f2u(d, s0);                                    break;
1678d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_U2F:        u2f(d, s0);                                    break;
1688d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_I2B:        i2b(d, s0);                                    break;
1698d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_B2I:        b2i(d, s0);                                    break;
170f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ADD:        add(d, s0, s1);                                break;
1718d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IADD:       iadd(d, s0, s1);                               break;
172f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SUB:        sub(d, s0, s1);                                break;
1738d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_ISUB:       isub(d, s0, s1);                               break;
174f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_MUL:        mul(d, s0, s1);                                break;
1758d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMUL:       imul(d, s0, s1);                               break;
176f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_MAD:        mad(d, s0, s1, s2);                            break;
1778d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMAD:       imad(d, s0, s1, s2);                           break;
178f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DP1:        dp1(d, s0, s1);                                break;
179f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DP2:        dp2(d, s0, s1);                                break;
180f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DP2ADD:     dp2add(d, s0, s1, s2);                         break;
181f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DP3:        dp3(d, s0, s1);                                break;
182f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DP4:        dp4(d, s0, s1);                                break;
183c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET2:       det2(d, s0, s1);                               break;
184c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET3:       det3(d, s0, s1, s2);                           break;
185c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET4:       det4(d, s0, s1, s2, s3);                       break;
186f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_CMP0:       cmp0(d, s0, s1, s2);                           break;
187f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ICMP:       icmp(d, s0, s1, control);                      break;
1888d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UCMP:       ucmp(d, s0, s1, control);                      break;
189f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SELECT:     select(d, s0, s1, s2);                         break;
190f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_EXTRACT:    extract(d.x, s0, s1.x);                        break;
191f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_INSERT:     insert(d, s0, s1.x, s2.x);                     break;
192f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FRC:        frc(d, s0);                                    break;
193f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_TRUNC:      trunc(d, s0);                                  break;
194f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FLOOR:      floor(d, s0);                                  break;
195f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ROUND:      round(d, s0);                                  break;
196f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ROUNDEVEN:  roundEven(d, s0);                              break;
197f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_CEIL:       ceil(d, s0);                                   break;
198f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_EXP2X:      exp2x(d, s0, pp);                              break;
199f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_EXP2:       exp2(d, s0, pp);                               break;
200f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LOG2X:      log2x(d, s0, pp);                              break;
201f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LOG2:       log2(d, s0, pp);                               break;
202f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_EXP:        exp(d, s0, pp);                                break;
203f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LOG:        log(d, s0, pp);                                break;
204f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_RCPX:       rcpx(d, s0, pp);                               break;
205f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DIV:        div(d, s0, s1);                                break;
2068d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IDIV:       idiv(d, s0, s1);                               break;
2078d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UDIV:       udiv(d, s0, s1);                               break;
208f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_MOD:        mod(d, s0, s1);                                break;
2098d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMOD:       imod(d, s0, s1);                               break;
2108d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMOD:       umod(d, s0, s1);                               break;
2118d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_SHL:        shl(d, s0, s1);                                break;
2128d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_ISHR:       ishr(d, s0, s1);                               break;
2138d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_USHR:       ushr(d, s0, s1);                               break;
214f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_RSQX:       rsqx(d, s0, pp);                               break;
215f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SQRT:       sqrt(d, s0, pp);                               break;
216f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_RSQ:        rsq(d, s0, pp);                                break;
217f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LEN2:       len2(d.x, s0, pp);                             break;
218f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LEN3:       len3(d.x, s0, pp);                             break;
219f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LEN4:       len4(d.x, s0, pp);                             break;
220f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DIST1:      dist1(d.x, s0, s1, pp);                        break;
221f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DIST2:      dist2(d.x, s0, s1, pp);                        break;
222f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DIST3:      dist3(d.x, s0, s1, pp);                        break;
223f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DIST4:      dist4(d.x, s0, s1, pp);                        break;
224f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_MIN:        min(d, s0, s1);                                break;
2258d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMIN:       imin(d, s0, s1);                               break;
2268d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMIN:       umin(d, s0, s1);                               break;
227f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_MAX:        max(d, s0, s1);                                break;
2288d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMAX:       imax(d, s0, s1);                               break;
2298d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMAX:       umax(d, s0, s1);                               break;
230f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LRP:        lrp(d, s0, s1, s2);                            break;
231f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_STEP:       step(d, s0, s1);                               break;
232f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SMOOTH:     smooth(d, s0, s1, s2);                         break;
2338ef6d1097d9fe71a2461a5040bddb1893bdbed6cAlexis Hetu			case Shader::OPCODE_ISINF:      isinf(d, s0);                                  break;
2348ef6d1097d9fe71a2461a5040bddb1893bdbed6cAlexis Hetu			case Shader::OPCODE_ISNAN:      isnan(d, s0);                                  break;
2358d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_FLOATBITSTOINT:
2368d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_FLOATBITSTOUINT:
2378d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_INTBITSTOFLOAT:
2388d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UINTBITSTOFLOAT: d = s0;                                   break;
2399cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_PACKSNORM2x16:   packSnorm2x16(d, s0);                     break;
2409cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_PACKUNORM2x16:   packUnorm2x16(d, s0);                     break;
241ffb35eb4ab1b99c9bb6583c39211386fa577ef02Alexis Hetu			case Shader::OPCODE_PACKHALF2x16:    packHalf2x16(d, s0);                      break;
2429cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_UNPACKSNORM2x16: unpackSnorm2x16(d, s0);                   break;
2439cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_UNPACKUNORM2x16: unpackUnorm2x16(d, s0);                   break;
244ffb35eb4ab1b99c9bb6583c39211386fa577ef02Alexis Hetu			case Shader::OPCODE_UNPACKHALF2x16:  unpackHalf2x16(d, s0);                    break;
245f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_POWX:       powx(d, s0, s1, pp);                           break;
246f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_POW:        pow(d, s0, s1, pp);                            break;
247f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SGN:        sgn(d, s0);                                    break;
2480f4480780a2bfad69cece5fd9cabd1bf89f7393eAlexis Hetu			case Shader::OPCODE_ISGN:       isgn(d, s0);                                   break;
249f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_CRS:        crs(d, s0, s1);                                break;
250f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FORWARD1:   forward1(d, s0, s1, s2);                       break;
251f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FORWARD2:   forward2(d, s0, s1, s2);                       break;
252f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FORWARD3:   forward3(d, s0, s1, s2);                       break;
253f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FORWARD4:   forward4(d, s0, s1, s2);                       break;
254f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFLECT1:   reflect1(d, s0, s1);                           break;
255f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFLECT2:   reflect2(d, s0, s1);                           break;
256f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFLECT3:   reflect3(d, s0, s1);                           break;
257f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFLECT4:   reflect4(d, s0, s1);                           break;
258f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFRACT1:   refract1(d, s0, s1, s2.x);                     break;
259f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFRACT2:   refract2(d, s0, s1, s2.x);                     break;
260f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFRACT3:   refract3(d, s0, s1, s2.x);                     break;
261f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_REFRACT4:   refract4(d, s0, s1, s2.x);                     break;
262f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_NRM2:       nrm2(d, s0, pp);                               break;
263f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_NRM3:       nrm3(d, s0, pp);                               break;
264f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_NRM4:       nrm4(d, s0, pp);                               break;
265f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ABS:        abs(d, s0);                                    break;
2660f4480780a2bfad69cece5fd9cabd1bf89f7393eAlexis Hetu			case Shader::OPCODE_IABS:       iabs(d, s0);                                   break;
267f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SINCOS:     sincos(d, s0, pp);                             break;
268f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_COS:        cos(d, s0, pp);                                break;
269f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SIN:        sin(d, s0, pp);                                break;
270f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_TAN:        tan(d, s0, pp);                                break;
271f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ACOS:       acos(d, s0, pp);                               break;
272f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ASIN:       asin(d, s0, pp);                               break;
273f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ATAN:       atan(d, s0, pp);                               break;
274f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ATAN2:      atan2(d, s0, s1, pp);                          break;
275f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_COSH:       cosh(d, s0, pp);                               break;
276f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_SINH:       sinh(d, s0, pp);                               break;
277f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_TANH:       tanh(d, s0, pp);                               break;
278f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ACOSH:      acosh(d, s0, pp);                              break;
279f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ASINH:      asinh(d, s0, pp);                              break;
280f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ATANH:      atanh(d, s0, pp);                              break;
2814f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_M4X4:       M4X4(d, s0, src1);                             break;
2824f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_M4X3:       M4X3(d, s0, src1);                             break;
2834f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_M3X4:       M3X4(d, s0, src1);                             break;
2844f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_M3X3:       M3X3(d, s0, src1);                             break;
2854f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_M3X2:       M3X2(d, s0, src1);                             break;
286a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEX:        TEX(d, s0, src1, project, bias);               break;
287a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLDD:     TEXGRAD(d, s0, src1, s2, s3);                  break;
288a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLDL:     TEXLOD(d, s0, src1, s0.w);                     break;
289a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLOD:     TEXLOD(d, s0, src1, s2.x);                     break;
2904f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_TEXSIZE:    TEXSIZE(d, s0.x, src1);                        break;
291f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_TEXKILL:    TEXKILL(cMask, d, dst.mask);                   break;
292a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXOFFSET:  TEXOFFSET(d, s0, src1, s2);                    break;
293a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x);         break;
294a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x);                 break;
295a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
2964f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_TEXGRAD:    TEXGRAD(d, s0, src1, s2, s3);                  break;
297a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4);     break;
298a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXBIAS:    TEXBIAS(d, s0, src1, s2.x);                    break;
299a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXOFFSETBIAS: TEXOFFSETBIAS(d, s0, src1, s2, s3.x);       break;
3004f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_DISCARD:    DISCARD(cMask, instruction);                   break;
301f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DFDX:       DFDX(d, s0);                                   break;
302f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_DFDY:       DFDY(d, s0);                                   break;
303f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_FWIDTH:     FWIDTH(d, s0);                                 break;
3044f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_BREAK:      BREAK();                                       break;
3054f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_BREAKC:     BREAKC(s0, s1, control);                       break;
3064f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_BREAKP:     BREAKP(src0);                                  break;
3074f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_CONTINUE:   CONTINUE();                                    break;
308f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_TEST:       TEST();                                        break;
3094f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_CALL:       CALL(dst.label, dst.callSite);                 break;
3104f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_CALLNZ:     CALLNZ(dst.label, dst.callSite, src0);         break;
3114f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_ELSE:       ELSE();                                        break;
3124f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_ENDIF:      ENDIF();                                       break;
3134f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_ENDLOOP:    ENDLOOP();                                     break;
3144f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_ENDREP:     ENDREP();                                      break;
3154f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_ENDWHILE:   ENDWHILE();                                    break;
3169aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu			case Shader::OPCODE_ENDSWITCH:  ENDSWITCH();                                   break;
3174f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_IF:         IF(src0);                                      break;
3184f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_IFC:        IFC(s0, s1, control);                          break;
319f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_LABEL:      LABEL(dst.index);                              break;
3204f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_LOOP:       LOOP(src1);                                    break;
3214f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_REP:        REP(src0);                                     break;
3224f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_WHILE:      WHILE(src0);                                   break;
3239aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu			case Shader::OPCODE_SWITCH:     SWITCH();                                      break;
3244f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_RET:        RET();                                         break;
3254f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			case Shader::OPCODE_LEAVE:      LEAVE();                                       break;
326f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_CMP:        cmp(d, s0, s1, control);                       break;
327f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ALL:        all(d.x, s0);                                  break;
328f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_ANY:        any(d.x, s0);                                  break;
32924f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_NOT:        bitwise_not(d, s0);                            break;
33024f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_OR:         bitwise_or(d, s0, s1);                         break;
33124f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_XOR:        bitwise_xor(d, s0, s1);                        break;
33224f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_AND:        bitwise_and(d, s0, s1);                        break;
3338d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_EQ:         equal(d, s0, s1);                              break;
3348d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_NE:         notEqual(d, s0, s1);                           break;
335f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case Shader::OPCODE_END:                                                       break;
336f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			default:
337f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				ASSERT(false);
338f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
339f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
340f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(dst.type != Shader::PARAMETER_VOID && dst.type != Shader::PARAMETER_LABEL && opcode != Shader::OPCODE_TEXKILL && opcode != Shader::OPCODE_NOP)
341f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
342f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(dst.saturate)
343f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
344f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.x) d.x = Max(d.x, Float4(0.0f));
345f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.y) d.y = Max(d.y, Float4(0.0f));
346f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.z) d.z = Max(d.z, Float4(0.0f));
347f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.w) d.w = Max(d.w, Float4(0.0f));
348f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
349f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.x) d.x = Min(d.x, Float4(1.0f));
350f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.y) d.y = Min(d.y, Float4(1.0f));
351f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.z) d.z = Min(d.z, Float4(1.0f));
352f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.w) d.w = Min(d.w, Float4(1.0f));
353f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
354f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
355f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(instruction->isPredicated())
356f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
357f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					Vector4f pDst;   // FIXME: Rename
358f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
359f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					switch(dst.type)
360f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
361f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					case Shader::PARAMETER_TEMP:
362f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						if(dst.rel.type == Shader::PARAMETER_VOID)
363f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						{
3644f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.x) pDst.x = r[dst.index].x;
3654f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.y) pDst.y = r[dst.index].y;
3664f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.z) pDst.z = r[dst.index].z;
3674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.w) pDst.w = r[dst.index].w;
368f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						}
369f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						else
370f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						{
3714f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							Int a = relativeAddress(dst);
372f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
3734f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.x) pDst.x = r[dst.index + a].x;
3744f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.y) pDst.y = r[dst.index + a].y;
3754f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.z) pDst.z = r[dst.index + a].z;
3764f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.w) pDst.w = r[dst.index + a].w;
377f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						}
378f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						break;
379f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					case Shader::PARAMETER_COLOROUT:
3801edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu						if(dst.rel.type == Shader::PARAMETER_VOID)
3811edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu						{
3824f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.x) pDst.x = oC[dst.index].x;
3834f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.y) pDst.y = oC[dst.index].y;
3844f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.z) pDst.z = oC[dst.index].z;
3854f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.w) pDst.w = oC[dst.index].w;
3861edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu						}
3871edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu						else
3881edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu						{
3894f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							Int a = relativeAddress(dst) + dst.index;
3901edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu
3914f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.x) pDst.x = oC[a].x;
3924f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.y) pDst.y = oC[a].y;
3934f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.z) pDst.z = oC[a].z;
3944f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens							if(dst.w) pDst.w = oC[a].w;
3951edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu						}
396f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						break;
397f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					case Shader::PARAMETER_PREDICATE:
3984f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.x) pDst.x = p0.x;
3994f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.y) pDst.y = p0.y;
4004f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.z) pDst.z = p0.z;
4014f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.w) pDst.w = p0.w;
402f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						break;
403f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					case Shader::PARAMETER_DEPTHOUT:
4044f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						pDst.x = oDepth;
405f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						break;
406f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					default:
407f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						ASSERT(false);
408f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
409f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
4104f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					Int4 enable = enableMask(instruction);
411f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
412f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					Int4 xEnable = enable;
413f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					Int4 yEnable = enable;
414f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					Int4 zEnable = enable;
415f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					Int4 wEnable = enable;
416f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
417f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(predicate)
418f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
419f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						unsigned char pSwizzle = instruction->predicateSwizzle;
420f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
4214f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						Float4 xPredicate = p0[(pSwizzle >> 0) & 0x03];
4224f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						Float4 yPredicate = p0[(pSwizzle >> 2) & 0x03];
4234f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						Float4 zPredicate = p0[(pSwizzle >> 4) & 0x03];
4244f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						Float4 wPredicate = p0[(pSwizzle >> 6) & 0x03];
425f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
426f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						if(!instruction->predicateNot)
427f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						{
428f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.x) xEnable = xEnable & As<Int4>(xPredicate);
429f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.y) yEnable = yEnable & As<Int4>(yPredicate);
430f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.z) zEnable = zEnable & As<Int4>(zPredicate);
431f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.w) wEnable = wEnable & As<Int4>(wPredicate);
432f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						}
433f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						else
434f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						{
435f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.x) xEnable = xEnable & ~As<Int4>(xPredicate);
436f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.y) yEnable = yEnable & ~As<Int4>(yPredicate);
437f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.z) zEnable = zEnable & ~As<Int4>(zPredicate);
438f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							if(dst.w) wEnable = wEnable & ~As<Int4>(wPredicate);
439f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						}
440f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
441f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
442f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.x) d.x = As<Float4>(As<Int4>(d.x) & xEnable);
443f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.y) d.y = As<Float4>(As<Int4>(d.y) & yEnable);
444f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.z) d.z = As<Float4>(As<Int4>(d.z) & zEnable);
445f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.w) d.w = As<Float4>(As<Int4>(d.w) & wEnable);
446f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
447f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.x) d.x = As<Float4>(As<Int4>(d.x) | (As<Int4>(pDst.x) & ~xEnable));
448f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.y) d.y = As<Float4>(As<Int4>(d.y) | (As<Int4>(pDst.y) & ~yEnable));
449f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.z) d.z = As<Float4>(As<Int4>(d.z) | (As<Int4>(pDst.z) & ~zEnable));
450f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.w) d.w = As<Float4>(As<Int4>(d.w) | (As<Int4>(pDst.w) & ~wEnable));
451f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
452f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
453f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				switch(dst.type)
454f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
455f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				case Shader::PARAMETER_TEMP:
456f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(dst.rel.type == Shader::PARAMETER_VOID)
457f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
4584f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.x) r[dst.index].x = d.x;
4594f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.y) r[dst.index].y = d.y;
4604f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.z) r[dst.index].z = d.z;
4614f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.w) r[dst.index].w = d.w;
462f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
463f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					else
464f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
4654f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						Int a = relativeAddress(dst);
466f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
4674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.x) r[dst.index + a].x = d.x;
4684f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.y) r[dst.index + a].y = d.y;
4694f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.z) r[dst.index + a].z = d.z;
4704f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.w) r[dst.index + a].w = d.w;
471f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
472f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					break;
473f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				case Shader::PARAMETER_COLOROUT:
4741edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu					if(dst.rel.type == Shader::PARAMETER_VOID)
4751edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu					{
4768b124c10248597cfecd21f7bf385900152467dadNicolas Capens						broadcastColor0 = (dst.index == 0) && broadcastColor0;
4778b124c10248597cfecd21f7bf385900152467dadNicolas Capens
4784f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.x) { oC[dst.index].x = d.x; }
4794f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.y) { oC[dst.index].y = d.y; }
4804f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.z) { oC[dst.index].z = d.z; }
4814f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.w) { oC[dst.index].w = d.w; }
4821edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu					}
4831edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu					else
4841edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu					{
4858b124c10248597cfecd21f7bf385900152467dadNicolas Capens						broadcastColor0 = false;
4864f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						Int a = relativeAddress(dst) + dst.index;
4871edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu
4884f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.x) { oC[a].x = d.x; }
4894f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.y) { oC[a].y = d.y; }
4904f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.z) { oC[a].z = d.z; }
4914f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						if(dst.w) { oC[a].w = d.w; }
4921edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu					}
493f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					break;
494f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				case Shader::PARAMETER_PREDICATE:
4954f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					if(dst.x) p0.x = d.x;
4964f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					if(dst.y) p0.y = d.y;
4974f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					if(dst.z) p0.z = d.z;
4984f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					if(dst.w) p0.w = d.w;
499f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					break;
500f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				case Shader::PARAMETER_DEPTHOUT:
5014f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					oDepth = d.x;
502f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					break;
503f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				default:
504f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					ASSERT(false);
505f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
506f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
507f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
508f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
509f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(currentLabel != -1)
510f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
511f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Nucleus::setInsertBlock(returnBlock);
512f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
513f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
5148b124c10248597cfecd21f7bf385900152467dadNicolas Capens		if(broadcastColor0)
515f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
5168b124c10248597cfecd21f7bf385900152467dadNicolas Capens			for(int i = 0; i < RENDERTARGETS; i++)
5178b124c10248597cfecd21f7bf385900152467dadNicolas Capens			{
5188b124c10248597cfecd21f7bf385900152467dadNicolas Capens				c[i] = oC[0];
5198b124c10248597cfecd21f7bf385900152467dadNicolas Capens			}
5208b124c10248597cfecd21f7bf385900152467dadNicolas Capens		}
5218b124c10248597cfecd21f7bf385900152467dadNicolas Capens		else
5228b124c10248597cfecd21f7bf385900152467dadNicolas Capens		{
5238b124c10248597cfecd21f7bf385900152467dadNicolas Capens			for(int i = 0; i < RENDERTARGETS; i++)
5248b124c10248597cfecd21f7bf385900152467dadNicolas Capens			{
5258b124c10248597cfecd21f7bf385900152467dadNicolas Capens				c[i] = oC[i];
5268b124c10248597cfecd21f7bf385900152467dadNicolas Capens			}
527f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
5287bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens
5297bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens		clampColor(c);
5307bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens
5317bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens		if(state.depthOverride)
5327bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens		{
5337bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens			oDepth = Min(Max(oDepth, Float4(0.0f)), Float4(1.0f));
5347bc079c277ad95ecd3c964aa6a9285029bf2fe81Nicolas Capens		}
535f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
5365d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens
5374f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	Bool PixelProgram::alphaTest(Int cMask[4])
5385d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	{
539f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(!state.alphaTestActive())
540f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
541f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			return true;
542f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
543f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
544f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int aMask;
545f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
546f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(state.transparencyAntialiasing == TRANSPARENCY_NONE)
547f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
5484f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			Short4 alpha = RoundShort4(c[0].w * Float4(0x1000));
549f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
5504f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			PixelRoutine::alphaTest(aMask, alpha);
551f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
552f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			for(unsigned int q = 0; q < state.multiSample; q++)
553f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
554f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				cMask[q] &= aMask;
555f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
556f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
557f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(state.transparencyAntialiasing == TRANSPARENCY_ALPHA_TO_COVERAGE)
558f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
5594f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			alphaToCoverage(cMask, c[0].w);
560f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
561f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else ASSERT(false);
562f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
563f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int pass = cMask[0];
564f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
565f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		for(unsigned int q = 1; q < state.multiSample; q++)
566f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
567f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			pass = pass | cMask[q];
568f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
569f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
5705d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		return pass != 0x0;
5715d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	}
5725d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens
5734f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4])
5745d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens	{
5751edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu		for(int index = 0; index < RENDERTARGETS; index++)
576f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
577f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(!state.colorWriteActive(index))
578f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
579f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				continue;
5805d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens			}
581f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
582049a187a80a1b9f873593bf2af1b5349d6575e18Alexis Hetu			if(!postBlendSRGB && state.writeSRGB && !isSRGB(index))
583f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
5844f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				c[index].x = linearToSRGB(c[index].x);
5854f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				c[index].y = linearToSRGB(c[index].y);
5864f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				c[index].z = linearToSRGB(c[index].z);
587f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
588f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
589f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(index == 0)
590f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
5914f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				fogBlend(c[index], fog);
592f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
593f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
594f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			switch(state.targetFormat[index])
595f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
596f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_R5G6B5:
597f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_X8R8G8B8:
598f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_X8B8G8R8:
599f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A8R8G8B8:
600f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A8B8G8R8:
601049a187a80a1b9f873593bf2af1b5349d6575e18Alexis Hetu			case FORMAT_SRGB8_X8:
602049a187a80a1b9f873593bf2af1b5349d6575e18Alexis Hetu			case FORMAT_SRGB8_A8:
603143dfc7e600b9cba5c60529946e4481dfbab8793Alexis Hetu			case FORMAT_G8R8:
6040cff3cbe88eb3e291bb1240cf1040f92296ef3e8Alexis Hetu			case FORMAT_R8:
605f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A8:
606f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_G16R16:
607f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A16B16G16R16:
608f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				for(unsigned int q = 0; q < state.multiSample; q++)
609f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
6104f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[index]));
611f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					Vector4s color;
612f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
61313c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens					if(state.targetFormat[index] == FORMAT_R5G6B5)
61413c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens					{
61513c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.x = UShort4(c[index].x * Float4(0xFBFF), false);
61613c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.y = UShort4(c[index].y * Float4(0xFDFF), false);
61713c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.z = UShort4(c[index].z * Float4(0xFBFF), false);
61813c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.w = UShort4(c[index].w * Float4(0xFFFF), false);
61913c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens					}
62013c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens					else
62113c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens					{
62213c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.x = convertFixed16(c[index].x, false);
62313c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.y = convertFixed16(c[index].y, false);
62413c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.z = convertFixed16(c[index].z, false);
62513c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens						color.w = convertFixed16(c[index].w, false);
62613c70cda1140ea2b335369d3506a55f1237a5982Nicolas Capens					}
627f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
628f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(state.multiSampleMask & (1 << q))
629f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
6304f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						alphaBlend(index, buffer, color, x);
6314f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						logicOperation(index, buffer, color, x);
6324f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						writeColor(index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
633f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
634f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
635f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				break;
636f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_R32F:
637f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_G32R32F:
638dbd1a8e6cb781672840a5f7d53d162247a4dbe98Alexis Hetu			case FORMAT_X32B32G32R32F:
639f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A32B32G32R32F:
64067fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens			case FORMAT_X32B32G32R32F_UNSIGNED:
6411abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_R32I:
6421abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_G32R32I:
6431abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_A32B32G32R32I:
6441abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_R32UI:
6451abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_G32R32UI:
6461abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_A32B32G32R32UI:
647bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_R16I:
648bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_G16R16I:
649bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_A16B16G16R16I:
650bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_R16UI:
651bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_G16R16UI:
652bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_A16B16G16R16UI:
653bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_R8I:
654bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_G8R8I:
655bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_A8B8G8R8I:
656bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_R8UI:
657bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_G8R8UI:
658bd7117d76aa3ca042146298f97f899577b76c84fAlexis Hetu			case FORMAT_A8B8G8R8UI:
659f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				for(unsigned int q = 0; q < state.multiSample; q++)
660f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
6614f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[index]));
6624f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					Vector4f color = c[index];
663f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
664f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(state.multiSampleMask & (1 << q))
665f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
6664f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						alphaBlend(index, buffer, color, x);
6674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens						writeColor(index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
668f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
669f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
670f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				break;
671f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			default:
672f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				ASSERT(false);
673f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
674f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
6751edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu	}
676f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
677a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	Vector4f PixelProgram::sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
678f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
679c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f tmp;
680c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
681f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID)
682f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
683a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			tmp = sampleTexture(sampler.index, uvwq, bias, dsx, dsy, offset, function);
684f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
685f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else
686f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
687c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Int index = As<Int>(Float(fetchRegister(sampler).x.x));
688f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
689f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
690f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
691f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(shader->usesSampler(i))
692f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
693f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					If(index == i)
694f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
695a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens						tmp = sampleTexture(i, uvwq, bias, dsx, dsy, offset, function);
696f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
697f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
698f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
699f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
700f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
701c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
70289a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		Vector4f c;
703c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.x = tmp[(sampler.swizzle >> 0) & 0x3];
704c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.y = tmp[(sampler.swizzle >> 2) & 0x3];
705c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.z = tmp[(sampler.swizzle >> 4) & 0x3];
706c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.w = tmp[(sampler.swizzle >> 6) & 0x3];
70789a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens
70889a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		return c;
709f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
710f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
711a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	Vector4f PixelProgram::sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
712f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
713c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		#if PERF_PROFILE
714c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Long texTime = Ticks();
715c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		#endif
716f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
7172337a192aa163b1076ba768e414c5fe27f1a9143Meng-Lin Wu		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture);
718a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		Vector4f c = SamplerCore(constants, state.sampler[samplerIndex]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, bias, dsx, dsy, offset, function);
719f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
720c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		#if PERF_PROFILE
721c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			cycles[PERF_TEX] += Ticks() - texTime;
722c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		#endif
72389a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens
72489a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		return c;
725f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
726f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
7271edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu	void PixelProgram::clampColor(Vector4f oC[RENDERTARGETS])
728f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
7291edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu		for(int index = 0; index < RENDERTARGETS; index++)
730f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
731f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(!state.colorWriteActive(index) && !(index == 0 && state.alphaTestActive()))
732f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
733f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				continue;
734f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
735f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
736f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			switch(state.targetFormat[index])
737f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
738f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_NULL:
739f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				break;
740f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_R5G6B5:
741f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A8R8G8B8:
742f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A8B8G8R8:
743f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_X8R8G8B8:
744f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_X8B8G8R8:
745049a187a80a1b9f873593bf2af1b5349d6575e18Alexis Hetu			case FORMAT_SRGB8_X8:
746049a187a80a1b9f873593bf2af1b5349d6575e18Alexis Hetu			case FORMAT_SRGB8_A8:
747143dfc7e600b9cba5c60529946e4481dfbab8793Alexis Hetu			case FORMAT_G8R8:
7480cff3cbe88eb3e291bb1240cf1040f92296ef3e8Alexis Hetu			case FORMAT_R8:
749f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A8:
750f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_G16R16:
751f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A16B16G16R16:
752f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				oC[index].x = Max(oC[index].x, Float4(0.0f)); oC[index].x = Min(oC[index].x, Float4(1.0f));
753f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				oC[index].y = Max(oC[index].y, Float4(0.0f)); oC[index].y = Min(oC[index].y, Float4(1.0f));
754f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				oC[index].z = Max(oC[index].z, Float4(0.0f)); oC[index].z = Min(oC[index].z, Float4(1.0f));
755f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				oC[index].w = Max(oC[index].w, Float4(0.0f)); oC[index].w = Min(oC[index].w, Float4(1.0f));
756f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				break;
757f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_R32F:
758f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_G32R32F:
759dbd1a8e6cb781672840a5f7d53d162247a4dbe98Alexis Hetu			case FORMAT_X32B32G32R32F:
760f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			case FORMAT_A32B32G32R32F:
7611abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_R32I:
7621abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_G32R32I:
7631abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_A32B32G32R32I:
7641abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_R32UI:
7651abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_G32R32UI:
7661abb6380a5bd669bc4581ada55ab12556f177ffeAlexis Hetu			case FORMAT_A32B32G32R32UI:
7678e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_R16I:
7688e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_G16R16I:
7698e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_A16B16G16R16I:
7708e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_R16UI:
7718e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_G16R16UI:
7728e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_A16B16G16R16UI:
7738e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_R8I:
7748e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_G8R8I:
7758e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_A8B8G8R8I:
7768e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_R8UI:
7778e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_G8R8UI:
7788e7675dd6f40b49f81f336a22e33e1516a990263Alexis Hetu			case FORMAT_A8B8G8R8UI:
779f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				break;
78067fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens			case FORMAT_X32B32G32R32F_UNSIGNED:
78167fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens				oC[index].x = Max(oC[index].x, Float4(0.0f));
78267fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens				oC[index].y = Max(oC[index].y, Float4(0.0f));
78367fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens				oC[index].z = Max(oC[index].z, Float4(0.0f));
78467fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens				oC[index].w = Max(oC[index].w, Float4(0.0f));
78567fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens				break;
786f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			default:
787f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				ASSERT(false);
788f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
789f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
790f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
791f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
7924f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	Int4 PixelProgram::enableMask(const Shader::Instruction *instruction)
793f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
7944f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
795f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
796f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(!whileTest)
797f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
798f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(shader->containsBreakInstruction() && instruction->analysisBreak)
799f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
8004f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				enable &= enableBreak;
801f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
802f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
803f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(shader->containsContinueInstruction() && instruction->analysisContinue)
804f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
8054f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				enable &= enableContinue;
806f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
807f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
808f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(shader->containsLeaveInstruction() && instruction->analysisLeave)
809f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
8104f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				enable &= enableLeave;
811f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
812f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
813f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
814f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		return enable;
815f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
816f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
817c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens	Vector4f PixelProgram::fetchRegister(const Src &src, unsigned int offset)
818f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
819f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Vector4f reg;
8205d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		unsigned int i = src.index + offset;
821f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
822f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		switch(src.type)
823f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
824f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_TEMP:
825f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(src.rel.type == Shader::PARAMETER_VOID)
826f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
8274f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				reg = r[i];
828f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
829f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			else
830f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
8312c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				Int a = relativeAddress(src, src.bufferIndex);
832f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
8334f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				reg = r[i + a];
834f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
835f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
836f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_INPUT:
837f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
838f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				if(src.rel.type == Shader::PARAMETER_VOID)   // Not relative
839f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
8404f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					reg = v[i];
841f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
842f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				else
843f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
8442c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu					Int a = relativeAddress(src, src.bufferIndex);
845f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
8464f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens					reg = v[i + a];
847f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
848f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
849f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
850f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_CONST:
8514f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			reg = readConstant(src, offset);
852f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
853f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_TEXTURE:
8544f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			reg = v[2 + i];
855f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
856f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_MISCTYPE:
857877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			if(src.index == Shader::VPosIndex) reg = vPos;
858877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			if(src.index == Shader::VFaceIndex) reg = vFace;
859f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
860f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_SAMPLER:
861f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(src.rel.type == Shader::PARAMETER_VOID)
862f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
863f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				reg.x = As<Float4>(Int4(i));
864f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
865f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			else if(src.rel.type == Shader::PARAMETER_TEMP)
866f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
8674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				reg.x = As<Float4>(Int4(i) + As<Int4>(r[src.rel.index].x));
868f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
869f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			return reg;
870f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_PREDICATE:   return reg; // Dummy
871f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_VOID:        return reg; // Dummy
872f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_FLOAT4LITERAL:
873f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			reg.x = Float4(src.value[0]);
874f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			reg.y = Float4(src.value[1]);
875f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			reg.z = Float4(src.value[2]);
876f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			reg.w = Float4(src.value[3]);
877f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
878f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_CONSTINT:    return reg; // Dummy
879f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_CONSTBOOL:   return reg; // Dummy
880f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_LOOP:        return reg; // Dummy
881f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_COLOROUT:
8821edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			if(src.rel.type == Shader::PARAMETER_VOID)   // Not relative
8831edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			{
8844f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				reg = oC[i];
8851edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			}
8861edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			else
8871edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			{
8882c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				Int a = relativeAddress(src, src.bufferIndex);
8891edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu
8904f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				reg = oC[i + a];
8911edcd8b626129ac8297cda0a297034d8dfeb5061Alexis Hetu			}
892f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
893f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::PARAMETER_DEPTHOUT:
8944f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			reg.x = oDepth;
895f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
896f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		default:
897f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			ASSERT(false);
898f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
899f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
900f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		const Float4 &x = reg[(src.swizzle >> 0) & 0x3];
901f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		const Float4 &y = reg[(src.swizzle >> 2) & 0x3];
902f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		const Float4 &z = reg[(src.swizzle >> 4) & 0x3];
903f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		const Float4 &w = reg[(src.swizzle >> 6) & 0x3];
904f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
905f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Vector4f mod;
906f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
907f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		switch(src.modifier)
908f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
909f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::MODIFIER_NONE:
910f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.x = x;
911f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.y = y;
912f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.z = z;
913f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.w = w;
914f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
915f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::MODIFIER_NEGATE:
916f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.x = -x;
917f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.y = -y;
918f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.z = -z;
919f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.w = -w;
920f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
921f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::MODIFIER_ABS:
922f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.x = Abs(x);
923f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.y = Abs(y);
924f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.z = Abs(z);
925f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.w = Abs(w);
926f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
927f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::MODIFIER_ABS_NEGATE:
928f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.x = -Abs(x);
929f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.y = -Abs(y);
930f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.z = -Abs(z);
931f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.w = -Abs(w);
932f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
933f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::MODIFIER_NOT:
934f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.x = As<Float4>(As<Int4>(x) ^ Int4(0xFFFFFFFF));
935f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.y = As<Float4>(As<Int4>(y) ^ Int4(0xFFFFFFFF));
936f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.z = As<Float4>(As<Int4>(z) ^ Int4(0xFFFFFFFF));
937f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			mod.w = As<Float4>(As<Int4>(w) ^ Int4(0xFFFFFFFF));
938f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			break;
939f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		default:
940f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			ASSERT(false);
941f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
942f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
943f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		return mod;
944f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
945f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
9462c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	RValue<Pointer<Byte>> PixelProgram::uniformAddress(int bufferIndex, unsigned int index)
9472c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	{
9482c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		if(bufferIndex == -1)
9492c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		{
9502c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			return data + OFFSET(DrawData, ps.c[index]);
9512c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		}
9522c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		else
9532c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		{
9542c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			return *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, ps.u[bufferIndex])) + index;
9552c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		}
9562c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	}
9572c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
9582c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	RValue<Pointer<Byte>> PixelProgram::uniformAddress(int bufferIndex, unsigned int index, Int& offset)
9592c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	{
9602c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		return uniformAddress(bufferIndex, index) + offset * sizeof(float4);
9612c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	}
9622c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
9634f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	Vector4f PixelProgram::readConstant(const Src &src, unsigned int offset)
964f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
965f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Vector4f c;
9665d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		unsigned int i = src.index + offset;
967f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
968f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(src.rel.type == Shader::PARAMETER_VOID)   // Not relative
969f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
9702c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i));
971f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
972f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.x = c.x.xxxx;
973f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.y = c.y.yyyy;
974f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.z = c.z.zzzz;
975f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.w = c.w.wwww;
976f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
977f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(shader->containsDefineInstruction())   // Constant may be known at compile time
978f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
979f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				for(size_t j = 0; j < shader->getLength(); j++)
980f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
981f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					const Shader::Instruction &instruction = *shader->getInstruction(j);
982f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
983f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					if(instruction.opcode == Shader::OPCODE_DEF)
984f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					{
985f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						if(instruction.dst.index == i)
986f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						{
987f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							c.x = Float4(instruction.src[0].value[0]);
988f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							c.y = Float4(instruction.src[0].value[1]);
989f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							c.z = Float4(instruction.src[0].value[2]);
990f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							c.w = Float4(instruction.src[0].value[3]);
991f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
992f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu							break;
993f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu						}
994f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu					}
995f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
996f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
997f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
998f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(src.rel.type == Shader::PARAMETER_LOOP)
999f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
10004f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			Int loopCounter = aL[loopDepth];
1001f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10022c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, loopCounter));
1003f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1004f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.x = c.x.xxxx;
1005f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.y = c.y.yyyy;
1006f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.z = c.z.zzzz;
1007f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.w = c.w.wwww;
1008f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1009f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else
1010f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
10112c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			Int a = relativeAddress(src, src.bufferIndex);
1012f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10132c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, a));
1014f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1015f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.x = c.x.xxxx;
1016f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.y = c.y.yyyy;
1017f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.z = c.z.zzzz;
1018f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			c.w = c.w.wwww;
1019f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1020f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1021f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		return c;
1022f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1023f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10242c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	Int PixelProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
1025f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1026f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ASSERT(var.rel.deterministic);
1027f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1028f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(var.rel.type == Shader::PARAMETER_TEMP)
1029f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
10304f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			return As<Int>(Extract(r[var.rel.index].x, 0)) * var.rel.scale;
1031f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1032f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(var.rel.type == Shader::PARAMETER_INPUT)
1033f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
10344f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			return As<Int>(Extract(v[var.rel.index].x, 0)) * var.rel.scale;
1035f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1036f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(var.rel.type == Shader::PARAMETER_OUTPUT)
1037f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
10384f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			return As<Int>(Extract(oC[var.rel.index].x, 0)) * var.rel.scale;
1039f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1040f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(var.rel.type == Shader::PARAMETER_CONST)
1041f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
104248be735fa7eb1e2684a631cc4270a4503c7d235aAlexis Hetu			return *Pointer<Int>(uniformAddress(bufferIndex, var.rel.index)) * var.rel.scale;
1043f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1044907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		else if(var.rel.type == Shader::PARAMETER_LOOP)
1045907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		{
1046907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens			return aL[loopDepth];
1047907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		}
1048f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else ASSERT(false);
1049f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1050f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		return 0;
1051f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1052f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1053f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	Float4 PixelProgram::linearToSRGB(const Float4 &x)   // Approximates x^(1.0/2.2)
1054f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1055f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Float4 sqrtx = Rcp_pp(RcpSqrt_pp(x));
1056f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Float4 sRGB = sqrtx * Float4(1.14f) - x * Float4(0.14f);
1057f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1058f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		return Min(Max(sRGB, Float4(0.0f)), Float4(1.0f));
1059f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1060f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10614f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::M3X2(Vector4f &dst, Vector4f &src0, const Src &src1)
1062f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1063c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1064c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1065f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1066f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = dot3(src0, row0);
1067f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = dot3(src0, row1);
1068f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1069f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10704f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::M3X3(Vector4f &dst, Vector4f &src0, const Src &src1)
1071f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1072c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1073c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1074c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
1075f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1076f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = dot3(src0, row0);
1077f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = dot3(src0, row1);
1078f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = dot3(src0, row2);
1079f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1080f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10814f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::M3X4(Vector4f &dst, Vector4f &src0, const Src &src1)
1082f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1083c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1084c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1085c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
1086c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row3 = fetchRegister(src1, 3);
1087f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1088f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = dot3(src0, row0);
1089f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = dot3(src0, row1);
1090f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = dot3(src0, row2);
1091f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.w = dot3(src0, row3);
1092f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1093f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
10944f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::M4X3(Vector4f &dst, Vector4f &src0, const Src &src1)
1095f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1096c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1097c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1098c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
1099f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1100f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = dot4(src0, row0);
1101f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = dot4(src0, row1);
1102f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = dot4(src0, row2);
1103f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1104f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
11054f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::M4X4(Vector4f &dst, Vector4f &src0, const Src &src1)
1106f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1107c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1108c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1109c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
1110c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row3 = fetchRegister(src1, 3);
1111f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1112f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = dot4(src0, row0);
1113f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = dot4(src0, row1);
1114f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = dot4(src0, row2);
1115f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.w = dot4(src0, row3);
1116f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1117f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1118a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias)
1119f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
11200484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens		if(project)
11210484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens		{
11220484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens			Vector4f proj;
11230484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens			Float4 rw = reciprocal(src0.w);
11240484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens			proj.x = src0.x * rw;
11250484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens			proj.y = src0.y * rw;
11260484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens			proj.z = src0.z * rw;
11270484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens
1128a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			dst = sampleTexture(src1, proj, src0.x, (src0), (src0), (src0), Implicit);
11290484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens		}
11300484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens		else
11310484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens		{
1132a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			dst = sampleTexture(src1, src0, src0.x, (src0), (src0), (src0), bias ? Bias : Implicit);
11330484c799e713845e139ecc18dbd7d9134d9f361dNicolas Capens		}
1134f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1135f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1136a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset)
113725d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1138a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Implicit, Offset});
113925d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
114025d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1141a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod)
114225d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1143a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
114425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
114525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1146a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias)
114725d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1148a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, bias, (src0), (src0), (src0), Bias);
1149a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	}
115067fdd834b8df137da2edf8a767bfaf51cf0bfecdNicolas Capens
1151a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias)
1152a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	{
1153a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, bias, (src0), (src0), offset, {Bias, Offset});
115425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
115525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1156a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
115725d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1158a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
115925d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
116025d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1161a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
116225d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1163a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
116425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
116525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1166a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
116725d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1168a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, (src0), Grad);
116925d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
117025d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1171a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
1172f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1173a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
1174f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1175f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1176a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void PixelProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod)
1177f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1178a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
1179f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1180f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
11814f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
11829bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu	{
118395ac1874dbdc4db63ff18279a1f8590d4b10b647Alexis Hetu		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + src1.index * sizeof(Texture);
118489a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		dst = SamplerCore::textureSize(texture, lod);
11859bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu	}
11869bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu
1187f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	void PixelProgram::TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask)
1188f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1189f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int kill = -1;
1190f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1191f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(mask & 0x1) kill &= SignMask(CmpNLT(src.x, Float4(0.0f)));
1192f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(mask & 0x2) kill &= SignMask(CmpNLT(src.y, Float4(0.0f)));
1193f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(mask & 0x4) kill &= SignMask(CmpNLT(src.z, Float4(0.0f)));
1194f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(mask & 0x8) kill &= SignMask(CmpNLT(src.w, Float4(0.0f)));
1195f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1196f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: Dynamic branching affects TEXKILL?
1197f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		//	if(shader->containsDynamicBranching())
1198f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		//	{
11994f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		//		kill = ~SignMask(enableMask());
1200f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		//	}
1201f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1202f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		for(unsigned int q = 0; q < state.multiSample; q++)
1203f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1204f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			cMask[q] &= kill;
1205f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1206f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1207f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: Branch to end of shader if all killed?
1208f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1209f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12104f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::DISCARD(Int cMask[4], const Shader::Instruction *instruction)
1211f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1212f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int kill = 0;
1213f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1214f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(shader->containsDynamicBranching())
1215f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
12164f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			kill = ~SignMask(enableMask(instruction));
1217f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1218f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1219f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		for(unsigned int q = 0; q < state.multiSample; q++)
1220f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1221f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			cMask[q] &= kill;
1222f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1223f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1224f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: Branch to end of shader if all killed?
1225f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1226f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1227f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	void PixelProgram::DFDX(Vector4f &dst, Vector4f &src)
1228f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1229f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = src.x.yyww - src.x.xxzz;
1230f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = src.y.yyww - src.y.xxzz;
1231f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = src.z.yyww - src.z.xxzz;
1232f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.w = src.w.yyww - src.w.xxzz;
1233f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1234f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1235f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	void PixelProgram::DFDY(Vector4f &dst, Vector4f &src)
1236f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1237f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = src.x.zwzw - src.x.xyxy;
1238f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = src.y.zwzw - src.y.xyxy;
1239f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = src.z.zwzw - src.z.xyxy;
1240f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.w = src.w.zwzw - src.w.xyxy;
1241f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1242f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1243f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	void PixelProgram::FWIDTH(Vector4f &dst, Vector4f &src)
1244f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1245f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// abs(dFdx(src)) + abs(dFdy(src));
1246f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.x = Abs(src.x.yyww - src.x.xxzz) + Abs(src.x.zwzw - src.x.xyxy);
1247f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.y = Abs(src.y.yyww - src.y.xxzz) + Abs(src.y.zwzw - src.y.xyxy);
1248f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.z = Abs(src.z.yyww - src.z.xxzz) + Abs(src.z.zwzw - src.z.xyxy);
1249f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		dst.w = Abs(src.w.yyww - src.w.xxzz) + Abs(src.w.zwzw - src.w.xyxy);
1250f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1251f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12524f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::BREAK()
1253f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
12546d12331ad5a27e85429abf33d54d6576546fff60Nicolas Capens		enableBreak = enableBreak & ~enableStack[enableIndex];
1255f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1256f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12574f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control)
1258f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1259f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int4 condition;
1260f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1261f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		switch(control)
1262f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1263f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
1264f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x);  break;
1265f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
1266f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x);  break;
1267f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
1268f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x);  break;
1269f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		default:
1270f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			ASSERT(false);
1271f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1272f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12734f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		BREAK(condition);
1274f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1275f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12764f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::BREAKP(const Src &predicateRegister)   // FIXME: Factor out parts common with BREAKC
1277f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
12784f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1279f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1280f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1281f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1282f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			condition = ~condition;
1283f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1284f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12854f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		BREAK(condition);
1286f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1287f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12884f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::BREAK(Int4 &condition)
1289f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
12904f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		condition &= enableStack[enableIndex];
1291f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12924f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableBreak = enableBreak & ~condition;
1293f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1294f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
12954f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::CONTINUE()
1296f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
12974f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableContinue = enableContinue & ~enableStack[enableIndex];
1298f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1299f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1300f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	void PixelProgram::TEST()
1301f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1302f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		whileTest = true;
1303f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1304f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13054f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::CALL(int labelIndex, int callSiteIndex)
1306f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1307f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(!labelBlock[labelIndex])
1308f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1309f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1310f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1311f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1312f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(callRetBlock[labelIndex].size() > 1)
1313f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
13144f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
1315f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1316f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13174f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 restoreLeave = enableLeave;
1318f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1319f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(labelBlock[labelIndex]);
1320f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
1321f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13224f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableLeave = restoreLeave;
1323f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1324f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13254f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::CALLNZ(int labelIndex, int callSiteIndex, const Src &src)
1326f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1327f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(src.type == Shader::PARAMETER_CONSTBOOL)
1328f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
13294f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			CALLNZb(labelIndex, callSiteIndex, src);
1330f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1331f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(src.type == Shader::PARAMETER_PREDICATE)
1332f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
13334f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			CALLNZp(labelIndex, callSiteIndex, src);
1334f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1335f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else ASSERT(false);
1336f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1337f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13384f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister)
1339f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
13404f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Bool condition = (*Pointer<Byte>(data + OFFSET(DrawData, ps.b[boolRegister.index])) != Byte(0));   // FIXME
1341f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1342f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(boolRegister.modifier == Shader::MODIFIER_NOT)
1343f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1344f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			condition = !condition;
1345f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1346f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1347f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(!labelBlock[labelIndex])
1348f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1349f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1350f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1351f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1352f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(callRetBlock[labelIndex].size() > 1)
1353f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
13544f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
1355f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1356f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13574f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 restoreLeave = enableLeave;
1358f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1359f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		branch(condition, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]);
1360f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
1361f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13624f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableLeave = restoreLeave;
1363f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1364f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13654f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister)
1366f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
13674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1368f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1369f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1370f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1371f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			condition = ~condition;
1372f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1373f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13744f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		condition &= enableStack[enableIndex];
1375f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1376f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(!labelBlock[labelIndex])
1377f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1378f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1379f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1380f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1381f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(callRetBlock[labelIndex].size() > 1)
1382f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
13834f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
1384f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1385f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13864f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableIndex++;
13874f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableStack[enableIndex] = condition;
13884f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 restoreLeave = enableLeave;
1389f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1390f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Bool notAllFalse = SignMask(condition) != 0;
1391f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		branch(notAllFalse, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]);
1392f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
1393f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13944f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableIndex--;
13954f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableLeave = restoreLeave;
1396f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1397f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
13984f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::ELSE()
1399f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1400f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifDepth--;
1401f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1402c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = ifFalseBlock[ifDepth];
1403c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1404f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1405f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(isConditionalIf[ifDepth])
1406f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
14074f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			Int4 condition = ~enableStack[enableIndex] & enableStack[enableIndex - 1];
1408f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Bool notAllFalse = SignMask(condition) != 0;
1409f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1410f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			branch(notAllFalse, falseBlock, endBlock);
1411f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14124f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			enableStack[enableIndex] = ~enableStack[enableIndex] & enableStack[enableIndex - 1];
1413f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1414f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else
1415f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1416f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Nucleus::createBr(endBlock);
1417f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Nucleus::setInsertBlock(falseBlock);
1418f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1419f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1420f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifFalseBlock[ifDepth] = endBlock;
1421f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1422f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifDepth++;
1423f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1424f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14254f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::ENDIF()
1426f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1427f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifDepth--;
1428f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1429c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = ifFalseBlock[ifDepth];
1430f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1431f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(endBlock);
1432f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(endBlock);
1433f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1434f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(isConditionalIf[ifDepth])
1435f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
14364f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			enableIndex--;
1437f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1438f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1439f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14404f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::ENDLOOP()
1441f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1442f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepDepth--;
1443f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14444f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		aL[loopDepth] = aL[loopDepth] + increment[loopDepth];   // FIXME: +=
1445f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1446c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1447c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1448f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1449f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(testBlock);
1450f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(endBlock);
1451f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14524f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		loopDepth--;
14534f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1454f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1455f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14564f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::ENDREP()
1457f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1458f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepDepth--;
1459f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1460c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1461c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1462f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1463f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(testBlock);
1464f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(endBlock);
1465f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14664f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		loopDepth--;
14674f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1468f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1469f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14704f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::ENDWHILE()
1471f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1472f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepDepth--;
1473f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1474c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1475c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1476f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1477f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(testBlock);
1478f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(endBlock);
1479f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14804f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableIndex--;
1481f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		whileTest = false;
1482f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1483f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
14849aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	void PixelProgram::ENDSWITCH()
14859aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	{
14869aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepDepth--;
14879aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1488c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
14899aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1490ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		Nucleus::createBr(endBlock);
14919aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		Nucleus::setInsertBlock(endBlock);
14929aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	}
14939aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
14944f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::IF(const Src &src)
1495f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1496f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(src.type == Shader::PARAMETER_CONSTBOOL)
1497f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
14984f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			IFb(src);
1499f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1500f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else if(src.type == Shader::PARAMETER_PREDICATE)
1501f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
15024f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			IFp(src);
1503f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1504f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else
1505f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1506c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Int4 condition = As<Int4>(fetchRegister(src).x);
15074f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens			IF(condition);
1508f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1509f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1510f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15114f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::IFb(const Src &boolRegister)
1512f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1513f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ASSERT(ifDepth < 24 + 4);
1514f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15154f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Bool condition = (*Pointer<Byte>(data + OFFSET(DrawData, ps.b[boolRegister.index])) != Byte(0));   // FIXME
1516f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1517f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(boolRegister.modifier == Shader::MODIFIER_NOT)
1518f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1519f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			condition = !condition;
1520f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1521f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1522c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *trueBlock = Nucleus::createBasicBlock();
1523c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = Nucleus::createBasicBlock();
1524f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1525f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		branch(condition, trueBlock, falseBlock);
1526f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1527f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		isConditionalIf[ifDepth] = false;
1528f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifFalseBlock[ifDepth] = falseBlock;
1529f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1530f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifDepth++;
1531f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1532f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15334f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::IFp(const Src &predicateRegister)
1534f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
15354f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1536f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1537f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1538f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1539f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			condition = ~condition;
1540f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1541f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15424f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		IF(condition);
1543f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1544f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15454f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::IFC(Vector4f &src0, Vector4f &src1, Control control)
1546f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1547f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int4 condition;
1548f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1549f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		switch(control)
1550f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1551f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
1552f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x);  break;
1553f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
1554f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x);  break;
1555f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
1556f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x);  break;
1557f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		default:
1558f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			ASSERT(false);
1559f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1560f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15614f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		IF(condition);
1562f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1563f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15644f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::IF(Int4 &condition)
1565f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
15664f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		condition &= enableStack[enableIndex];
1567f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15684f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableIndex++;
15694f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableStack[enableIndex] = condition;
1570f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1571c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *trueBlock = Nucleus::createBasicBlock();
1572c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = Nucleus::createBasicBlock();
1573f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1574f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Bool notAllFalse = SignMask(condition) != 0;
1575f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1576f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		branch(notAllFalse, trueBlock, falseBlock);
1577f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1578f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		isConditionalIf[ifDepth] = true;
1579f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifFalseBlock[ifDepth] = falseBlock;
1580f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1581f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		ifDepth++;
1582f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1583f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1584f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	void PixelProgram::LABEL(int labelIndex)
1585f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1586f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(!labelBlock[labelIndex])
1587f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1588f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1589f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1590f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1591f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(labelBlock[labelIndex]);
1592f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		currentLabel = labelIndex;
1593f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1594f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15954f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::LOOP(const Src &integerRegister)
1596f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
15974f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		loopDepth++;
1598f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
15994f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		iteration[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData, ps.i[integerRegister.index][0]));
16004f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		aL[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData, ps.i[integerRegister.index][1]));
16014f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		increment[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData, ps.i[integerRegister.index][2]));
1602f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16034f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		//	If(increment[loopDepth] == 0)
1604f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		//	{
16054f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		//		increment[loopDepth] = 1;
1606f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		//	}
1607f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1608c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1609c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1610c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1611f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1612f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepTestBlock[loopRepDepth] = testBlock;
1613f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepEndBlock[loopRepDepth] = endBlock;
1614f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1615f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: jump(testBlock)
1616f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(testBlock);
1617f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(testBlock);
1618f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16194f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		branch(iteration[loopDepth] > 0, loopBlock, endBlock);
1620f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(loopBlock);
1621f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16224f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		iteration[loopDepth] = iteration[loopDepth] - 1;   // FIXME: --
1623f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1624f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepDepth++;
1625f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1626f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16274f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::REP(const Src &integerRegister)
1628f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
16294f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		loopDepth++;
1630f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16314f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		iteration[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData, ps.i[integerRegister.index][0]));
16324f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		aL[loopDepth] = aL[loopDepth - 1];
1633f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1634c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1635c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1636c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1637f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1638f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepTestBlock[loopRepDepth] = testBlock;
1639f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepEndBlock[loopRepDepth] = endBlock;
1640f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1641f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: jump(testBlock)
1642f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(testBlock);
1643f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(testBlock);
1644f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16454f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		branch(iteration[loopDepth] > 0, loopBlock, endBlock);
1646f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(loopBlock);
1647f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16484f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		iteration[loopDepth] = iteration[loopDepth] - 1;   // FIXME: --
1649f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1650f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepDepth++;
1651f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1652f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16534f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::WHILE(const Src &temporaryRegister)
1654f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
16554f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableIndex++;
1656f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1657c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1658c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1659c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1660f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1661f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepTestBlock[loopRepDepth] = testBlock;
1662f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepEndBlock[loopRepDepth] = endBlock;
1663f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16644f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 restoreBreak = enableBreak;
16654f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		Int4 restoreContinue = enableContinue;
1666f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1667d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		// TODO: jump(testBlock)
1668f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::createBr(testBlock);
1669f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(testBlock);
16704f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableContinue = restoreContinue;
1671f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1672c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		const Vector4f &src = fetchRegister(temporaryRegister);
1673f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Int4 condition = As<Int4>(src.x);
16744f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		condition &= enableStack[enableIndex - 1];
16752ff2948b730812543a6d0702377084c472e3404dNicolas Capens		if(shader->containsLeaveInstruction()) condition &= enableLeave;
16766d12331ad5a27e85429abf33d54d6576546fff60Nicolas Capens		if(shader->containsBreakInstruction()) condition &= enableBreak;
16774f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableStack[enableIndex] = condition;
1678f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1679f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Bool notAllFalse = SignMask(condition) != 0;
1680f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		branch(notAllFalse, loopBlock, endBlock);
1681f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1682f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(endBlock);
16834f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableBreak = restoreBreak;
1684f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1685f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		Nucleus::setInsertBlock(loopBlock);
1686f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1687f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		loopRepDepth++;
1688f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1689f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
16909aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	void PixelProgram::SWITCH()
16919aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	{
1692c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
16939aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
16949aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepTestBlock[loopRepDepth] = nullptr;
16959aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepEndBlock[loopRepDepth] = endBlock;
16969aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1697d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		Int4 restoreBreak = enableBreak;
1698d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
1699d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		BasicBlock *currentBlock = Nucleus::getInsertBlock();
1700d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
1701d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		Nucleus::setInsertBlock(endBlock);
1702d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		enableBreak = restoreBreak;
1703d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
1704d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		Nucleus::setInsertBlock(currentBlock);
1705d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
17069aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepDepth++;
17079aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	}
17089aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
17094f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::RET()
1710f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
1711f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		if(currentLabel == -1)
1712f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1713f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			returnBlock = Nucleus::createBasicBlock();
1714f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Nucleus::createBr(returnBlock);
1715f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1716f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		else
1717f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		{
1718c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens			BasicBlock *unreachableBlock = Nucleus::createBasicBlock();
1719f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1720f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			if(callRetBlock[currentLabel].size() > 1)   // Pop the return destination from the call stack
1721f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
1722f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				// FIXME: Encapsulate
17234f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens				UInt index = callStack[--stackIndex];
1724f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
17251933654b62251805d4575b05b6829275b0fe6142Nicolas Capens				Value *value = index.loadValue();
1726b98fe5cd1eaa821083d816cf86a20eefe22f57c7Nicolas Capens				SwitchCases *switchCases = Nucleus::createSwitch(value, unreachableBlock, (int)callRetBlock[currentLabel].size());
1727f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1728f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				for(unsigned int i = 0; i < callRetBlock[currentLabel].size(); i++)
1729f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				{
1730b98fe5cd1eaa821083d816cf86a20eefe22f57c7Nicolas Capens					Nucleus::addSwitchCase(switchCases, i, callRetBlock[currentLabel][i]);
1731f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				}
1732f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
1733f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			else if(callRetBlock[currentLabel].size() == 1)   // Jump directly to the unique return destination
1734f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
1735f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				Nucleus::createBr(callRetBlock[currentLabel][0]);
1736f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
1737f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			else   // Function isn't called
1738f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			{
1739f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu				Nucleus::createBr(unreachableBlock);
1740f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			}
1741f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1742f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Nucleus::setInsertBlock(unreachableBlock);
1743f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu			Nucleus::createUnreachable();
1744f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		}
1745f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
1746f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
17474f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens	void PixelProgram::LEAVE()
1748f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	{
17494f172c78cfca2c1f2b989ffa7cef1dc31586d8fcNicolas Capens		enableLeave = enableLeave & ~enableStack[enableIndex];
1750f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu
1751f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: Return from function if all instances left
1752f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu		// FIXME: Use enableLeave in other control-flow constructs
1753f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu	}
17545d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens}
1755